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、镜像拉取

bash 复制代码
docker pull tomcat:8.5-jre8-alpine
bash 复制代码
# 查看是否下载完成
docker images | grep tomcat

1.2、镜像导出

bash 复制代码
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

bash 复制代码
# 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

bash 复制代码
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。

  • 运行并查看
bash 复制代码
kubectl apply -f pod-restart-policy-always-demo.yaml
kubectl get pod -owide

pod 已经正常地跑在 k8s31node1 上,且重启次数是 0(也就是没有重启过)。

2.1、正常停止容器

  • 查找主进程
bash 复制代码
# 进入 pod 中的容器
# -- 固定写法
[root@k8s31master ~]# kubectl exec -it pod-restart-policy-always -- /bin/bash
# 查看主进程
bash-4.4# ps -ef

tomcat 的 PID 是 1,说明 tomcat 是容器的 主进程。我们正常停止 tomcat,容器就会正常退出。

  • 停止 tomcat 服务
bash 复制代码
# 运行 tomcat 停止脚本
bash-4.4# /usr/local/tomcat/bin/shutdown.sh
  • 查看 pod

会发现容器重启了 1 次。

2.2、非正常停止容器

  • 杀死 tomcat 服务
bash 复制代码
[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

bash 复制代码
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

  • 运行并查看
bash 复制代码
kubectl apply -f pod-restart-policy-onfailure-demo.yaml
kubectl get pod -owide

刚开始重启次数是 0。

3.1、正常停止容器

  • 停止 tomcat 服务
bash 复制代码
[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 并重新运行
bash 复制代码
# 删除容器
[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 服务
bash 复制代码
[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

bash 复制代码
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

  • 运行并查看
bash 复制代码
kubectl apply -f pod-restart-policy-never-demo.yaml
kubectl get pod -owide

4.1、正常停止容器

  • 停止 tomcat 服务
bash 复制代码
[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 并重启
bash 复制代码
# 删除容器
[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 服务
bash 复制代码
[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:不会自动重启已终止的容器。

相关推荐
Serverless 社区7 分钟前
阿里云函数计算 AgentRun 全新发布,构筑智能体时代的基础设施
人工智能·阿里云·云原生·serverless·云计算
小马爱打代码1 小时前
zookeeper:一致性原理和算法
分布式·zookeeper·云原生
1024find4 小时前
Spark on k8s部署
大数据·运维·容器·spark·kubernetes
kura_tsuki5 小时前
[Docker集群] Docker 容器入门
运维·docker·容器
能不能别报错17 小时前
K8s学习笔记(十六) 探针(Probe)
笔记·学习·kubernetes
能不能别报错18 小时前
K8s学习笔记(十四) DaemonSet
笔记·学习·kubernetes
火星MARK20 小时前
k8s面试题
容器·面试·kubernetes
Serverless社区21 小时前
阿里云函数计算 AgentRun 全新发布,构筑智能体时代的基础设施
阿里云·云原生·serverless·函数计算
赵渝强老师21 小时前
【赵渝强老师】Docker容器的资源管理机制
linux·docker·容器·kubernetes
能不能别报错1 天前
K8s学习笔记(十五) pause容器与init容器
笔记·学习·kubernetes