サイドカーパターン

メインコンテナと同じ Pod に補助コンテナを並べ、ネットワークと Volume を共有して横断的関心事を分離する設計パターン

Kubernetes設計パターン

サイドカーパターンとは

サイドカーパターンは、メインのアプリケーションコンテナと同じ Pod に補助コンテナを並べ、ログ収集、監視、プロキシといった横断的関心事をメインから切り離す設計パターンである。

同じ Pod に入れることが要点で、これは配置の都合ではない。Pod 内のコンテナはネットワーク名前空間を共有するので localhost で互いに届き、同じ Volume を両方からマウントできる。この 2 点があるおかげで、補助側はメインのプロセスに一切手を入れずにメインのログを読み、メイン宛ての通信を受けられる。さらにスケジューリング・スケール・削除が Pod 単位で動くため、メインが生きている間だけ補助が生きているという関係が自然に保たれる。

構図としては、本体のコードにライブラリを埋め込む代わりに、隣に別プロセスを置いて同じ資源を覗かせる形である。ライブラリ方式と分かれる判断点は 2 つで、言語をまたいで同じ機能を配りたいか (サイドカーは本体の実装言語に依存しない)、本体を再デプロイせずに補助側だけ差し替えたいか (イメージが別なので個別に更新できる)。どちらも不要ならライブラリで足りる。

サイドカーのユースケース

サイドカーに出すのは、本体の関心事から外れていて、かつどのアプリケーションでも同じ形になる仕事である。

サイドカー役割
ログ収集ログを集約・転送Fluent Bit
プロキシトラフィック制御、mTLSEnvoy (Istio)
監視メトリクス収集ADOT Collector
シークレット秘密情報の注入Vault Agent

プロキシのサイドカーを全 Pod へ配り、証明書や経路制御を制御面から一括して扱う仕組みへ発展させたものがサービスメッシュで、サイドカーパターンの一適用例を基盤側で自動化したものにあたる。

Kubernetes での定義

最も素朴な書き方は、containers にメインと並べる形である。次の例では emptyDir の Volume を両方のコンテナがマウントし、アプリが書いたログファイルを収集側が読む。

apiVersion: v1
kind: Pod
spec:
  containers:
    - name: app
      image: my-app:1.4.2
      ports: [{ containerPort: 8080 }]
      volumeMounts:
        - name: logs
          mountPath: /var/log/app
    - name: log-collector
      image: fluent/fluent-bit:3.1.9
      volumeMounts:
        - name: logs
          mountPath: /var/log/app
  volumes:
    - name: logs
      emptyDir: {}

タグを版で固定してあるのは、可変タグだとノードによって違う中身が動いたり、再起動しただけで版が変わったりするためである。

起動順と終了順を保証する書き方

containers に並べる書き方には順序の保証がない。収集側より先にアプリが立ち上がって初期のログを取り逃す、Job でアプリが終わっても補助側が走り続けて Pod が完了しない、といった噛み合わせの悪さが出る。これに対して Kubernetes は、initContainers の要素に restartPolicy: Always を付けたものをサイドカーとして扱う書き方を用意している。名前は初期化コンテナだが、終わって次へ進むのではなくそのまま走り続ける。

apiVersion: v1
kind: Pod
spec:
  initContainers:
    - name: log-collector
      image: fluent/fluent-bit:3.1.9
      restartPolicy: Always     # これがサイドカーの指定 (init のまま終わらない)
      volumeMounts:
        - name: logs
          mountPath: /var/log/app
  containers:
    - name: app
      image: my-app:1.4.2
      ports: [{ containerPort: 8080 }]
      volumeMounts:
        - name: logs
          mountPath: /var/log/app
  volumes:
    - name: logs
      emptyDir: {}

この形にすると挙動が変わる。起動は初期化コンテナの順序規則に従い、後ろに書いた初期化コンテナとメインコンテナはこのサイドカーが起動した後で始まる (起動したと見なされるのはプロセスが動き出した時点で、startupProbe を書いた場合はそれが成功した時点)。終了時は、kubelet がメインコンテナの完全な停止を待ってからサイドカーを止め、Pod 仕様に書いた順序の逆で落とす。Job では、メインコンテナが終わればサイドカーが走っていても完了が妨げられない。初期化コンテナと違って probe を書けるのもこの形の特徴で、readinessProbe を付けるとその結果が Pod の ready 判定に反映される。

この書き方は Kubernetes v1.28 で alpha として入り、v1.29 以降は機能ゲートが既定で有効、v1.33 で stable になった (2026 年 8 月時点)。クラスターの版が v1.29 未満なら従来の並置に留まるため、起動順は初期化コンテナや本体側のリトライで吸収することになる。

サイドカー vs Lambda Layer

同じ「本体に手を入れず機能を足す」目的でも、Pod 相当の入れ物が無い Lambda では手段が変わる。Lambda Layer は別プロセスを隣に置くのではなく、同じ実行環境にファイルを重ねる仕組みで、性質はかなり違う。

観点サイドカー (ECS/EKS)Lambda Layer
実行環境別コンテナ同一プロセス
通信localhost関数内呼び出し
用途プロキシ、ログ収集共通ライブラリ、ADOT
リソース独立した CPU/メモリLambda のメモリを共有

サイドカーの注意点

運用で効いてくるのは、リソースの積み上がりと順序、そして障害時の切り分けである。

注意点実際に何が起きるか対策
リソースが二重に乗るPod の要求量にサイドカー分が加算され、1 ノードに載る Pod 数が減る実測して CPU/メモリの要求と上限を絞る
起動順・終了順収集側の起動前のログが落ちる、Job が完了しないinitContainers + restartPolicy: Always (v1.29 以降)
終了時の猶予メインが終了猶予を使い切ると、サイドカーは SIGTERM の直後に SIGKILL を受け、バッファを吐き出せない吐き出し間隔を短くし、終了時にまとめて処理する設計を避ける
障害の切り分けどちらのコンテナ由来の不調か分からなくなるkubectl logs <pod> -c <container> でコンテナ単位に見る

入れるかどうかは、その機能を本体の言語とデプロイ周期から切り離す価値が、Pod あたりのリソースと運用の複雑さの増分を上回るかで決まる。1 つの Pod に補助コンテナが 3 つも 4 つも並び始めたら、本体の設計か、基盤側の共通機構へ寄せる合図である。

この記事は役に立ちましたか?

関連用語

関連する記事