Kubernetes - 滚动更新杀死旧 pod 而不启动新 pod
Kubernetes - Rolling update killing off old pod without bringing up new one
我目前正在使用 Deployments 在我的 K8S 集群中管理我的 pods。
我的一些部署需要 2 个 pods/replicas,一些需要 3 个 pods/replicas,一些只需要 1 个 pod/replica。我遇到的问题是 pod/replica.
我的 YAML 文件是:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: user-management-backend-deployment
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 2
selector:
matchLabels:
name: user-management-backend
template:
metadata:
labels:
name: user-management-backend
spec:
containers:
- name: user-management-backend
image: proj_csdp/user-management_backend:3.1.8
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
livenessProbe:
httpGet:
port: 8080
path: /user_management/health
initialDelaySeconds: 300
timeoutSeconds: 30
readinessProbe:
httpGet:
port: 8080
path: /user_management/health
initialDelaySeconds: 10
timeoutSeconds: 5
volumeMounts:
- name: nfs
mountPath: "/vault"
volumes:
- name: nfs
nfs:
server: kube-nfs
path: "/kubenfs/vault"
readOnly: true
我有一个旧版本 运行 没问题。
# kubectl get po | grep user-management-backend-deployment
user-management-backend-deployment-3264073543-mrrvl 1/1 Running 0 4d
现在我要更新图片:
# kubectl set image deployment user-management-backend-deployment user-management-backend=proj_csdp/user-management_backend:3.2.0
现在按照 RollingUpdate 设计,K8S 应该在保持旧 pod 工作的同时启动新 pod,只有当新 pod 准备好接收流量时,旧 pod 才会被删除。但是我看到的是旧的 pod 被立即删除并创建了新的 pod,然后开始占用流量需要时间,这意味着我必须降低流量。
# kubectl get po | grep user-management-backend-deployment
user-management-backend-deployment-3264073543-l93m9 0/1 ContainerCreating 0 1s
# kubectl get po | grep user-management-backend-deployment
user-management-backend-deployment-3264073543-l93m9 1/1 Running 0 33s
我用过 maxSurge: 2
& maxUnavailable: 1
但这似乎不起作用。
知道为什么这不起作用吗?
好像是maxUnavailable: 1
;我能够轻而易举地重现您设置该值的体验,并通过将其设置为 maxUnavailable: 0
轻而易举地获得正确的体验
这是我的 "pseudo-proof" 调度程序如何达到您遇到的行为:
因为replicas: 1
,k8s 的理想状态恰好是Ready
中的一个Pod。在滚动更新操作期间,这是您请求的策略,它将创建一个新的 Pod,使总数达到 2。但是您授予 k8s 允许 一个 Pod 处于不可用状态,并且您指示它将 desired 数量 Pods 保持为 1。因此,它满足了所有这些约束:1 个 Pod,所需数量,处于不可用状态,允许通过R-U策略。
通过将 maxUnavailable
设置为零,您可以正确地指示 k8s 永远不会让任何 Pod 不可用,即使这意味着短时间内 Pods 超过 replica
计数
如前所述,您可以将 maxUnavailable 设置为 0 以获得所需的结果。一些额外的注意事项:
当使用有状态服务装载将由新 pod 使用的单个特定卷时,您不应该期望这会起作用。该卷将附加到即将更换的 pod,因此无法附加到新的 pod。
文档指出,如果您已将 .spec.strategy.rollingUpdate.maxSurge 设置为 0,则不能将其设置为 0。
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#max-unavailable
将策略类型设置为 RollingUpdate
,即使只有一个副本,也会在删除旧容器之前创建一个新容器。策略类型 Recreate
在创建新策略之前杀死旧的 pods
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment
我目前正在使用 Deployments 在我的 K8S 集群中管理我的 pods。
我的一些部署需要 2 个 pods/replicas,一些需要 3 个 pods/replicas,一些只需要 1 个 pod/replica。我遇到的问题是 pod/replica.
我的 YAML 文件是:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: user-management-backend-deployment
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 2
selector:
matchLabels:
name: user-management-backend
template:
metadata:
labels:
name: user-management-backend
spec:
containers:
- name: user-management-backend
image: proj_csdp/user-management_backend:3.1.8
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
livenessProbe:
httpGet:
port: 8080
path: /user_management/health
initialDelaySeconds: 300
timeoutSeconds: 30
readinessProbe:
httpGet:
port: 8080
path: /user_management/health
initialDelaySeconds: 10
timeoutSeconds: 5
volumeMounts:
- name: nfs
mountPath: "/vault"
volumes:
- name: nfs
nfs:
server: kube-nfs
path: "/kubenfs/vault"
readOnly: true
我有一个旧版本 运行 没问题。
# kubectl get po | grep user-management-backend-deployment
user-management-backend-deployment-3264073543-mrrvl 1/1 Running 0 4d
现在我要更新图片:
# kubectl set image deployment user-management-backend-deployment user-management-backend=proj_csdp/user-management_backend:3.2.0
现在按照 RollingUpdate 设计,K8S 应该在保持旧 pod 工作的同时启动新 pod,只有当新 pod 准备好接收流量时,旧 pod 才会被删除。但是我看到的是旧的 pod 被立即删除并创建了新的 pod,然后开始占用流量需要时间,这意味着我必须降低流量。
# kubectl get po | grep user-management-backend-deployment
user-management-backend-deployment-3264073543-l93m9 0/1 ContainerCreating 0 1s
# kubectl get po | grep user-management-backend-deployment
user-management-backend-deployment-3264073543-l93m9 1/1 Running 0 33s
我用过 maxSurge: 2
& maxUnavailable: 1
但这似乎不起作用。
知道为什么这不起作用吗?
好像是maxUnavailable: 1
;我能够轻而易举地重现您设置该值的体验,并通过将其设置为 maxUnavailable: 0
这是我的 "pseudo-proof" 调度程序如何达到您遇到的行为:
因为replicas: 1
,k8s 的理想状态恰好是Ready
中的一个Pod。在滚动更新操作期间,这是您请求的策略,它将创建一个新的 Pod,使总数达到 2。但是您授予 k8s 允许 一个 Pod 处于不可用状态,并且您指示它将 desired 数量 Pods 保持为 1。因此,它满足了所有这些约束:1 个 Pod,所需数量,处于不可用状态,允许通过R-U策略。
通过将 maxUnavailable
设置为零,您可以正确地指示 k8s 永远不会让任何 Pod 不可用,即使这意味着短时间内 Pods 超过 replica
计数
如前所述,您可以将 maxUnavailable 设置为 0 以获得所需的结果。一些额外的注意事项:
当使用有状态服务装载将由新 pod 使用的单个特定卷时,您不应该期望这会起作用。该卷将附加到即将更换的 pod,因此无法附加到新的 pod。
文档指出,如果您已将 .spec.strategy.rollingUpdate.maxSurge 设置为 0,则不能将其设置为 0。
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#max-unavailable
将策略类型设置为 RollingUpdate
,即使只有一个副本,也会在删除旧容器之前创建一个新容器。策略类型 Recreate
在创建新策略之前杀死旧的 pods
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment