14

我目前正在使用 Deployments 来管理我的 K8S 集群中的 pod。

我的一些部署需要 2 个 pod/副本,有些需要 3 个 pod/副本,其中一些只需要 1 个 pod/副本。我遇到的问题是带有一个 pod/副本的问题。

我的 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但这似乎不起作用。

任何想法为什么这不起作用?

4

3 回答 3

24

它似乎是maxUnavailable: 1; 我能够轻松地重现您设置该值的体验,并通过将其设置为maxUnavailable: 0

这是调度程序如何达到您所遇到的行为的“伪证明”:

因为replicas: 1,k8s 所需的状态恰好是一个 Pod 中的一个Ready。在滚动更新操作期间,这是您请求的策略,它将创建一个新 Pod,使总数达到 2。但是您授予 k8s 权限以使一个 Pod处于不可用状态,并指示它保留所需数量的Pod Pod 为 1。因此,它满足了所有这些约束:1 个 Pod,所需数量,处于不可用状态,由 RU 策略允许。

通过将 设置maxUnavailable为零,您正确地指示 k8s 永远不要让任何 Pod 不可用,即使这意味着 Pod 会replica在短时间内激增超过计数

于 2017-09-23T07:27:36.597 回答
2

将策略类型设置为RollingUpdate新的 pod 会在旧的 pod 被删除之前创建,即使只有一个副本也是如此。策略类型Recreate在创建新 Pod 之前杀死旧 Pod https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment

于 2020-04-22T13:45:57.803 回答
1

正如已经回答的那样,您可以将 maxUnavailable 设置为 0 以获得所需的结果。一些额外的注意事项:

  1. 当使用挂载将由新 pod 使用的单个特定卷的有状态服务时,您不应期望这会起作用。该卷将附加到即将更换的 pod,因此无法附加到新 pod。

  2. 文档指出,如果您已将 .spec.strategy.rollingUpdate.maxSurge 设置为 0,则无法将其设置为 0。

https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#max-unavailable

于 2017-10-12T01:50:16.763 回答