サイドカーを付けて資源を測ってみる
目標
サイドカーを実際に付けてみて、その代償を数字で確認します。リソースがどのように加算されるか、どちらが先に起動するか、何が共有されるかを、クラスターに問い合わせて確かめます。
なぜ重要なのか
サイドカーは「機能をもう1つ追加する」ように見えますが、実際にはデプロイの単位が大きくなることです。Podのリクエスト量が加算され、起動が遅くなり、障害点が1つ増えます。その代償を知らずに増やすと、いつの間にかコンテナ5つ入りのPodになります。
環境
このPodはkwokを使って本物のkube-apiserverを起動します。Podが実際に実行されるわけではありませんが、スペック・状態・QoSの計算はすべて本物です。
ステップ
- サイドカーなしのDeployment →
/root/sc/01-plain.yaml - 正式なサイドカーの追加 →
/root/sc/02-sidecar.yaml - リクエスト量の合計 →
/root/sc/03-sum.txt - 起動順序 →
/root/sc/04-order.txt - 共有されるもの →
/root/sc/05-share.txt - ボリュームでつなぐ →
/root/sc/06-volume.yaml - QoSクラス →
/root/sc/07-qos.txt - DaemonSetとの比較 →
/root/sc/08-decide.md
参考
- 正式なサイドカーとは、
initContainersにrestartPolicy: Alwaysを指定したものです。containersにもう1つ入れるだけのものとは違います。 - サイドカーのリソースはrequestsは小さく、limitsは余裕を持たせて設定します。本体とは逆です。
サイドカーなしのPodから始める
サイドカーなしのDeployment → /root/sc/01-plain.yaml
/root/sc/01-plain.yamlにコンテナ1つのDeploymentを書きます。名前はweb、イメージはnginx:1.27-alpine、replicasは2、そしてresources.requestsにcpu 100m・memory 128Miを指定します。kubectl apply -fで適用してください。
正式なサイドカーを追加する
正式なサイドカーの追加 → /root/sc/02-sidecar.yaml
同じDeploymentにサイドカーを追加して/root/sc/02-sidecar.yamlとして保存し、適用します。
containersではなくinitContainersに入れ、restartPolicy: Alwaysを指定します。それがKubernetes 1.29からの正式なサイドカーで、本体より先に起動し、本体が終わると一緒に終了します。名前はproxy、イメージは何でもよく(busybox:1.36にsleep infinity)、requestsはcpu 50m・memory 64Miにします。
Podのリクエスト量は合計になる
リクエスト量の合計 → /root/sc/03-sum.txt
kubectl get pod <파드> -o jsonpath(プレースホルダーはPod名です)で2つのコンテナのcpu requestsをそれぞれ取り出し、その合計を/root/sc/03-sum.txtに본체 + 사이드카 = 합の形式で1行に書いてください(プレースホルダーは本体の値、サイドカーの値、合計です。単位はm)。スケジューラーが配置先を探すときに見る値が、この合計です。
どちらが先に起動するか
起動順序 → /root/sc/04-order.txt
kubectl get pod <파드> -o jsonpath='{.status.initContainerStatuses[*].name} {.status.containerStatuses[*].name}'(プレースホルダーはPod名です)で確認し、/root/sc/04-order.txtに2行で書きます。(1)先に起動するコンテナの名前、(2)なぜその順序でなければならないのか。プロキシの起動が遅れると最初のリクエストがどこへ向かうか、考えてみてください。
何を共有するか
共有されるもの → /root/sc/05-share.txt
2つのコンテナが共有するものと共有しないものを、/root/sc/05-share.txtに書きます。4行で、ネットワーク / ファイルシステムのルート / プロセス一覧 / ボリュームです。各行は<항목>: 공유|비공유の形式(プレースホルダーは項目名です。「共有」と「非共有」を意味する2つの韓国語の語のどちらかを書きます)で書き、共有されないものには、どうすれば共有されるかを書き添えてください。
ボリュームでつなぐ
ボリュームでつなぐ → /root/sc/06-volume.yaml
本体が書いたファイルをサイドカーに読ませるには、同じボリュームを両方にマウントする必要があります。emptyDirを1つ作り、本体は/var/log/appに、サイドカーは/logsにマウントしたマニフェストを/root/sc/06-volume.yamlに書いて、適用してください。
QoSクラスを確認する
QoSクラス → /root/sc/07-qos.txt
kubectl get pod <파드> -o jsonpath='{.status.qosClass}'(プレースホルダーはPod名です)の結果を見て、/root/sc/07-qos.txtに2行で書きます。(1)クラス、(2)requestsをまったく指定しなかった場合にどのクラスになり、なぜ危険なのか。BestEffortはメモリ圧迫時に真っ先に落とされます。
DaemonSetのほうがよいか
DaemonSetとの比較 → /root/sc/08-decide.md
/root/sc/08-decide.mdに3行で書きます。(1)サイドカーが妥当となる3つの条件のうち、このケースがどれに当てはまるか、(2)当てはまらないならDaemonSetのほうがよい理由、(3)リソースの観点での違い。付ける前に問うべき質問が、これです。