一、Pod的生命周期
-
pod的创建过程;
-
运行初始化容器的过程;init container
-
运行主容器过程:main container
-容器启动后钩子(port start) 、容器终止前钩子(pre stop)
-容器的存活性探测(liveness probe)、就绪性探测(readiness probe)
4.pod终止的过程
1、整个生命周期,Pod会出现5种状态或者说是5种相位
Pending |
挂起 |
apiserver已经创建pod,但他未完成调度或者处于镜像下载过程 |
Running |
运行中 |
pod已经被调度到节点上面了,并且pod上面所有需要的容器服务都已经被kubelet创建完成 |
Succeeded |
成功 |
pod中毒的所有容器都已经被成功终止并且不会被重启(pod已经被创建成功) |
Failed |
失败 |
返回一个非0的推出状态码 |
Unknown |
未知 |
apiserver暂时无法获取pod对象的状态信息,通常由网络通信失败导致 |
2、Pod的创建和终止过程
创建:
1.用户通过kubectl或其他api客户端提交需要创建的pod给apiserver;
2.apiserver之后就生成pod信息,并存入etcd(键值对),然后向客户端返回确认信息;
3.apiserver开始反映etcd中的pod对象的变化,其他组件使用watch(监听)机制来跟踪检查apiserver上的pod对象的变动;
4.scheduler发现有新的pod的对象要创建,开始为pod分配主机并将结果信息更新到apiserver;
5.node节点上的kubelet发现有pod调度请求,尝试启动容器,并将调度结果返回到apiserver
6.apiserver将接收到的pod状态信息存入etcd中去;
终止:
1.用户向apiserver发送删除pod对象的命令
2.apiserver中的pod对象信息会随着时间的推移而更新,在宽限期内(30s),pod被视为dead
3.将pod标记为terminating状态
4.kubelet在watch到pod对象变成terminating状态的时候,会启动pod的关闭过程
5.端点控制器检测到pod对象有关闭的行为时,会将pod对象到此端点的所有service资源删除
6.如果被删除的pod定义了一个prestop钩子处理器的时候,那么将会在pod成为terminating状态的时候执行
7.pod对象收到停止的信号
8.30s宽限期结束后,不管什么状态下,pod都会立即终止
9.kubelet请求apiserver将此pod资源的宽限期设置为0从而完成删除操作,此时pod对于用户已不可见
3、初始化容器
Kubernetes按照顺序执行,必须上一个容器完成才能启动下一个,如果其中上一个启动失败的话,Kubernetes将会进入重启,必须要有容器都初始化完成!
# 我们创建一个pod,里面运行两个容器
vim init.yml
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: v1
kind: Pod
metadata:
name: init-test
namespace: dev
spec:
containers:
- name: nginx-init
image: nginx:1.17.1
ports:
- name: nginx-ports
containerPort: 80
initContainers:
- name: test-mysql
image: busybox:1.30 # 创建之后 pod状态一直是INIT,初始化状态;镜像版本号不对
command: ['sh', '-c', 'until ping 172.16.52.201 -c 1 ; do echo waiting for mysql...; sleep 2; done;']
#查看pod状态
kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
init-test 0/1 Init:ErrImagePull 0 28s 10.244.166.129 node1 <none> <none>
#修改配置文件中的版本号为latest;在执行create;
kubectl get pods -n dev -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
init-test 1/1 Running 0 18s 10.244.166.130 node1 <none> <none>
4、钩子函数
Exec命令 |
在容器内执行一次命令 |
TCPSocket |
在当前容器访问指定的Socket |
HTTPGet |
在当前容器中向某个url发送http请求 |
#钩子函数
#Exec命令:在容器内执行一次命令
lifecycle:
postSatrt:
exec:
commmand:
- cat
- /tmp/healthy
#TCPSocket:在当前容器访问指定的Socket
lifecycle:
postSatrt:
tcpSocket:
port: 8080
#HTTPGet:在当前容器中向某个url发送http请求
lifecycle:
postSatrt:
httpGet:
path: / #URL地址
port: 80 #端口号
host: X.X.X.X #IP地址
scheme: HTTP #支持的协议,HTTP或者HTTPS
#配置钩子函数
vim poststart.yml
apiVersion: v1
kind: Pod
metadata:
name: poststart
namespace: dev
spec:
containers:
- name: nginxpod
image: nginx:latest
ports:
- name: nginxport
containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo postStart... > /usr/share/nginx/html/index.html"]
preStop:
exec:
command: ["/usr/sbin/nginx", "-s", "quit"]
#查看运行状态
[root@master ~]# kubectl exec -it poststart -n dev -- /bin/sh
# cat /usr/share/nginx/html/index.html
postStart...
5.容器的探测和使用
主要作用是检测pod中的容器是否正常工作,如果探测对象的pod没有达到预期的状态的话,那么kubernetes将会把出现问题的pod进行移除;
kubernetes主要有一下两种探测的类型:
libeness probes |
存活性探测 |
readiness probes |
就绪性探针 |
(1)libeness probes
主要决定是否重启容器,检测pod的资源是否处于正常状态,kubernetes根据状态绝对是否重启容器;
(2)readiness probes:
主要决定是否将请求转发给容器,检测pod资源是否完成启动,可以接受请求,如过不是,kubernetes则不会向该pod转发流量 ;
———————————————————————————————————————————
我们通过之前文章里面提到explain命令可以去查看livenessProbe下的资源清单:
kubectl expalin pod.spec.containers.livenessProbe
我们可以得到很多很多英文,我也看不懂哈哈;所以通过某站老师的课做了个总结:
exec<object> | # |
tcpSocket<object> | # |
httpGet<object> | # |
initialDelaySeconds <integer> |
容器启动后等待多少秒执行第一次探测 |
timeoutDeconds <integer> |
探测超过时间。默认和最小值都是1秒 |
periodSeconds <integer> |
执行探测间隔多少时间,默认是10秒,最小是1秒 |
failureThreshold <integer> |
连续探测失败多少次才被认定失败。默认的时候是3,最小值是1 |
successThreshold <integer> |
连续探测成功多少次才被认定成功。默认是1 |
#测试,存活性探针
vim podliveness.yml
apiVersion: v1
kind: Pod
metadata:
name: liveness-pod
namespace: dev
spec:
containers:
- name: nginx-pod
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
livenessProbe:
exec:
command: ["bin/cat", "/tmp/hello.txt" ] # nginx本身是没有hello.txt的文件,所以无法查看
# 查看创建的pod对象
# 因为nginx本身是没有hello.txt的文件所以 command没有办法执行存活测试所以不断重启
[root@master ~]# kubectl get pod -n dev -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liveness-pod 1/1 Running 0 27s 10.244.166.167 node1 <none> <none>
liveness-pod 1/1 Running 0 31s 10.244.166.167 node1 <none> <none>
liveness-pod 0/1 CreateContainerError 0 31s 10.244.166.167 node1 <none> <none>
liveness-pod 0/1 CreateContainerError 0 31s 10.244.166.167 node1 <none> <none>
liveness-pod 1/1 Running 1 (2s ago) 32s 10.244.166.168 node1 <none> <none>
liveness-pod 1/1 Running 1 (3s ago) 33s 10.244.166.168 node1 <none> <none>
6.容器的重启策略
重启策略是为了在我们进行探测的时候出现问题,kubernetes就会按照我们配置的重启策略对pod进行重启;
Always |
容器失效时,自动重启容器(默认) |
OnFailure |
容器终止运行且退出码不为0时重启 |
Never |
不论状态是什么都不会重启该容器 |
我们使用上一步使用的liveness配配置文件,因为我们在配置文件中有一个command是查看容器中的Hello.txt文件,但是我们容器本身是没有的所以容器就会不断重启,我们使用重启策略设置从不重启;
vim podliveness.yml
apiVersion: v1
kind: Pod
metadata:
name: liveness-pod
namespace: dev
spec:
containers:
- name: nginx-pod
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
livenessProbe:
exec:
command: ["bin/cat", "/tmp/hello.txt" ] # nginx本身是没有hello.txt的文件,所以无法查看
restartPolicy: Never # 重启策略
二、Pod的调度
定向调度 |
NodeName、NodeSelector |
亲和性调度 |
NodeAffinity、PodAffinity、PodAntiAffinity |
污点(容忍)调度 |
Taints、Toleration |
1.定向调度
NodeName:根据节点Node的名字进行定向调度;
apiVersion: v1
kind: Pod
metadata:
name: nginx-nodename
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
nodeName: node1 # 通过nodename对pod进行定向调度
NodeSelector:根据节点Node的标签进行定向调度;
apiVersion: v1
kind: Pod
metadata:
name: nginx-nodeselector
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
nodeSelector:
test: run # 通过标签为test=run对pod的进行定向调度
2.亲和性调度
亲和性调度的原则:通过配置优先选择满足节点需求的Node上去,如果都不满足会分配到其他节点;如果有一些pod之间存在资源依赖的情况我们可以使用亲和性调度;如果一个应用,如nginx需要多个node上面至少有一个,我们可以使用反亲和性,这样可以提高资源的利用率;
(1)NodeAffinity
requiredDuringDchedulingIgnoredDuringExecution (硬限制,Node节点必须满足指定的所有条件才行)
nodeSelectorTerms 节点选择列表
matchFields 按节点字段列出的节点选择器要求列表
matchExpressions 按节点标签列出的节点选择器要求列表 (一般这个比较推荐使用)
key
values
operator 关系符, Exists,DoesNotExist,In,NotIn,Gt,Lt
preferredDuringSchedulingIgnoredDuringExecution (软限制,优先调度满足规则的Node上去)
preference 一个节点选择器项,与相应的权重相关联
matchFields 按节点字段列出的节点选择器要求列表
matchExpressions 按节点标签列出的节点选择器要求列表 (一般这个比较推荐使用)
key
values
operator 关系符, Exists,DoesNotExist,In,NotIn,Gt,Lt
weight # 权重 1-100
# 关系符使用说明
- matchExpressions:
- key: nodetest
operator: Exists # 匹配存在标签的key为nodetest的节点
- key: nodetest
operator: In # 匹配标签的key为nodetest的节点,且value是x或者y的节点
value: ["x","y"]
- key: nodetest
operator: Gt # 匹配标签的key为nodetest的节点,且value大于x的节点
values: "x"
##其他的都是以此类摧!!!
#硬限制
apiVersion: v1
kind: Pod
metadata:
name: pod-affinity
namespace: test
spec:
containers:
- name: nginx-pod
image: nginx:1.17.1
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:#硬限制
nodeSelectorTerms:
- matchExpressions:#匹配存在nodeenv标签的node加入进去
- key: nodeenv
operator: Exists #In,该类型需要多一个value字段,会同时符合key的值的情况下也要复合values中的一个;
#values: ["pro","max"]
#软限制
apiVersion: v1
kind: Pod
metadata:
name: pod-aaffinity
namespace: test
spec:
containers:
- name: nginx-pod
image: nginx:1.17.1
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:#软限制
- weight: 1
preference:
matchExpressions:
- key: nodeenv
operator: In
values: ["xxx","yyy"] # 优先找符合要求的,没有则选择其他
nodeAffinity注意事项:
1.如果同时定义了nodeAffinity和nodeSelector,那么必须两个条件都满足,pod才能运行到指定的node上去;
2.如果nodeAffinity指定了多个nodeSelectorTerms,那么只需要其中一个能满足就能匹配成功
3.如果一个nodeSelectorTerms中有多个matchExpressions,则一个节点必须满足所有的才能匹配成功
4.如果一个pod所在的Node在pod运行期间其标签发生了改变,不再符合该pod的节点亲和性需求,则系统将忽略此变化
(2) podAffinity
requiredDuringDchedulingIgnoredDuringExecution (硬限制)
namespaces #指定pod的名称空间
topplogKey #指定调度作用域
labelSelector #标签选择器
matchExpressions #按节点标签列出的节点选择器要求列表 (一般这个比较推荐使用)
key
values
operator #关系符, Exists,DoesNotExist,In,NotIn.
matchLabels #指定多个matchExpressions映射的内容
preferredDuringSchedulingIgnoredDuringExecution (软限制)
podAffinityTerm #选项
namespaces #指定pod的名称空间
topplogKey #指定调度作用域
labelSelector #标签选择器
matchExpressions #按节点标签列出的节点选择器要求列表 (一般这个比较推荐使用)
key
values
operator #关系符, Exists,DoesNotExist,In,NotIn.
matchLabels #指定多个matchExpressions映射的内容
weight 权重1-100
#topplogKey指定调度作用域如下
1.如果指定为kubernetes.io/hostname,那就是以Node节点为区分范围;
2.如果指定beta.kubernetes.io/os,则以Node节点的操作系统类型来区分;
#测试,我们举一个例子,环境,先准备一个标签为run:pro的pod,使用nodename定向调度到node1上去;
apiVersion: v1
kind: Pod
metadata:
name: pod
namespace: test
labels:
run: pro
spec:
containers:
- name: nginx-pod
image: nginx:1.17.1
nodeName: node1
#我们创建一个新的pod,使用In,亲和性调度,让他根据标签调度到Node1上去;
apiVersion: v1
kind: Pod
metadata:
name: podaff
namespace: test
spec:
containers:
- name: nginx
image: nginx:1.17.1
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: run
operator: In
values: ["pro","xxx"]
topologyKey: kubernetes.io/hostname
(3)podAntiAffinity
apiVersion: v1
kind: Pod
metadata:
name: podaff
namespace: test
spec:
containers:
- name: nginx
image: nginx:1.17.1
affinity:
podAntiAffinity: #反亲和性
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: run
operator: In
values: ["pro","xxx"]
topologyKey: kubernetes.io/hostname
3.调度、污点、容忍
污点:
站在node的角度,在node的上面配置一些污点属性,来决定是否通过pod调度过来;如果node上面配置了污点属性,那么将拒绝pod进来,也可以将不符合污点的正在运行的pod驱逐出去。kubernetes在创建的时候 master节点会自动创建一个污点,所以pod不会调度到master节点上去;
污点的格式为:key=value:effect, key和value是污点的标签,effect是描述污点,支持下面三个选项:
PreferNoDchedule | 尽量不要来,除非没有办法 |
NoSchedule | 新的就不要来了,本来的就不要动了 |
NoExecute | 新的也不要来了,本来的也赶紧走 |
#设置污点
kubectl taint nodes node1 key=value:effect
#去除污点
kubectl taint nodes node1 key:effect-
#去除所有污点
kubectl taint nodes node1 key-
#测试演示
1.给node1增加一个test=1的污点,设置为PreferNoSchedule
[root@master ~]# kubectl taint nodes node1 test=1:PreferNoSchedule
node/node1 tainted
2.去除node1的污点
[root@master ~]# kubectl taint nodes node1 test:PreferNoSchedule-
node/node1 untainted
3.去除所有污点
[root@master ~]# kubectl taint nodes node1 test-
容忍:
我们可以在node上面添加污点拒绝pod调度进来,但是如果非要pod调度到有污点的node上面来 我们可以用到容忍;
key |
对应着要容忍的污点的键,空意味着匹配所有的键 |
value | 对应着要容忍的污点的值 |
operator | key-value的运算符,支持Equal和Exists(默认) |
effect | 对应污点的effect,空意味着匹配所有影响 |
tolerationSeconds | 容忍时间,当effect为NodeExecte时生效,表示pod在Node上的停留时间 |
apiVersion: v1
kind: Pod
metadata:
name: pod
namespace: test
labels:
run: pro
spec:
containers:
- name: nginx-pod
image: nginx:1.17.1
tolerations: # 添加容忍
- key: "run"
operator: "Equal" # 操作符 默认的话是Exists 这样就不需要value 只要key匹配上去那就容忍
value: "run" # 污点的value
effect: "NoExecute" # 必须和node的污点相同
Pod基本上主要的内容都已经完成了,下面就是控制器什么,以上有问题的可以在评论区指出,共同学习,这么多我也记不住,哈哈哈哈!