Kubernetes 1.28でFeatureGateになったSidecar containersをJobで試す
はじめに
こんにちは、三村です。
先日Kubernetes 1.28がリリースされました。
今回のバージョンでSidecar containersの機能がFeatureGateとして追加されました。
従来のKubernetesでは、1つのPodに複数のコンテナを配置することはできましたが、どちらがサイドカーなのかといった区別はなく、Kubernetesの機能としてサイドカーコンテナがあるというわけではありませんでした。
Kubernetes 1.28からは、initContainerのrestartPolicyにAlwaysを指定することでinitContainerがサイドカーコンテナとして動作するようになりました。
今回はこの機能をKind上で試してみたので、その使用方法と挙動を紹介します。
サンプルコードや設定ファイルは以下のレポジトリに置いています。
Kuberentesクラスタの構築
以下のようなcluster.yamlを作成します。
重要なポイントは2点あり、一つは1.28のバージョンを指定すること、もう一つは最後の行で、Sidecar containersの機能はFeatureGateであるため、設定を入れて有効化する必要があることです。
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
image: kindest/node:v1.28.0
- role: worker
image: kindest/node:v1.28.0
- role: worker
image: kindest/node:v1.28.0
featureGates:
SidecarContainers: true
この設定を元に、kindでクラスタを作成します。
$ kind create cluster --config cluster.yaml
Jobでのサイドカーコンテナの動作確認
次に、Jobを作成して、サイドカーコンテナが動作することを確認します。
メインのコンテナとして30秒後に"main application"と出力するコンテナと、サイドカーコンテナとしてHTTPサーバを起動するコンテナを作成します。
以下にサンプルコードを貼りました。
これらをappとsidecarというイメージ名でDocker imageをビルドし、Kind上にロードしておきます。
package main
import (
"fmt"
"time"
)
func main() {
time.Sleep(30 * time.Second)
fmt.Println("main application")
}
package main
import (
"io"
"net/http"
)
func main() {
handler := func(w http.ResponseWriter, _ *http.Request) {
io.WriteString(w, "Sidecar application\n")
}
http.HandleFunc("/", handler)
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic(err)
}
}
そして、Jobのマニフェストを作成します。
サイドカーコンテナはinitContainersとして定義し、restartPolicyにAlwaysを指定します。
apiVersion: batch/v1
kind: Job
metadata:
name: sample-job
spec:
template:
spec:
containers:
- name: app
image: app
imagePullPolicy: IfNotPresent
initContainers:
- name: sidecar
image: sidecar
imagePullPolicy: IfNotPresent
restartPolicy: Always
restartPolicy: Never
このmanifestをapplyし、Jobを作成します。
kubectl apply -f job.yaml
Jobの状態を確認します。
$ kubectl get job sample-job -w
NAME COMPLETIONS DURATION AGE
sample-job 0/1 1s 1s
sample-job 0/1 3s 3s
sample-job 0/1 33s 33s
sample-job 0/1 35s 35s
sample-job 1/1 35s 35s
期待通りにJobが正常に完了します。
今回、サイドカーコンテナが常駐型プログラムであるにもかかわらず、メインのコンテナが終了すればJob全体が正常に終了しました。(従来のサイドカー構成ではこれでは正常終了しません。)
この挙動については次の章で解説します。
Sidecar containersの何が嬉しいのか
Sidecar containersの機能を使うことで一番嬉しいのは、Jobの終了時にサイドカーコンテナにシグナルを送る必要がなくなることです。
従来のKubernetesでは、サイドカー構成のJobを作成する際、Pod内のすべてのコンテナがexit code 0で終了しないとJobが正常終了しませんでした。そのため、サイドカーコンテナで常駐型プログラムを動かす場合は、何かしらの方法でメインのコンテナが終了する際にサイドカーコンテナを終了する必要がありました。
これには、shareProcessNamespace
を使ってコンテナ間でPID名前空間を共有し、メインのコンテナからサイドカーコンテナにSIGTERMのシグナル送るなどの方法を取る必要がありましたが、自分でプログラムにこれを実装する必要があり非常に煩雑でした。
Sidecar containersの機能を使うと、メインのコンテナが終了するとinitContainersのコンテナにSIGTERMが自動で送られるため、このような特別な設定をせずともJobが完了してくれます。
まとめ
今回の記事では、Kubernetes 1.28でFeatureGateとなったSidecar containersの機能をJobで使う方法とその挙動について紹介しました。
これまでのKurbenetesでサイドカーパターンを使用すると、サイドカーコンテナの終了処理を考慮する必要がありましたが、Kubernetes 1.28からはこのような特別な設定をする必要がなくなりました。
Discussion