Tengo un JOB de Kubernetes que realiza migraciones de bases de datos en una base de datos CloudSQL.
Una forma de acceder a la base de datos de CloudSQL desde GKE es usar el contenedor de proxy de CloudSQL y luego conectarse a través de localhost . Genial, eso está funcionando hasta ahora. Pero debido a que estoy haciendo esto dentro de un JOB K8s, el trabajo no se marca como finalizado con éxito porque el proxy continúa ejecutándose.
$ kubectrl get po NAME READY STATUS RESTARTS AGE db-migrations-c1a547 1/2 Completed 0 1mAunque el resultado dice 'completado', uno de los dos contenedores iniciales aún se está ejecutando: el proxy.
¿Cómo puedo hacer que el proxy salga al completar las migraciones dentro del contenedor 1?
La mejor manera que he encontrado es compartir el espacio de nombres del proceso entre contenedores y usar la capacidad SYS_PTRACE securityContext para permitirle eliminar el sidecar.
apiVersion: batch/v1 kind: Job metadata: name: my-db-job spec: template: spec: restartPolicy: OnFailure shareProcessNamespace: true containers: - name: my-db-job-migrations command: ["/bin/sh", "-c"] args: - | <your migration commands>; sql_proxy_pid=$(pgrep cloud_sql_proxy) && kill -INT $sql_proxy_pid; securityContext: capabilities: add: - SYS_PTRACE - name: cloudsql-proxy image: gcr.io/cloudsql-docker/gce-proxy:1.17 command: - "/cloud_sql_proxy" args: - "-instances=$(DB_CONNECTION_NAME)=tcp:5432"Una posible solución sería una implementación separada de cloudsql-proxy con un servicio coincidente. Entonces solo necesitaría su contenedor de migración dentro del trabajo que se conecta a su servicio de proxy.
Esto viene con algunas desventajas:
Si desea abrir el proxy de cloudsql para todo el clúster, debe reemplazar tcp:3306 con tcp:0.0.0.0:3306 en el parámetro -instance en el proxy de cloudsql.
Hay 3 formas de hacer esto.
1- Use una IP privada para conectar su trabajo de K8s a Cloud SQL, como lo describe @newoxo en una de las respuestas. Para hacer eso, su clúster debe ser un clúster nativo de VPC. El mío no lo estaba y no estaba pensando en mover todas mis cosas a un nuevo grupo. Así que no pude hacer esto.
2- Coloque el contenedor de proxy de Cloud SQL en una implementación separada con un servicio, como lo describe @Christian Kohler. Este parece un buen enfoque, pero no es recomendado por Google Cloud Support.
Estaba a punto de tomar esta dirección (solución n. ° 2), pero decidí probar otra cosa.
Y aquí está la solución que funcionó para mí:
3- Puede comunicarse entre diferentes contenedores en el mismo Pod/Trabajo utilizando el sistema de archivos. La idea es decirle al contenedor del proxy de Cloud SQL cuando se realiza el trabajo principal y luego eliminar el proxy de Cloud SQL. Aquí está cómo hacerlo:
En el archivo yaml (my-job.yaml)
apiVersion: v1 kind: Pod metadata: name: my-job-pod labels: app: my-job-app spec: restartPolicy: OnFailure containers: - name: my-job-app-container image: my-job-image:0.1 command: ["/bin/bash", "-c"] args: - | trap "touch /lifecycle/main-terminated" EXIT { your job commands here } volumeMounts: - name: lifecycle mountPath: /lifecycle - name: cloudsql-proxy-container image: gcr.io/cloudsql-docker/gce-proxy:1.11 command: ["/bin/sh", "-c"] args: - | /cloud_sql_proxy -instances={ your instance name }=tcp:3306 -credential_file=/secrets/cloudsql/credentials.json & PID=$! while true do if [[ -f "/lifecycle/main-terminated" ]] then kill $PID exit 0 fi sleep 1 done securityContext: runAsUser: 2 # non-root user allowPrivilegeEscalation: false volumeMounts: - name: cloudsql-instance-credentials mountPath: /secrets/cloudsql readOnly: true - name: lifecycle mountPath: /lifecycle volumes: - name: cloudsql-instance-credentials secret: secretName: cloudsql-instance-credentials - name: lifecycle emptyDir:Básicamente, cuando termine su trabajo principal, creará un archivo en /lifecycle que será identificado por el observador agregado al contenedor cloud-sql-proxy, que eliminará el proxy y terminará el contenedor.
¡Espero que ayude! Hazme saber si tienes alguna pregunta.
Basado en: https://stackoverflow.com/a/52156131/7747292