K8s の拡張ワークロード OpenKruise の運用とメンテナンスの強化

K8s の拡張ワークロード OpenKruise の運用とメンテナンスの強化

OpenKruise の基本的な概念と、よく使用されるいくつかの拡張コントローラーについてはすでに学習しました。次に、他の高度な機能について学習していきましょう。

サイドカーセット

SidecarSet は、アドミッション Webhook を通じてクラスター内に作成された適格なポッドにサイドカー コンテナーを自動的に挿入することをサポートします。 SidecarSet は、Pod の作成時にサイドカー コンテナを挿入するだけでなく、挿入されたサイドカー コンテナ イメージを Pod 内でインプレースでアップグレードする機能も提供します。 SidecarSet は、サイドカー コンテナーの定義とライフサイクルをビジネス コンテナーから分離します。これは主に、監視エージェントやログエージェントなどのステートレス サイドカー コンテナを管理するために使用されます。

たとえば、SidecarSet リソース オブジェクトを次のように定義します。

 #サイドカーセット- demo.yaml
apiバージョン:アプリクルーズio / v1alpha1
種類:サイドカーセット
メタデータ:
名前: scs -デモ
仕様:
セレクター:
matchLabels : #非常に重要な属性。app = nginxPod一致します
アプリ: nginx
更新戦略:
タイプ:ローリングアップデート
最大利用不可: 1
コンテナ:
-名前:サイドカー1
画像:ビジーボックス
コマンド: [ "sleep" , "999d" ]
ボリュームマウント:
-名前:ログ-ボリューム
マウントパス: / var / log
volumes : #このプロパティはpod.spec.volumes統合されます
-名前:ログ-ボリューム
空のディレクトリ: {}

次のリソース オブジェクトを作成するだけです。

 ➜ kubectl サイドカーセットを取得する
名前が一致しました 更新済み 準備完了 年齢
scs-デモ 0 0 0 6秒

上記の SidecarSet オブジェクトを定義するときに、ラベル セレクターという非常に重要な属性が含まれていることに注意してください。 app=nginx​ の Pod を一致させ、以下に定義されている sidecar1​ コンテナをその Pod に挿入します。たとえば、上記の SidecarSet オブジェクトと一致するように、ラベル app=nginx を含む Pod を次のように定義します。

 APIバージョン: v1
種類:ポッド
メタデータ:
ラベル:
app : nginx #SidecarSet指定されたラベルに一致
名前:テストポッド
仕様:
コンテナ:
-名前:アプリ
イメージ: nginx : 1.7.9

上記のリソース オブジェクトを直接作成します。

  kubectl get podテスト- pod
名前準備完了ステータス再起動年齢
テスト-ポッド2/2実行0 22

Pod には 2 つのコンテナがあり、上で定義した sidecar1 コンテナが自動的に挿入されていることがわかります。

 ➜ kubectl get pod test-pod -o yaml
APIバージョン: v1
種類: ポッド
メタデータ:
ラベル:
アプリ: nginx
名前: テストポッド
名前空間: デフォルト
仕様:
コンテナ:
- 指示:
- 寝る
- 999日
環境:
- 名前: IS_INJECTED
値: "true"
画像: ビジーボックス
imagePullPolicy: 常に
名前: サイドカー1
リソース: {}
ボリュームマウント:
-マウントパス: /var/log
名前: ログボリューム
- イメージ: nginx:1.7.9
イメージプルポリシー: IfNotPresent
名前: アプリ
# ......
ボリューム:
- 空のディレクトリ: {}
名前: ログボリューム
# ......

次に、SidecarSet のサイドカー コンテナ イメージを更新し、busybox:1.35.0 に置き換えます。

 ➜ kubectl patch sidecarset scs-demo --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value": "busybox:1.35.0"}]'
sidecarset.apps.kruise.io/scs-demo にパッチを適用しました

更新後、Pod 内のサイドカー コンテナを確認します。

 ➜ kubectl ポッドを取得テストポッド
名前 準備完了 ステータス 再起動 年齢
test-pod 2/2 実行中 1 (67秒前) 28分
➜ kubectl ポッドテストポッドの説明
......
イベント:
タイプ 理由 年齢 送信元 メッセージ
---- ------ ---- ---- -------
# ......
通常 10m kubelet を作成 コンテナアプリを作成
正常 10m kubelet コンテナアプリを開始
通常の Killing 114s kubelet コンテナ sidecar1 の定義が変更されたため、再起動されます
通常のプル 84s kubelet イメージ "busybox:1.35.0" のプル
通常 77 秒 (11 分で x2) kubelet コンテナ sidecar1 を作成
正常に起動しました 77 秒 (11 分で x2) kubelet コンテナ sidecar1 を起動しました
通常のプル 77 秒 kubelet イメージ「busybox:1.35.0」を 6.901558972 秒で正常にプルしました (待機時間を含めると 6.901575894 秒)
➜ kubectl get pod test-pod -o yaml |grep sexybox
kruise.io/sidecarset-inplace-update-state: '{"scs-demo":{"revision":"f78z4854d9855xd6478fzx9c84645z2548v24z26455db 46bdfzw44v49v98f2cw","updateTimestamp":"2023-04-04T08:05:18Z","lastCont ainerStatuses":{"sidecar1":{"imageID":"docker.io/library/busybox@sha256:b5d6fe0712636ceb7430189de28819e195e8966372edfc2d9409d79402a0dc16"}}}}'
画像: ビジーボックス:1.35.0
イメージ: docker.io/library/busybox:1.35.0
イメージID: docker.io/library/busybox@sha256:223ae047b1065bd069aac01ae3ac8088b3ca4a527827e283b85112f29385fb1b

メインコンテナに影響を与えることなく、Pod 内のサイドカーコンテナイメージがそのまま busybox:1.35.0 にアップグレードされていることがわかります。

