Jah*_*nov 5 google-cloud-sql kubernetes cloud-sql-proxy
我在一个吊舱内有两个容器。一个是我的应用程序容器,第二个是 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
Run Code Online (Sandbox Code Playgroud)
这就是为什么,我认为指定终止顺序是一个好主意,以便我的应用程序容器首先终止,然后才是 cloudsql 一个。
我在文档中找不到任何可以做到这一点的东西。但也许有一些方法。
目前,Kubernetes pod API 无法直接实现这一点。容器可以按任何顺序终止。Cloud SQL pod 可能会比您的应用程序更快地消亡,例如,如果它需要执行的清理工作较少或需要排出的动态请求较少。
从Pod 的终止:
当用户请求删除某个 Pod 时,系统会在允许强制杀死该 Pod 之前记录预期的宽限期,并向每个容器中的主进程发送一个 TERM 信号。
您可以通过将 Cloud SQL 和主容器包装在不同的入口点来在一定程度上解决这个问题,这些入口点使用共享的 pod 级文件系统在彼此之间传达它们的退出状态。
此解决方案不适用于 Cloud SQL 代理的 1.16 版本(请参阅评论),因为此版本不再将 shell 与容器捆绑在一起。1.17 版本现在在 Alpine 或 Debian Buster 变体中可用,因此该版本现在是一个可行的升级目标,它再次与此解决方案兼容。
像下面这样的包装器可能会对此有所帮助:
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
Run Code Online (Sandbox Code Playgroud)
您还需要一个本地临时空间来用于通信生命周期事件:
volumes:
- name: lifecycle
emptyDir:
Run Code Online (Sandbox Code Playgroud)
这个解决方案是如何工作的?它在 Cloud SQL 代理容器中拦截SIGTERMKubernetes 主管在关闭时传递给每个 Pod容器的信号。在该容器中运行的“主进程”是一个 shell,它产生了一个运行 Cloud SQL 代理的子进程。因此,Cloud SQL 代理不会立即终止。相反,shell 代码会阻塞等待来自主容器它已成功退出的信号(通过文件系统中出现的简单方式)。只有在那时,Cloud SQL 代理进程才会终止并且 sidecar 容器返回。
当然,如果您的容器关闭时间过长并超过配置的宽限期,这对强制终止没有影响。
解决方案取决于您正在运行的容器是否有可用的 shell;这适用于 Cloud SQL 代理(使用alpine或debian变体时 1.16 和 1.17 之后的版本除外),但您可能需要对本地容器构建进行更改,以确保您自己的应用程序容器也是如此。
| 归档时间: |
|
| 查看次数: |
2509 次 |
| 最近记录: |