Kubernetes中单个Pod中容器终止的控制顺序

时间:2018-09-03 10:55:43

标签: kubernetes google-cloud-sql 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

这就是为什么,我认为指定终止顺序是一个好主意,这样我的应用程序容器首先被终止,然后才是cloudsql一个。

我在文档中找不到任何可以做到这一点的东西。但是也许有办法。

1 个答案:

答案 0 :(得分:1)

目前,这不是直接通过Kubernetes pod API可以实现的。容器可以任何顺序终止。 Cloud SQL Pod可能比您的应用程序更快死掉,例如,如果它执行的清除次数较少或执行中的流失请求较少,则该请求会消失。

来自Termination of Pods

  

当用户请求删除Pod时,系统会记录允许的Pod被强制杀死之前的预定宽限期,并将TERM信号发送到每个容器中的主进程。


通过将Cloud SQL和主要容器包装在不同的入口点中,可以在某种程度上解决此问题,它们使用共享的容器级文件系统在彼此之间传达退出状态。

如下所示的包装器可能对此有所帮助:

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:

当然,这取决于您正在运行的容器是否有可用的外壳; Cloud SQL代理确实如此,但是您可能需要对内部版本进行更改以确保您自己的应用程序容器确实如此。