このセクションは、ワークロード向けに新しい組み込みのサイドカーコンテナ機能を導入する方を対象としています。
サイドカーコンテナは、ブログ記事で述べられているように、新しいコンセプトではありません。 Kubernetesは、このコンセプトを実装するために、1つのPod内に複数のコンテナを実行することを許可します。 通常のコンテナとしてサイドカーコンテナを実行するには多くの制限がありますが、新しい組み込みのサイドカーコンテナのサポートで解消されます。
This is a stable feature in Kubernetes, and has been since version v1.33. It was first available in the v1.28 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate SidecarContainers, Kubernetes ignores it but does not report any error.
Kubernetesクラスターが必要、かつそのクラスターと通信するためにkubectlコマンドラインツールが設定されている必要があります。 このチュートリアルは、コントロールプレーンのホストとして動作していない少なくとも2つのノードを持つクラスターで実行することをおすすめします。 まだクラスターがない場合、minikubeを使って作成するか、 以下のいずれかのKubernetesプレイグラウンドも使用できます:
作業するKubernetesサーバーは次のバージョン以降のものである必要があります: 1.29.バージョンを確認するには次のコマンドを実行してください: kubectl version.
サイドカーコンテナは、同じPod内でメインのアプリケーションコンテナと共に実行されるセカンダリコンテナです。 これらのコンテナは、ロギング、モニタリング、セキュリティ、データ同期などの追加サービスや機能を提供することで、メインのアプリケーションコードを直接変更することなく、プライマリ アプリケーションコンテナ の機能を強化または拡張するために使用されます。 サイドカーコンテナのコンセプトページで詳細を読むことができます。
サイドカーコンテナのコンセプトは新しいものではなく、このコンセプトには複数の実装があります。 Podを定義する人が実行したいサイドカーコンテナだけでなく、Podの実行開始前にいくつかのアドオンがPodを変更することで、追加のサイドカーコンテナが存在している場合があることもわかります。 それらの追加のサイドカーを 注入する メカニズムは、多くの場合Mutating Webhookです。 例えば、サービスメッシュアドオンは、異なるPod間の通信において、相互TLSと暗号化の設定をするサイドカーを注入することがあります。
サイドカーコンテナのコンセプト自体は目新しいものではありませんが、Kubernetesにおけるこの機能のネイティブ実装は新しいものです。 そして、どの新機能にもあるように、この機能の導入には一定の課題が生じる可能性があります。
このチュートリアルでは、エンドユーザーだけでなく、サイドカーコンテナの作成者も経験しうる課題と解決策を取り上げます。
サイドカーコンテナに関してKubernetesのネイティブサポートを利用することには、いくつかの利点があります:
SIGTERMシグナルによって終了します。
サイドカーコンテナがグレースフルシャットダウンされない場合、サイドカーコンテナを終了させるためにSIGKILLシグナルが使用されます。restartPolicy: OnFailureまたはrestartPolicy: Neverである場合、ネイティブサイドカーコンテナはPodの完了をブロックしません。
レガシーサイドカーコンテナでは、この状況を処理するために特別な配慮を必要とします。restartPolicy: Neverによって通常のコンテナが再起動されないとしても、組み込みのサイドカーコンテナは、それらが完了するたびに再起動されます。更なる情報について学習するには、Initコンテナとの違いを参照してください。
SidecarContainersフィーチャーゲートは、Kubernetesバージョン1.29でベータ版となり、デフォルトで有効化されています。
一部のクラスターでは、この機能が無効化されていたり、この機能と互換性のないソフトウェアがインストールされていたりすることがあります。
このような場合、Podが拒否されたり、サイドカーコンテナによってPodの起動がブロックされたりすることで、Podが使用不能になる可能性があります。 Podが単に初期化中に止まってしまうため、この状況を検知するのは容易です。 しかし問題の原因が明らかでないことが多いです。
以下は、ワークロードにサイドカーコンテナを導入する際に考慮すべきことや、トラブルシューティングの手順です。
最初のステップとして、APIサーバーとノードの両方がKubernetesバージョン1.29以降であることを確認してください。 以前のバージョンで動いているノードがあり、フィーチャーゲートが有効化されていないクラスターでは、正しく動作しません。
フィーチャーゲートが、コントロールプレーン内のAPIサーバーと全てのノードで有効化されていることを確認してください。
フィーチャーゲートが有効かどうかを確認する方法の1つとしては、このようなコマンドを実行することです:
APIサーバー用:
kubectl get --raw /metrics | grep kubernetes_feature_enabled | grep SidecarContainers
個々のノード用:
kubectl get --raw /api/v1/nodes/<node-name>/proxy/metrics | grep kubernetes_feature_enabled | grep SidecarContainers
以下のような出力が表示された場合:
kubernetes_feature_enabled{name="SidecarContainers",stage="BETA"} 1
これは機能が有効化されていることを意味します。
この機能の検証時に問題に遭遇した場合、それはサードパーティ製ツールやMutating Webhookのいずれかが正しく動作していないことを示している可能性があります。
SidecarContainersフィーチャーゲートが有効な場合、PodのAPIには新しいフィールドが追加されます。
一部のツールやMutating Webhookは、より古いバージョンのKubernetes APIで構築されている可能性があります。
ツールが様々なパッチ戦略を使用してPodオブジェクトを変更する際に、未知のフィールドをそのまま渡す場合、これは問題とはなりません。 しかし、未知のフィールドを取り除いてしまうツールも存在します。 もしそのようなツールを使用している場合、それらをKubernetes APIクライアントコードのバージョン1.28以降で再コンパイルしなければなりません。
これを確認する方法は、Mutating Admissionを通過したPodでkubectl describe podコマンドを使用することです。
いずれかのツールが新しいフィールド(restartPolicy:Always)を取り除いた場合、コマンド出力に表示されません。
このような問題に遭遇した場合、オブジェクト全体の更新ではなく、パッチ戦略のいずれかを使用してオブジェクトの変更をするよう、ツールやWebhookの作成者に助言してください。
自動的にサイドカーを注入するソフトウェアを使用している場合、ネイティブサイドカーコンテナを使用できるようにするために、いくつかの戦略を取ることができます。 基本的にはどの戦略も、サイドカーが注入されるPodが、この機能をサポートするノードに配置されるかどうかを決定するために採用できる選択肢です。
一例として、Istioコミュニティでのこの会話をたどることができます。 この議論は、下記に列挙した選択肢について検討されています。
restartPolicy=Alwaysを指定したInitコンテナを注入し、それをNativeSidecarと呼ぶことにする。NativeSidecarは、最初の実行を示すファイルを空のディレクトリに書き込み、終了コード0で即座に終了しなければならない。NativeSidecarは、再起動時(ネイティブサイドカーがサポートされている場合)に、ファイルがすでに空のディレクトリ内に存在することを確認し、そのファイルを変更する。
これは、組み込みのサイドカーコンテナがサポートされ、実行されていることを示している。OldWaySidecarと呼ぶことにする。OldWaySidecarは、起動時に空のディレクトリ内にファイルが存在するかどうかを確認する。NativeSidecarが実行されていないことをファイルが示している場合、それはサイドカー機能がサポートされていないと推定し、自らがサイドカーであることを前提として動作する。NativeSidecarが実行されていることをファイルが示している場合、何もせず永久にスリープする(PodがrestartPolicy=Alwaysのとき)、または終了コード0で即座に終了する(PodがrestartPolicy!=Alwaysのとき)。