问题-具有多个活动副本集的Kubernetes部署

时间:2020-03-02 06:24:00

标签: kubernetes kubernetes-helm

我有一个Kubernetes部署,它是两个具有不同配置的ACTIVE ReplicaSet的所有者/父级。

此设置由Helm管理。

我尝试制作revisionHistory: 0。由于ReplicaSet处于非活动状态,因此无法使用。由于节点上的资源限制,这个旧的ReplicaSet尝试启动一个pod并使其处于挂起状态。

我尝试更新Deployment,并且仅更新了新的ReplicaSet。旧的保持不变。

我也无法删除此ReplicaSet。这给我带来了很多麻烦。

有人可以帮我解决这个问题吗?

头盔部署模板-

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example
  namespace: kube-system
spec:
  selector:
    matchLabels:
      k8s-app: example
  replicas: 1
  template:
    metadata:
      labels:
        k8s-app: example
    spec:
      serviceAccountName: example
      nodeSelector:
        node-role: example-node
      containers:
      - name: example
        image: example-image:vX.X.X
        resources:
          requests:
            cpu: 100m
        ports:
        - name: example-port
          containerPort: XXXX
        - name: example-port-1
          containerPort: XXXX
        readinessProbe:
          httpGet:
            path: /example
            port: XXXX
          initialDelaySeconds: 5
          timeoutSeconds: 5
      - name: example-sidecar
        image: example-image-sidecar:vX.X.X
        resources:
          limits:
            memory: 400Mi
          requests:
            cpu: 100m
        env:
          - name: MY_POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: MY_POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
        command:
          - command
          - --container=example
          - --cpu=200m
          - --extra-cpu=10m
          - --memory=300Mi
          - --extra-memory=2Mi
          - --threshold=5
          - --deployment=example

堆栈:使用Kops和Helm 2.13.1在AWS EC2上部署的独立K8

输出-

kubectl get rs -o wide -n kube-system | grep example

NAME               DESIRED  CURRENT READY   AGE     CONTAINERS IMAGES SELECTOR
example-6d4f99bc54 0        0       0       12h     example,example-sidecar example-image:vX.X.X,example-image-sidecar:vX.X.X k8s-app=example,pod-template-hash=6d4f99bc54
example-59d46955b6 0        0       0       13h     example,example-sidecar example-image:vX.X.X,example-image-sidecar:vX.X.X k8s-app=example,pod-template-hash=59d46955b6
example-5855866cdb 0        0       0       18h     example,example-sidecar example-image:vX.X.X,example-image-sidecar:vX.X.X k8s-app=example,pod-template-hash=5855866cdb
example-ccc5cf5cd0 0        0       0       18h     example,example-sidecar example-image:vX.X.X,example-image-sidecar:vX.X.X k8s-app=example,pod-template-hash=ccc5cf5cd
example-66db79f578 1        1       0       19h     example,example-sidecar example-image:vX.X.X,example-image-sidecar:vX.X.X k8s-app=example,pod-template-hash=66db79f578
example-759469945f 1        1       1       19h     example,example-sidecar example-image:vX.X.X,example-image-sidecar:vX.X.X k8s-app=example,pod-template-hash=759469945f
example-ff8f986960 0        0       0       19h     example,example-sidecar example-image:vX.X.X,example-image-sidecar:vX.X.X k8s-app=example,pod-template-hash=ff8f98696

kubectl describe deployments example -n kube-system

