pky*_*eck 17 google-cloud-sql docker kubernetes
我有一个Kubernetes JOB在CloudSQL数据库上进行数据库迁移.
从GKE访问CloudSQL数据库的一种方法是使用CloudSQL代理容器然后通过连接localhost.太棒了 - 到目前为止工作正常.但是因为我在K8s中这样做,JOB所以作业没有被标记为成功完成,因为代理继续运行.
$ kubectrl get po
NAME READY STATUS RESTARTS AGE
db-migrations-c1a547 1/2 Completed 0 1m
Run Code Online (Sandbox Code Playgroud)
即使输出显示"已完成",最初的两个容器之一仍在运行 - 代理.
如何在完成容器1内的迁移时使代理退出?
小智 10
一种可能的解决方案是使用匹配服务的单独的cloudql-proxy部署.然后,您只需要在连接到代理服务的作业中使用迁移容器.
这有一些缺点:
如果你想打开CLOUDSQL代理整个集群必须更换tcp:3306同tcp:0.0.0.0:3306在-instance上CLOUDSQL代理参数.
Gro*_*Src 10
我发现的最好方法是在容器之间共享进程命名空间并使用 SYS_PTRACE securityContext 功能来允许您终止 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"
Run Code Online (Sandbox Code Playgroud)
有 3 种方法可以做到这一点。
1- 如@newoxo 在其中一个答案中所述,使用私有 IP 将您的 K8s 作业连接到 Cloud SQL。为此,您的集群需要是 VPC 原生集群。我的不是,我也不想将我所有的东西移动到一个新的集群。所以我无法做到这一点。
2- 如@Christian Kohler 所述,将 Cloud SQL 代理容器与服务放在单独的部署中。这看起来是一个不错的方法,但 Google Cloud 支持并不推荐这样做。
我正要朝这个方向前进(解决方案 #2),但我决定尝试其他方法。
这是对我有用的解决方案:
3- 您可以使用文件系统在同一个 Pod/Job 中的不同容器之间进行通信。思路是告诉Cloud SQL Proxy容器什么时候完成主要工作,然后kill掉cloud sql代理。这是如何做到的:
在 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:
Run Code Online (Sandbox Code Playgroud)
基本上,当您的主要工作完成后,它会在 /lifecycle 中创建一个文件,该文件将由添加到 cloud-sql-proxy 容器的观察者识别,这将终止代理并终止容器。
我希望它有帮助!如果您有任何问题,请告诉我。
基于:https : //stackoverflow.com/a/52156131/7747292
| 归档时间: |
|
| 查看次数: |
2127 次 |
| 最近记录: |