はじめに
Kubernetes 1.29からBeta機能となったSidecar Containerという機能を使う機会があったので、これについて一問一答形式で概要を共有してみようと思います。
小粒なTipsになりますがご参考にしてください。
公式DOC: https://kubernetes.io/ja/docs/concepts/workloads/pods/sidecar-containers/
Q. Sidecar Containerってどんな機能?
Podが複数のコンテナで構成されるとき、メインとなる業務ロジックが実装されたコンテナとは別に、ログコレクターやネットワークプロキシをセカンドコンテナとして一緒にデプロイするケースがかねてより存在しました。このセカンドコンテナを従来から「サイドカーコンテナ」と呼んでいました。
Kubernetes 1.29からBeta機能となったSidecar Containerは少し特殊なInitContainerで、起動したコンテナはCompletedで終了などせずメインコンテナと並んで稼働し続けます。これによって従来のサイドカーコンテナのユースケースをネイティブ機能として提供されます。
Q. 何が嬉しいの?
従来のサイドカーコンテナの場合、主に以下のような問題点がありました。
【起動順序・終了順序の制御が困難】
例えば、Istioを使っている場合ネットワークプロキシの役割でサイドカーコンテナとしてenvoyが構成されます。しかし起動のラグで通信を取りこぼしてしまう可能性があるため起動順序は
envoy → メインコンテナ
となって欲しいです。これを実現するためにIstioではコンテナの起動順序を制御するような機能追加していました。
また、Pod終了時も
メインコンテナ → envoy
の順番で終了して欲しいためこういった制御を入れていました。
Sidecar Container機能は、InitContainerがベースとなるためk8sは一番最初に起動しようと試みます。これによってメインコンテナとの関係性を明確に定義できるようになり、whileループなどでお隣のコンテナの様子を伺う処理を書かなくても良くなります。
【Jobが完了しない】
Kubernetes Jobもサイドカーコンテナが存在する場合は、メインコンテナが完了後でもサイドカーコンテナがしなないため、Job・Podが残り続けてしまいます。
これに対応するために、過去に私は以下のように対応を施しています。
jobTemplate:
spec:
template:
spec:
shareProcessNamespace: true
restartPolicy: Never
containers:
- name: job
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
command:
- /bin/sh
- -c
args:
- |
{{ .Values.job.command }} && kill -s TERM $(pidof pilot-agent)
...
実施していることの要点は主に2つです。
- Pod内のコンテナ間でプロセスの名前空間を共有するため、shareProcessNamespace: trueに設定する
- コンテナに渡すコマンドにkillコマンドを抱き合わせて、ジョブの実行が終わり次第でサイドカーコンテナのプロセスに直接SIGTERMを渡す
これでは、プロセス共有の必要があるためセキュリティ的にも不安が残る筋の悪い対応に見えます。
Sidecar Container機能はこれらの制御をKubernetesのレイヤーで対応することになります。 Sidecar Containerとして定義されたものはJobの完了判定に含まれないので、メインコンテナさえCompletedになればJobは完了として判定されます。 これによってメインコンテナからSIGTERMを送るような処理を書かなくても綺麗に落ちてくれます。
Q. どうやって設定するの?
設定方法は極めてシンプルで、以下2点を設定します。
- いままでサイドカーコンテナとしてcontainersに設定していたものをinitContainersセクションに移行
- 1で設定したinitContainersに
restartPolicy: Always
を追記する
これでSidecar Containerとして認識されます。
Q. 注意することある?
- コンテナ起動順序をサイドカーコンテナ → メインコンテナを確実にする場合、サイドカーコンテナにstartupProbeを設定する startupProbeを設定しないと、サイドカーコンテナをキックしたら、次のコンテナもキックしてしまうので確実にサイドカーコンテナ→ メインコンテナと起動順序を制御したい場合は必須です
- terminationGracePeriodSecondsをサイドカーコンテナ込みの時間となるように見直す terminationGracePeriodSecondsはメインコンテナだけでなくサイドカーコンテナもスコープに含みます。したがって、時間切れでPodが強制削除されないように再度見直しをかけて、十分な秒数を見極めます。
今後は複数コンテナでPodを構成するユースケースでの正攻法となる機能だと思うのでぜひキャッチアップしてみてください。