基本機能

サイドカーの挿入は Pod 作成フェーズでのみ行われ、Pod 仕様のみが更新され、Pod が属するワークロード テンプレートには影響しないことに注意してください。デフォルトの k8s コンテナ フィールドに加えて、spec.containers は注入を容易にするために次のフィールドも拡張します。

 APIバージョン: apps.kruise.io/v1alpha1
種類: サイドカーセット
メタデータ:
名前: サイドカーセット
仕様:
セレクタ:
一致ラベル:
アプリ: サンプル
コンテナ:
#デフォルトの K8s コンテナ フィールド
- 名前: nginx
画像: nginx:alpine
ボリュームマウント:
- マウントパス: /nginx/conf
名前: nginxconf
# 拡張サイドカーコンテナフィールド
podInjectPolicy: BeforeAppContainer
shareVolumePolicy: #データボリュームの共有
タイプ: 無効 |有効
transferEnv: #環境変数の共有
- sourceContainerName: main # メインコンテナのPROXY_IP環境変数が、現在定義されているサイドカーコンテナに挿入されます
環境変数名: PROXY_IP
ボリューム:
- 名前: nginxconf
ホストパス: /data/nginx/conf

  • podInjectPolicy​ は、 pod.spec.containers にコンテナが挿入される場所を定義します。
  • BeforeAppContainer: ポッドの元のコンテナの前面への挿入を意味します (デフォルト)。
  • AfterAppContainer: ポッドの元のコンテナの背面への注入を意味します。
  • データ量の共有。
  • 共有指定ボリューム: spec.volumes を使用して、サイドカー自体に必要なボリュームを定義します。
  • すべてのボリュームを共有する: spec.containers[i].shareVolumePolicy.type = enabled を使用します |ポッド アプリケーション コンテナーのボリュームをマウントするかどうかを制御するには無効にします。これは、ログ収集などのサイドカーによく使用されます。有効に構成すると、アプリケーション コンテナー内のすべてのマウント ポイントがサイドカーの同じパスに挿入されます (サイドカー自体で宣言されたデータ ボリュームとマウント ポイントを除く)。
  • 環境変数の共有: spec.containers[i].transferEnv を使用して、他のコンテナから環境変数を取得できます。これにより、sourceContainerName という名前のコンテナ内の envName という名前の環境変数がこのコンテナにコピーされます。

SidecarSet は、サイドカー コンテナーのインプレース アップグレードをサポートするだけでなく、幅広いアップグレードおよびグレースケール戦略も提供します。同様に、SidecarSet オブジェクトの updateStrategy​ 属性の下で、partition​ を構成して、保持する古いバージョンの Pod の数または割合を定義することもできます。デフォルトは 0 です。リリース プロセス中に使用できない Pod の最大数を示す maxUnavailable 属性を構成することもできます。

  • {matched pod}=100、partitinotallow=40、maxUnavailable=10 の場合、コントローラーは 100-40=60 個の Pod を新しいバージョンにリリースしますが、同時にリリースされる Pod は 10 個だけです。各ポッドがリリースされると、60 個のポッドすべてがリリースされるまで、別のポッドがリリースされます。
  • {matched pod}=100、partitinotallow=80、maxUnavailable=30 の場合、コントローラーは 20 個の Pod を新しいバージョンにリリースします。 maxUnavailable 数に達したため、これらの 20 個の Pod は同時に解放されます。

リリースを一時停止するには、paused: true を設定することもできます。この場合、新しく作成および拡張されたポッドにはインジェクション機能が引き続き実装され、更新されたポッドは更新されたバージョンを変更せずに保持し、更新されていないポッドは更新を一時停止します。

 APIバージョン: apps.kruise.io/v1alpha1
種類: サイドカーセット
メタデータ:
名前: サイドカーセット
仕様:
# ...
更新戦略:
タイプ: ローリングアップデート
最大利用不可: 20%
パーティション: 10
一時停止: true

カナリアリリース

カナリアリリースが必要なビジネスでは、セレクターを使用して実装できます。最初にカナリアリリースする必要があるポッドの場合は、[canary.release] = true​ の固定ラベルを追加し、selector.matchLabels を通じてポッドを選択します。

たとえば、現在、3 つのレプリカを持つ Pod があり、ラベル app=nginx も次のように設定されています。

 APIバージョン: アプリ/v1
種類: デプロイメント
メタデータ:
名前: nginx
名前空間: デフォルト
仕様:
レプリカ: 3
改訂履歴制限: 3
セレクタ:
一致ラベル:
アプリ: nginx
テンプレート:
メタデータ:
ラベル:
アプリ: nginx
仕様:
コンテナ:
- 名前: ngx
イメージ: nginx:1.7.9
ポート:
- コンテナポート: 80

作成後、ラベル app=nginx を持つ Pod が 4 つあります。これらはすべて上記で作成した SidecarSet オブジェクトと一致するため、busybox イメージを含む sidecar1 コンテナーが挿入されます。

 ➜ kubectl get pods -l app=nginx
名前 準備完了 ステータス 再起動 年齢
nginx-6457955f7-7hnjw 2/2 実行中 0 51秒
nginx-6457955f7-prkgz 2/2 実行中 0 51秒
nginx-6457955f7-tbtxk 2/2 実行中 0 51秒
テストポッド 2/2 実行中 0 4m2s

ここで、test-pod アプリケーションのカナリア戦略を実行し、サイドカー コンテナ イメージを busybox:1.35.0 に更新する場合は、updateStrategy の下に selector.matchLabels プロパティ canary.release: "true" を追加します。

 piバージョン: apps.kruise.io/v1alpha1
