2026年8月2日

2026年8月2日

KubernetesのSidecarパターンの実装方法|ネイティブサイドカー(restartPolicy: Always)の書き方と注意点

Sidecarパターンは、アプリ本体のコンテナの横に補助役のコンテナを同じPodで動かし、ログの転送・プロキシ・設定の再読み込みといった周辺の仕事を任せる設計です。現在のKubernetesでは、initContainers に restartPolicy: Always を付ける「ネイティブサイドカー」が正式な書き方になっており、起動順と終了順を制御できます。この記事では、サイドカーが向く場面と向かない場面、ネイティブサイドカーの書き方、従来の書き方との違い、運用でつまずく点を説明します。

ネイティブサイドカーは Kubernetes 1.28 でアルファとして入り、1.29 で既定で有効、1.33 で安定版(GA)になりました(2026年10月現在)。マネージドサービスでは、コントロールプレーンだけでなくノード側(kubelet)の版もこれに対応している必要があります。

Sidecarパターンで何ができるか

同じPodのコンテナは、ネットワーク名前空間とボリュームを共有します。この性質を使うのがサイドカーです。

  • localhostで通信できる:本体が 127.0.0.1:8080 で待ち受け、サイドカーのプロキシが外からの通信を受けて本体に渡す、という構成が取れます。サービスメッシュのプロキシはこの形の代表例です。
  • ボリュームを共有できる:本体が emptyDir に書いたログファイルを、サイドカーが読み取って転送できます。
  • ライフサイクルがそろう:同じPodなので、同じノードで一緒に起動し、一緒に消えます。

一方で、向かない場面もあります。本体と別々にスケールさせたい処理(たとえばキューの処理役)、本体とは別の頻度で更新したいもの、全ノードで1つ動けば足りるもの(ノード単位のログ収集エージェントなど)は、別のDeploymentやDaemonSetにしたほうが無駄がありません。サイドカーはPodの数だけ複製されるため、Podが100個あればサイドカーも100個動き、そのCPUとメモリを消費します。

ネイティブサイドカーの書き方

本体がファイルに書いたログを、サイドカーが標準出力に流す例です。ファイルにしかログを書けないアプリでも、サイドカー経由で kubectl logs やクラスタのログ収集に乗せられます。

apiVersion: v1
kind: Pod
metadata:
  name: app-with-log-sidecar
spec:
  initContainers:
    - name: log-streamer
      image: busybox:1.36
      restartPolicy: Always
      command: ["sh", "-c", "touch /var/log/app/app.log && tail -F /var/log/app/app.log"]
      volumeMounts:
        - name: app-logs
          mountPath: /var/log/app
      resources:
        requests:
          cpu: 10m
          memory: 16Mi
        limits:
          memory: 32Mi
  containers:
    - name: app
      image: busybox:1.36
      command: ["sh", "-c", "while true; do echo \"$(date) request handled\" >> /var/log/app/app.log; sleep 5; done"]
      volumeMounts:
        - name: app-logs
          mountPath: /var/log/app
  volumes:
    - name: app-logs
      emptyDir: {}
kubectl apply -f app-with-log-sidecar.yaml
kubectl get pod app-with-log-sidecar
kubectl logs app-with-log-sidecar -c log-streamer -f

ポイントは、サイドカーを containers ではなく initContainers に書き、restartPolicy: Always を付けることです。普通のinitContainerは処理を終えてから次へ進みますが、restartPolicy: Always を付けたものは起動したまま動き続け、落ちれば再起動されます。

kubectl get pod のREADY列には、サイドカーも数に含まれます。上の例なら 2/2 になれば両方が準備できています。

従来の書き方(containersに並べる)との違い

