サイドカーコンテナを持つJobが完了しない問題の対処法


はじめに

Cloud SQL Proxyをサイドカーコンテナとして使用するJobが完了しない問題に出会したので、その解決方法を共有します。なぜ完了しないかというと、メインプロセスが終わったあとでもサイドカーのプロセスが動いているからです。
なので、メインプロセスが終わった時点でサイドカー側にプロセスを終了するようなシグナルを送らなければいけません。

解決法

解決法は何種類かあるみたいです。

  1. まず、コンテナ間でボリュームを共有する。メインのプロセスが終わった時点で、そのボリュームに適当なファイルを作る。サイドカーコンテナ側ではボリューム内にファイルができたかを検知するループを回し、できた時点でプロセスを終了する。
  2. Pod内のコンテナ間でPID Namespaceを共有し、メインコンテナ側でサイドカーコンテナのプロセスをkillする。

今回は2番の方が簡潔だったため、こちらを採用しました。

my-db-job.yaml
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"
          - "-instances=$(DB_CONNECTION_NAME)=tcp:3306"

ポイントはsecurityContext/capabilitiesにSYS_PTRACEを追加している点です。
SYS_PTRACEをつけるとseccomp制限が無効になり、セキュリティレベルが低下するためオススメできるかわかりませんが、公式のドキュメントにも書かれている内容ではあります。

Pod内のコンテナ間でプロセス名前空間を共有する

心配な方は1の方法でやるといいと思います。参考記事も共有しておきます。

サイドカーコンテナを含む Kubernetes Job を完了させる

まとめ

サイドカーコンテナを持つJobが完了しない問題の対処法を紹介しました。Cloud SQL Proxyを使っているとサイドカーならではの問題に対処しないといけないし、日本語の記事も意外と少ないので、また何か共有できそうな情報があれば随時書いていこうと思います。