我有一个容器内有两个容器。一个是我的应用程序容器,第二个是CloudSQL代理容器。基本上我的应用程序容器依赖于此CloudSQL容器。
问题是当pod终止时,CloudSQL代理容器首先被终止,并且仅在几秒钟之后我的应用程序容器被终止。
因此,在我的容器终止之前,它会不断向CloudSQL容器发送请求,从而导致错误:
could not connect to server: Connection refused Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5432
这就是为什么,我认为指定终止顺序是个好主意,这样我的应用程序容器首先终止,然后才终止cloudql。
我无法在文档中找到任何可以执行此操作的内容。但也许有一些方法。
目前Kubernetes pod API无法直接实现这一点。容器可以任何顺序终止。 Cloud SQL pod可能比您的应用程序死得更快,例如,如果它执行的清理工作较少或者正在减少飞行中的请求。
当用户请求删除pod时,系统会在允许pod强制终止之前记录预期的宽限期,并将TERM信号发送到每个容器中的主进程。
您可以通过将Cloud SQL和主容器包装在不同的入口点来解决这个问题,这些入口点使用共享的pod级文件系统在彼此之间传递它们的退出状态。
像下面这样的包装可能对此有所帮助:
containers:
- command: ["/bin/bash", "-c"]
args:
- |
trap "touch /lifecycle/main-terminated" EXIT
<your entry point goes here>
volumeMounts:
- name: lifecycle
mountPath: /lifecycle
- name: cloudsql_proxy
image: gcr.io/cloudsql-docker/gce-proxy
command: ["/bin/bash", "-c"]
args:
- |
/cloud_sql_proxy <your flags> &
PID=$!
function stop {
while true; do
if [[ -f "/lifecycle/main-terminated" ]]; then
kill $PID
fi
sleep 1
done
}
trap stop EXIT
# We explicitly call stop to ensure the sidecar will terminate
# if the main container exits outside a request from Kubernetes
# to kill the Pod.
stop &
wait $PID
volumeMounts:
- name: lifecycle
mountPath: /lifecycle
您还需要一个本地临时空间来用于通信生命周期事件:
volumes:
- name: lifecycle
emptyDir:
当然,这些取决于你正在运行的容器,它们可以使用shell;对于Cloud SQL代理也是如此,但您可能需要对构建进行更改以确保您自己的应用程序容器也是如此。