以前は、サイドカーも containers に本体と並べて書くのが普通でした。今でも動きますが、次の問題がありました。

  • 起動順が保証されない:本体がサイドカーのプロキシより先に起動し、起動直後の通信に失敗することがありました。
  • Jobが終わらない:Jobの本体が処理を終えても、サイドカーが動き続けるためPodが完了にならず、Jobがいつまでも終わりませんでした。
  • 終了順が保証されない:Pod停止時に、本体がまだ通信している最中にプロキシが先に止まることがありました。

ネイティブサイドカーでは、これらが次のように解決されます。

  • サイドカーは本体(containers)より先に起動します。サイドカーに startupProbe を書くと、それが成功するまで次のコンテナの起動を待ちます。
  • 本体のコンテナがすべて終了すると、サイドカーは自動的に停止されます。Jobでも完了扱いになります。
  • Pod停止時は、本体が先に止まり、その後にサイドカーが起動とは逆の順に止まります。

既存の構成を書き換えるときは、サイドカーのコンテナを containers から initContainers に移して restartPolicy: Always を足すのが基本の手順です。ただし、Helmチャートやサービスメッシュがサイドカーを自動で注入している場合は、その仕組み側の設定で切り替えることになります。対応状況はチャートやメッシュの版で異なるため、各プロジェクトのドキュメントで確認してください。

起動順を待たせる:startupProbe

本体がサイドカーのプロキシ経由で通信する場合、プロキシの準備ができる前に本体が起動すると困ります。サイドカーに startupProbe を書くと、kubeletはその成功を待ってから本体を起動します。

initContainers:
  - name: proxy
    image: your-registry.example.com/proxy:1.0.0
    restartPolicy: Always
    ports:
      - containerPort: 15000
    startupProbe:
      tcpSocket:
        port: 15000
      periodSeconds: 2
      failureThreshold: 30

この例では2秒おきに最大30回(約60秒)、ポート15000への接続を試します。イメージ名とポートは、実際に使うプロキシのものに置き換えてください。ネイティブサイドカーでは、livenessProbe・readinessProbe も通常のコンテナと同じように使えます。サイドカーのreadinessProbeが失敗している間は、Pod全体がReadyになりません。

運用でつまずく点

リソースの見積もり

サイドカーの requests はPodのrequestsに加算され、スケジューリングの判断に使われます。サイドカーにrequestsを書き忘れると、ノードの空き計算が実態と合わなくなります。逆に大きく見積もりすぎると、Podの数だけ無駄が積み上がります。本体と同じく、実測を見て決めます。

ログの見方

kubectl logs <pod名> はコンテナを指定しないと、どのコンテナのログか分かりにくくなります。複数コンテナのPodでは -c <コンテナ名> を付ける習慣にしておくと、調査の取り違えが減ります。全コンテナを一度に見たいときは --all-containers が使えます。

ポートの衝突

同じPodのコンテナはネットワークを共有するため、本体とサイドカーが同じポートで待ち受けることはできません。本体を変更せずにプロキシを挟む場合は、待ち受けポートの割り振りを先に決めておきます。

更新の単位

サイドカーのイメージだけを更新する場合も、Podの作り直し(Deploymentならローリングアップデート)になります。本体に影響しない更新のつもりでも、本体のPodが入れ替わる点に注意します。本番に入れる前に、検証用の名前空間で起動順と停止時の挙動を確かめてから反映してください。

まとめ

  • Sidecarパターンは、同じPodでネットワークとボリュームを共有する補助コンテナに、ログ転送やプロキシなどを任せる設計です。
  • 現在の正式な書き方は、initContainers に restartPolicy: Always を付けるネイティブサイドカーです(1.33でGA)。
  • ネイティブサイドカーは本体より先に起動して後に止まり、Jobの完了を妨げません。起動待ちには startupProbe を使います。
  • Podの数だけ複製されるため、ノード単位で足りる処理はDaemonSet、独立してスケールさせたい処理は別のDeploymentにします。
  • requestsの設定、-c を付けたログ確認、ポートの割り振りを最初に決めておくと運用が楽になります。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