Name:                   example
Namespace:              kube-system
CreationTimestamp:      Tue, 03 Mar 2020 00:48:18 +0530
Labels:                 k8s-app=example
Annotations:            deployment.kubernetes.io/revision: 27
Selector:               k8s-app=example
Replicas:               1 desired | 1 updated | 2 total | 1 available | 1 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:           k8s-app=example
  Service Account:  example
  Containers:
   example:
    Image:       example-image:vX.X.X
    Ports:       8080/TCP, 8081/TCP
    Host Ports:  0/TCP, 0/TCP
    Limits:
      cpu:     1630m
      memory:  586Mi
    Requests:
      cpu:        1630m
      memory:     586Mi
    Readiness:    http-get http://:8080/healthz delay=5s timeout=5s period=10s #success=1 #failure=3
    Environment:  <none>
    Mounts:       <none>
   example-sidecar:
    Image:      example-image-sidecar:vX.X.X
    Port:       <none>
    Host Port:  <none>
    Command:
      command
      --container=example
      --cpu=200m
      --extra-cpu=10m
      --memory=300Mi
      --extra-memory=2Mi
      --threshold=5
      --deployment=example
    Limits:
      memory:  400Mi
    Requests:
      cpu:  100m
    Environment:
      MY_POD_NAME:        (v1:metadata.name)
      MY_POD_NAMESPACE:   (v1:metadata.namespace)
    Mounts:              <none>
  Volumes:               <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
OldReplicaSets:  example-759469945f (1/1 replicas created)
NewReplicaSet:   example-66db79f578 (1/1 replicas created)
Events:          <none>
kubectl rollout history deployments example -n kube-system

deployment.extensions/example 
REVISION  CHANGE-CAUSE
1         <none>
16        <none>
17        <none>
21        <none>
24        <none>
26        <none>
27        <none>

3 个答案:

答案 0 :(得分:0)

理论

我尝试更新Deployment,并且仅更新了新的ReplicaSet。旧的保持不变。

在这种情况下,问题是您有2个不同的Deployments。您正在编辑的一个(这样一个rs得到更新)和另一个(旧的)以其他方式创建。

通常,您无法轻易删除ReplicaSet,因为它是由另一个实体控制的。

在Kubernetes中,可以通过以下方式删除rs

  • 使用rs查找“旧” kubectl get replicaset -n kube-system的名称。
  • 找到受“ rs”控制的“旧” kubectl describe <rs-name>
  • 对象
  • 删除该rs的父对象。

实践

您观察到多个rs的事实意味着您一直在尝试更新Deployment

kubectl get rs -o wide -n kube-system | grep example

NAME               DESIRED  CURRENT     READY   AGE     
example-6d4f99bc54 0        0       0   12h 
example-59d46955b6 0        0       0   13h 
example-5855866cdb 0        0       0   18h 
example-ccc5cf5cd0 0        0       0   18h 
example-66db79f578 1        1       0   19h     
example-759469945f 1        1       1   19h 
example-ff8f986960 0        0       0   19h 

从该输出中,我们可以看到19小时前创建的example-759469945f仍然有效(DESIRED/CURRENT/READY = 1/1/1)。之后,尝试进行更新,因此其他rs被更新过程一一创建。

由于Deployment的问题,所有这些尝试均未成功(我们将在后面讨论)。

