1.集群与节点信息
查看集群信息
[root@master ~]# kubectl cluster-info
Kubernetes control plane is running at https://172.20.251.148:6443
CoreDNS is running at https://172.20.251.148:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
查看节点信息
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master.novalocal Ready control-plane,master 43m v1.23.6
node1 Ready <none> 10m v1.23.6
node2 Ready <none> 9m50s v1.23.6
查看节点详细信息
[root@master ~]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master.novalocal Ready control-plane,master 44m v1.23.6 172.20.251.148 <none> CentOS Linux 8 (Core) 4.18.0-193.6.3.el8_2.x86_64 docker://20.10.14
node1 Ready <none> 11m v1.23.6 172.20.251.123 <none> CentOS Linux 8 (Core) 4.18.0-193.6.3.el8_2.x86_64 docker://20.10.14
node2 Ready <none> 10m v1.23.6 172.20.251.120 <none> CentOS Linux 8 (Core) 4.18.0-193.6.3.el8_2.x86_64 docker://20.10.14
描述节点详细信息
[root@master ~]# kubectl describe node master
...
node节点管理集群
[root@node1 ~]# kubectl get pods
The connection to the server localhost:8080 was refused - did you specify the right host or port?
# node节点查询报错
[root@node1 ~]# mkdir /root/.kube
# 在node节点root用户家目录创建.kube文件夹
[root@node1 ~]# scp master:/etc/kubernetes/admin.conf /root/.kube/config
The authenticity of host 'master (172.20.251.148)' can't be established.
ECDSA key fingerprint is SHA256:y4GFkbzewn4PujQNgjHnRTd63vTDo7NsAy0jEBZa3o8.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'master' (ECDSA) to the list of known hosts.
admin.conf
# 复制master节点配置文件
[root@node1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master.novalocal Ready control-plane,master 47m v1.23.6
node1 Ready <none> 14m v1.23.6
node2 Ready <none> 14m v1.23.6
# 验证结果
节点标签
[root@master ~]# kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
master.novalocal Ready control-plane,master 48m v1.23.6 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master.novalocal,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
node1 Ready <none> 15m v1.23.6 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node1,kubernetes.io/os=linux
node2 Ready <none> 15m v1.23.6 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node2,kubernetes.io/os=linux
# 查看节点标签信息
[root@master ~]# kubectl label node node1 node-role.kubernetes.io/node=
node/node1 labeled
[root@master ~]# kubectl label node node2 node-role.kubernetes.io/node=
node/node2 labeled
# 设置节点标签信息
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master.novalocal Ready control-plane,master 50m v1.23.6
node1 Ready node 17m v1.23.6
node2 Ready node 17m v1.23.6
# 验证结果
多维度标签
[root@master ~]# kubectl label node node1 zone=A business=game --overwrite
node/node1 labeled
[root@master ~]# kubectl label node node2 zone=B business=game --overwrite
node/node2 labeled
[root@master ~]# kubectl get nodes --show-labels
# 验证
[root@master ~]# kubectl get nodes -L zone
NAME STATUS ROLES AGE VERSION ZONE
master.novalocal Ready control-plane,master 53m v1.23.6
node1 Ready node 20m v1.23.6 A
node2 Ready node 20m v1.23.6 B
# 显示节点相对应的标签
[root@master ~]# kubectl label node node1 zone-
node/node1 unlabeled
# 取消标签信息
标签选择器
[root@master ~]# kubectl get node -l "zone in (A,B)"
NAME STATUS ROLES AGE VERSION
node1 Ready node 22m v1.23.6
node2 Ready node 22m v1.23.6
2.Namespace
在 Kubernetes 中,“名字空间(Namespace)”提供一种机制,将同一集群中的资源划分为相互隔离的组。 同一名字空间内的资源名称要唯一,但跨名字空间时没有这个要求。 名字空间作用域仅针对带有名字空间的对象,例如 Deployment、Service 等, 这种作用域对集群访问的对象不适用,例如 StorageClass、Node、PersistentVolume 等。
对于同一种资源的不通版本,就可以直接使用label来划分即可,不需要使用namespace来区分
查看namespace信息
[root@master ~]# kubectl get namespace
NAME STATUS AGE
default Active 160m
# pod未指定的情况下分配到default
kube-node-lease Active 160m
# 节点资源
kube-public Active 160m
# 此命名空间下的资源可以被所有人访问
kube-system Active 160m
# 所有有kubernetes系统创建的资源都处于这个命名空间
# namespace可以简写成ns
创建namespace
[root@master ~]# kubectl create namespace test1
namespace/test1 created
# 命令创建
[root@master ~]# kubectl edit namespace test1
# 可以通过edit修改namespace的yaml文件
[root@master ~]# kubectl get namespace test1 -o yaml
# 只查询使用这种方法
[root@master ~]# vim create_namespace.yml
apiVersion: v1
kind: Namespace
metadata:
name: test2
保存退出
[root@master ~]# kubectl apply -f create_namespace.yml
namespace/test2 created
# 通过yaml文件创建
[root@master ~]# kubectl get namespace
NAME STATUS AGE
default Active 165m
kube-node-lease Active 166m
kube-public Active 166m
kube-system Active 166m
test1 Active 3m22s
test2 Active 20s
# 验证
删除namespace
注意:删除一个namespace会自动删除所有属于该namespace的资源
[root@master ~]# kubectl delete namespace test1
namespace "test1" deleted
# 命令删除
[root@master ~]# kubectl delete -f create_namespace.yml
namespace "test2" deleted
# yaml文件删除
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 168m
kube-node-lease Active 168m
kube-public Active 168m
kube-system Active 168m
验证
3.工作负载(workloads)
工作负载是在 Kubernetes 上运行的应用程序。
无论你的负载是单一组件还是由多个一同工作的组件构成,在 Kubernetes 中你 可以在一组 Pods 中运行它。在 Kubernetes 中,Pod 代表的是集群上处于运行状态的一组 容器。
Kubernetes Pods 有确定的生命周期。 例如,当某 Pod 在你的集群中运行时,Pod 运行所在的 节点 出现致命错误时, 所有该节点上的 Pods 都会失败。Kubernetes 将这类失败视为最终状态: 即使该节点后来恢复正常运行,你也需要创建新的 Pod 来恢复应用。
不过,为了让用户的日子略微好过一些,你并不需要直接管理每个 Pod。 相反,你可以使用 负载资源 来替你管理一组 Pods。 这些资源配置 控制器 来确保合适类型的、处于运行状态的 Pod 个数是正确的,与你所指定的状态相一致。
workloads分为pod与controllers
pod通过控制器实现应用的运行,如何伸缩,升级等
controllers 在集群中管理pod
pod与控制器之间通过label-selector相关联,是唯一的关联方式
比如:
labels:
app: nginx
# 在pod的yaml里指定
labels:
app: nginx
# 在控制器的yaml里指定
4.Pod
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
Pod (就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器, 这些容器是相对紧密的耦合在一起的。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于 在同一逻辑主机上运行的云应用。
除了应用容器,Pod 还可以包含在 Pod 启动期间运行的 Init 容器。 你也可以在集群中支持临时性容器 的情况下,为调试的目的注入临时性容器。
就 Docker 概念的术语而言,Pod 类似于共享名字空间和文件系统卷的一组 Docker 容器。
Pod分类
无控制器管理的自主式pod 没有副本控制器控制,删除自主式pod后
不会重新创建
控制器管理的pod 控制器会按照定义的策略控制pod的数量,发现
pod数量少了,会立即自动建立出来新的pod;一旦发现pod多了,也
会自动杀死多余的Pod。
YAML格式查找帮助方法(需掌握)
[root@master ~]# kubectl api-versions
# 查看api版本
[root@master ~]# kubectl explain pod
KIND: Pod
VERSION: v1
...
# 查看资源写法,VERSION即yaml文件中的apiVersion
[root@master ~]# kubectl explain pod.spec
# 查看下级资源写法
创建一个自主式Pod
[root@master ~]# vim pod1.yml
apiVersion: v1
# api版本号
kind: Pod
# 资源类型
metadata:
name: nginx-test1
# Pod名称
spec:
containers:
- name: test
# 容器名称
image: nginx:latest
# 容器镜像
# 生产环境不建议使用latest,刚使用还好,使用久了就没分不清是哪个版本,也不好更新
imagePullPolicy: IfNotPresent
# 容器拉取策略
# 默认为always,即总是下载,IfNotPresent表示优先使用本地镜像,否则下载,Nerver表示仅使用本地镜像
ports:
- name: nginx-port
# 端口号名称
containerPort: 80
# 容器需要监听的端口号
保存退出
[root@master ~]# kubectl apply -f pod1.yml
pod/nginx-test1 created
# 应用yaml文件创建
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-test1 1/1 Running 0 62s 10.3.2.2 node2 <none> <none>
# 查询pod详细信息
[root@master ~]# curl 10.3.2.2
# 验证
[root@master ~]# kubectl describe pod nginx-test1
# 描述pod详细信息
Pod标签
为pod设置lebel,用于控制器通过label与pod关联
[root@master ~]# kubectl label pod nginx-test1 zone=A
pod/nginx-test1 labeled
# 为nginx-test1打上zone=A的标签
[root@master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-test1 1/1 Running 0 7m34s zone=A
# 查看pod标签
[root@master ~]# kubectl get pods -l zone=A
NAME READY STATUS RESTARTS AGE
nginx-test1 1/1 Running 0 8m30s
# 通过标签查询pod
[root@master ~]# kubectl get pods -l "zone in (A,B)"
NAME READY STATUS RESTARTS AGE
nginx-test1 1/1 Running 0 9m1s
# 通过集合查询
[root@master ~]# kubectl label pod nginx-test1 zone-
pod/nginx-test1 unlabeled
# 删除标签
[root@master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-test1 1/1 Running 0 9m54s <none>
# 验证
pod的label与node的label操作方式几乎相同
node的label用于pod调度到指定label的node节点
pod的label用于controller关联控制的pod
删除Pod
[root@master ~]# kubectl delete pod nginx-test1
pod "nginx-test1" deleted
# 也可以通过yaml文件删除,加上-f参数
Pod资源限制
[root@node1 ~]# kubectl explain pod.spec.containers.resources
# 查看资源写法
[root@master ~]# vim pod1.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx-test1
spec:
containers:
- name: test
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
resources:
limits:
memory: "100Mi"
# 最大内存限制为100M
requests:
memory: "50Mi"
# 最小内存限制为50M
Pod重启策略(重要)
Always:表示容器挂了总是重启,这是默认策略
OnFailures:表容器状态为错误时才重启,也就是容器正常终止时才重
启
Never:表示容器挂了不予重启
对于Always这种策略,容器只要挂了,就会立即重启,这样是很耗费
资源的。所以Always重启策略是这么做的:第一次容器挂了立即重
启,如果再挂了就要延时10s重启,第三次挂了就等20s重启… 依次
类推
一个Pod包含多个容器
[root@master ~]# vim pod2.yml
apiVersion: v1
kind: Pod
metadata:
name: busybox-test1
spec:
containers:
- name: test1
image: busybox:latest
imagePullPolicy: IfNotPresent
command:
- sleep
- "3600"
- name: test2
# 注意容器名不要重复
image: busybox:latest
imagePullPolicy: IfNotPresent
command:
- sleep
- "3600"
保存退出
[root@master ~]# kubectl apply -f pod2.yml
pod/nginx-test1 created
# 应用yaml文件创建pod
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
busybox-test1 2/2 Running 1 (4s ago) 11s
# 验证
不交互直接执行命令
[root@master ~]# kubectl exec -it busybox-test1 -c test1 -- touch /111
# -c容器名为可选项,如果一个pod中只有一个容器,可以不用指定
和容器交互操作
[root@master ~]# kubectl exec -it busybox-test1 -c test1 -- /bin/sh
# 和docker exec几乎一致,只是多了--和指定容器
/ # ls
111 bin dev etc home proc root sys tmp usr var
删除pod
[root@master ~]# kubectl delete pod busybox-test1
pod "busybox-test1" deleted
Pod调度(重要)
我们为了实现容器主机资源平衡使用, 可以使用约束把pod调度到指定的
node节点
nodeName 用于将pod调度到指定的node名称上
nodeSelector 用于将pod调度到匹配Label的node上
[root@master ~]# vim pod1.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx-test1
spec:
nodeName: node1
# 通过nodeName调度到node1节点
containers:
- name: test1
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
保存退出
[root@master ~]# kubectl apply -f pod1.yml
pod/nginx-test1 created
# 应用yaml文件创建pod
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-test1 1/1 Running 0 74s 10.3.1.4 node1 <none> <none>
# 验证
[root@master ~]# kubectl delete pod nginx-test1
pod "nginx-test1" deleted
# 删除pod
[root@master ~]# kubectl label node node1 zone=A --overwrite
node/node1 not labeled
# 给node1节点打标签
[root@master ~]# vim pod1.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx-test1
spec:
nodeSelector:
# nodeSelector节点选择器
zone: A
# 指定调度到标签为zone=A的节点
containers:
- name: test1
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
保存退出
[root@master ~]# kubectl apply -f pod1.yml
pod/nginx-test1 created
# 应用yaml文件创建pod
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-test1 1/1 Running 0 5s 10.3.1.5 node1 <none> <none>
# 验证
[root@master ~]# kubectl delete pod nginx-test1
pod "nginx-test1" deleted
# 删除pod
5.Pod的生命周期
有些pod(比如跑nginx服务),正常情况下会一直运行中,但如果手动删除
它,此pod会终止
也有些pod(比如执行计算任务),任务计算完后就会自动终止
上面两种场景中,pod从创建到终止的过程就是pod的生命周期。
Pod阶段
Pod 的 status 字段是一个 PodStatus 对象,其中包含一个 phase 字段。
Pod 的阶段(Phase)是 Pod 在其生命周期中所处位置的简单宏观概述。 该阶段并不是对容器或 Pod 状态的综合汇总,也不是为了成为完整的状态机。
取值 | 描述 |
---|---|
Pending(悬决) | Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。 |
Running(运行中) | Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。 |
Succeeded(成功) | Pod 中的所有容器都已成功终止,并且不会再重启。 |
Failed(失败) | Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。 |
Unknown(未知) | 因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。 |
如果某节点死掉或者与集群中其他节点失联,Kubernetes 会实施一种策略,将失去的节点上运行的所有 Pod 的 phase 设置为 Failed。
容器启动
- pod中的容器在创建前,有初始化容器(init container)来进行初始化环境
- 初化完后,主容器(main container)开始启动
- 主容器启动后,有一个post start的操作(启动后的触发型操作,或者叫启
动后钩子) - post start后,就开始做健康检查
第一个健康检查叫存活状态检查(liveness probe ),用来检查主容
器存活状态的
第二个健康检查叫准备就绪检查(readyness probe),用来检查主容
器是否启动就绪
容器终止
- 可以在容器终止前设置pre stop操作(终止前的触发型操作,或者叫终止
前钩子) - 当出现特殊情况不能正常销毁pod时,大概等待30秒会强制终止
- 终止容器后还可能会重启容器(视容器重启策略而定)。
HealthCheck健康检查
方式 | 说明 |
---|---|
LivenessProbe(存活状态探测) | 检查后不健康,重启pod |
readinessProbe(就绪型探测) | 检查后不健康,将容器设置为Notready;如果使用service来访问,流量不会转发给此种状态的pod |
Probe探测方式
方式 | 说明 |
---|---|
Exec | 执行命令 |
HTTPGet | http请求某一个URL路径 |
TCP | tcp连接某一个端口 |
liveness-exec
[root@node1 ~]# kubectl explain pod.spec.containers.livenessProbe
# 查询资源写法
[root@master ~]# vim pod-liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec
spec:
containers:
- name: liveness
image: busybox:latest
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
# pod启动延迟5秒后探测
periodSeconds: 5
# 每5秒探测一次
保存退出
[root@master ~]# kubectl apply -f pod-liveness-exec.yaml
pod/liveness-exec created
# 应用yaml文件创建pod
[root@master ~]# kubectl describe pod liveness-exec
...
# 验证
[root@master ~]# kubectl delete pod liveness-exec
pod "liveness-exec" deleted
# 删除pod
liveness-httpget
[root@master ~]# vim pod-liveness-httpget.yml
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget
spec:
containers:
- name: test1
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: nginx
containerPort: 80
livenessProbe:
httpGet:
port: nginx
# 指定端口名,也可以直接写80端口
path: /index.html
initialDelaySeconds: 3
# 延迟3秒开始探测
periodSeconds: 5
# 每隔5秒探测一次
保存退出
[root@master ~]# kubectl apply -f pod-liveness-httpget.yml
pod/liveness-httpget created
# 应用yaml文件创建pod
[root@master ~]# kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
# 非交互式删除nginx主页文件
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
liveness-httpget 1/1 Running 1 (5s ago) 2m46s
# 注意5秒前已经RESTART过一次
[root@master ~]# kubectl delete pod liveness-httpget
pod "liveness-httpget" deleted
# 删除pod
liveness-tcp
[root@master ~]# vim pod-liveness-tcp.yml
apiVersion: v1
kind: Pod
metadata:
name: liveness-tcp
spec:
containers:
- name: test1
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: nginx
containerPort: 80
livenessProbe:
tcpSocket:
port: 80
# 连接80端口进行探测
initialDelaySeconds: 3
periodSeconds: 5
保存退出
[root@master ~]# kubectl apply -f pod-liveness-tcp.yml
pod/liveness-httpget created
# 应用yaml文件创建pod
[root@master ~]# kubectl exec -it liveness-tcp -- /usr/sbin/nginx -s stop
2022/04/25 07:08:22 [notice] 36#36: signal process started
# 关闭nginx
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
liveness-tcp 1/1 Running 1 (26s ago) 41s
# 验证
[root@master ~]# kubectl delete pod liveness-tcp
pod "liveness-tcp" deleted
# 删除pod
readiness
[root@master ~]# vim pod-readiness-httpet.yml
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget
spec:
containers:
- name: test1
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: nginx
containerPort: 80
readinessProbe:
# 替换为readinessProbe
httpGet:
port: nginx
path: /index.html
initialDelaySeconds: 3
periodSeconds: 5
保存退出
[root@master ~]# kubectl apply -f pod-readiness-httpet.yml
pod/readiness-httpget created
# 应用yaml文件创建pod
[root@master ~]# kubectl exec -it readiness-httpget -- rm -rf /usr/share/nginx/html/index.html
# 删除nginx主页
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
readiness-httpget 0/1 Running 0 76s
# 验证
[root@master ~]# kubectl exec -it readiness-httpget -- touch /usr/share/nginx/html/index.html
# 创建nginx主页
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
readiness-httpget 1/1 Running 0 2m16s
# 验证
readiness+liveness综合
[root@master ~]# vim pod-readiness-liveness-httpget.yml
apiVersion: v1
kind: Pod
metadata:
name: readiness-liveness-httpget
spec:
containers:
- name: test1
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: nginx
containerPort: 80
livenessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
readinessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 5
periodSeconds: 5
保存退出
[root@master ~]# kubectl apply -f pod-readiness-liveness-httpget.yml
pod/readiness-liveness-httpget created
# 应用yaml文件创建pod
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
readiness-httpget 1/1 Running 0 75m
readiness-liveness-httpget 0/1 Running 0 35s
# 验证
[root@master ~]# kubectl delete pod readiness-httpget
pod "readiness-httpget" deleted
[root@master ~]# kubectl delete pod readiness-liveness-httpget
pod "readiness-liveness-httpget" deleted
# 删除pod
post-start
[root@master ~]# vim pod-poststart.yml
apiVersion: v1
kind: Pod
metadata:
name: poststart
spec:
containers:
- name: test1
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: nginx
containerPort: 80
lifecycle:
# 生命周期事件
postStart:
exec:
command: ["touch", "/usr/share/nginx/html/test1"]
保存退出
[root@master ~]# kubectl apply -f pod-poststart.yml
pod/poststart created
# 应用yaml文件创建pod
[root@master ~]# kubectl exec -it poststart -- ls /usr/share/nginx/html
50x.html index.html test1
# 验证
pre-stop
[root@master ~]# vim pod-prestop.yml
apiVersion: v1
kind: Pod
metadata:
name: prestop
spec:
containers:
- name: test1
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: nginx
containerPort: 80
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 60000"]
# 容器终止前sleep 60000秒
保存退出
[root@master ~]# kubectl apply -f pod-prestop.yml
pod/prestop created
# 应用yaml文件创建pod
[root@master ~]# kubectl delete pod prestop
pod "prestop" deleted
# 验证,删除需要很久
注意: 当出现特殊情况不能正常销毁pod时,大概等待30秒会强制终止
6.Pod控制器
controller用于控制pod
控制器主要分为:
ReplicationController(相当于ReplicaSet的老版本,现在建议使用
Deployments加ReplicaSet替代RC)
ReplicaSet 副本集,控制pod扩容,裁减
Deployments 控制pod升级,回退
StatefulSets 部署有状态的pod应用
DaemonSet 运行在所有集群节点(包括master), 比如使用
filebeat,node_exporter
Jobs 一次性
Cronjob 周期性
Deployment&ReplicaSet
Replicaset控制器的功能:
支持新的基于集合的selector(以前的rc里没有这种功能)
通过改变Pod副本数量实现Pod的扩容和缩容
Deployment控制器的功能:
Deployment集成了上线部署、滚动升级、创建副本、回滚等功能
Deployment里包含并使用了ReplicaSet
Deployment用于部署无状态应用
无状态应用的特点:
所有pod无差别
所有pod中容器运行同一个image
所有pod可以运行在集群中任意node上
所有pod无启动顺序先后之分
随意pod数量扩容或缩容
例如简单运行一个静态web程序
创建deployment
[root@master ~]# kubectl create deployment nginx1 --image=nginx:latest --port=80 --replicas=1
# --replicas=1意为副本数为1
deployment.apps/nginx1 created
# 命令创建deployment
[root@master ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx1 1/1 1 1 4m11s
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx1-568c8cbc8c-7hsr4 1/1 Running 0 151m 10.3.1.9 node1 <none> <none>
# 验证
[root@master ~]# kubectl explain deployment
# 查询资源写法
[root@master ~]# vim nginx2-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx2
# deployment名
spec:
replicas: 1
# 副本集,deployment里使用了replicaset
selector:
matchLabels:
app: nginx
# 匹配的pod标签,表示deployment和rs控制器控制带有此标签的pod
template:
# 代表pod的配置模板
metadata:
labels:
app: nginx
# pod的标签
spec:
containers:
# 以下为pod里的容器定义
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
保存退出
[root@master ~]# kubectl apply -f nginx2-deployment.yml
deployment.apps/nginx2 created
# 应用yaml文件创建deployment
[root@master ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx1 1/1 1 1 173m
nginx2 1/1 1 1 2m28s
# 验证
[root@master ~]# kubectl delete deployment nginx2
deployment.apps "nginx2" deleted
# 删除deployment,里面的pod也会被自动删除
访问deployment
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx1-568c8cbc8c-7hsr4 1/1 Running 0 175m 10.3.1.9 node1 <none> <none>
# 查看pod的ip地址
[root@master ~]# curl 10.3.1.9
# 验证
[root@node1 ~]# curl 10.3.1.9
# 任一集群内节点皆可访问,集群外机器不行
删除deployment中的pod
[root@master ~]# kubectl delete pod nginx1-568c8cbc8c-7hsr4
pod "nginx1-568c8cbc8c-7hsr4" deleted
# 删除deployment中的pod
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx1-568c8cbc8c-nm6m7 1/1 Running 0 2m58s
# 可以看到,即使删除还是会重新启动一个新的pod,但是更改了IP,因此IP不是固定的
# 比如把整个集群关闭再启动,pod也会自动启动,但是IP地址还是变化了
既然IP地址不是固定的,所以需要一个固定的访问endpoint给用户,那么这种方式就是service
Pod版本升级
[root@master ~]# kubectl set image -h
# 查看帮助
[root@master ~]# kubectl describe pod nginx1-568c8cbc8c-nm6m7 |grep Image
Image: nginx:latest
Image ID: docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
# 验证nginx版本
[root@master ~]# kubectl set image deployment nginx1 nginx=nginx:1.16 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/nginx1 image updated
# deployment nginx1代表名为nginx1的deployment
# nginx=nginx:1.16,nginx为容器名
# --record表示会记录,不建议使用此参数,因为将在未来移除,暂时没有替代方案
[root@master ~]# kubectl get deployment nginx1 -o yaml
# 查看容器名
[root@master ~]# kubectl rollout status deployment nginx1
deployment "nginx1" successfully rolled out
[root@master ~]# kubectl exec -it nginx1-78f4ffd896-xbfnh -- nginx -v
nginx version: nginx/1.16.1
# 验证
Pod版本回退
[root@master ~]# kubectl rollout history deployment nginx1
deployment.apps/nginx1
REVISION CHANGE-CAUSE
1 kubectl set image deployment nginx1 nginx1=nginx:1.16 --record=true
2 kubectl set image deployment nginx1 nginx=nginx:1.16 --record=true
# 查看版本历史信息[root@master ~]# kubectl rollout history deployment nginx1 --revision=1
deployment.apps/nginx1 with revision #1
Pod Template:
Labels: app=nginx1
pod-template-hash=568c8cbc8c
Annotations: kubernetes.io/change-cause: kubectl set image deployment nginx1 nginx1=nginx:1.16 --record=true
Containers:
nginx:
Image: nginx:latest
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
# 定义要回退的版本(还需要执行才是真的回退版本)
[root@master ~]# kubectl rollout undo deployment nginx1 --to-revision=1
deployment.apps/nginx1 rolled back
# 执行回退
[root@master ~]# kubectl exec -it nginx1-568c8cbc8c-d6q2b -- nginx -v
nginx version: nginx/1.21.5
# 验证
副本扩容
[root@master ~]# kubectl scale -h
# 查看帮助
[root@master ~]# kubectl scale deployment nginx1 --replicas=2
deployment.apps/nginx1 scaled
# 定义nginx1副本数为2
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx1-568c8cbc8c-d6q2b 1/1 Running 0 3m22s 10.3.2.16 node2 <none> <none>
nginx1-568c8cbc8c-fmgct 1/1 Running 0 27s 10.3.1.11 node1 <none> <none>
# 验证
[root@master ~]# kubectl scale deployment nginx1 --replicas=1
deployment.apps/nginx1 scaled
# 副本裁剪
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx1-568c8cbc8c-d6q2b 1/1 Running 0 4m21s 10.3.2.16 node2 <none> <none>
# 验证
多副本滚动更新
[root@master ~]# kubectl scale deployment nginx1 --replicas=16
deployment.apps/nginx1 scaled
# 扩容为16个副本
[root@master ~]# kubectl get pods
# 验证
[root@master ~]# kubectl set image deployment nginx1 nginx=nginx1.16 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/nginx1 image updated
# 滚动更新
[root@master ~]# kubectl rollout status deployment nginx1
Waiting for deployment "nginx1" rollout to finish: 8 out of 16 new replicas have been updated...
# 验证
YAML单独创建replicaset
[root@node1 ~]# kubectl explain replicaset
# 查询资源写法
[root@master ~]# vim replicaset.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-rs
spec:
# replicaset的spec
replicas: 2
# 副本数
selector:
# 标签选择器,对应pod的标签
matchLabels:
app: nginx
# 匹配的label
template:
metadata:
name: nginx
# pod名
labels:
# 对应上面定义的标签选择器selector里面的内容
app: nginx
spec:
# pod的spec
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
保存退出
[root@master ~]# kubectl apply -f replicaset.yml
replicaset.apps/nginx-rs created
[root@master ~]# kubectl get replicaset
NAME DESIRED CURRENT READY AGE
nginx-rs 2 2 2 2m11s
nginx1-568c8cbc8c 1 1 1 3h37m
nginx1-774b7d5bd6 1 1 0 14m
nginx1-78f4ffd896 0 0 0 31m
[root@master ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx1 1/1 1 1 3h42m
# 找不到deployment,说明创建replicaset并没有创建deployment
7.Pod控制器进阶
DaemonSet:
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
DaemonSet 的一些典型用法:
在每个节点上运行集群守护进程
在每个节点上运行日志收集守护进程
在每个节点上运行监控守护进程
一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。 一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。
[root@node1 ~]# kubectl explain daemonset
# 查询资源写法
[root@master ~]# vim nginx-daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-daemonset
spec:
selector:
matchLabels:
name: nginx-test
template:
metadata:
labels:
name: nginx-test
spec:
tolerations:
# 代表容忍
- key: node-role.kubernetes.io/master
# 能容忍的污点key
effect: NoSchedule
# 能容忍的污点effect
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
保存退出
[root@master ~]# kubectl apply -f nginx-daemonset.yml
daemonset.apps/nginx-daemonset created
# 应用yaml文件创建daemonset
[root@master ~]# kubectl get daemonset
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
nginx-daemonset 3 3 3 3 3 <none> 3m16s
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-daemonset-7t5zh 1/1 Running 0 3m59s 10.3.0.2 master.novalocal <none> <none>
nginx-daemonset-jhfpd 1/1 Running 0 3m59s 10.3.2.33 node2 <none> <none>
nginx-daemonset-kwj8h 1/1 Running 0 3m59s 10.3.1.27 node1 <none> <none>
# 验证
[root@master ~]# kubectl delete daemonset nginx-daemonset
daemonset.apps "nginx-daemonset" deleted
# 删除daemonset
Job
Job 会创建一个或者多个 Pods,并将继续重试 Pods 的执行,直到指定数量的 Pods 成功终止。 随着 Pods 成功结束,Job 跟踪记录成功完成的 Pods 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pods。 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行。
一种简单的使用场景下,你会创建一个 Job 对象以便以一种可靠的方式运行某 Pod 直到完成。 当第一个 Pod 失败或者被删除(比如因为节点硬件失效或者重启)时,Job 对象会启动一个新的 Pod。
你也可以使用 Job 以并行的方式运行多个 Pod。
[root@node1 ~]# kubectl explain job
# 查询资源写法
[root@master ~]# vim job.yml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
# job名
spec:
template:
metadata:
name: pi
# pod名
spec:
containers:
- name: pi
# 容器名
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
imagePullPolicy: IfNotPresent
restartPolicy: Never
# 执行完后不重启
# 计算圆周率2000位的小案例
[root@master ~]# kubectl get jobs
NAME COMPLETIONS DURATION AGE
pi 1/1 2m21s 9m20s
[root@master ~]# kubectl logs pi-pznvw
3.14159265358979323...
# 验证
[root@master ~]# vim job2.yml
apiVersion: batch/v1
kind: Job
metadata:
name: busybox-job
spec:
completions: 10
# 执行job的次数
parallelism: 1
# 执行job的并发数
template:
metadata:
name: busybox-job-pod
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command: ["echo", "test"]
restartPolicy: Never
保存退出
# 创建固定次数job小案例
[root@master ~]# kubectl apply -f job2.yml
job.batch/busybox-job created
# 应用yaml文件创建job
[root@master ~]# kubectl get job
NAME COMPLETIONS DURATION AGE
busybox-job 3/10 34s 34s
# 验证
CronJob
CronJob 创建基于时隔重复调度的 Jobs。
一个 CronJob 对象就像 crontab (cron table) 文件中的一行。 它用 Cron 格式进行编写, 并周期性地在给定的调度时间执行 Job。
[root@node1 ~]# kubectl explain cronjob
# 查询资源写法
[root@master ~]# vim cronjob.yml
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "* * * * *"
# 同linux定时任务写法一致
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
imagePullPolicy: IfNotPresent
restartPolicy: OnFailure
保存退出
[root@master ~]# kubectl apply -f cronjob.yml
cronjob.batch/hello created
# 应用yaml文件创建cronjob
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-27514895-plsfx 0/1 Completed 0 98s
hello-27514896-rhxwf 0/1 Completed 0 38s
# 验证,每分钟整点执行一次
8.Service
将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
使用 Kubernetes,你无需修改应用程序即可使用不熟悉的服务发现机制。 Kubernetes 为 Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名, 并且可以在它们之间进行负载均衡。
Service作用:
通过service为pod客户端提供访问pod方法,即可客户端访问pod入口
通过标签动态感知pod IP地址变化等
防止pod失联
定义访问pod访问策略
通过label-selector相关联
通过Service实现Pod的负载均衡(TCP/UDP 4层)
底层实现主要通过iptables和IPVS二种网络模式
Service底层实现原理:
底层流量转发与负载均衡实现均可以通过iptables或ipvs实现
对比:
- Iptables:
灵活,功能强大(可以在数据包不同阶段对包进行操作)
规则遍历匹配和更新,呈线性时延 - IPVS:
工作在内核态,有更好的性能
调度算法丰富:rr,wrr,lc,wlc,ip hash
Service类型
Service类型分为:
- ClusterIP
默认,分配一个集群内部可以访问的虚拟IP - NodePort
在每个Node上分配一个端口作为外部访问入口 - LoadBalancer
工作在特定的Cloud Provider上,例如Google Cloud,AWS,OpenStack - ExternalName
表示把集群外部的服务引入到集群内部中来,即实现了集群内部pod和集群外部的服务进行通信
ClusterIP类型
ClusterIP根据是否生成ClusterIP又可分为普通Service和Headless Service
两类:
- 普通Service:
为Kubernetes的Service分配一个集群内部可访问的固定虚拟
IP(Cluster IP), 实现集群内的访问。 - Headless Service:
该服务不会分配Cluster IP, 也不通过kube-proxy做反向代理和负载均
衡。而是通过DNS提供稳定的网络ID来访问,DNS会将headless
service的后端直接解析为podIP列表。
CluserIP
[root@master ~]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.2.0.1 <none> 443/TCP 11h
# 默认只有kubernetes本身自己的services
[root@master ~]# kubectl expose deployment nginx1 --port=80 --target-port=80 --protocol=TCP
service/nginx1 exposed
# 命令创建,nginx1的deployment映射端口
# 默认是--type=ClusterIP,也可以使用--type="NodePort"
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.2.0.1 <none> 443/TCP 11h
nginx1 ClusterIP 10.2.141.14 <none> 80/TCP 78s
[root@master ~]# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 172.20.251.148:6443 11h
nginx1 10.3.1.32:80 99s
[root@master ~]# curl 10.2.141.14
# 验证
# 集群内部任一节点皆可访问,集群外机器无法访问
[root@node1 ~]# kubectl explain service
# 查询资源写法
[root@master ~]# vim nginx_service.yml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
clusterIP: 10.2.1.2
# 这个IP可以不知道,让它自动分配,需要与集群分配的网络对应
type: ClusterIP
# ClusterIP类型,也可以不指定,默认为ClusterIP
ports:
# 指定service,端口及容器端口
- port: 80
# service ip中的端口
protocol: TCP
targetPort: 80
# pod中的端口
selector:
# 指定后端pod标签(不是deployment的标签)
app: nginx
# 可使用命令kubectl get pod -l app=nginx查询
保存退出
[root@master ~]# kubectl apply -f nginx_service.yml
service/my-service created
# 应用yaml文件创建service
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.2.0.1 <none> 443/TCP 11h
my-service ClusterIP 10.2.1.2 <none> 80/TCP 2m37s
nginx1 ClusterIP 10.2.141.14 <none> 80/TCP 16m
[root@master ~]# kubectl get pod -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx2-66857ff745-d8hfg 1/1 Running 0 57s
nginx2-66857ff745-vbbk4 1/1 Running 0 57s
[root@master ~]# curl 10.2.1.2
...
# 验证
[root@master ~]# kubectl exec -it nginx2-66857ff745-d8hfg -- /bin/bash
root@nginx2-66857ff745-d8hfg:/# echo web1> /usr/share/nginx/html/index.html
root@nginx2-66857ff745-d8hfg:/# exit
exit
[root@master ~]# kubectl exec -it nginx2-66857ff745-d8hfg -- /bin/bash
root@nginx2-66857ff745-d8hfg:/# echo web2> /usr/share/nginx/html/index.html
root@nginx2-66857ff745-d8hfg:/# exit
exit
# 两个pod做成不同主页测试负载均衡
[root@master ~]# curl 10.2.1.2
web2
# 多次访问测试负载均衡,但是算法紊乱
sessionAffinity
[root@master ~]# kubectl patch svc my-service -p '{"spec": {"sessionAffinity":"ClientIP"}}'
service/my-service patched
# 设置sessionAffinity为Clientip (类似nginx的ip_hash算法,lvs的source hash算法)
[root@master ~]# curl 10.2.1.2
web1
# 多次访问,会话粘贴
[root@master ~]# kubectl patch svc my-service -p '{"spec": {"sessionAffinity":"None"}}'
service/my-service patched
# 设置回sessionAffinity为None
[root@master ~]# curl 10.2.1.2
web2
# 测试多次访问,负载均衡
修改为ipvs调度方式
[root@master ~]# kubectl edit configmap kube-proxy -n kube-system
36 scheduler: "rr"
# 修改ipvs算法为rr
44 mode: "ipvs"
# 默认为空,加上ipvs
保存退出
# 修改kube-proxy的配置文件
[root@master ~]# kubectl get pods -n kube-system |grep kube-proxy
kube-proxy-h8hqn 1/1 Running 0 11h
kube-proxy-n9dc9 1/1 Running 0 12h
kube-proxy-t66mh 1/1 Running 0 11h
# 查看kube-system的namespace中kube-proxy有关的pod
[root@master ~]# kubectl logs kube-proxy-h8hqn -n kube-system|grep "proxy mode"
I0425 02:37:45.742994 1 server_others.go:561] "Unknown proxy mode, assuming iptables proxy" proxyMode=""
# 验证,还未修改过来
[root@master ~]# kubectl delete pods -n kube-system kube-proxy-h8hqn
pod "kube-proxy-h8hqn" deleted
[root@master ~]# kubectl delete pods -n kube-system kube-proxy-n9dc9
pod "kube-proxy-n9dc9" deleted
[root@master ~]# kubectl delete pods -n kube-system kube-proxy-t66mh
pod "kube-proxy-t66mh" deleted
# 删除kube-proxy-xxx的所有pod,让它重新拉取新的kube-proxy-xxx的pod
[root@master ~]# kubectl logs kube-proxy-ssnhb -n kube-system|grep ipvs
I0425 14:25:59.868775 1 server_others.go:269] "Using ipvs Proxier"
I0425 14:25:59.868807 1 server_others.go:271] "Creating dualStackProxier for ipvs"
# 验证,已经修改为ipvs
[root@master ~]# dnf -y install ipvsadm
# 安装ipvsadm查看规则
[root@master ~]# ipvsadm -Ln
TCP 10.2.1.2:80 rr
-> 10.3.1.33:80 Masq 1 0 0
-> 10.3.2.45:80 Masq 1 0 0
[root@master ~]# curl 10.2.1.2
web1
# 多次访问验证rr算法
headless service
有时不需要或不想要负载均衡,以及单独的 Service IP。 遇到这种情况,可以通过指定 Cluster IP(spec.clusterIP)的值为 “None” 来创建 Headless Service。
你可以使用无头 Service 与其他服务发现机制进行接口,而不必与 Kubernetes 的实现捆绑在一起。
对这无头 Service 并不会分配 Cluster IP,kube-proxy 不会处理它们, 而且平台也不会为它们进行负载均衡和路由。 DNS 如何实现自动配置,依赖于 Service 是否定义了选择算符。
普通的ClusterIP service是service name解析为cluster ip,然后cluster ip对
应到后面的pod ip
而无头service是指service name 直接解析为后面的pod ip
[root@master ~]# vim headless-service.yml
apiVersion: v1
kind: Service
metadata:
name: headless-service
spec:
clusterIP: None
# None代表无头服务
type: ClusterIP
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
# 指定后端pod标签
app: nginx
保存退出
[root@master ~]# kubectl apply -f headless-service.yml
service/headless-service created
# 应用yaml文件创建service
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
headless-service ClusterIP None <none> 80/TCP 26s
kubernetes ClusterIP 10.2.0.1 <none> 443/TCP 21h
# 验证
[root@master ~]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.2.0.10 <none> 53/UDP,53/TCP,9153/TCP 21h
# 查看kube-dns服务的IP
# 看到coreDNS的服务地址是10.2.0.10
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx1-568c8cbc8c-hgprl 1/1 Running 0 10h 10.3.1.32 node1 <none> <none>
nginx2-66857ff745-d8hfg 1/1 Running 0 9h 10.3.1.33 node1 <none> <none>
nginx2-66857ff745-vbbk4 1/1 Running 0 9h 10.3.2.45 node2 <none> <none>
# 查询
NodePort类型
如果你将 type 字段设置为 NodePort,则 Kubernetes 控制平面将在 --service-node-port-range 标志指定的范围内分配端口(默认值:30000-32767)。 每个节点将那个端口(每个节点上的相同端口号)代理到你的服务中。 你的服务在其 .spec.ports[*].nodePort 字段中要求分配的端口。
如果你想指定特定的 IP 代理端口,则可以设置 kube-proxy 中的 --nodeport-addresses 参数 或者将kube-proxy 配置文件 中的等效 nodePortAddresses 字段设置为特定的 IP 块。 该标志采用逗号分隔的 IP 块列表(例如,10.0.0.0/8、192.0.2.0/25)来指定 kube-proxy 应该认为是此节点本地的 IP 地址范围。
[root@master ~]# kubectl edit service my-service
31 type: NodePort
保存退出
# 修改类型为NodePort
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.2.0.1 <none> 443/TCP 21h
my-service NodePort 10.2.1.2 <none> 80:31483/TCP 102s
[root@master ~]# curl 172.20.251.148:31483
web1
# 验证
LoadBalancer
在使用支持外部负载均衡器的云提供商的服务时,设置 type 的值为 “LoadBalancer”, 将为 Service 提供负载均衡器。 负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段发布出去。
例:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
clusterIP: 10.0.171.239
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 192.0.2.127
ExternalName 类型
类型为 ExternalName 的服务将服务映射到 DNS 名称,而不是典型的选择器,例如 my-service 或者 cassandra。 你可以使用 spec.externalName 参数指定这些服务。
例:
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com