6.1 滚动更新
滚动更新是一次只更新小部分副本,成功后再更新更多的副本,最终完成所有副本的更新。滚动更新的最大好处是零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性。
6.1.1 更新
6.1.1.1 set image
kubectl set image deployment/web container-eh09qq=wordpress:6.8 --record
备注:container-eh09qq为容器名字。
6.1.1.2 edit yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx1001
name: nginx1001
namespace: default
spec:
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx1001
template:
metadata:
labels:
app: nginx1001
spec:
containers:
- image: wangjinxiong/nginx:tools #修改这个
imagePullPolicy: Always
name: nginx
restartPolicy: Always
6.1.2 回滚
查看历史版本
kubectl rollout history deployment/web
查看历史版本的镜像
kubectl rollout history deployment/web --revision=3
回滚到上一个版本
kubectl rollout undo deployment/web
回滚到指定版本
kubectl rollout undo deployment/web --to-revision=1
6.2 状态检测
6.2.1 Init容器
container的restartPolicy有三种:Nerver,OnFailure, Always(默认)。
- Init容器总是运行到成功完成为止。也就是Init容器会退出结束。
- 每个Init容器都必须在下一个Init容器启动之前成功完成。
Init容器可以通过kubectl explain pod.spec.initContainers查看init容器的属性配置。init容器属于 pod 的初始化容器列表。初始化容器是在容器启动之前按顺序执行。如果Pod的Init容器失败,Kubernetes会不断重启该Pod,直到Init容器成功为止(除非Pod对应的restartPolicy为Never)。因为Init容器具有与应用程序容器分离的单独镜像,所以它们的启动相关代码具有如下优势:
- 应用程序镜像可以分离出创建和部署的角色,而没必要联合它们构建一个单独的镜像。
- Init容器使用Linux Namespace,所以相比应用程序容器来说具有不同的文件系统视图。因此,它们能够具有访问Secret的权限,而应用程序则不能。
- 它们必须在应用容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容器能够提供一种简单的阻塞或延迟应用容器的启动方法,直到满足一组先决条件。
- 如果Pod重启,所有Init容器必须重新执行
- Init容器具有应用容器的所有字段,除了readinessProbe。因为Init容器无法定义不同于完成(completion)的就绪(readiness)之外的其他状态。
Init Container(初始化容器) 在很多应用场景中,应用在启动之前都需要进行如下初始化操作。
- 等待其他关联组件正确运行(例如数据库或某个后台服务)。
- 基于环境变量或配置模板生成配置文件。 ◎ 从远程数据库获取本地所需配置,或者将自身注册到某个中央 数据库中。
- 下载相关依赖包,或者对系统进行一些预配置操作。
例子:
cat init-test0915.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx0915
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx0915
template:
metadata:
labels:
app: nginx0915
spec:
volumes:
- name: host-time
hostPath:
path: /etc/localtime
type: ''
- name: pvc0915
persistentVolumeClaim:
claimName: pvc0915
initContainers:
- name: busybox
image: wangjinxiong/busybox:1.28.4.1
imagePullPolicy: IfNotPresent
command:
- cp
- "/home/index.html"
- "/work-dir"
volumeMounts:
- mountPath: /etc/localtime
name: host-time
readOnly: true
- name: pvc0915
mountPath: /work-dir
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: web80
volumeMounts:
- mountPath: /etc/localtime
name: host-time
readOnly: true
- name: pvc0915
mountPath: /usr/share/nginx/html
6.2.2 LivenessProbe 和ReadinessProbe
Kubernetes 对 Pod 的健康状态可以通过两类探针来检查: LivenessProbe 和ReadinessProbe,kubelet定期执行这两类探针来诊断容 器的健康状况。
(1)LivenessProbe探针:用于判断容器是否存活(Running状 态),如果LivenessProbe探针探测到容器不健康,则kubelet将杀掉该容器,并根据容器的重启策略做相应的处理。如果一个容器不包含 LivenessProbe探针,那么kubelet认为该容器的LivenessProbe探针返回的 值永远是Success。
(2)ReadinessProbe探针:用于判断容器服务是否可用(Ready状 态),达到Ready状态的Pod才可以接收请求。对于被Service管理的 Pod,Service与Pod Endpoint的关联关系也将基于Pod是否Ready进行设 置。如果在运行过程中Ready状态变为False,则系统自动将其从Service 的后端Endpoint列表中隔离出去,后续再把恢复到Ready状态的Pod加回 后端Endpoint列表。这样就能保证客户端在访问Service时不会被转发到 服务不可用的Pod实例上。
LivenessProbe和ReadinessProbe均可配置以下三种实现方式。
(1)ExecAction:在容器内部执行一个命令,如果该命令的返回 码为0,则表明容器健康。 在下面的例子中,通过执行“cat /tmp/health”命令来判断一个容器运 行是否正常。在该Pod运行后,将在创建/tmp/health文件10s后删除该文 件,而LivenessProbe健康检查的初始探测时间(initialDelaySeconds)为 15s,探测结果是Fail,将导致kubelet杀掉该容器并重启它。
(2)TCPSocketAction:通过容器的IP地址和端口号执行TCP检 查,如果能够建立TCP连接,则表明容器健康。
在下面的例子中,通过与容器内的localhost:80建立TCP连接进行健 康检查:
(3)HTTPGetAction:通过容器的IP地址、端口号及路径调用 HTTP Get方法,如果响应的状态码大于等于200且小于400,则认为容器 健康。 在下面的例子中,kubelet定时发送HTTP请求到 localhost:80/_status/healthz来进行容器应用的健康检查。
探测的时间:
(1) initialDelaySeconds: 10 指定容器启动10 之后开始执行Liveness探测,我们一般会根据应用启动的准备时间来设置。比如某个应用正常启动要花30秒,那么initialDelaySeconds的值就应该大于30。
(2) periodSeconds: 5 指定每5秒执行一次Liveness 探测。Kubernetes如果连续执行3次Liveness 探测均失败,则会杀掉并重启容器。
(3) failureThreshold:当探测失败时,Kubernetes将在放弃之前重试的次数。存活探测情况下的放弃就意味着重新启动容器,就绪探测情况下的放弃Pod会被打上未就绪的标签。默认值是3,最小值是1。
(4) timeoutSeconds:探测的超时后等待多少秒。默认值是1秒,最小值是1。(在Kubernetes 1.20版本之前,exec探针会忽略timeoutSeconds,探针会无限期地持续运行,甚至可能超过所配置的限期,直到返回结果为止。)
6.2.2.1 LivenessProbe例子
6.2.2.1.1 ExecAction
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod0922
spec:
containers:
- name: liveness-exec-container
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/live; sleep 30; rm -rf /tmp/live; sleep 600"]
livenessProbe:
exec:
command: ["test","-e","/tmp/live"]
initialDelaySeconds: 1
periodSeconds: 3
6.2.2.1.2 TCPSocketAction
apiVersion: v1
kind: Pod
metadata:
name: liveness-tcpsocket-pod0922
spec:
containers:
- name: liveness-tcpsocket-container
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 10
6.2.2.1.3 HTTPGetAction
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget-pod0922
spec:
containers:
- name: liveness-httpget-container
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 10
6.2.2.2 ReadinessProbe
6.2.2.2.1 ExecAction
apiVersion: v1
kind: Pod
metadata:
name: readiness-exec-pod0922
spec:
containers:
- name: readiness-exec-container
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/live; sleep 30; rm -rf /tmp/live; sleep 600"]
readinessProbe:
exec:
command: ["test","-e","/tmp/live"]
initialDelaySeconds: 1
periodSeconds: 3
6.2.2.2.2 TCPSocketAction
apiVersion: v1
kind: Pod
metadata:
name: readiness-tcpsocket-pod0922
spec:
containers:
- name: readiness-tcpsocket-container
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 10
6.2.2.2.3 HTTPGetAction
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget-pod0922
spec:
containers:
- name: readiness-httpget-container
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 10