【问题标题】:Can not override `replicas` of deployment k8s无法覆盖部署 k8s 的“副本”
【发布时间】:2020-11-11 18:10:03
【问题描述】:

我遇到过这样的问题:

首先,我使用 helm 创建了一个 release nginx

helm upgrade --install --namespace test nginx bitnami/nginx --debug

LAST DEPLOYED: Wed Jul 22 15:17:50 2020
NAMESPACE: test
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                DATA  AGE
nginx-server-block  1     2s

==> v1/Deployment
NAME   READY  UP-TO-DATE  AVAILABLE  AGE
nginx  0/1    1           0          2s

==> v1/Pod(related)
NAME                    READY  STATUS             RESTARTS  AGE
nginx-6bcbfcd548-kdf4x  0/1    ContainerCreating  0         1s

==> v1/Service
NAME   TYPE          CLUSTER-IP    EXTERNAL-IP  PORT(S)                     AGE
nginx  LoadBalancer  10.219.6.148  <pending>    80:30811/TCP,443:31260/TCP  2s


NOTES:
Get the NGINX URL:

  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        Watch the status with: 'kubectl get svc --namespace test -w nginx'

  export SERVICE_IP=$(kubectl get svc --namespace test nginx --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
  echo "NGINX URL: http://$SERVICE_IP/"

K8s 只创建一个有 1 个 pod 的部署:

# Source: nginx/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app.kubernetes.io/name: nginx
    helm.sh/chart: nginx-6.0.2
    app.kubernetes.io/instance: nginx
    app.kubernetes.io/managed-by: Tiller
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: nginx
      app.kubernetes.io/instance: nginx
  replicas: 1
  ...

其次,我使用 kubectl 命令编辑部署以扩展到 2 个 pod

kubectl -n test  edit deployment nginx

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2020-07-22T08:17:51Z"
  generation: 1
  labels:
    app.kubernetes.io/instance: nginx
    app.kubernetes.io/managed-by: Tiller
    app.kubernetes.io/name: nginx
    helm.sh/chart: nginx-6.0.2
  name: nginx
  namespace: test
  resourceVersion: "128636260"
  selfLink: /apis/extensions/v1beta1/namespaces/test/deployments/nginx
  uid: d63b0f05-cbf3-11ea-99d5-42010a8a00f1
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  ...

我保存了这个,检查状态以查看部署已扩展到 2 个 pod:

kubectl -n test get deployment

NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   2/2     2            2           7m50s

最后,我使用 helm 升级版本,正如预期的那样,helm 将像第一步一样覆盖部署到 1 个 pod,但现在,即使您设置了值(在 values.yaml 中),部署也会保留值 replicas: 2 helm 文件)到任意数量。 我使用了helm 命令的选项--recreate-pods

helm upgrade --install --namespace test nginx bitnami/nginx --debug --recreate-pods
Release "nginx" has been upgraded. Happy Helming!
LAST DEPLOYED: Wed Jul 22 15:31:24 2020
NAMESPACE: test
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                DATA  AGE
nginx-server-block  1     13m

==> v1/Deployment
NAME   READY  UP-TO-DATE  AVAILABLE  AGE
nginx  0/2    2           0          13m

==> v1/Pod(related)
NAME                    READY  STATUS             RESTARTS  AGE
nginx-6bcbfcd548-b4bfs  0/1    ContainerCreating  0         1s
nginx-6bcbfcd548-bzhf2  0/1    ContainerCreating  0         1s
nginx-6bcbfcd548-kdf4x  0/1    Terminating        0         13m
nginx-6bcbfcd548-xfxbv  1/1    Terminating        0         6m16s

==> v1/Service
NAME   TYPE          CLUSTER-IP    EXTERNAL-IP    PORT(S)                     AGE
nginx  LoadBalancer  10.219.6.148  34.82.120.134  80:30811/TCP,443:31260/TCP  13m