在几次失败的尝试之后,您又回滚到example-66db79f578,它也是由损坏的Deployment创建的(这就是最新的example-6d4f99bc54具有0/0/0而不是{ 1/1/0

那个破损的Deployment根本原因,为什么您有两个副本集,其中CURRENT = 1(example-759469945fexample-66db79f578和{{1 }}和1/1/1

请注意,此1/1/0中使用了RollingUpdate策略。

Deployment

这就是为什么旧的StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge 不能退役,而新的rs不能完全“运行”(具有与DESIRED/CURRENT/READY匹配的值)的原因

一旦修复rs并应用更改,您将只得到一个Deployment

为了修复部署,需要检查k8尝试为pod创建example-66db79f578时出了什么问题

您可以通过以下方式进行操作:

# check the pod name
kubectl get pods -n kube-system | grep 66db79f578

# describe pod. it shall give you the root cause in "Events:" section
kubectl describe pod example-66db79f578-<somehash>

# additionally you can try checking logs for the containers on that pod.

kubectl logs example-66db79f578-<somehash>  example
kubectl logs example-66db79f578-<somehash>  example-sidecar

# fix :)
# apply changes

修复损坏的Deployment后,您将可以毫无问题地应用它。

希望有帮助。

答案 1 :(得分:0)

在这种情况下,明确指定部署update strategy会有所帮助。
从您的部署说明中,我们可以看到默认情况下获得的选项:

StrategyType:           RollingUpdate
RollingUpdateStrategy:  25% max unavailable, 25% max surge

您可以使用以下命令查看完整的YAML:
kubectl get deployment example -n kube-system -o yaml --export

注意kube-system名称空间不是放置自定义部署的最佳位置。我建议使用通过kubectl create ns namespace-namedefault名称空间创建的自定义名称空间

有两种方法可以解决此问题。您应该在创建新的Pod之前强制部署摆脱旧的Pod:

方法之一。。在这里,我将更新类型设置为“重新创建”。更新后,部署会立即杀死所有Pod,并使用相同数量的副本启动新版本的Pod。即使副本> 1,该服务也可能会停机。

strategy:
  type: Recreate

方法之二:在下一个示例中,我将滚动更新选项设置为maxSurge=0maxUnavailable=1 在下一次更新后,Deployment将首先杀死一个Pod,然后创建Pod的新版本,以使总副本数等于规范中设置的数量。新的Pod就绪后,该过程将与下一个Pod重复。如果只有一个副本,则可能会导致停机。

strategy:
  rollingUpdate:
    maxSurge: 0
    maxUnavailable: 1
  type: RollingUpdate

更新类型说明:
k explain deployment.spec.strategy.type

Type of deployment. Can be "Recreate" or "RollingUpdate". Default is
 RollingUpdate.

选项说明:
kubectl explain deployment.spec.strategy.rollingUpdate

 maxSurge   <string>
   The maximum number of pods that can be scheduled above the desired number
   of pods. Value can be an absolute number (ex: 5) or a percentage of desired
   pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number
   is calculated from percentage by rounding up. By default, a value of 1 is
   used. Example: when this is set to 30%, the new RC can be scaled up
   immediately when the rolling update starts, such that the total number of
   old and new pods do not exceed 130% of desired pods. Once old pods have
   been killed, new RC can be scaled up further, ensuring that total number of
   pods running at any time during the update is at most 130% of desired pods.

 maxUnavailable <string>
   The maximum number of pods that can be unavailable during the update. Value
   can be an absolute number (ex: 5) or a percentage of desired pods (ex:
   10%). Absolute number is calculated from percentage by rounding down. This
   can not be 0 if MaxSurge is 0. By default, a fixed value of 1 is used.
   Example: when this is set to 30%, the old RC can be scaled down to 70% of
   desired pods immediately when the rolling update starts. Once new pods are
   ready, old RC can be scaled down further, followed by scaling up the new
   RC, ensuring that the total number of pods available at all times during
   the update is at least 70% of desired pods.

答案 2 :(得分:0)

我们对Openshift有一个类似的问题,即同一副本部署拥有2个副本集。不幸的是,此问题导致其Pod大约每100秒频繁重启。这是因为两个副本集使用的是不同的映像。 (我们经常升级图像)

同一部署(Deployment / ua-operator)拥有2个副本集(ua-operator-776546f4ff,ua-operator-b6c858456)。我们可以看到pod状态的“ restartCount”参数始终为0。但是pod只能存活100秒钟。这不是由应用程序问题引起的。这是2个副本集,可以进行滚动升级(但不能滚动升级)。

查看2个副本集(ua-operator-776546f4ff,ua-operator-b6c858456),可以看到它们不幸地使用了2个不同的图像。 复制集/ ua-operator-776546f4ff使用的是ua-operator:APM_202006202301 复制集/ ua-operator-b6c858456正在使用ua-operator:APM_202006212301

虽然部署(Deployment / ua-operator)仅指定更新的映像: 部署/ ua-operator正在使用ua-operator:APM_202006212301

所以问题是: 有人创建了新的Deployment / ua-operator,但没有完全删除旧的Deployment / ua-operator,因此使用旧的ua-operator:APM_202006202301映像的旧副本集/ ua-operator-776546f4ff并未被删除,并且现在仍然存在,并且成为新的Deployment / ua-operator的子代。不幸的是,这两个副本集使用的是不同的图像。这就是始终重新启动ua-operator pod的原因。

我不确定这是Kubernetes还是Openshift缺陷。但是我们可以通过等待旧的部署完全删除然后创建新的ua-operator部署来避免这种情况。