Welcome to Elvin's blog

2.k8s.Pod生命周期,健康检查

#Pod生命周期,健康检查

pod创建过程
Init容器
就绪探测
存活探测
生命周期钩子

#Pod创建过程

  • master节点:kubectl -> kube-api -> kubenlet -> CRI容器环境初始化
  • Node节点: pause容器(网络和数据卷) -> Init容器(若有) -> 主容器(start,容器探针,top)

#Init容器

  • Init容器用来阻塞或延迟应用容器的启动,直到满足决条件,成功退出
  • 在所有的 Init 容器没有成功之前,Pod不会变成 Ready 状态,容器端口不会在Service聚集
  • init容器是在普通容器之前运行的专用容器,可以包含普通容器映像中不存在的应用程序或安装脚本

#init容器 实例

#init-pod.yaml
apiVersion: v1
kind: Pod
metadata:
 name: init-pod
 labels:
   app: myapp
spec:
 containers:
 - name: myapp
   image: busybox
   command: ['sh', '-c', 'echo -n "running at " && date +%T && sleep 600']
 initContainers:
 - name: init-mydb
   image: busybox
   command: ['sh', '-c', 'until nslookup init-db; do echo waiting for init-db;date +%T; sleep 2;echo ; done;']
#init-db.yaml
kind: Service
apiVersion: v1
metadata:
 name: init-db
spec:
 ports:
   - protocol: TCP
     port: 80
     targetPort: 3366
#创建
kubectl create -f init-pod.yaml
#查看pod状态 init没成功
kubectl get pod
#查看log
kubectl logs init-pod -c init-mydb

#创建svr
kubectl create -f init-db.yaml
#查看
kubectl get svc

#svc有ip地址,等待init容器运行成功
kubectl get pod

#删除
kubectl delete -f init-pod.yaml
kubectl delete -f init-db.yaml

#探针

#探针是kubelet对容器执行的定期诊断,有三种类型的处理程序:

  • ExecAction:exec探针,在容器内执行命令,退出返回码为0则认为诊断成功
  • TCPSocketAction:tcp探针,对容器的IP:端口,进行TCP检查,端口打开则诊断成功
  • HTTPGetAction:httpget探针,执行httpGet请求 200<=状态码<400 则诊断成功

#探测结果:

  • 成功:容器通过了诊断
  • 失败:容器未通过诊断
  • 未知:诊断失败,不会采取任何行动

探测方式

  • readinessProbe:就绪探测,检测成功之前,Pod状态为 Failure,请求不会接入此pod对象
  • livenessProbe:存活探测,在容器整个生命周期循环检测,如探测结果失败,则kubelet关闭或重启容器

两种探测方式可一起配合使用


#就绪检测-httpget探针 readinessProbe.httpget

#readiness-demo.yaml
apiVersion: v1
kind: Pod
metadata:
 name: readiness-httpget-pod
 namespace: default
spec:
 containers:
 - name: readiness-httpget-container
   image: alivv/nginx:node
   imagePullPolicy: IfNotPresent
   readinessProbe:
     httpGet:
       port: 80
       path: /index1.html
     initialDelaySeconds: 1     #容器启动延迟首次检测,默认0
     periodSeconds: 3           #探测频率,默认10s
     #timeoutSeconds:1         #探测超时,默认1s
     #successThreshold:         #失败后连续多少次成功才被认为通过检测,默认1
     #failureThreshold:         #成功后多少次连续失败才被仍为检测失败,默认3
#创建pod
kubectl create -f readiness-demo.yaml

#查看
kubectl get pod readiness-httpget-pod
kubectl get pod readiness-httpget-pod -o wide
#pod已runing但没Ready
#curl 容器ip 能正常访问
curl $(kubectl get pod -o wide |awk '/readiness-httpget-pod/{print $6}')
#查看log发现404报错,因为/index1.html不存在
kubectl logs readiness-httpget-pod -c readiness-httpget-container

#进入容器,创建文件
kubectl exec -it readiness-httpget-pod -c readiness-httpget-container -- sh
echo nginx >/usr/share/nginx/html/index1.html #创建文件
exit    #退出容器
#再次查看pod已处于Ready正常状态
kubectl get pod readiness-httpget-pod

#删除
kubectl delete -f readiness-demo.yaml

#存活检测-exec探针 livenessProbe.exec