種類: サイドカーセット
メタデータ:
名前: テストサイドカーセット
仕様:
更新戦略:
タイプ: ローリングアップデート
セレクタ:
一致ラベル:
canary.release: "true"
コンテナ:
- 名前: サイドカー1
画像: ビジーボックス:1.35.0
# ......

次に、テストポッドに canary.release=true ラベルを追加する必要があります。

 APIバージョン: v1
種類: ポッド
メタデータ:
ラベル:
アプリ: nginx
canary.release: "true"
名前: テストポッド
仕様:
コンテナ:
- 名前: アプリ
イメージ: nginx:1.7.9

更新後、test-pod のサイドカー イメージが更新され、他の Pod は変更されていないことがわかります。これはサイドカーのグレースケール機能を実装します。

 ➜ kubectl ポッドテストポッドの説明
イベント:
タイプ 理由 年齢 送信元 メッセージ
---- ------ ---- ---- -------
通常の強制終了 7分53秒 kubelet コンテナ sidecar1 の定義が変更されました。再起動されます
通常作成 7分23秒 (8分17秒かけて2回) kubelet コンテナ sidecar1 を作成
正常 7分23秒で開始 (8分17秒かけて2回) kubelet コンテナ sidecar1 を開始
通常のプル 7m23s kubelet イメージ「busybox」のプル
通常のプルは 7 分 23 秒で kubelet が実行し、イメージ「busybox」が 603.928658 ミリ秒で正常にプルされました

ホットアップグレード

SidecarSet のインプレース アップグレードでは、まずコンテナーの古いバージョンを停止し、次にコンテナーの新しいバージョンを作成します。この方法は、ログ収集用のエージェントなど、Pod サービスの可用性に影響を与えないサイドカー コンテナーに適しています。

ただし、このアップグレード方法は、Istio Envoy などの多くのプロキシやランタイム サイドカー コンテナーでは問題があります。 Envoy は Pod 内のプロキシ コンテナとして、すべてのトラフィックをプロキシします。直接再起動すると、Pod サービスの可用性に影響します。 Envoy サイドカーを個別にアップグレードする必要がある場合は、複雑な正常な終了と調整のメカニズムが必要です。したがって、このサイドカー コンテナーのアップグレードには新しいソリューションを提供します。

 # ホットアップグレードサイドカーセット.yaml
APIバージョン: apps.kruise.io/v1alpha1
種類: サイドカーセット
メタデータ:
名前: hotupgrade-sidecarset
仕様:
セレクタ:
一致ラベル:
アプリ: hotupgrade
コンテナ:
- 名前: サイドカー
画像: openkruise/hotupgrade-sample:sidecarv1
imagePullPolicy: 常に
ライフサイクル:
投稿開始:
実行:
指示:
- /bin/sh
-/migrate.sh
アップグレード戦略:
アップグレードタイプ: ホットアップグレード
hotUpgradeEmptyイメージ: openkruise/hotupgrade-sample:empty

  • upgradeType​: HotUpgrade は、サイドカー コンテナー タイプがホット アップグレード ソリューションであることを示します。
  • hotUpgradeEmptyImage​: サイドカー コンテナーをホット アップグレードする場合、企業はホット アップグレード プロセス中にコンテナーを切り替えるための空のコンテナーを提供する必要があります。空のコンテナは、コマンド、ライフサイクル、プローブなど、サイドカー コンテナと同じ構成 (イメージ アドレスを除く) を持ちますが、何も実行しません。
  • lifecycle.postStart: ホット アップグレード プロセス中の状態移行は、postStart フックで完了します。スクリプトは、ビジネスの特性に応じて実装する必要があります。たとえば、nginx のホット アップグレードでは、Listen FD 共有とトラフィック ドレイン (リロード) 操作の完了が必要です。

一般的に、ホット アップグレード機能には次の 2 つのプロセスが含まれます。

  • Pod が作成されると、ホット アップグレード コンテナーが挿入されます。
  • インプレースアップグレードする場合は、ホットアップグレードプロセスを完了します。

ホットアップグレードコンテナを挿入する

Pod が作成されると、SidecarSet Webhook によって 2 つのコンテナが挿入されます。

  • {sidecarContainer.name}-1​: 次の図 envoy-1​ に示すように、このコンテナーは実際に動作しているサイドカー コンテナーを表します (例: envoy:1.16.0)。
  • {sidecarContainer.name}-2​: 次の図に示すように、envoy-2​ はビジネスによって構成された hotUpgradeEmptyImage​ コンテナーです (例: empty:1.0)。これは、後続のホット アップグレード メカニズムに使用されます。

ホットアップグレードコンテナを挿入する

ホットアップグレードプロセス

ホット アップグレード プロセスは、主に次の 3 つのステップに分かれています。

  • アップグレード: 空のコンテナを最新のサイドカーコンテナにアップグレードします。例: envoy-2.Image = envoy:1.17.0
  • 移行: lifecycle.postStart はホットアップグレードプロセスで状態の移行を完了し、移行が完了すると終了します。
  • リセット: 状態の移行が完了すると、ホット アップグレード プロセスによって envoy-1 コンテナーが空のイメージに設定されます。例: envoy-1.Image = empty:1.0

上記の 3 つの手順で、ホット アップグレードのプロセス全体が完了します。 Pod で複数のホット アップグレードを実行すると、上記の 3 つの手順が繰り返し実行されます。

ホットアップグレードプロセス

ここでは、OpenKruise の公式例を使用して説明します。まず、上記の hotupgrade-sidecarset SidecarSet を作成します。次に、次のように CloneSet オブジェクトを作成します。

 # ホットアップグレードクローンセット.yaml
APIバージョン: apps.kruise.io/v1alpha1
種類: CloneSet
メタデータ:
名前: ビジーボックス
ラベル:
アプリ: hotupgrade
仕様:
レプリカ: 1
セレクタ:
一致ラベル:
アプリ: hotupgrade
テンプレート:
メタデータ:
ラベル:
アプリ: hotupgrade
仕様:
コンテナ:
- 名前: ビジーボックス
画像: openkruise/hotupgrade-sample:busybox