NOTES:
Get the NGINX URL:

  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        Watch the status with: 'kubectl get svc --namespace test -w nginx'

  export SERVICE_IP=$(kubectl get svc --namespace test nginx --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
  echo "NGINX URL: http://$SERVICE_IP/"

结果:在我手动编辑部署中的replicas 后,我无法使用 helm 覆盖此值replicas,但我仍然可以更改图像等,...只有副本不会更改 我已经运行 --debug 并且 helm 仍然使用 replicas: 1 创建部署

# Source: nginx/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app.kubernetes.io/name: nginx
    helm.sh/chart: nginx-6.0.2
    app.kubernetes.io/instance: nginx
    app.kubernetes.io/managed-by: Tiller
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: nginx
      app.kubernetes.io/instance: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app.kubernetes.io/name: nginx
        helm.sh/chart: nginx-6.0.2
        app.kubernetes.io/instance: nginx
        app.kubernetes.io/managed-by: Tiller
    spec:      
      containers:
        - name: nginx
          image: docker.io/bitnami/nginx:1.19.1-debian-10-r0
          imagePullPolicy: "IfNotPresent"
          ports:
            - name: http
              containerPort: 8080
            
          livenessProbe:
            failureThreshold: 6
            initialDelaySeconds: 30
            tcpSocket:
              port: http
            timeoutSeconds: 5
            
          readinessProbe:
            initialDelaySeconds: 5
            periodSeconds: 5
            tcpSocket:
              port: http
            timeoutSeconds: 3
            
          resources:
            limits: {}
            requests: {}
            
          volumeMounts:
            - name: nginx-server-block-paths
              mountPath: /opt/bitnami/nginx/conf/server_blocks
      volumes:
        - name: nginx-server-block-paths
          configMap:
            name: nginx-server-block
            items:
              - key: server-blocks-paths.conf
                path: server-blocks-paths.conf

但是 k8s 部署将保持值 replicas 与编辑手册一样一次 replicas: 2

据我所知,helm 命令的输出是创建 k8s yaml 文件,为什么在这种情况下我不能使用helm 覆盖特定值replicas

提前谢谢!!!

P/S:我只想知道这里的行为是什么,Tks

Helm 版本

Client: &version.Version{SemVer:"v2.13.1", GitCommit:"618447cbf203d147601b4b9bd7f8c37a5d39fbb4", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.13.0", GitCommit:"79d07943b03aea2b76c12644b4b54733bc5958d6", GitTreeState:"clean"}

【问题讨论】:

  • 您解决了这个问题吗?你的 k8s 集群版本是多少?
  • 因为我认为这是 helm 行为,所以问题与 K8s 无关。 @汉克斯
  • 看看Supported Version Skew It is not recommended to use Helm with a version of Kubernetes that is newer than the version it was compiled against 我已经使用 v3.0 对此进行了测试,它按预期工作。如下所述,您是否尝试使用 --set replicaCount 字段?

标签: kubernetes kubernetes-helm


【解决方案1】:

请使用 helm 中的 replicaCount 字段来管理副本。

我将其视为选项here

【讨论】:

  • 是的,我只需要使用replicaCount 来覆盖它但我想了解这里的行为:当前depoyment 有replicas: 2,values.yaml 中的默认值为:replicaCount: 1,为什么 Helm 不能改变副本数?
【解决方案2】:

让我知道您正在使用的 helm 版本。还有一个已知错误,它没有升级副本,请检查链接 https://github.com/helm/helm/issues/4654

【讨论】:

    【解决方案3】:

    请看Supported Version Skew

    当 Helm 的新版本发布时,它会针对特定的 Kubernetes 次要版本进行编译。例如,Helm 3.0.0 使用 Kubernetes 1.16.2 客户端与 Kubernetes 交互,因此它与 Kubernetes 1.16 兼容。

    从 Helm 3 开始,Helm 被假定与编译它所针对的 n-3 个 Kubernetes 版本兼容。由于 Kubernetes 在次要版本之间的变化,Helm 2 的支持政策稍微严格一些,假设兼容 n-1 个版本的 Kubernetes

    例如,如果您使用的是 针对 Kubernetes 1.17 客户端 API 编译的 Helm 3 版本,那么它应该可以安全使用Kubernetes 1.17、1.16、1.15 和 1.14。如果您使用的是针对 Kubernetes 1.16 客户端 API 编译的 Helm 2 版本,那么它应该可以安全地与 Kubernetes 1.16 和 1.15 一起使用强>.

    不建议将 Helm 与比它编译时所针对的版本新的 Kubernetes 版本一起使用,因为 Helm 不做任何前向兼容性保证。

    如果您选择将 Helm 与它不支持的 Kubernetes 版本一起使用,则使用它需要您自担风险。

    我已经使用 1.17.9 k8s 版本和 helm 3.2v 测试了这些行为,并且下面提到的所有部署更新方法都按预期工作。

    helm upgrade --install nginx bitnami/nginx 
    helm fetch bitnami/nginx --untar (create custom vaules.yaml and change the replicaCount parameter in values.yaml and save it)
    helm upgrade --install nginx bitnami/nginx -f values.yaml ./nginx
    helm upgrade --install nginx bitnami/nginx -f values.yaml ./nginx --set replicaCount=2
    

    注意Values Files

    values.yaml 是默认值,它可以被父图表的 values.yaml 覆盖,而该值又可以被用户提供的值文件覆盖,而该文件又可以被 --set 参数覆盖。

    所以我的建议是让你的工具保持最新。

    注意Helm 2 support plan.

    对于 Helm 2,我们将继续接受错误修复并修复出现的任何安全问题,但不会接受任何新功能。所有功能开发都将移至 Helm 3。

    Helm 3 公开发布 6 个月后,Helm 2 将停止接受错误修复。只接受安全问题

    Helm 3 公开发布 12 个月后,对 Helm 2 的支持将正式结束

    【讨论】:

      【解决方案4】:

      关注Helm的官方文档:Helm | Docs

      Helm 2 使用了双向战略合并补丁。在升级过程中,它将最新图表的清单与建议图表的清单(在 helm 升级期间提供的清单)进行比较。它比较了这两个图表之间的差异,以确定需要对 Kubernetes 中的资源应用哪些更改。如果更改被带外应用到集群(例如在 kubectl 编辑期间),则不会考虑这些更改。这导致资源无法回滚到之前的状态:因为 Helm 仅将上次应用的图表的清单视为其当前状态,如果图表的状态没有变化,则实时状态保持不变。

      而且这个东西会在Helm v3中得到改进,因为Helm v3已经删除了Tiller,你的值会完全适用于Kubernetes resourcesHelmKubernetes的值会保持一致。

      ==> 结果是你用Helm version 3就不会再遇到这个问题了

      【讨论】:

        猜你喜欢
        • 2022-01-17
        • 2020-12-14
        • 2021-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多