Kubernetesサーバーサイド適用(SSA)とは何ですか?
サーバーサイドアプライ(SSA)は、2021年8月のv1.22リリース以来、Kubernetesで一般提供されています。これは、宣言型のリソース管理の戦略であり、差分計算を改善し、kubectl applyコマンドのロジックをサーバーに移動することでマージ競合について警告します。
この記事では、SSAがどのように機能し、なぜ従来のクライアントサイド適用(CSA)アプローチよりも好まれるのかを説明します。また、クラスター内のオブジェクトに変更を加える際にSSAを有効にする方法についても学びます。
宣言的更新の理解
kubectl applyコマンドは宣言的オブジェクト更新を実行します。Kubernetesに特定のフィールドを変更するよう指示するのではなく、オブジェクトがどのように表示されるかの完全な表現を提供します。システムは、クラスターの既存の状態と比較して自動的に差異を計算します。そして、マニフェストファイルで表現された望ましい状態に変えるためのアクションを実行します。
こちらがシンプルなPodマニフェストです:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:latest
このマニフェストで kubectl apply を実行すると、実行される新しい Pod が開始されます
nginx:latest画像。クラスタの現在の状態と望ましい状態の違いは明確です:以前には存在しなかったPodが作成されました。
nginx名前。
その後、Podのプロパティの1つを変更することでマニフェストを修正することができます。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.23
今回は、既存の状態と望ましい状態の違いはそれほど大きくありません。kubectl apply コマンドは、修正されたことを検出します。
imageフィールドを更新して、ポッドの設定をそれに応じて更新してください。
クライアントサイド適用の問題点
変更を比較し、競合を解決することは、宣言的なアップデートにおいて最も重要な部分です。このプロセスはデフォルトでKubectl内で実行されます。クライアントはサーバー上の既存のオブジェクトを特定し、その変更を比較する責任があります。
kubectl apply コマンドは、オブジェクトに last-applied-configuration アノテーションを書き込み、このプロセスを支援します。これにより、ライブオブジェクトに存在するが受信するマニフェストから削除されたフィールドを特定することが可能になります。クライアントは、その後、オブジェクトからそれらを削除して新しい状態を達成することができます。
このアプローチは、複数のエージェントが同じオブジェクトを更新している場合に問題です。たとえば、単一のオブジェクトはKubectlとクラスター内の専用コントローラーの両方によって変更される可能性があります。クライアントサイドの適用は、どのエージェントがフィールドを変更したかを追跡することも、競合が発生したときに理解することもできません。単にローカルマニフェストを既存のオブジェクトのlast-applied-configurationと比較し、変更をマージするだけです。
クライアントサイドの適用は、KubernetesのKubectlに本質的に結びついています。独自の宣言的更新を行いたいサードパーティツールは、Kubectlを呼び出すか、作成し直す必要があります。
applyゼロからの論理。この2つの選択肢はどちらも特に理想的ではありません。
サーバーサイドアプライの仕組み
CSAの根本的な問題は、古いローカルマニフェストが決して検出されないことです。別の適用者があなたがkubectl applyを実行する前にオブジェクトを変更すると、あなたの古いローカルのリビジョンが正しい新しいリビジョンを上書きしてしまう可能性があります。SSAが有効になっている場合、競合が検出され、更新がブロックされます。これは、あなたのローカル状態が最新のものであることを強制する中央集権的なシステムです。
SSAは、オブジェクト内の各フィールドに関する情報を保存する制御プレーン機構を追加することによって機能します。これは、last-applied-configuration注釈を新しいmetadata.managedFieldsフィールドに置き換えます。オブジェクト内の各フィールドはmanagedFields内で追跡されます。
フィールドには、それを所有するクライアントを特定する「フィールドマネージャー」が割り当てられます。Kubectlを使ってマニフェストを適用すると、Kubectlが指定されたマネージャーになります。フィールドのマネージャーは、オブジェクトを更新するコントローラーや外部インテグレーションでもあります。
マネージャーは互いのフィールドを更新することを禁じられています。他のコントローラーが現在所有しているフィールドは、kubectl applyを使用して変更することができません。これらのマージコンフリクトを解決するために、3つの戦略があります。
値を強制的に上書きする - 一部の状況では、更新を強制的に行いたい場合があります。これにより、その値が変更され、新しいフィールドマネージャーに所有権が移転します。これは、ポピュレートしたフィールドの管理を維持する必要のあるコントローラー向けに主に設計されています。手動で更新を強制するには、次のように設定することができます。
--force-conflicts- 値を上書きしないでください - 適用者はローカル設定からフィールドを削除し、リクエストを繰り返すことができます。フィールドは既存の値を保持します。フィールドを削除することで、既存の管理者に所有権を譲渡することによって競合が解決されます。
- 管理の共有 - 申請者は、サーバー上の既存の値に合わせてローカルの値を更新できます。所有権を主張し続けながらリクエストを繰り返すと、SSAは既存の管理者と管理を共有することを許可します。これは、申請者がフィールドの現在の状態を受け入れたが、将来的にそれを管理したい可能性を示しているためです。
Kubectlのフラグ。
このアプローチは、従来の kubectl apply よりもはるかに強力です。意図しない上書きを防ぎ、コントローラーが制御するフィールドの所有権を信頼性高く主張でき、完全に宣言的です。SSA は、オブジェクトの最新の全状態を記録するだけでなく、異なるユーザーが個別のフィールドをどのように変更したかを追跡します。また、これにより、言語に関係なく、任意のツール内で apply を使用できるようになります。
kubectlバイナリの可用性。操作を開始する方法に関わらず、一貫した結果が得られます。
SSAを今日使用する
Kubectl applyを実行するたびに--server-sideフラグを設定することでSSAを有効にできます:
kubectl apply -f nginx.yaml --server-side
pod/nginx serverside-applied
コマンドの出力は、SSAが使用されたことを強調するように変更されます。
オブジェクトのYAMLマニフェストを検査すると、管理されたフィールドが明らかになります:
kubectl get pod nginx -o yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2022-11-24T16:02:29Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:spec:
f:containers:
k:{"name":"nginx"}:
.: {}
f:image: {}
f:name: {}
manager: kubectl
operation: Apply
time: "2022-11-24T16:02:29Z"
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:status:
f:conditions:
k:{"type":"ContainersReady"}:
.: {}
f:lastProbeTime: {}
f:lastTransitionTime: {}
f:status: {}
f:type: {}
k:{"type":"Initialized"}:
.: {}
f:lastProbeTime: {}
f:lastTransitionTime: {}
f:status: {}
f:type: {}
k:{"type":"Ready"}:
.: {}
f:lastProbeTime: {}
f:lastTransitionTime: {}
f:status: {}
f:type: {}
f:containerStatuses: {}
f:hostIP: {}
f:phase: {}
f:podIP: {}
f:podIPs:
.: {}
k:{"ip":"10.244.0.186"}:
.: {}
f:ip: {}
f:startTime: {}
manager: kubelet
operation: Update
subresource: status
time: "2022-11-24T16:02:31Z"
...
フィールドは、それらを所有するマネージャーによってグループ化されています。この例では、spec は Pod が作成された方法であるため、Kubectl によって管理されています。しかし、status フィールドは、Pod のライフサイクル中にそのフィールドの値を変更するノードによって Kubelet によって管理されています。
SSAはコントローラーでも使用可能です。これにより、より強力なセマンティクスとオブジェクトを再構築する新しい種類のコントローラーが可能になります。このモデルは、まずオブジェクトのフィールドを最初からコントローラーの満足のいく形に再構築し、その後結果をサーバーに適用することで変更を処理します。望ましい変更を生成するための操作の順序を手動で設定するよりも、より自然な方法です。
SSAでオブジェクトが管理されているかを確認する
オブジェクトがCSAまたはSSAを使用しているかどうかは、KubectlでそのYAMLマニフェストを取得することで確認できます:
kubectl get pod nginx -o yamlもしlast-applied-configuration注釈が表示されている場合、あなたのオブジェクトはCSAによって管理されています。
apiVersion: v1
kind: Pod
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"nginx","namespace":"default"},"spec":{"containers":[{"image":"nginx:latest","name":"nginx"}]}}
creationTimestamp: "2022-11-24T14:20:07Z"
name: nginx
namespace: default
...
...
もしmetadata.managedFieldsが表示される場合、オブジェクトにはSSAが使用されています。
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2022-11-24T16:02:29Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:spec:
f:containers:
k:{"name":"nginx"}:
.: {}
f:image: {}
f:name: {}
manager: kubectl
operation: Apply
time: "2022-11-24T16:02:29Z"
...
...
...
次回 kubectl apply を実行する際に --server-side フラグを追加するか省略することで、CSA と SSA の間でオブジェクトを移動できます。Kubernetes は last-applied-configuration を managedFields に変換し、その逆も処理します。
SSAへのアップグレードは、ローカルマニフェストがサーバー上のオブジェクトと異なる場合にコンフリクトを引き起こす可能性があります。これは、最後のオブジェクトに対する適用操作以降に、kubectl scaleやkubectl labelのような命令的なコマンドを実行した場合に発生します。SSAに変換する前に、ローカルマニフェストがライブオブジェクトと正確に一致していることを確認する必要があります。
要約
サーバーサイド適用は、Kubernetesのコントロールプレーンによってフィールドが追跡される宣言的オブジェクト管理のアプローチです。これにより、堅牢な競合検出と柔軟な解決策が可能になります。SSAは、フィールドが警告なしに意図せず上書きされることを許すクライアントサイド適用の限界に対処しています。
SSAは現在一般的に利用可能ですが、kubectl applyを実行するたびに手動で指定する必要があります。SSAは、Kubectlを使用する人間のオペレーターやコントローラーループのように、いくつかの異なるプロセスによってオブジェクトが管理されている状況で最も有用であることを考慮する価値があります。オブジェクトを作成および更新するためにkubectl applyのみを使用している場合、SSAからはあまり恩恵を受けません。
将来のKubernetesリリースではCSAが削除され、SSAがデフォルトかつ唯一のオプションになると予想されています。--server-sideフラグはその後不要になります。
