K8s(四)Pod资源——pod生命周期、重启策略、容器钩子与容器探测
如题,主要内容包括pod重启策略、初始化容器、容器钩子与容器探测的内容
目录
参考资料
Pod的生命周期可以分为以下几个阶段:
- Pending(等待):在这个阶段,Pod被创建,并且正在等待被调度到一个节点上运行。此时,Pod的容器镜像正在下载,网络和存储资源正在分配。
- Running(运行中):一旦Pod成功调度到节点上,它进入Running状态。在此阶段,Pod中的容器开始在节点上运行,并且可以处理请求。
- Succeeded(成功):如果Pod中的所有容器成功完成了它们的任务,并且退出状态码为0,那么Pod将进入Succeeded状态。一般情况下,这意味着Pod已经完成了它的工作。
- Failed(失败):如果Pod中的任何容器以非零的退出状态码退出,或者其中一个容器无法启动,那么Pod将进入Failed状态。这表示Pod执行出现了问题。
- Unknown(未知):如果无法获取Pod的状态信息,或者与Pod关联的节点失去联系,那么Pod将进入Unknown状态。
除了这些基本的生命周期阶段,Pod还可以经历一些其他的状态转换,例如:
- Terminating(终止中):当Pod被删除或终止时,它进入Terminating状态。在此阶段,Pod的容器正在停止,并且资源正在释放。
- Evicted(驱逐):如果节点上的资源不足,Kubernetes可能会驱逐Pod,将其从节点上移除。这将导致Pod进入Evicted状态。
- ContainerCreating(创建容器):当Pod的容器正在创建时,Pod将进入ContainerCreating状态。这通常发生在调度期间,当容器镜像正在下载或容器正在启动时。
这些状态和状态转换代表了Pod在其生命周期中可能经历的不同阶段和情况。Kubernetes通过监控和管理Pod的状态来确保Pod的正常运行和可靠性。 ——以上内容由gpt生成
Pod生命周期
Pod生命周期一般包含以下几个流程:
1、创建pause容器
主要目的是为了实现Pod级别的网络和存储隔离。当Pod中有多个容器时,这些容器共享相同的网络命名空间和存储卷。Pause容器的存在使得每个容器都可以共享同一个网络命名空间和存储卷,从而实现它们之间的通信和数据共享。
2、创建初始化容器
初始化容器是在Kubernetes中用于在主应用容器之前运行的特殊容器。它的作用是在主应用启动之前完成一些准备工作,比如加载配置、准备数据或解决依赖项。它可以确保主应用容器在启动时具备必要的环境和资源。
初始化容器是串行运行的,一个初始化容器运行成功才能运行下一个初始化容器,全部执行完才能执行主容器,并且初始化容器内的数据可以被主容器用到。
初始化容器不支持pod就绪探测,因为初始化容器在pod就绪之前就已经完成
如果初始化容器运行失败,k8s也会根据重启策略restartPolicy决定是否进行重启
3、主容器
4、前置钩子/容器停止前钩子(PreStop Hook)
5、后置钩子/容器启动后钩子(PostStart Hook) 后置钩子是在容器启动后立即运行的命令或脚本。它可以用于在容器启动后执行一些初始化任务,例如加载配置或启动辅助进程。
Pod重启策略
当容器异常时,可以通过设置RestartPolicy字段,设置pod重启策略来对pod进行重启等操作
#查看帮助
kubectl explain pod.spec.restartPolicy
KIND: Pod
VERSION: v1
FIELD: restartPolicy <string>
DESCRIPTION:
Restart policy for all containers within the pod. One of Always, OnFailure,
Never. Default to Always. More info:
<https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy>
Possible enum values:
- `"Always"` #只要异常退出,立即自动重启
- `"Never"` #不会重启容器
- `"OnFailure"`#容器错误退出,即退出码不为0时,则自动重启
#测试Always策略,创建always.yaml
cat > always.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: always-pod
namespace: default
spec:
restartPolicy: Always
containers:
- name: test-pod
image: docker.io/library/tomcat
imagePullPolicy: IfNotPresent
EOF
kubectl apply -f always.yaml
kubectl get po #查看状态
NAME READY STATUS RESTARTS AGE
always-pod 1/1 Running 0 22s
#进入容器去关闭容器
kubectl exec -it always-pod -- /bin/bash
shutdown.sh
#查看当前状态,可以看到always-pod重启计数器为1
kubectl get po
NAME READY STATUS RESTARTS AGE
always-pod 1/1 Running 1 (5s ago) 70s
#测试never策略,创建never.yaml
cat > never.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: never-pod
namespace: default
spec:
restartPolicy: Never
containers:
- name: test-pod
image: docker.io/library/tomcat
imagePullPolicy: IfNotPresent
EOF
kubectl apply -f never.yaml
kubectl exec -it never-pod -- /bin/bash
shutdown.sh
#不会重启,状态为completed
kubectl get pods | grep never
never-pod 0/1 Completed 0 73s
#测试OnFailure策略,创建onfailure.yaml
cat > onfailure.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: onfailure-pod
namespace: default
spec:
restartPolicy: OnFailure
containers:
- name: test-pod
image: docker.io/library/tomcat
imagePullPolicy: IfNotPresent
EOF
kubectl apply -f onfailure.yaml
#进去后进行异常退出
kubectl exec -it onfailure-pod -- /bin/bash
kill 1
#查看pods状态,已经重启
kubectl get po | grep onfailure
onfailure-pod 1/1 Running 1 (43s ago) 2m11s
#进入后进行正常退出
kubectl exec -it onfailure-pod -- /bin/bash
shutdown.sh
#查看pods状态,没有重启,进入completed状态
kubectl get po | grep onfailure
onfailure-pod 0/1 Completed 1 3m58s
#清理环境
kubectl delete -f always.yaml
kubectl delete -f never.yaml
kubectl delete -f onfailure.yaml
初始化容器
参考资料Init Containers | Kubernetes
#查看帮助
kubectl explain pod.spec.initContainers #初始化容器字段与container区别不大
#创建一个初始化容器的yaml
cat > init1.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: init1
namespace: default
spec:
initContainers:
- name: init1
image: docker.io/library/nginx
imagePullPolicy: IfNotPresent
command: ["echo","the first test"]
- name: init2
image: docker.io/library/nginx
imagePullPolicy: IfNotPresent
command: ["/bin/bash","-c","echo 'the secend test'"]
containers:
- name: test
image: docker.io/library/nginx
imagePullPolicy: IfNotPresent
EOF
kubectl apply -f init1.yaml
#持续监控pod状态,可以看到经过了两个init状态,初始化完成后进入running状态
kubectl get pods -w
NAME READY STATUS RESTARTS AGE
init1 0/1 Pending 0 0s
init1 0/1 Pending 0 0s
init1 0/1 Init:0/2 0 0s
init1 0/1 Init:0/2 0 1s
init1 0/1 Init:1/2 0 2s
init1 0/1 PodInitializing 0 3s
init1 1/1 Running 0 4s
容器钩子
参考文档 Container Lifecycle Hooks | Kubernetes
容器启动后钩子(PostStart
容器停止前钩子(PreStop
#查看帮助
kubectl explain pods.spec.containers.lifecycle
postStart <Object>
preStop <Object>
kubectl explain pods.spec.containers.lifecycle.postStart
exec <Object>
httpGet <Object>
tcpSocket <Object>
#创建启动后钩子的yaml
cat > hook.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: hook
namespace: default
spec:
containers:
- name: test
image: docker.io/library/nginx
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo 'test'"]
preStop:
exec:
command: ["/bin/sh","-c","pkill ssh"] #在pod停止前,使用命令关闭某些进程
EOF
kubectl apply -f hook.yaml
get pods -w
NAME READY STATUS RESTARTS AGE
init1 1/1 Running 0 57m
hook 0/1 Pending 0 0s
hook 0/1 Pending 0 0s
hook 0/1 ContainerCreating 0 0s
hook 0/1 ContainerCreating 0 0s
hook 1/1 Running 0 1s
kubectl delete -f hook.yaml
kubectl delete -f init1.yaml
容器探测
容器探测包括启动探测,就绪探测与存活探测
1、启动探测Startup Probe
- 用于检测容器内的应用程序是否仍在运行。
- 如果启动探测失败,则 Kubernetes 认为容器处于不健康状态,并尝试重新启动容器。
- 如果启动探测成功,则容器被认为是健康的,并继续正常运行。
- 常见的启动探测方式包括发送 HTTP 请求到容器的特定端点或执行命令并检查返回值。
2、就绪探测Readiness Probe
- 用于检测容器是否已经启动完成并准备好接收流量。
- 就绪探测与存活探测类似,但是 在容器启动期间进行检测,而不仅仅是容器启动后。
- 如果就绪探测失败,则 Kubernetes 认为容器尚未启动完成,将从服务负载均衡中剔除该容器。
- 如果就绪探测成功,则容器被认为已经启动完成并准备好接收流量。
- 常见的就绪探测方式与存活探测相似,包括发送 HTTP 请求或执行命令。
3、存活探测Liveness Probe
- 用于检测容器是否准备好接收流量。
- 如果存活探测失败,则 Kubernetes 认为容器尚未准备好处理流量,将从服务负载均衡中剔除该容器。
- 如果存活探测成功,则容器被认为是准备好接收流量的,并加入到服务负载均衡中。
- 常见的存活探测方式包括发送 HTTP 请求到容器的特定端点或执行命令并检查返回值。
存活探测与就绪探测的区别:
可以采取相同的探测方式,只是处理方式不同,就绪探测失败后将pod的IP与port从对应的endpoint列表中删除,也就是会拒绝外部对其进行访问;存活探测探测失败后将根据重启策略进行处理 存活探测关注容器内应用程序的运行状态,用于重新启动不健康的容器,确保应用程序持续运行。
就绪探测关注容器是否已经准备好接收流量,用于在容器启动过程中防止将流量发送给尚未完全准备好的容器。
k8s中启动探测会最先进行,随后就绪探测和存活探测会同时进行
参考资料:配置存活、就绪和启动探针 | Kubernetes
启动探测
#查看帮助
kubectl explain pod.spec.containers.startupProbe
exec <Object> #执行命令,如果返回为0则探测成功
failureThreshold <integer> #失败的重试次数,超过就视为失败,默认为3
grpc <Object> #用于对接grpc端口
httpGet <Object> #调用http get,响应的状态码>=200且<400则探测成功
initialDelaySeconds <integer> #启动后多久开始探测,默认为0
periodSeconds <integer> #探测的时间间隔,默认10秒
successThreshold <integer> #需要探测成功的次数,默认为1,在启动和存活探测中必须为1
tcpSocket <Object> #通过ip和port进行tcp检查,如果能建立连接则探测成功
terminationGracePeriodSeconds <integer> #在删除Pod之前等待的时间,用于清理
timeoutSeconds <integer> #等待响应的超时时间,默认为1
#使用command
cat > qidongtance-command.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: qidong
namespace: default
spec:
containers:
- name: test
image: docker.io/library/nginx
imagePullPolicy: IfNotPresent
startupProbe:
exec:
command:
- "/bin/sh"
- "-c"
- "echo '1'"
initialDelaySeconds: 10 #启动后10秒开始探测
periodSeconds: 5 #探测间隔5秒
successThreshold: 1 #成功一次即成功
failureThreshold: 3 #失败可重试三次
timeoutSeconds: 5 #超时5秒即失败
EOF
kubectl apply -f qidongtance-command.yaml
#看到过了10+5秒进入了就绪状态
kubectl get pods -w
NAME READY STATUS RESTARTS AGE
qidong 0/1 Pending 0 0s
qidong 0/1 Pending 0 0s
qidong 0/1 ContainerCreating 0 0s
qidong 0/1 ContainerCreating 0 1s
qidong 0/1 Running 0 2s
qidong 0/1 Running 0 16s
qidong 1/1 Running 0 16s
#修改命令为错误的命令,使其不正常执行,返回码为1
...
startupProbe:
exec:
command:
- "/bin/sh"
- "-c"
- "qweasdaq"
...
kubectl delete -f qidongtance-command.yaml
kubectl apply -f qidongtance-command.yaml
#pod重启了4次,后面显示失败
kubectl get pods -w
NAME READY STATUS RESTARTS AGE
qidong 1/1 Running 0 78s
qidong 1/1 Terminating 0 5m6s
qidong 1/1 Terminating 0 5m6s
qidong 0/1 Terminating 0 5m6s
qidong 0/1 Terminating 0 5m6s
qidong 0/1 Terminating 0 5m6s
qidong 0/1 Pending 0 0s
qidong 0/1 Pending 0 0s
qidong 0/1 ContainerCreating 0 0s
qidong 0/1 ContainerCreating 0 1s
qidong 0/1 Running 0 1s
qidong 0/1 Running 1 (2s ago) 27s
qidong 0/1 Running 2 (2s ago) 47s
qidong 0/1 Running 2 (5s ago) 50s
qidong 0/1 Running 3 (1s ago) 66s
qidong 0/1 Running 4 (1s ago) 86s
qidong 0/1 CrashLoopBackOff 4 (1s ago) 106s
#清理
kubectl delete -f qidongtance-command.yaml
#使用tcpsocket
cat > qidongtance-tcp.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: qidong
namespace: default
spec:
containers:
- name: test
image: docker.io/library/nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80 #给一个容器端口80
startupProbe:
tcpSocket:
port: 80 #探测80端口
initialDelaySeconds: 10
periodSeconds: 5
successThreshold: 1
failureThreshold: 3
timeoutSeconds: 5
EOF
kubectl apply -f qidongtance-tcp.yaml
#成功运行
kubectl get pods -w
NAME READY STATUS RESTARTS AGE
qidong 0/1 Pending 0 0s
qidong 0/1 Pending 0 0s
qidong 0/1 ContainerCreating 0 0s
qidong 0/1 ContainerCreating 0 1s
qidong 0/1 Running 0 1s
qidong 0/1 Running 0 16s
qidong 1/1 Running 0 16s
qidong 1/1 Running 0 22s
#curl访问
curl 10.10.234.91:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="<http://nginx.org/>">nginx.org</a>.<br/>
Commercial support is available at
<a href="<http://nginx.com/>">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
#清理
kubectl delete -f qidongtance-tcp.yaml
#使用http get
cat > qidongtance-httpget.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: qidong
namespace: default
spec:
containers:
- name: test
image: docker.io/library/nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
startupProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 5
successThreshold: 1
failureThreshold: 3
timeoutSeconds: 5
EOF
kubectl apply -f qidongtance-httpget.yaml
kubectl get pods -w #运行正常
NAME READY STATUS RESTARTS AGE
qidong 0/1 Pending 0 0s
qidong 0/1 Pending 0 0s
qidong 0/1 ContainerCreating 0 0s
qidong 0/1 ContainerCreating 0 1s
qidong 0/1 Running 0 2s
qidong 0/1 Running 0 16s
qidong 1/1 Running 0 16s
#curl测试
curl 10.10.234.93:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="<http://nginx.org/>">nginx.org</a>.<br/>
Commercial support is available at
<a href="<http://nginx.com/>">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
#清理
kubectl delete -f qidongtance-httpget.yaml
存活探测
#查看帮助,与启动探测相似
kubectl explain pod.spec.containers.livenessProbe
#存活探测每隔一段时间进行探测,确保业务的存活
#存活探测
cat > cunhuotance-command.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: cunhuo
namespace: default
spec:
containers:
- name: test
image: busybox:1.28
imagePullPolicy: IfNotPresent
args: #探针测试文件
- "/bin/sh"
- "-c"
- "touch /1.txt; sleep 20; rm -rf /1.txt" #使其20秒后删除该文件
livenessProbe:
initialDelaySeconds: 10
periodSeconds: 5
exec: #探测的命令
command:
- cat
- /1.txt
EOF
kubectl apply -f cunhuotance-command.yaml
#查看发现经过20秒,探活失败,容器结束,重启后探活,失败循环往复
kubectl get pods -w
NAME READY STATUS RESTARTS AGE
cunhuo 1/1 Running 0 8s
cunhuo 0/1 Completed 0 21s
cunhuo 1/1 Running 1 (2s ago) 22s
cunhuo 0/1 Completed 1 (23s ago) 43s
cunhuo 0/1 CrashLoopBackOff 1 (4s ago) 45s
cunhuo 1/1 Running 2 (15s ago) 56s
kubectl get pods -w
NAME READY STATUS RESTARTS AGE
cunhuo 0/1 CrashLoopBackOff 2 (12s ago) 88s
cunhuo 1/1 Running 3 (32s ago) 108s
cunhuo 0/1 Completed 3 (52s ago) 2m8s
cunhuo 0/1 CrashLoopBackOff 3 (2s ago) 2m10s
cunhuo 0/1 CrashLoopBackOff 3 (26s ago) 2m34s
#清理
kubectl delete -f cunhuotance-command.yaml
#使用httpdget与tcp需要结合代码进行演示,过于繁杂就不演示了
就绪探测
就绪探测主要用于与pod与service相对接的场景下进行使用
探测pod内接口,探测成功则代表程序启动,就开放对外的接口访问,如果探测失败,则暂时不开放接口访问,直到探测成功
#就绪探测举例
apiVersion: v1
kind: Service
metadata:
name: java
spec:
type: NodePort
ports:
- name: yewu
port: 8080
targetPort: 8080
nodePort: 31180 #封装到外侧的端口
- name: guanli
port: 8081
targetPort: 8081
nodePort: 31181
selector:
app: java
---
apiVersion: v1
kind: Pod
metadata:
name: java
spec:
containers:
- name: java
labels:
app: java
image: xxxxx #封装了代码的容器镜像
imagePullPolicy: IfNotPresent
ports:
- name: yewu
containerPort: 8080
- name: guanli
containerPort: 8081
readinessProbe:
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 5
httpGet: #进行就绪探测8081端口
scheme: HTTP
port: 8081
path: xxx
更多推荐
所有评论(0)