作成が完了すると、CloneSet によって管理される Pod に、sidecar-1​ と sidecar-2 の 2 つのコンテナが挿入されます。

 ➜ kubectl サイドカーセットを取得 hotupgrade-sidecarset
名前が一致しました 更新済み 準備完了 年齢
hotupgrade-sidecarset 1 1 0 58秒
➜ kubectl get pods -l app=hotupgrade
名前 準備完了 ステータス 再起動 年齢
busybox-nd5bp 3/3 実行中 0 31秒
➜ kubectl ポッド busybox-nd5bp を記述します
名前: busybox-nd5bp
名前空間: デフォルト
ノード: node2/10.206.16.10
# ......
制御元: CloneSet/busybox
コンテナ:
サイドカー-1:
コンテナ ID: containerd://511aa4b60d36483177e92805653c1b618495e47d8d5de331008259f78b3be89e
画像: openkruise/hotupgrade-sample:sidecarv1
イメージ ID: docker.io/openkruise/hotupgrade-sample@sha256:3d677ca19712b67d2c264374736d71089d21e100eff341f6b4bb0f5288ec6f34
環境:
IS_INJECTED: 真
SIDECARSET_VERSION: (v1:metadata.annotations['version.sidecarset.kruise.io/sidecar-1'])
SIDECARSET_VERSION_ALT: (v1:metadata.annotations['versionalt.sidecarset.kruise.io/sidecar-1'])
# ......
サイドカー2:
コンテナ ID: containerd://6b0678695ccb977695248e41108606b409ad0c7e3e4fe1ba9b48e839e3c235ef
画像: openkruise/hotupgrade-sample:empty
イメージ ID: docker.io/openkruise/hotupgrade-sample@sha256:606be602967c9f91c47e4149af4336c053e26225b717a1b5453ac8fa9a401cc5
環境:
IS_INJECTED: 真
SIDECARSET_VERSION: (v1:metadata.annotations['version.sidecarset.kruise.io/sidecar-2'])
SIDECARSET_VERSION_ALT: (v1:metadata.annotations['versionalt.sidecarset.kruise.io/sidecar-2'])
# ......
ビジーボックス:
コンテナ ID: containerd://da7eebb0161bab37f7de75635e68c5284a973a21f6d3f095bb5e8212ac8ce908
画像: openkruise/hotupgrade-sample:busybox
イメージ ID: docker.io/openkruise/hotupgrade-sample@sha256:08f9ede05850686e1200240e5e376fc76245dd2eb56299060120b8c3dba46dc9
# ......
# ......
イベント:
タイプ 理由 年齢 送信元 メッセージ
---- ------ ---- ---- -------
通常スケジュール 50 秒 default-scheduler default/busybox-nd5bp を node2 に正常に割り当てました
通常のプル 49s kubelet イメージ「openkruise/hotupgrade-sample:sidecarv1」のプル
通常のプルに 41 秒かかりました。kubelet イメージ「openkruise/hotupgrade-sample:sidecarv1」を 7.929984849 秒で正常にプルしました (待機時間を含めると 7.929998445 秒)
通常 41s kubelet を作成 コンテナ sidecar-1 を作成
正常に起動しました 41 秒 kubelet コンテナ sidecar-1 を起動しました
通常のプル 36 秒 kubelet イメージ「openkruise/hotupgrade-sample:empty」のプル
通常のプルに 29 秒かかりました。kubelet イメージ「openkruise/hotupgrade-sample:empty」を 7.434180553 秒で正常にプルしました (待機時間を含めると 7.434189239 秒)
通常 29s kubelet を作成しました コンテナ sidecar-2 を作成しました
正常に起動しました 29s kubelet コンテナ sidecar-2 を起動しました
通常のプル 29s kubelet イメージ「openkruise/hotupgrade-sample:busybox」のプル
通常のプル 22 秒 kubelet イメージ「openkruise/hotupgrade-sample:busybox」を 6.583450981 秒 (待機時間を含めると 6.583456512 秒) で正常にプルしました
通常 22s kubelet を作成 コンテナ busybox を作成
正常 22秒でkubeletが起動しました コンテナbusyboxが起動しました
......

busybox メイン コンテナは、100 ミリ秒ごとにサイドカー (versinotallow=v1) サービスを要求します。

 ➜ kubectl ログ -f busybox-nd5bp -c busybox
I0404 09:12:26.513128 1 main.go:39] サイドカー サーバーの要求が成功し、応答(本文 = これはバージョン(v1) のサイドカーです)
I0404 09:12:26.623496 1 main.go:39] サイドカー サーバーの要求が成功し、応答(本文 = これはバージョン(v1) のサイドカーです)
I0404 09:12:26.733958 1 main.go:39] サイドカー サーバーの要求が成功し、応答(本文 = これはバージョン(v1) のサイドカーです)
......

ここで、サイドカー コンテナをアップグレードし、イメージを openkruise/hotupgrade-sample:sidecarv2 に変更します。

 ➜ kubectl patch sidecarset hotupgrade-sidecarset --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value": "openkruise/hotupgrade-sample:sidecarv2"}]'

更新後、ポッドのステータスを確認すると、sidecar-2 イメージが正常に更新されていることがわかります。

 ➜ kubectl ポッドを取得 -l app=hotupgrade
