как отключить cloud-sql-proxy в хуке предварительной установки Helm Chart

Я запускаю приложение django в кластере Kubernetes на gcloud. Я реализовал миграцию базы данных как хук перед установкой руля, который запускает мой контейнер приложения и выполняет миграцию базы данных. Я использую cloud-sql-proxy в дополнительном шаблоне, как рекомендовано в официальном руководстве: https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine

В основном это запускает мое приложение и контейнеры cloud-sql-proxy внутри модуля, описанного в задании. Проблема в том, что cloud-sql-proxy никогда не завершает работу после того, как мое приложение завершило миграцию, в результате чего предварительное задание прервалось по таймауту и ​​отменило мое развертывание. Как мне корректно выйти из контейнера cloud-sql-proxy после завершения моего контейнера приложения, чтобы задание могло быть завершено?

Вот мое определение шаблона хука до установки:

apiVersion: batch/v1
kind: Job
metadata:
  name: database-migration-job
  labels:
    app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
    app.kubernetes.io/instance: {{ .Release.Name | quote }}
    app.kubernetes.io/version: {{ .Chart.AppVersion }}
    helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
  annotations:
    # This is what defines this resource as a hook. Without this line, the
    # job is considered part of the release.
    "helm.sh/hook": pre-install,pre-upgrade
    "helm.sh/hook-weight": "-1"
    "helm.sh/hook-delete-policy": hook-succeeded,hook-failed
spec:
  activeDeadlineSeconds: 230
  template:
    metadata:
      name: "{{ .Release.Name }}"
      labels:
        app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
        app.kubernetes.io/instance: {{ .Release.Name | quote }}
        helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    spec:
      restartPolicy: Never
      containers:
      - name: db-migrate
        image: {{ .Values.my-project.docker_repo }}{{ .Values.backend.image }}:{{ .Values.my-project.image.tag}}
        imagePullPolicy: {{ .Values.my-project.image.pullPolicy }}
        env:
        - name: DJANGO_SETTINGS_MODULE
          value: "{{ .Values.backend.django_settings_module }}"
        - name: SENDGRID_API_KEY
          valueFrom:
            secretKeyRef:
              name: sendgrid-api-key
              key: sendgrid-api-key
        - name: DJANGO_SECRET_KEY
          valueFrom:
            secretKeyRef:
              name: django-secret-key
              key: django-secret-key
        - name: DB_USER
          value: {{ .Values.postgresql.postgresqlUsername }}
        - name: DB_PASSWORD
          {{- if .Values.postgresql.enabled }}
          value: {{ .Values.postgresql.postgresqlPassword }}
          {{- else }}
          valueFrom:
            secretKeyRef:
              name: database-password
              key: database-pwd
          {{- end }}
        - name: DB_NAME
          value: {{ .Values.postgresql.postgresqlDatabase }}
        - name: DB_HOST
          {{- if .Values.postgresql.enabled }}
          value: "postgresql"
          {{- else }}
          value: "127.0.0.1"
          {{- end }}
        workingDir: /app-root
        command: ["/bin/sh"]
        args: ["-c", "python manage.py migrate --no-input"]
      {{- if eq .Values.postgresql.enabled false }}
      - name: cloud-sql-proxy
        image: gcr.io/cloudsql-docker/gce-proxy:1.17
        command:
          - "/cloud_sql_proxy"
          - "-instances=<INSTANCE_CONNECTION_NAME>=tcp:<DB_PORT>"
          - "-credential_file=/secrets/service_account.json"
        securityContext:
          #fsGroup: 65532
          runAsNonRoot: true
          runAsUser: 65532
        volumeMounts:
        - name: db-con-mnt
          mountPath: /secrets/
          readOnly: true
      volumes:
      - name: db-con-mnt
        secret:
          secretName: db-service-account-credentials
      {{- end }}

Довольно забавно, если я убью задание с помощью kubectl delete jobs database-migration-job после завершения миграции, обновление Helm завершится и моя новая версия приложения будет установлена.


person Vess Perfanov    schedule 21.06.2020    source источник


Ответы (1)


Что ж, у меня есть решение, которое будет работать, но может быть взломано. Во-первых, в Kubernetes отсутствует функция, которая обсуждается в проблеме.

В Kubernetes v1.17 контейнеры в одном могут совместно использовать процесс пространства имен. Это позволяет нам убить прокси-контейнер из контейнера приложения. Поскольку это работа Kubernetes, в включить обработчики postStop для контейнера приложения.

С помощью этого решения, когда ваше приложение завершается и завершается нормально (или ненормально), Kubernetes выполнит последнюю команду из вашего умирающего контейнера, который в этом случае будет kill another process. Это должно привести к успешному завершению работы или к провалу в зависимости от того, как вы будете убивать процесс. Код выхода процесса будет кодом выхода контейнера, тогда в основном это будет код выхода задания.

person Akin Ozer    schedule 21.06.2020
comment
Отличная информация. Поды могут совместно использовать пространства имен процессов, что было особенно полезно. Я использовал совместное использование процесса, чтобы завершить выполнение исполняемого файла cloud-sql-proxy простым kullall после того, как я выполнил миграцию в команде. Это помогло. Однако, когда я попробовал preStop, мне показалось, что я столкнулся с этой ошибкой: github.com/kubernetes/kubernetes/ issues / 55807. В основном мой preStop никогда не выполнялся. Может, мне чего-то не хватает. Спасибо. - person Vess Perfanov; 22.06.2020
comment
Да, я не знал, как это будет работать по-другому в Иове. Вы можете преобразовать свое поле команды dockerfile в script.sh и создать этот файл, запустив строку с вашим заданием, тогда следующая строка будет убивать все процессы, а затем она обязательно будет запущена. - person Akin Ozer; 23.06.2020