K8S 容器重启策略
今天我们来实验容器重启策略。官网描述如下:
Pod 的
spec
中包含一个restartPolicy
字段,其可能取值包括 Always、OnFailure 和 Never。默认值是 Always。Pod 的重启策略(restartPolicy)应用于 Pod 中的 应用容器(也叫主容器,spec.containers 定义的容器)和 常规的 Init 容器(初始化容器)。
Always
:只要容器终止就自动重启容器(这是默认的重启策略)。OnFailure
:只有在容器错误退出(退出状态非零)时才重新启动容器。Never
:不会自动重启已终止的容器。所谓容器终止,就是指容器内运行的主进程终止。
- 在 Linux 容器中,PID 1 是容器的主进程。如果这个进程退出,Docker 或 containerd 等容器运行时会认为该容器已经完成其工作,并停止容器。因此,如果你的应用程序作为 PID 1 运行,那么当应用程序退出时,容器也会终止。
假设有如下三个节点的 K8S 集群:
k8s31master 是控制节点
k8s31node1、k8s31node2 是工作节点
容器运行时是 containerd
一、镜像准备
1.1、镜像拉取
docker pull tomcat:8.5-jre8-alpine
# 查看是否下载完成
docker images | grep tomcat
1.2、镜像导出
docker save -o tomcat-8.5-jre8-alpine.tar.gz 镜像TAG
或者
docker save 镜像TAG -o tomcat-8.5-jre8-alpine.tar.gz
都可以
1.3、镜像导入工作节点 containerd
# k8s31node1 执行
[root@k8s31node1 ~]# ctr -n=k8s.io images import tomcat-8.5-jre8-alpine.tar.gz
[root@k8s31node1 ~]# ctr -n=k8s.io images ls|grep tomcat
# k8s31node2 执行
[root@k8s31node2 ~]# ctr -n=k8s.io images import tomcat-8.5-jre8-alpine.tar.gz
[root@k8s31node2 ~]# ctr -n=k8s.io images ls|grep tomcat
说明:
- ctr 是 containerd 命令
- ctr images import:导入镜像
- -n=k8s.io:K8S 镜像存储命名空间
二、Always
- 编写资源文件
pod-restart-policy-always-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-restart-policy-always
labels:
app: tomcat
spec:
nodeName: k8s31node1
containers:
- name: tomcat
image: tomcat:8.5-jre8-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
nodeName 指定它运行在 node1 节点上。
restartPolicy 没写,没写就是 Always。
- 运行并查看
kubectl apply -f pod-restart-policy-always-demo.yaml
kubectl get pod -owide
pod 已经正常地跑在 k8s31node1 上,且重启次数是 0(也就是没有重启过)。
2.1、正常停止容器
- 查找主进程
# 进入 pod 中的容器
# -- 固定写法
[root@k8s31master ~]# kubectl exec -it pod-restart-policy-always -- /bin/bash
# 查看主进程
bash-4.4# ps -ef
tomcat 的 PID 是 1,说明 tomcat 是容器的 主进程。我们正常停止 tomcat,容器就会正常退出。
- 停止 tomcat 服务
# 运行 tomcat 停止脚本
bash-4.4# /usr/local/tomcat/bin/shutdown.sh
- 查看 pod
会发现容器重启了 1 次。
2.2、非正常停止容器
- 杀死 tomcat 服务
[root@k8s31master ~]# kubectl exec -it pod-restart-policy-always -- /bin/bash
# 杀死 PID=1 的进程,也就是杀死 tomcat
bash-4.4# kill 1
- 查看 pod
重启了第二次。
2.3、结论
Always
:只要容器终止就自动重启容器。
三、OnFailure
- 编写资源文件
pod-restart-policy-onfailure-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-restart-policy-onfailure
labels:
app: tomcat
spec:
restartPolicy: OnFailure
nodeName: k8s31node1
containers:
- name: tomcat
image: tomcat:8.5-jre8-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
restartPolicy: OnFailure
- 运行并查看
kubectl apply -f pod-restart-policy-onfailure-demo.yaml
kubectl get pod -owide
刚开始重启次数是 0。
3.1、正常停止容器
- 停止 tomcat 服务
[root@k8s31master ~]# kubectl exec -it pod-restart-policy-onfailure -- /bin/bash
# 运行 tomcat 停止脚本
bash-4.4# /usr/local/tomcat/bin/shutdown.sh
- 查看 pod
会发现正常停止容器,容器状态是 Completed,但重启次数是0,也就是没有重启。
3.2、非正常停止容器
- 删除 pod 并重新运行
# 删除容器
[root@k8s31master ~]# kubectl delete -f pod-restart-policy-onfailure-demo.yaml
# 重新运行
[root@k8s31master ~]# kubectl apply -f pod-restart-policy-onfailure-demo.yaml
# 查看
[root@k8s31master ~]# kubectl get pod -owide
- 杀死 tomcat 服务
[root@k8s31master ~]# kubectl exec -it pod-restart-policy-onfailure -- /bin/bash
# 杀死 PID=1 的进程,也就是杀死 tomcat
bash-4.4# kill 1
- 查看 pod
重启次数是1,也就重启了一次。
3.3、结论
OnFailure
:只有在容器错误退出(退出状态非零)时才重新启动容器。正常退出,容器状态是 Completed,但不会重启。
四、Never
- 编写资源文件
pod-restart-policy-never-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-restart-policy-never
labels:
app: tomcat
spec:
restartPolicy: Never
nodeName: k8s31node1
containers:
- name: tomcat
image: tomcat:8.5-jre8-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
restartPolicy: Never
- 运行并查看
kubectl apply -f pod-restart-policy-never-demo.yaml
kubectl get pod -owide
4.1、正常停止容器
- 停止 tomcat 服务
[root@k8s31master ~]# kubectl exec -it pod-restart-policy-never -- /bin/bash
# 运行 tomcat 停止脚本
bash-4.4# /usr/local/tomcat/bin/shutdown.sh
- 查看 pod
会发现正常停止容器,容器状态是 Completed,但重启次数是0,也就是没有重启。
4.2、非正常停止容器
- 删除 pod 并重启
# 删除容器
[root@k8s31master ~]# kubectl delete -f pod-restart-policy-never-demo.yaml
# 重新运行
[root@k8s31master ~]# kubectl apply -f pod-restart-policy-never-demo.yaml
# 查看
[root@k8s31master ~]# kubectl get pod -owide
- 杀死 tomcat 服务
[root@k8s31master ~]# kubectl exec -it pod-restart-policy-never -- /bin/bash
# 杀死 PID=1 的进程,也就是杀死 tomcat
bash-4.4# kill 1
- 查看 pod
容器状态是 Error,重启次数是 0,说明并没有重启容器。
4.3、结论
Never
:不会自动重启已终止的容器。