Kubernetes:在多容器 Pod/Job 中停止 CloudSQL 代理 sidecar 容器

问题描述 投票:0回答:8

我有一个 Kubernetes

JOB
,它可以在 CloudSQL 数据库上进行数据库迁移。
从 GKE 访问 CloudSQL 数据库的一种方法是使用 CloudSQL 代理容器,然后通过
localhost
连接。太棒了 - 到目前为止还有效。但因为我是在 K8s 中执行此操作,所以该作业未标记为已成功完成,因为代理继续运行。

JOB

即使输出显示“已完成”,最初的两个容器之一仍在运行 - 代理。

如何让代理在完成容器 1 内的迁移后退出?

docker kubernetes google-cloud-sql
8个回答
34
投票
共享进程命名空间

,并使用 SYS_PTRACE securityContext 功能来允许您杀死 sidecar。 $ kubectrl get po NAME READY STATUS RESTARTS AGE db-migrations-c1a547 1/2 Completed 0 1m



14
投票

这有一些缺点:

网络延迟较高,没有pod本地mysql通信
  • 如果您向整个 kubernetes 集群提供 sql 端口,可能会出现安全问题
  • 如果要向整个集群开放 cloudsql-proxy,则必须将 cloudsql-proxy 上的
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"

参数中的

tcp:3306
替换为
tcp:0.0.0.0:3306
    


11
投票

1- 使用私有 IP 将您的 K8s 作业连接到 Cloud SQL,如 @newoxo 在答案之一中所述。为此,您的集群需要是 VPC 本机集群。我的不是,而且我不想将所有东西移动到新集群。所以我没能做到这一点。

2- 将 Cloud SQL 代理容器与服务一起放置在单独的部署中,如 @Christian Kohler 所述。这看起来是一个不错的方法,但 Google Cloud 支持人员不建议这样做。

我正打算朝这个方向前进(解决方案#2),但我决定尝试其他方法。

这是

对我有用的解决方案:

3-您可以使用文件系统在同一 Pod/Job 中的不同容器之间进行通信。这个想法是告诉Cloud SQL代理容器主要工作何时完成,然后终止云SQL代理。以下是具体操作方法:

在yaml文件(my-job.yaml)中

-instance

基本上,当你的主要工作完成时,它将在 /lifecycle 中创建一个文件,该文件将由添加到 cloud-sql-proxy 容器的观察程序识别,这将杀死代理并终止容器。

希望有帮助!如果您有任何疑问,请告诉我。

基于:

https://stackoverflow.com/a/52156131/7747292


3
投票
Kubernetes Jobs 中的 Sidecar 容器?


3
投票

https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine#private-ip


2
投票
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:

concurrencyPolicy: Replace
...这将在需要再次运行时用新实例替换当前 pod。但是,您必须确保后续的 cron 运行足够分开。
    


0
投票
在没有 shell 的无发行版环境中运行,其他答案对我不起作用

我设法通过将

CloudSQLProxy 二进制文件

与我的部署捆绑在一起并运行 bash 脚本来启动 CloudSQLProxy 然后启动我的应用程序来解决这个问题。

Dockerfile:

spec

Shell 脚本(run_migrations.sh):

FROM golang:1.19.4 RUN apt update COPY . /etc/mycode/ WORKDIR /etc/mycode RUN chmod u+x ./scripts/run_migrations.sh RUN chmod u+x ./bin/cloud_sql_proxy.linux-amd64 RUN go install ENTRYPOINT ["./scripts/run_migrations.sh"]

K8s(通过 Pulumi):

#!/bin/sh # This script is run from the parent directory dbConnectionString=$1 cloudSQLProxyPort=$2 echo "Starting Cloud SQL Proxy" ./bin/cloud_sql_proxy.linux-amd64 -instances=${dbConnectionString}=tcp:5432 -enable_iam_login -structured_logs & CHILD_PID=$! echo "CloudSQLProxy PID: $CHILD_PID" echo "Migrating DB..." go run ./db/migrations/main.go MAIN_EXIT_CODE=$? kill $CHILD_PID; echo "Migrations complete."; exit $MAIN_EXIT_CODE



0
投票
import * as k8s from '@pulumi/kubernetes' const jobDBMigrations = new k8s.batch.v1.Job("job-db-migrations", { metadata: { namespace: namespaceName, labels: appLabels, }, spec: { backoffLimit: 4, template: { spec: { containers: [ { image: pulumi.interpolate`gcr.io/${gcpProject}/${migrationsId}:${migrationsVersion}`, name: "server-db-migration", args: [ dbConnectionString, ], }, ], restartPolicy: "Never", serviceAccount: k8sSAMigration.metadata.name, }, }, }, }, { provider: clusterProvider, });

端点,可用于关闭 sidecar 代理。不再需要共享进程空间或写入文件等解决方法。

只需将 

quitquitquit

标志添加到 sql-cloud-proxy 并通过在作业定义的参数中发送 POST 请求来终止 sidecar:

--quitquitquit

在此处了解更多信息:

https://github.com/GoogleCloudPlatform/cloud-sql-proxy/issues/828

© www.soinside.com 2019 - 2024. All rights reserved.