名前 準備完了 ステータス 再起動 年齢
busybox-nd5bp 3/3 実行中 2 (45秒前) 23分
➜ kubectl ポッド busybox-nd5bp を記述します
......
イベント:
......
通常のプル 33s kubelet イメージ「openkruise/hotupgrade-sample:sidecarv2」のプル
通常の Killing 33s kubelet コンテナ sidecar-2 の定義が変更され、再起動されます
正常 25 秒で開始 (22 分で x2) kubelet コンテナ sidecar-2 を開始
通常 25 秒で作成 (22 分で x2) kubelet コンテナ sidecar-2 を作成
通常プル 25 秒 kubelet イメージ「openkruise/hotupgrade-sample:sidecarv2」を 8.169453753 秒で正常にプルしました (待機時間を含めると 8.16946743 秒)
通常の Killing 14s kubelet コンテナ sidecar-1 の定義が変更され、再起動されます
正常 ResetContainerSucceed 14s sidecarset-controller サイドカー コンテナ イメージを正常に空にリセットしました
通常のプル 14s kubelet イメージ「openkruise/hotupgrade-sample:empty」のプル
通常 12s を作成 (22m で x2) kubelet コンテナ sidecar-1 を作成
正常 12 秒で開始 (22 分で x2) kubelet コンテナ sidecar-1 を開始
通常のプル 12 秒 kubelet イメージ「openkruise/hotupgrade-sample:empty」を 1.766097364 秒で正常にプルしました (待機時間を含めると 1.766109087 秒)

更新プロセス中、busybox コンテナはサイドカー サービスを要求し続けますが、失敗した要求は発生しません。

 ➜ kubectl ログ -f busybox-nd5bp -c busybox
I0306 11:08:47.587727 1 main.go:39] サイドカー サーバーの要求が成功し、応答(本文 = これはバージョン(v1) のサイドカーです)
I0404 09:14:28.588973 1 main.go:39] サイドカー サーバーの要求が成功し、応答(本文 = これはバージョン(v2) のサイドカーです)
# ......

ホット アップグレードのサンプル コード全体は、リポジトリ https://github.com/openkruise/samples/tree/master/hotupgrade にあります。

コンテナの再起動

ContainerRecreateRequest​ コントローラーは、ユーザーが既存の Pod 内の 1 つ以上のコンテナーを再起動/再構築するのに役立ちます。 Kruise が提供するインプレース アップグレードと同様に、コンテナーが再構築されても、Pod 内の他のコンテナーは引き続き正常に実行されます。再構築が完了すると、コンテナの restartCount が増加したことを除いて、Pod に他の変更は発生しません。

ただし、古いコンテナの rootfs​ に一時的に書き込まれたファイルは失われますが、ボリュームマウント内のデータは引き続き存在することに注意してください。この機能は、Pod コンテナを停止するために kruise-daemon コンポーネントに依存しています。

コンテナを再構築するポッドの ContainerRecreateRequest カスタム リソース (CRR) を送信します。

 # crr-demo.yaml
APIバージョン: apps.kruise.io/v1alpha1
種類: ContainerRecreateRequest
メタデータ:
名前: crr-dmo
仕様:
podName: ポッド名
コンテナ: # 再構築するコンテナ名のリスト、少なくとも1つ
- 名前: アプリ
- 名前: サイドカー
戦略:
failurePolicy: Fail # 「失敗」または「無視」。コンテナが停止するか再構築に失敗すると、CRR は直ちに終了します。
orderedRecreate: false # 'true' は、前のコンテナが再構築されるまで待ってから次のコンテナの再構築を開始することを意味します
terminationGracePeriodSeconds: 30 # コンテナが正常に終了するまでの待機時間。入力されていない場合は、Pod で定義されたものがデフォルトになります。
unreadyGracePeriodSeconds: 3 # 再構築前にポッドを未準備に設定し、再構築を開始する前にこの期間待機します
minStartedSeconds: 10 # 再構築後、再構築が成功したとみなすには、新しいコンテナが少なくともこの期間実行され続ける必要があります。
activeDeadlineSeconds: 300 # CRR 実行がこの時間を超えると、すぐに完了としてマークされます (未完了のコンテナは失敗としてマークされます)
ttlSecondsAfterFinished: 1800 # CRR が終了すると、この時間が経過すると自動的に削除されます

通常、リスト内のコンテナーは 1 つずつ停止されますが、orderedRecreate​ が true に設定されていない限り、同時に再作成および開始される可能性があります。 unreadyGracePeriodSeconds​ 機能は、各 Pod の作成時に readinessGate​ を挿入する KruisePodReadinessGate​ 機能ゲートに依存しています。それ以外の場合、デフォルトでは、Kruise ワークロードによって作成された Pod のみに readinessGate が挿入されます。つまり、CRR 再構築中にこれらの Pod のみが unreadyGracePeriodSeconds を使用できます。

ユーザーが CRR を作成すると、Kruise Webhook はその時点でのコンテナの containerID/restartCount を spec.containers[x].statusContext​ に記録します。 kruise-daemon の実行中に、実際のコンテナの現在の containerID​ が statusContext​ と一致していないか、restartCount が増加していることがわかった場合、コンテナが正常に再構築されたとみなされます (たとえば、インプレース アップグレードが発生した可能性があります)。

コンテナ再起動リクエスト

通常、kruise-daemon は preStop フックを実行した後にコンテナを停止し、その後 kubelet はコンテナが終了したことを感知し、新しいコンテナを作成して起動します。最後に、kruise-daemon は、新しいコンテナが minStartedSeconds 時間以上正常に起動されたことを確認すると、このコンテナのフェーズ ステータスを Succeeded として報告します。

コンテナの再構築とインプレース アップグレードが同時にトリガーされた場合:

  • kubelet がインプレース アップグレードの要件に従ってコンテナを停止または再構築した場合、kruise-daemon はコンテナの再構築が完了したと判断します。
  • kruise-daemon が最初にコンテナを停止した場合、Kubelet はインプレース アップグレードを続行します。つまり、新しいバージョンのコンテナを作成して起動します。
  • 複数の ContainerRecreateRequest リソースが Pod に対して送信された場合、それらは時系列順に 1 つずつ実行されます。

