文章目录
前言
本文是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的特性--线性执行
yaml
apiVersion: v1
kind: Pod
metadata:
name: initc-1
labels:
app: initc
spec:
containers:
- name: myapp-container
image: wangyanglinux/tools:busybox
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: wangyanglinux/tools:busybox
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
- name: init-mydb
image: wangyanglinux/tools:busybox
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
bash
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
yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp
image: wangyanglinux/myapp:v1.0
initContainers:
- name: randexit
image: wangyanglinux/tools:randexitv1
args: ["--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给删除了
bash
kubectl delete pod --all
bash
kubectl delete service svc名称
1.创建pod
bash
mkdir 6
1.pod.yaml
yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-1
namespace: default
labels:
app: myapp
spec:
containers:
- name: myapp-1
image: wangyanglinux/myapp:v1.0
2.pod.yaml
yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-2
namespace: default
labels:
app: myapp
version: v1
spec:
containers:
- name: myapp-1
image: wangyanglinux/myapp:v1.0
2.创建svc
bash
kubectl create svc clusterip myapp --tcp=80:80
3.实验标签子集
创建这个3.pod.yaml
yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-3
namespace: default
labels:
app: test
version: v1
spec:
containers:
- name: myapp-1
image: wangyanglinux/myapp:v1.0
bash
kubectl create -f 3.pod.yaml
然后再
bash
curl myapp的ip/hostname.html
会发现,没有pod-3,因为这个pod的label,并不在我们的子集匹配里面
4.实验基于HTTP的就绪探测
创建4.pod.yaml
yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget-pod
namespace: default
labels:
app: myapp
env: test
spec:
containers:
- name: readiness-httpget-container
image: wangyanglinux/myapp:v1.0
imagePullPolicy: IfNotPresent
readinessProbe:
httpGet:
port: 80
path: /index1.html
initialDelaySeconds: 1
periodSeconds: 3
然后再
bash
curl myapp的ip/hostname.html
会发现也没有这个,因为这个就绪探测是通不过的
我们可以手动的创建这个HTML
5.实验基于exec的就绪探测
创建5.pod.yaml
这个会检查这个文件是否存在
在新创建的时候,就可以
kubectl get pod -w 监测pod的状态
yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-exec-pod
namespace: default
spec:
containers:
- name: readiness-exec-container
image: wangyanglinux/tools:busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live; sleep 3600"]
readinessProbe:
exec:
command: ["test","-e","/tmp/live"]
initialDelaySeconds: 1
periodSeconds: 3

6.实验基于TCP的就绪探测
TCP是作为补充的一种方式,但是有了HTTP和exec基本够用了,知道了就行。
yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-tcp-pod
spec:
containers:
- name: readiness-exec-container
image: wangyanglinux/myapp:v1.0
readinessProbe:
initialDelaySeconds: 5
timeoutSeconds: 1
tcpSocket:
port: 80
存活探测
如果pod内部不指定存活探测,可能会发生容器运行但是无法提供服务的情况
成功:静默
失败:根据重启的策略进行重启的动作
未知:静默
存活探测如果探测失败,是会把现在容器给杀死,再重新创建一个容器
实验
创建7.pod.yaml
yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
namespace: default
spec:
containers:
- name: liveness-exec-container
image: wangyanglinux/tools:busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live;sleep 3600"]
livenessProbe:
exec:
command: ["test","-e","/tmp/live"]
initialDelaySeconds: 1
periodSeconds: 3
过段时间会发现,重启了1次
创建下面的这个pod,然后把index给删除,进行实验
yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget-pod
namespace: default
spec:
containers:
- name: liveness-httpget-container
image: wangyanglinux/myapp:v1.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
port: 80
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 3
启动探测

实验
先创建pod,然后进入到这个容器里面
先创建/usr/local/nginx/html/index2.html,会发现pod没有处于就绪状态
然后再创建/usr/local/nginx/html/index1.html,会发现pod处于就绪状态
该实验说明了,启动探测执行完,再执行就绪探测
yaml
apiVersion: v1
kind: Pod
metadata:
name: startupprobe-1
namespace: default
spec:
containers:
- name: myapp-container
image: wangyanglinux/myapp:v1.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
port: 80
path: /index2.html
initialDelaySeconds: 1
periodSeconds: 3
startupProbe:
httpGet:
path: /index1.html
port: 80
failureThreshold: 30
periodSeconds: 10
四、钩子
钩子分为启动后钩子和关闭前钩子
启动后钩子可能会没有执行完就执行到了容器的启动命令
关闭前钩子是在容器被杀死前执行。
执行方式跟探针相比,少了一个TCP,不过TCP的方式真的很low
实验
基于exec的
创建 10.pod.yaml,然后创建这个pod
当容器创建好之后,进入到容器里面
我们就会看到/usr/share/message里面写入了postStart
yaml
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-exec-pod
spec:
containers:
- name: lifecycle-exec-container
image: wangyanglinux/myapp:v1
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo postStart > /usr/share/message"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo preStop > /usr/share/message"]
然后执行一个小脚本
bash
while true;
do
cat message
done
再把这个容器给delete掉,就会看到打印preStop
基于HTTP的
先开启这个
bash
docker run -it --rm -p 1234:80 wangyanglinux/myapp:v1.0
11.pod.yaml
然后把下面的这个pod创建再删除
yaml
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-httpget-pod
labels:
name: lifecycle-httpget-pod
spec:
containers:
- name: lifecycle-httpget-container
image: wangyanglinux/myapp:v1.0
ports:
- containerPort: 80
lifecycle:
postStart:
httpGet:
host: 192.168.66.11
path: index.html
port: 1234
preStop:
httpGet:
host: 192.168.66.11
path: hostname.html
port: 1234
就会发现请求了两次
这里还有一个符合的实验。想做可以做一下
yaml
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-pod
labels:
app: lifecycle-pod
spec:
containers:
- name: busybox-container
image: wangyanglinux/tools:busybox
command: ["/bin/sh","-c","touch /tmp/live ; sleep 600; rm -rf /tmp/live;
sleep
3600"]
livenessProbe:
exec:
command: ["test","-e","/tmp/live"]
initialDelaySeconds: 1
periodSeconds: 3
lifecycle:
postStart:
httpGet:
host: 192.168.66.11
path: index.html
port: 1234
preStop:
httpGet:
host: 192.168.66.11
path: hostname.html
port: 1234
- name: myapp-container
image: wangyanglinux/myapp:v1.0
livenessProbe:
httpGet:
port: 80
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 3
readinessProbe:
httpGet:
port: 80
path: /index1.html
initialDelaySeconds: 1
periodSeconds: 3
initContainers:- name: init-myservice
image: wangyanglinux/tools:busybox
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for
myservice; sleep 2; done;']- name: init-mydb
image: wangyanglinux/tools:busybox
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep
2; done;']