k8s学习-pod的生命周期
文章目录
- 前言
- 一、pod的生命周期
- 二、initC
- 实验一
- 实验二
- 三、探针
- 探针的方式
- 探针类型
- 就绪探测
- 实验
- 1.创建pod
- 2.创建svc
- 3.实验标签子集
- 4.实验基于HTTP的就绪探测
- 5.实验基于exec的就绪探测
- 6.实验基于TCP的就绪探测
- 存活探测
- 实验
- 启动探测
- 实验
- 四、钩子
- 实验
- 基于exec的
- 基于HTTP的
前言
本文是k8s的学习笔记,资源是
【k8s教程】薪享宏福Kubernetes v1.29 |2024最新版!B站最强!百万播放汪洋授课,轻松拿捏k8s
一、pod的生命周期
pod的生命周期主要有两大块内容
分别是initc,mainc
mainc又有两大特性,分别是钩子和探针
探针这里分为了启动探测,就绪探测,存活探测
钩子分为启动前钩子和启动后钩子
本文主要就围绕这些内容进行展开。
二、initC
initC是一个init容器,它跟普通的容器是很像的
但是有以下几点点
1.initc是线性执行的,每个init容器都必须在下一个init容器启动之前成功完成,否则阻塞
2.init容器总是运行到成功完成为止,如果有一个init容器失败,都从头重新开始
3.如果 Pod 的 Init 容器失败,Kubernetes会不断地重启该Pod,直到Init 容器成功为止。然而,如果Pod 对应的restartPolicy为Never,它不会重新启动
实验一
新创建下面这个pod,观察get pod 和 describe,
再分别执行下面的命令,就可以看到pod的特性–线性执行
apiVersion: v1
kind: Pod
metadata:name: initc-1labels:app: initc
spec:containers:- name: myapp-containerimage: wangyanglinux/tools:busyboxcommand: ['sh', '-c', 'echo The app is running! && sleep 3600']initContainers:- name: init-myserviceimage: wangyanglinux/tools:busyboxcommand: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']- name: init-mydbimage: wangyanglinux/tools:busyboxcommand: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
kubectl create svc clusterip myservice --tcp=80:80
kubectl create svc clusterip mydb --tcp=80:80
实验二
新创建这个pod,观察get pod ,describe,和logs
就会发现init失败,原因是init的返回码是1,也就是没有成功。
把下面的返回码和name给再改一下,再新创建一个pod
就会发现成功了。也就是印证了init的另外一个特性,成功的返回码为0
apiVersion: v1
kind: Pod
metadata:name: myapp-podlabels:app: myapp
spec:containers:- name: myappimage: wangyanglinux/myapp:v1.0initContainers:- name: randexitimage: wangyanglinux/tools:randexitv1args: ["--exitcode=1"]
三、探针
探针是由当前节点的kubelet对容器执行的定期诊断
探针的方式
要执行诊断,kubelet调用由容器实现的Handler
有三种类型
- ExecAction:在容器内执行指定命令
- TCPSocketAction:对指定端口上的容器的IP地址进行TCP检查
- HTTPGetAction:对指定的端口和路径上的容器的IP地址进行HTTPGet请求。
每次探测都将获得以下三种结果之一:
- 成功:容器通过了诊断
- 失败:容器未通过诊断
- 未知:诊断失败,因此不会采取任何行动
探针类型
在上面我们说了探针有三种类型
分别是
- 开始检测 startupProbe
- 存活检测 livenessProbe
- 就绪探测 readinessProbe
就绪探测
如果pod内部的容器不添加就绪探测,默认就绪。
如果添加了就绪探测,只有就绪通过以后,才标记修改为就绪状态。
当前pod内的所有的容器都就绪,才标记当前Pod就绪
成功:将当前的C标记为就绪
失败:静默(不进行任何处理,本身就是非就绪的)
未知:静默
实验
下面我们要体验就绪探测,按照下面这张图进行pod的创建和svc的创建
svc有两大特性
1.标签的子集匹配
2.pod必须是就绪状态
关于svc,后面还会有详细的讲解
首先要先把我们之前创建的pod和service给删除了
kubectl delete pod --all
kubectl delete service svc名称
1.创建pod
mkdir 6
1.pod.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-1namespace: defaultlabels:app: myapp
spec:containers:- name: myapp-1image: wangyanglinux/myapp:v1.0
2.pod.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-2namespace: defaultlabels:app: myappversion: v1
spec:containers:- name: myapp-1image: wangyanglinux/myapp:v1.0
2.创建svc
kubectl create svc clusterip myapp --tcp=80:80
3.实验标签子集
创建这个3.pod.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-3namespace: defaultlabels:app: testversion: v1
spec:containers:- name: myapp-1image: wangyanglinux/myapp:v1.0
kubectl create -f 3.pod.yaml
然后再
curl myapp的ip/hostname.html
会发现,没有pod-3,因为这个pod的label,并不在我们的子集匹配里面
4.实验基于HTTP的就绪探测
创建4.pod.yaml
apiVersion: v1
kind: Pod
metadata:name: readiness-httpget-podnamespace: defaultlabels:app: myappenv: test
spec:containers:- name: readiness-httpget-containerimage: wangyanglinux/myapp:v1.0imagePullPolicy: IfNotPresentreadinessProbe:httpGet:port: 80path: /index1.htmlinitialDelaySeconds: 1periodSeconds: 3
然后再
curl myapp的ip/hostname.html
会发现也没有这个,因为这个就绪探测是通不过的
我们可以手动的创建这个HTML
5.实验基于exec的就绪探测
创建5.pod.yaml
这个会检查这个文件是否存在
在新创建的时候,就可以
kubectl get pod -w 监测pod的状态
apiVersion: v1
kind: Pod
metadata:name: readiness-exec-podnamespace: default
spec:containers:- name: readiness-exec-containerimage: wangyanglinux/tools:busyboximagePullPolicy: IfNotPresentcommand: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live; sleep 3600"]readinessProbe:exec:command: ["test","-e","/tmp/live"]initialDelaySeconds: 1periodSeconds: 3
6.实验基于TCP的就绪探测
TCP是作为补充的一种方式,但是有了HTTP和exec基本够用了,知道了就行。
apiVersion: v1kind: Podmetadata:name: readiness-tcp-podspec:containers:- name: readiness-exec-containerimage: wangyanglinux/myapp:v1.0readinessProbe:initialDelaySeconds: 5timeoutSeconds: 1tcpSocket:port: 80
存活探测
如果pod内部不指定存活探测,可能会发生容器运行但是无法提供服务的情况
成功:静默
失败:根据重启的策略进行重启的动作
未知:静默
存活探测如果探测失败,是会把现在容器给杀死,再重新创建一个容器
实验
创建7.pod.yaml
apiVersion: v1
kind: Pod
metadata:name: liveness-exec-podnamespace: default
spec:containers:- name: liveness-exec-containerimage: wangyanglinux/tools:busyboximagePullPolicy: IfNotPresentcommand: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live;sleep 3600"]livenessProbe:exec:command: ["test","-e","/tmp/live"]initialDelaySeconds: 1periodSeconds: 3
过段时间会发现,重启了1次
创建下面的这个pod,然后把index给删除,进行实验
apiVersion: v1
kind: Pod
metadata:name: liveness-httpget-podnamespace: default
spec:containers:- name: liveness-httpget-containerimage: wangyanglinux/myapp:v1.0imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80livenessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 1periodSeconds: 3timeoutSeconds: 3
启动探测
实验
先创建pod,然后进入到这个容器里面
先创建/usr/local/nginx/html/index2.html,会发现pod没有处于就绪状态
然后再创建/usr/local/nginx/html/index1.html,会发现pod处于就绪状态
该实验说明了,启动探测执行完,再执行就绪探测
apiVersion: v1kind: Podmetadata:name: startupprobe-1namespace: defaultspec:containers:- name: myapp-containerimage: wangyanglinux/myapp:v1.0imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index2.htmlinitialDelaySeconds: 1periodSeconds: 3startupProbe:httpGet:path: /index1.htmlport: 80failureThreshold: 30periodSeconds: 10
四、钩子
钩子分为启动后钩子和关闭前钩子
启动后钩子可能会没有执行完就执行到了容器的启动命令
关闭前钩子是在容器被杀死前执行。
执行方式跟探针相比,少了一个TCP,不过TCP的方式真的很low
实验
基于exec的
创建 10.pod.yaml,然后创建这个pod
当容器创建好之后,进入到容器里面
我们就会看到/usr/share/message里面写入了postStart
apiVersion: v1
kind: Pod
metadata:name: lifecycle-exec-pod
spec:containers:- name: lifecycle-exec-containerimage: wangyanglinux/myapp:v1lifecycle:postStart:exec:command: ["/bin/sh", "-c", "echo postStart > /usr/share/message"]preStop:exec:command: ["/bin/sh", "-c", "echo preStop > /usr/share/message"]
然后执行一个小脚本
while true;
do
cat message
done
再把这个容器给delete掉,就会看到打印preStop
基于HTTP的
先开启这个
docker run -it --rm -p 1234:80 wangyanglinux/myapp:v1.0
11.pod.yaml
然后把下面的这个pod创建再删除
apiVersion: v1
kind: Pod
metadata:name: lifecycle-httpget-podlabels:name: lifecycle-httpget-pod
spec:containers:- name: lifecycle-httpget-containerimage: wangyanglinux/myapp:v1.0ports:- containerPort: 80lifecycle:postStart:httpGet:host: 192.168.66.11path: index.htmlport: 1234preStop:httpGet:host: 192.168.66.11path: hostname.htmlport: 1234
就会发现请求了两次
这里还有一个符合的实验。想做可以做一下
apiVersion: v1kind: Podmetadata:name: lifecycle-podlabels:app: lifecycle-podspec:containers:- name: busybox-containerimage: wangyanglinux/tools:busyboxcommand: ["/bin/sh","-c","touch /tmp/live ; sleep 600; rm -rf /tmp/live;
sleep3600"]livenessProbe:exec:command: ["test","-e","/tmp/live"]initialDelaySeconds: 1periodSeconds: 3lifecycle:postStart:httpGet:host: 192.168.66.11path: index.htmlport: 1234preStop:httpGet:host: 192.168.66.11path: hostname.htmlport: 1234- name: myapp-containerimage: wangyanglinux/myapp:v1.0livenessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 1periodSeconds: 3timeoutSeconds: 3readinessProbe:httpGet:port: 80
path: /index1.htmlinitialDelaySeconds: 1periodSeconds: 3initContainers:- name: init-myserviceimage: wangyanglinux/tools:busyboxcommand: ['sh', '-c', 'until nslookup myservice; do echo waiting for
myservice; sleep 2; done;']- name: init-mydbimage: wangyanglinux/tools:busyboxcommand: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep
2; done;']