イメージプルジョブ

NodeImage​ と ImagePullJob は、Kruise v0.8.0 以降に提供される CRD です。 Kruise は、各ノードに対して NodeImage を自動的に作成します。この NodeImage には、このノードで事前加熱する必要があるイメージが含まれます。たとえば、ここに 3 つのノードがある場合、3 つの NodeImage オブジェクトが自動的に作成されます。

 ➜ kubectl ノードイメージを取得する
名前 希望 引っ張り 成功 失敗 年齢
マスター1 0 0 0 0 5d
ノード1 0 0 0 0 5d
ノード2 0 0 0 0 5d

たとえば、ノード 1 の NodeImage オブジェクトを見てみましょう。

 ➜ kubectl で nodeimage node1 -o yaml を取得します
APIバージョン: apps.kruise.io/v1alpha1
種類: NodeImage
メタデータ:
名前: ノード1
# ......
仕様: {}
状態:
希望: 0
失敗: 0
引っ張る: 0
成功: 0

たとえば、このノードで ubuntu:latest イメージをプルする場合は、仕様を次のように変更できます。

 ......
仕様:
画像:
ubuntu: # イメージ名
タグ:
- タグ: 最新 # ミラータグ
プルポリシー:
ttlSecondsAfterFinished: 300 # [必須] プルが300秒以上完了(成功または失敗)したら、NodeImageからこのタスクをクリアします
timeoutSeconds: 600 # [オプション] 各プルのタイムアウト。デフォルトは600です。
backoffLimit: 3 # [オプション] プルの再試行回数。デフォルトは 3
activeDeadlineSeconds: 1200 # [オプション] タスク全体のタイムアウト。デフォルト値はありません

更新後、ステータスからプルの進行状況と結果を確認でき、プルが完了してから 600 秒後にタスクがクリアされることがわかります。

 ➜ kubectl ノードイメージ node1 を記述します
名前: ノード1
名前空間:
# ......
仕様:
画像:
Ubuntuの場合:
タグ:
作成日時: 2023-04-04T09:29:18Z
プルポリシー:
アクティブ期限秒数: 1200
バックオフ制限: 3
タイムアウト秒数: 600
終了後の TTL 秒数: 300
タグ: 最新
状態:
希望: 1
失敗: 0
画像のステータス:
Ubuntuの場合:
タグ:
完了時間: 2023-04-04T09:29:28Z
フェーズ: 成功
進捗: 100
開始時間: 2023-04-04T09:29:18Z
タグ: 最新
引っ張る: 0
成功: 1
イベント:
タイプ 理由 年齢 送信元 メッセージ
---- ------ ---- ---- -------
通常の PullImageSucceed 11 秒 kruise-daemon-imagepuller イメージ ubuntu:latest、ecalpsedTime 10.066193581 秒

node1 でイメージがプルダウンされたことがわかります。

 ubuntu@node1:~$ sudo ctr -n k8s.io i ls |grep ubuntu
docker.io/library/ubuntu:最新アプリケーション/vnd.oci.image.index.v1+json sha256:67211c14fa74f070d27cc59d69a7fa9aeff8e28ea118ef3babc295a0428a6d21 28.2 MiB linux/amd64、linux/arm/v7、linux/arm64/v8、linux/ppc64le、linux/s390x io.cri-containerd.image=managed
docker.io/library/ubuntu@sha256:67211c14fa74f070d27cc59d69a7fa9aeff8e28ea118ef3babc295a0428a6d21 application/vnd.oci.image.index.v1+json sha256:67211c14fa74f070d27cc59d69a7fa9aeff8e28ea118ef3babc295a0428a6d21 28.2 MiB linux/amd64、linux/arm/v7、linux/arm64/v8、linux/ppc64le、linux/s390x io.cri-containerd.image=managed
ubuntu@ノード1:~$

さらに、ユーザーは ImagePullJob オブジェクトを作成して、どのノードでイメージを事前加熱するかを指定できます。

たとえば、次に示すように ImagePullJob リソース オブジェクトを作成します。

 APIバージョン: apps.kruise.io/v1alpha1
種類: ImagePullJob
メタデータ:
名前: いつもの仕事
仕様:
image: nginx:1.9.1 # [必須] 完全なイメージ名 name:tag
並列処理: 10 # [オプション] 同時にプルするノードの最大数。デフォルトは 1
セレクター: # [オプション] ノード名リストまたはラベルセレクターを指定します (設定できるのは 1 つだけです)
名前:
- ノード1
- ノード2
一致ラベル:
ノードタイプ: xxx
# podSelector: # [オプション] これらのポッドが配置されているノード上のイメージをプルするためのポッドラベルセレクター。セレクタと同時に設定することはできません。
# ポッドラベル: xxx
完了ポリシー:
タイプ: Always # [オプション] デフォルトは Always
activeDeadlineSeconds: 1200 # [オプション] デフォルト値なし、Alwaysタイプにのみ有効
ttlSecondsAfterFinished: 300 # [オプション] デフォルト値なし、Alwaysタイプにのみ有効
pullPolicy: # [オプション] デフォルト backoffLimit=3、timeoutSecnotallow=600
バックオフ制限: 3
タイムアウト秒数: 300
プルシークレット:
-シークレット名1
-シークレット名2

セレクター フィールドでは、ノード名のリストまたはラベル セレクター (設定できるのは 1 つのみ) を指定できます。セレクターが設定されていない場合は、すべてのノードが予熱対象として選択されます。あるいは、これらのポッドが配置されているノードでイメージをプルするように podSelector を構成することもできます。 podSelector と selector を同時に設定することはできません。

