如何在使用pvc和initContainer进行部署时执行头盔更新?

时间:2020-06-23 14:20:46

标签: kubernetes-helm kubernetes-pvc kubernetes-deployment

我对掌舵和kubernetes还是很陌生,所以我不确定这是一个错误还是做错了什么。在发布之前,我到处都在寻找答案,找不到任何能回答我问题的东西。

我有一个使用永久卷和初始化容器的部署。我将其值传递给头盔,以通知头盔初始化容器的图像已更改,还是主应用程序容器已更改。

可能相关,但可能不相关:我需要为一系列Web资源(我称为收集器)部署一个部署。我不知道这最后一部分是否相关,但是如果我这样做了,我可能就不会在这里了。

我跑步时

helm upgrade --install my-release helm_chart/ --values values.yaml --set init_image_tag=$INIT_IMAGE_TAG --set image_tag=$IMAGE_TAG

第一次一切正常。但是,当我第二次运行它时,INIT_IMAGE_TAG不变,但是IMAGE_TAG改变了

  • a)它尝试重新初始化Pod
  • b)它无法重新初始化Pod,因为它无法装入卷

预期行为:

  • a)由于初始化容器未更改,请勿重新初始化pod
  • b)安装该卷

我的values.yaml仅包含一个名为collectors

的列表

我的模板是:

{{ $env := .Release.Namespace }}
{{ $image_tag := .Values.image_tag }}
{{ $init_image_tag := .Values.init_image_tag }}
{{- range $colname := .Values.collectors }}


apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{ $colname }}-claim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-sc
  resources:
    requests:
      storage: 10Gi

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ $colname }}-ingest
  labels:
    app: {{ $colname }}-ingest
spec:
  replicas: 1
  selector:
    matchLabels:
      app: {{ $colname }}-ingest
  template:
    metadata:
      labels:
        app: {{ $colname }}-ingest
    spec:
          fsGroup: 1000
      containers:
      - name: {{ $colname }}-main
        image: xxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/main_image:{{ $image_tag }}
        env:
        - name: COLLECTOR
          value: {{ $colname }}
        volumeMounts:
        - name: storage
          mountPath: /home/my/dir
      initContainers:
      - name: {{ $colname }}-init
        image: xxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/init_image:{{ $init_image_tag }}
        volumeMounts:
        - name: storage
          mountPath: /home/my/dir
        env:
        - name: COLLECTOR
          value: {{ $colname }}
      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: {{ $colname }}-claim
---

{{ end }}

helm version的输出:version.BuildInfo {版本:“ v3.2.0-rc.1”,GitCommit:“ 7bffac813db894e06d17bac91d14ea819b5c2310”,GitTreeState:“ clean”,GoVersion:“ go1.13.10”}

kubectl version的输出:客户端版本:version.Info {主要:“ 1”,次要:“ 17”,GitVersion:“ v1.17.3”,GitCommit:“ 06ad960bfd03b39c8310aaf92d1e7c12ce618213”,GitTreeState:“ clean”, BuildDate:“ 2020-02-11T18:14:22Z”,GoVersion:“ go1.13.6”,编译器:“ gc”,平台:“ linux / amd64”} 服务器版本:version.Info {主要:“ 1”,次要:“ 14+”,GitVersion:“ v1.14.9-eks-f459c0”,GitCommit:“ f459c0672169dd35e77af56c24556530a05e9ab1”,GitTreeState:“ clean”,生成日期:“ 2020-03 -18T04:24:17Z“,GoVersion:” go1.12.12“,编译器:” gc“,平台:” linux / amd64“}

云提供商/平台(AKS,GKE,Minikube等):EKS

有人知道这是一个错误还是我以某种方式滥用头盔/ kubernetes?

谢谢

1 个答案:

答案 0 :(得分:1)

更新部署时,它需要完成几个步骤:

  1. 具有旧pod规范的现有Pod仍在运行。
  2. Deployment控制器使用新的pod规范启动一个新的Pod。
  3. 它等待该Pod达到“正在运行”状态。
  4. 它终止了一个旧的Pod。
  5. 如果有多个副本,请重复执行直到替换完每个Pod。

这里的重要细节是(有意地)新旧Pod都在运行。

在显示的示例中,您以ReadWriteOnce访问模式安装了PersistentVolumeClaim。这对于Deployments确实不能很好地工作。当旧的Pod运行时,它拥有PVC支架,这将阻止新的Pod启动,从而阻止部署进行。 (这并非真正针对Helm,并且与是否拥有initContainer无关。)

这里有两个选项:

  • 不要将数据存储在本地卷中。这是最好的方法,尽管它涉及重新架构应用程序。如果数据是关系类型的数据,则将数据存储在单独的数据库容器中(例如, ,在卷中首选PostgreSQL容器而不是SQLite);或者,如果您可以访问Amazon S3之类的网络存储,请将其保存在此处。这样完全可以避免此问题,并使您可以根据需要运行任意数量的副本。

  • 使用ReadWriteMany卷。持久卷具有access mode。如果您可以将该卷声明为ReadWriteMany,则可以安装多个Pod,此方案将起作用。但是,许多更常见的卷类型都不支持此访问模式(AWSElasticBlockStore和HostPath显然仅为ReadWriteOne)。

  • 将部署策略设置为Recreate。您可以配置部署如何管理更新。如果您change to a Recreate strategy

      apiVersion: apps/v1
      kind: Deployment
      spec:
        strategy:
          type: Recreate
    

    然后将首先删除旧的Pod。这将中断零宕机时间的升级,但将允许此特定情况继续进行。