#live-exec.yaml
apiVersion: v1
kind: Pod
metadata:
 name: liveness-exec-pod
 namespace: default
spec:
 containers:
 - name: liveness
   image: busybox
   imagePullPolicy: IfNotPresent
   command: ["/bin/sh","-c","touch /tmp/live ; sleep 10; rm -f /tmp/live; sleep
  3600"]
   livenessProbe:
     exec:
       command: ["test","-e","/tmp/live"]
     initialDelaySeconds: 1
     periodSeconds: 3
     failureThreshold: 1
#创建
kubectl create -f live-exec.yaml

#查看restart数量增加
kubectl get pod liveness-exec-pod
#exec探针,使用命令检测文件是否存在
#Pod会反复重启,因为sleep 10s后删除文件rm -f /tmp/live

#删除
kubectl delete -f live-exec.yaml

#存活检测-httpget探针 livenessProbe-httpget

#live-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
 name: liveness-httpget-pod
 namespace: default
spec:
 containers:
 - name: liveness-httpget-container
   image: alivv/nginx:node
   imagePullPolicy: IfNotPresent
   ports:
   - name: http
     containerPort: 80
   livenessProbe:
     httpGet:
       port: http
       path: /index.html
     initialDelaySeconds: 1
     periodSeconds: 3
     timeoutSeconds: 5    #超时
#创建
kubectl create -f live-httpget.yaml

#查看
kubectl get pod liveness-httpget-pod
#curl 容器ip 能正常访问
curl $(kubectl get pod -o wide |awk '/liveness-httpget-pod/{print $6}')/index.html

#删除容器index.html
kubectl exec -it liveness-httpget-pod -- rm -f /usr/share/nginx/html/index.html
#再次curl 容器ip/index.html 会404报错
#等待一会儿,查看pod增加RESTARTS数量
kubectl get pod liveness-httpget-pod

#删除
kubectl delete -f live-httpget.yaml

#存活检测-tcp探针 livenessProbe-tcp

#live-tcp.yaml
apiVersion: v1
kind: Pod
metadata:
 name: liveness-tcp-pod
spec:
 containers:
 - name: liveness-tcp
   image: alivv/nginx:node
   livenessProbe:
     initialDelaySeconds: 5
     timeoutSeconds: 1
     tcpSocket:
       port: 8080
#创建
kubectl create -f live-tcp.yaml

#等待1分钟后查看
kubectl get pod liveness-tcp-pod
#因为8080端口没存在,Pod会反复重启

#删除
kubectl delete -f live-tcp.yaml

#Pod Hook 容器生命周期钩子

Hook类型

  • PostStart: 容器创建后立即执行
  • PreStop: 容器终止前立即执行

Hook命令

  • exec: 执行一段命令
  • HTTP: 发送HTTP请求

#实例

#lifecycle-demo.yaml
apiVersion: v1
kind: Pod
metadata:
 name: lifecycle-demo
spec:
 containers:
 - name: lifecycle-demo-container
   image: alivv/nginx:node
   lifecycle:
     postStart:
       exec:
         command: ["/bin/sh", "-c", "echo nginx postStart >/usr/share/nginx/html/index2.html"]
     preStop:
       exec:
         command: ["/bin/sh", "-c", "echo nginx postStop  >/usr/share/nginx/html/index3.html"]
#创建
kubectl create -f lifecycle-demo.yaml

#查看
kubectl get pod lifecycle-demo
#查看创建的index2.html文件
#curl 容器ip/index2.html 能正常访问
curl $(kubectl get pod -o wide |awk '/lifecycle-demo/{print $6}')/index2.html

#删除
kubectl delete -f lifecycle-demo.yaml

#Pod的status状态值

  • 挂起(Pending): Pod已被Kubernetes系统接受,但有容器尚未创建完成
  • 运行中(Running): Pod所有容器已创建,容器正在运行,或处于启动或重启状态
  • 成功(Succeeded) Pod所有容器都被成功终止,并且不会再重启
  • 失败(Failed): Pod所有容器已终止,以非0状态退出或者被系统终止
  • 未知(Unknown): 无法取得Pod状态,通常是Pod所在主机通信失败

Blog地址 https://www.cnblogs.com/elvi/p/11755628.html
本文git地址 https://gitee.com/alivv/k8s/tree/master/notes

posted @ 2019-10-28 22:16  blog-elvin-vip  阅读(869)  评论(0编辑  收藏  举报