同時に、ImagePullJob には 2 つの completionPolicy タイプがあります。

  • 常時: このジョブは 1 回限りのウォームアップであり、成功または失敗に関係なく終了することを示します。
  • activeDeadlineSeconds: ジョブ全体の期限終了時刻。
  • ttlSecondsAfterFinished: 時間がこの制限を超えると、ジョブは自動的にクリーンアップされ、削除されます。
  • なし: このジョブは長時間実行され、終了することはなく、指定されたイメージは一致するノードで毎日再ウォームアップされることを示します。

同様に、プレヒートするイメージがプライベート リポジトリからのものである場合は、pullSecrets を通じてリポジトリのシークレット情報を指定できます。

イメージがプライベート リポジトリからのものである場合は、pullSecrets を使用してリポジトリのシークレット情報を指定できます。

 # ...
仕様:
プルシークレット:
-シークレット名1
-シークレット名2

ImagePullJob​ は名前空間スコープのリソースであるため、これらの Secret は ImagePullJob が配置されている名前空間に存在する必要があります。次に、pullSecrets フィールドにこれらのシークレットの名前を記述するだけです。

コンテナの起動順序

コンテナ起動優先順位は、ポッド内のコンテナの起動順序を制御する方法を提供します。一般的に、Pod コンテナの起動と終了の順序は Kubelet によって管理されます。 Kubernetes にはかつて、コンテナ内にタイプ フィールドを追加して、さまざまなタイプのコンテナの開始および停止の優先順位を識別するという KEP 計画がありましたが、既存のコード アーキテクチャに大きな変更となると考えられたため、sig-node によって提案が拒否されました。

この機能は、所有者のタイプに関係なく Pod オブジェクトで機能するため、Deployment、CloneSet、その他のワークロードに適用できます。

たとえば、Pod で apps.kruise.io/container-launch-priority アノテーションを定義することで、コンテナが順番に起動するように設定できます。

 APIバージョン: v1
種類: ポッド
注釈:
apps.kruise.io/container-launch-priority: 順序あり
仕様:
コンテナ:
- 名前: サイドカー
# ...
- 名前: メイン
# ...

Kruise は、フロント コンテナー (サイドカー) がバック コンテナー (メイン) より前に開始されるようにします。

さらに、カスタム順序で開始することもできますが、Pod コンテナに KRUISE_CONTAINER_PRIORITY 環境変数を追加する必要があります。

 APIバージョン: v1
種類: ポッド
仕様:
コンテナ:
- 名前: メイン
# ...
- 名前: サイドカー
環境:
- 名前: KRUISE_CONTAINER_PRIORITY
値: "1"
# ...

この環境変数の値の範囲は [-2147483647, 2147483647] です。指定されていない場合、デフォルト値は 0 です。重みが高いコンテナは、重みが低いコンテナよりも先に起動することが保証されます。ただし、同じ重量のコンテナの起動順序は保証されないことに注意してください。

リソースの配分

Secret や ConfigMap などの名前空間レベルのリソースの名前空間間の配布と同期のシナリオでは、ネイティブ Kubernetes は現在、ユーザーによる手動の配布と同期のみをサポートしており、非常に不便です。例えば:

  • ユーザーが SidecarSet の imagePullSecrets 機能を使用する必要がある場合、まず関連する名前空間内に対応する Secret を繰り返し作成し、これらの Secret 構成の正確性と一貫性を確保する必要があります。
  • ユーザーが ConfigMap を使用していくつかの共通環境変数を構成する場合、多くの場合、ConfigMap を複数の名前空間に配信する必要があり、その後の変更では複数の名前空間間の同期が必要になることがよくあります。
  • 複数の名前空間のIngressオブジェクトは同じSecretオブジェクトを使用する必要があります

名前空間間のリソース配布と複数の同期を必要とするこれらのシナリオに対応するため、OpenKruise は、これらのリソースをより便利かつ自動的に配布および同期できる新しい CRD (ResourceDistribution) を設計しました。

ResourceDistribution は現在、Secret と ConfigMap の 2 種類のリソースの配布と同期をサポートしています。

ResourceDistribution​ はグローバル CRD であり、主に resource​ と target​ の 2 つのフィールドで構成されます。 resource​ フィールドは、ユーザーが配布するリソースを記述するために使用され、targets フィールドは、ユーザーが配布するターゲット名前空間を記述するために使用されます。

 APIバージョン: apps.kruise.io/v1alpha1
種類: リソース配布
メタデータ:
名前: サンプル
仕様:
リソース: ... ...
対象: ... ...

リソース フィールドは、以下に示すように、完全かつ正しいリソースの説明である必要があります。

 APIバージョン: apps.kruise.io/v1alpha1
種類: リソース配布
メタデータ:
名前: サンプル
仕様:
リソース:
APIバージョン: v1
種類: ConfigMap
メタデータ:
名前: ゲームデモ
データ:
ゲームのプロパティ: |
敵の種類=エイリアン、モンスター
プレイヤーの最大寿命=5
プレイヤーの初期ライフ: "3"
ui_properties_file_name: ユーザーインターフェース.properties
ユーザーインターフェースのプロパティ: |
color.good=紫
color.bad=黄色
許可テキストモード=true
対象: ... ...

ユーザーは、まずローカル名前空間内に対応するリソースを作成してテストし、リソース構成が正しいことを確認してからコピーすることができます。

現在、targets​ フィールドは、allNamespaces​、includedNamespaces​、namespaceLabelSelector​、excludedNamespaces など、ユーザーが配布するターゲット名前空間を記述する 4 つのルールをサポートしています。

  • allNamespaces: bool 値。true の場合は、すべての名前空間に配布します。
  • IncludedNamespaces: ターゲット名前空間を名前で一致させます。
  • namespaceLabelSelector: LabelSelector を使用して、ターゲットの名前空間を一致させます。
  • removedNamespaces: 配布したくない特定の名前空間を除外するには、Name を使用します。

