Pod生命周期
官方文档:
https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/
启动一个容器
[wjjk8s@server1 manifest]$ vim pod.yaml
[wjjk8s@server1 manifest]$ kubectl create -f pod.yaml
[wjjk8s@server1 manifest]$ kubectl describe pod
pod可以包含多个容器,应用运行在这些容器里面,同时pod也可以有一个或多个先于应用容器启动的init容器。
init容器与普通容器非常像,除了如下两点:
他们总是运行到完成。 init容器不支持readiness,因为他们必须在pod就绪之前运行完成。
每个init容器运行成功下一个才能运行如果pod的init容器失败,kubernetes会不断重启该pod,直到init容器成功为止,然而,如果pod对应的restartPolicy为Never,他不会重新启动。
因为 Init 容器具有与应用容器分离的单独镜像,其启动相关代码具有如下优势:
Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。例如,没有必要仅为了在安装过程中使用类似 sed、 awk、 python 或 dig 这样的工具而去FROM 一个镜像来生成一个新的镜像。
Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。
由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。
一、init容器实验
1、定义了一个 Init 容器的简单 Pod
[wjjk8s@server1 manifest]$ vim init.yaml #复制会有缩进
[wjjk8s@server1 manifest]$ \vi init.yaml #加转移取消缩进
[wjjk8s@server1 manifest]$ cat init.yaml
[wjjk8s@server1 manifest]$ kubectl create -f init.yaml
pod/myapp-pod created
[wjjk8s@server1 manifest]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/1 0 18s
#inith还未准备好
#查看详细信息时发现
[wjjk8s@server1 manifest]$ kubectl exec -it myapp-pod -c init-myservice -- sh #进入pod中的init容器
2、创建一个service.yaml
[wjjk8s@server1 manifest]$ vim service.yaml
[wjjk8s@server1 manifest]$ kubectl create -f service.yaml
[wjjk8s@server1 manifest]$ kubectl get svc #成功创建了一个服务
3、等待后容器生成成功,init容器初始化成功,退出
[wjjk8s@server1 manifest]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-pod 1/1 Running 0 16m
[wjjk8s@server1 manifest]$ kubectl get pod -o wide #集群内部分配成功
4、进入容器,查看dns解析
[wjjk8s@server1 ~]$ kubectl run test1 -it --image=busyboxplus --image-pull-policy='IfNotPresent'
/ # nslookup myservice.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: myservice.default.svc.cluster.local
Address 1: 10.107.1.234 myservice.default.svc.cluster.local
改错
[wjjk8s@server1 manifest]$ kubectl run test -it --image=busybox #运行不成功出现错误
#镜像仓库问题,指定镜像仓库即可
[wjjk8s@server1 manifest]$kubectl run test -it --image=busyboxplus --image-pull-policy='IfNotPresent' #使用本地镜像
test 0/1 ImagePullBackOff 0 4m55s
#显示拉取依然错误,排错发现是对应服务器国内阿里云镜像没做,用server1发送一个即可,并刷新即可
[root@server4 ~]# systemctl daemon-reload
[root@server4 ~]# systemctl restart docker
#成功运行
二、探针实验
就绪监测和存活监测,默认没有探针,需要自己定义。
探针 是由 kubelet 对容器执行的定期诊断。要执行诊断,kubelet 调用由容器实现的 Handler。有三种类型的处理程序:
ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。
每次探测都将获得以下三种结果之一:
成功:容器通过了诊断。
失败:容器未通过诊断。
未知:诊断失败,因此不会采取任何行动。
Kubelet 可以选择是否执行在容器上运行的三种探针执行和做出反应:
**livenessProbe**:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 重启策略 的影响。如果容器不提供存活探针,则默认状态为 Success。
**readinessProbe**:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。
startupProbe: 指示容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet 将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探测,则默认状态为成功Success。
该什么时候使用存活(liveness)和就绪(readiness)探针?
如果容器中的进程能够在遇到问题或不健康的情况下自行崩溃,则不一定需要存活探针; kubelet 将根据 Pod 的restartPolicy 自动执行正确的操作。
如果您希望容器在探测失败时被杀死并重新启动,那么请指定一个存活探针,并指定restartPolicy 为 Always 或 OnFailure。
如果要仅在探测成功时才开始向 Pod 发送流量,请指定就绪探针。在这种情况下,就绪探针可能与存活探针相同,但是 spec 中的就绪探针的存在意味着 Pod 将在没有接收到任何流量的情况下启动,并且只有在探针探测成功后才开始接收流量。
如果您希望容器能够自行维护,您可以指定一个就绪探针,该探针检查与存活探针不同的端点。
请注意,如果您只想在 Pod 被删除时能够排除请求,则不一定需要使用就绪探针;在删除 Pod 时,Pod 会自动将自身置于未完成状态,无论就绪探针是否存在。当等待 Pod 中的容器停止时,Pod 仍处于未完成状态
1、liveness测试,存活检测
(1).删除之前实验时创建的myservice服务
[wjjk8s@server1 manifest]$ kubectl delete svc myservice
[wjjk8s@server1 manifest]$ kubectl delete pod myapp-pod
(2)、创建liveness测试容器
[wjjk8s@server1 manifest]$ vim pod.yaml
[wjjk8s@server1 manifest]$ kubectl create -f pod.yaml
[wjjk8s@server1 manifest]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 32s
[wjjk8s@server1 manifest]$ curl 10.244.1.26 #成功连接监测成功
(3)、更改监测错误端口会不断重启
[wjjk8s@server1 manifest]$ vim pod.yaml
port: 8080
[wjjk8s@server1 manifest]$ kubectl get pod -o wide
2、readinessProbe就绪监测
(1)创建readinessProbe测试容器
[wjjk8s@server1 manifest]$ vim pod.yaml
[wjjk8s@server1 manifest]$ kubectl create -f pod.yaml
[wjjk8s@server1 manifest]$ kubectl get pod #就绪监测没有通过
NAME READY STATUS RESTARTS AGE
nginx 0/1 Running 0 31s
[wjjk8s@server1 manifest]$ kubectl logs nginx #查看日志找原因,因为nginx的发布目录里,找不到test.html文件
2020/04/23 23:32:34 [error] 6#6: *52 open() "/usr/share/nginx/html/test.html" failed (2: No such file or directory), client: 10.244.1.1, server: localhost, request: "GET /test.html HTTP/1.1", host: "10.244.1.28:80"
(2)将test文件写入,通过探针的就绪检测
[wjjk8s@server1 manifest]$ kubectl exec -it nginx -- sh
#cd /usr/share/nginx/html
#ls
50x.html index.html
#echo westos > test.html