allNamespaces​、includedNamespaces​、namespaceLabelSelector​ の間には OR 関係があり、excludedNamespaces​ が設定されると、これらの名前空間は明示的に除外されます。さらに、ターゲットは kube-system および kube-public 名前空間を自動的に無視します。

正しく構成されたターゲット フィールドは次のようになります。

 APIバージョン: apps.kruise.io/v1alpha1
種類: リソース配布
メタデータ:
名前: サンプル
仕様:
リソース: ... ...
ターゲット:
含まれる名前空間:
リスト:
- 名前: ns-1
- 名前: ns-4
名前空間ラベルセレクター:
一致ラベル:
グループ: テスト
除外される名前空間:
リスト:
- 名前: ns-3

この構成は、ResourceDistributionのターゲットネームスペースには間違いなくNS-1とNS-4が含まれることを示しており、ラベルがNamesPacelabelSelectorを満たす名前空間もターゲットネームスペースに含まれます。ただし、NS-3は、exprodedNamesSpacesで明示的に除外されているため、NAMESPACELABELSELECTORを満たしていても含まれません。

同期されたリソースを更新する必要がある場合は、リソースフィールドを更新できます。更新後、すべてのターゲットネームスペースのリソースは自動的に同期および更新されます。リソースが更新されるたびに、ResourceDistributionはリソースの新しいバージョンのハッシュ値を計算し、リソースの注釈に記録します。 ResourceDistributionは、リソースの新しいバージョンのハッシュ値が現在のリソースとは異なることがわかった場合にのみ、リソースを更新します。

 APIバージョン: v1
種類: ConfigMap
メタデータ:
名前: デモ
注釈:
kruise.io/Resourcedistribution.resource.from:サンプル
Kruise.io/Resourcedistribution.Resource.Distributed.Timestamp:2021-09-06 08:44:52.7861421 +0000 UTC M = +12896.810364601
Kruise.io/Resourcedistribution.Resource.HashCode:0821A13321B2C76B5BD63341A0D97FB46BFDBB2F914E2AD6613D10632FA4B63
... ...

もちろん、ユーザーは、自分が何をしているのかを知らない限り、リソースを直接変更するためにリソース分布をバイパスしないことを強くお勧めします。

  • リソースのハッシュ値は、リソースが直接変更された後に自動的に計算されないため、リソースフィールドが次に変更されると、リソース配分がこれらのリソースの直接的な変更を上書きする可能性があります。
  • Resourcedistributionは、kruise.io/resourcedistribution.resource.fromを使用して、このResourcedistributionによってリソースが分散されているかどうかを判断します。注釈が変更または削除された場合、変更されたリソースはResourcedistributionによって矛盾するリソースと見なされ、ResourceDistributionを通じて同期して更新することはできません。

これらの強化されたコントローラーに加えて、OpenKruiseには多くの高度な機能があります。詳細については、公式ウェブサイトhttps://openkruise.ioにアクセスできます。

<<:  AWSでEKSクラスターを作成する方法について説明します

>>:  企業はどのように Harbor を活用して生産性を向上できるのでしょうか?

推薦する

エッジコンピューティングに関する3つの誤解を解く

[51CTO.com クイック翻訳] 毎日何百万台ものマシンやデバイスがインターネットに接続されてお...

ブランドリバースマーケティングの根底にあるロジックを1つの記事で理解しましょう!

ソーシャル ネットワークの台頭により、ブランド マーケティングの方法とアプローチは多様化しています。...

weloveservers-各種低価格アーティファクト/VPS 4月プロモーション第一弾

weloveserversは4月にプロモーションVPSをリリースしました。openvzベースで、25...

DNSPodのWu HongshengがTencentの買収とオープンな協力について語る

テンセントのDNSPodは、アリババのHiChinaを抜いて中国でナンバーワンのドメイン名解決(DN...

地方第二人材サイトの代替運用方法の共有

二流のローカルタレントサイトは比較的小規模で、実力があります。一流都市のタレントサイトとの激しい競争...

ウェブマスターネットワークニュース: オンライン著作権侵害対策開始、360 度モバイル検索が公開

1. B2B 電子商取引の将来はどこへ向かうのでしょうか?現在、大規模な総合B2Bサービスプラットフ...

Baidu の統計情報を使用して Web サイトをチェックする

Baidu Statistics は Baidu の公式統計ツールです。Baidu Statisti...

Baidu の Web2.0 戦略を分析する上での考察

Baidu が最近発表した Web2.0 スパム対策戦略は、私たちウェブマスターに大きなインスピレー...

SEO担当者の皆さん、上司が何を重視しているか知っていますか?

今日、インターネットで質疑応答を見ました。内容は、SEOについて何も知らない上司に、SEOをうまく行...

クラウドネイティブ向けに誕生した、第3世代のShenlongクラウドサーバーがリリースされました

[51CTO.com からのオリジナル記事] 過去 10 年間で、クラウド コンピューティングは生活...

高品質なバックリンクを構築する方法

ウェブサイトの制作に携わっている方や SEO に携わっている方なら、外部リンクの重要性をご存知でしょ...

モバイルインターネットが新たな賭けをリセット 馬化騰:時が来れば儲かる日が来る

最近、テンセントは組織構造の調整とモバイルインターネット戦略のアップグレードを発表しました。テンセン...

「いつも思っていた」ことが多すぎると、実際には初心者ウェブマスターのキャリアを台無しにすることになる

ウェブサイトを構築するのは簡単な作業ではありません。これは誰もが理解できると思います。しかし、インタ...

湖南岳陽あなたのクラスは、Facebookグループマーケティングで良い仕事をするための最適な時期を目指すべきです

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますFaceb...