このドキュメントでは、Google Distributed Cloud(GDC)のエアギャップ内の専用ノードプール内にコンテナ ワークロードを分離して、Kubernetes クラスタのセキュリティと管理を強化する方法について説明します。ワークロードを分離すると、Pod をより詳細に制御でき、Kubernetes クラスタでの権限昇格攻撃のリスクを軽減できます。専用ノードプールの利点と制限事項の詳細については、ノード分離の概要をご覧ください。
コンテナ ワークロードの分離には、次のようないくつかのワークフローがあります。
ノードプールに taint とラベルを適用する: taint とラベルをノードプールに適用して、そこで実行するように明示的にラベル付けされていない限り、Pod がノードプールから離れるようにします。
toleration とノード アフィニティ ルールを追加する: toleration とルールを Pod に適用して、指定されたノードプールでのみ実行されるようにします。
分離が機能していることを確認する: テイントされたノードプールで、実行するようにラベル付けした Pod のみが実行されていることを確認します。
これらのワークフローは、Kubernetes クラスタのノードプールの管理を担当するプラットフォーム管理者グループ内の IT 管理者や、コンテナ ワークロードの管理を担当するアプリケーション オペレータ グループ内のアプリケーション デベロッパーなどのユーザーを対象としています。詳細については、GDC のエアギャップ環境のユーザー グループのドキュメントをご覧ください。
始める前に
作業を始める前に、次のことを確認してください。
専用ノードプールに使用するノードラベルとノード taint に特定の名前を選択します。例:
workloadType=untrusted
必要に応じて、組織 IAM 管理者に、名前空間にバインドされていないユーザー クラスタ デベロッパー ロール(
user-cluster-developer
)の付与を依頼します。
新しいノードプールに taint とラベルを適用する
新しいノードプールに taint またはラベルを適用すると、後で追加されたノードを含むすべてのノードが、指定された taint とラベルを自動的に取得します。
新しいノードプールに taint とラベルを追加する手順は次のとおりです。
ノードプールを作成するときに、
Cluster
カスタム リソースのnodePools
セクションを直接編集します。nodePools: # Several lines of code are omitted here. - machineTypeName: n2-standard-2-gdc name: nodepool-1 nodeCount: 3 taints: - key: "TAINT_KEY" value: "TAINT_VALUE" effect: "TAINT_EFFECT" labels: LABEL_KEY: LABEL_VALUE
次のように置き換えます。
TAINT_KEY
: スケジュールするTAINT_EFFECT
に関連付けられた Key-Value ペアの taint キー部分。例:workloadType
TAINT_VALUE
: スケジュールするTAINT_EFFECT
に関連付けられた Key-Value ペアの taint 値の部分。例:untrusted
TAINT_EFFECT
: 次のいずれかの効果値。NoSchedule
: この taint を容認しない Pod はノード上にスケジュールされません。既存の Pod はノードから強制排除されません。PreferNoSchedule
: Kubernetes は、この taint を容認しない Pod をノード上にスケジュールすることを避けます。NoExecute
: ノードですでに実行されている Pod は、ノードから強制排除されます。ノードでまだ実行されていない Pod は、ノード上にスケジュールされません。
LABEL_KEY: LABEL_VALUE
: ノードラベルの Key-Value ペア。ワークロード マニフェストで指定したセレクタに対応しています。
Cluster
リソースを適用して、新しいノードプールを作成します。kubectl apply -f cluster.yaml --kubeconfig MANAGEMENT_API_SERVER
MANAGEMENT_API_SERVER
は、Kubernetes クラスタがホストされているゾーン API サーバーの kubeconfig パスに置き換えます。ターゲット ゾーンの API サーバーの kubeconfig ファイルをまだ生成していない場合は、ゾーン管理 API サーバー リソースをご覧ください。
既存のノードプールに taint とラベルを適用する
既存のノードプールに taint またはラベルを適用するには、既存の各ノードに変更を適用する必要があります。ノードプール構成を動的に更新することはできません。
既存のノードプールに taint とラベルを追加する手順は次のとおりです。
専用ノードプール内のノードを一覧表示します。
kubectl get node --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG \ -l baremetal.cluster.gke.io/node-pool=NODE_POOL_NAME
次の変数を置き換えます。
KUBERNETES_CLUSTER_KUBECONFIG
: Kubernetes クラスタの kubeconfig パス。NODE_POOL_NAME
: 専用ノードプールの名前。
出力から、ノードプール内のすべてのノードの各ノード ID をメモします。
ノードプール内の各ノードに、次の taint を適用します。
kubectl taint nodes NODE_ID \ TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
次の変数を置き換えます。
NODE_ID
: 専用ノードプール内のワーカーノードの ID。TAINT_KEY=TAINT_VALUE
: スケジュールするTAINT_EFFECT
に関連付けられた Key-Value ペア。例:workloadType=untrusted
TAINT_EFFECT
: 次のいずれかの効果値。NoSchedule
: この taint を容認しない Pod はノード上にスケジュールされません。既存の Pod はノードから強制排除されません。PreferNoSchedule
: Kubernetes は、この taint を容認しない Pod をノード上にスケジュールすることを避けます。NoExecute
: ノードですでに実行されている Pod は、ノードから強制排除されます。ノードでまだ実行されていない Pod は、ノード上にスケジュールされません。
KUBERNETES_CLUSTER_KUBECONFIG
: Kubernetes クラスタの kubeconfig パス。
ノードプール内の各ノードに、コンテナ ワークロードで定義するセレクタに対応するラベルを適用します。
kubectl label NODE_ID \ LABEL_KEY:LABEL_VALUE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
次の変数を置き換えます。
NODE_ID
: 専用ノードプール内のワーカーノードの ID。LABEL_KEY:LABEL_VALUE
: ノードラベルの Key-Value ペア。ワークロード マニフェストで指定したセレクタに対応しています。KUBERNETES_CLUSTER_KUBECONFIG
: Kubernetes クラスタの kubeconfig パス。
toleration とノード アフィニティ ルールを追加する
専用ノードプールに taint を追加しても、追加した taint に対応する toleration がなければ、ワークロードはそのノードプールでスケジュールできません。toleration をワークロードの仕様に追加して、taint が追加されたノードプールで Pod がスケジュールされるようにします。
専用ノードプールにラベルを付けた場合は、ノード アフィニティ ルールを追加して、そのノードプールにのみワークロードをスケジュールするように GDC に指示することもできます。
専用ノードプールで実行するようにコンテナ ワークロードを構成する手順は次のとおりです。
コンテナ ワークロード マニフェスト ファイル(
Deployment
カスタム リソースなど)の.spec.template.spec
セクションに次のセクションを追加します。# Several lines of code are omitted here. spec: template: spec: tolerations: - key: TAINT_KEY operator: Equal value: TAINT_VALUE effect: TAINT_EFFECT affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: LABEL_KEY operator: In values: - "LABEL_VALUE" # Several lines of code are omitted here.
次のように置き換えます。
TAINT_KEY
: 専用ノードプールに適用した taint キー。TAINT_VALUE
: 専用ノードプールに適用した taint 値。TAINT_EFFECT
: 次のいずれかの効果値。NoSchedule
: この taint を容認しない Pod はノード上にスケジュールされません。既存の Pod はノードから強制排除されません。PreferNoSchedule
: Kubernetes は、この taint を容認しない Pod をノード上にスケジュールすることを避けます。NoExecute
: ノードですでに実行されている Pod は、ノードから強制排除されます。ノードでまだ実行されていない Pod は、ノード上にスケジュールされません。
LABEL_KEY
: 専用ノードプールに適用したノードラベルのキー。LABEL_VALUE
: 専用ノードプールに適用したノードラベル値。
たとえば、次の
Deployment
リソースは、workloadType=untrusted:NoExecute
taint に対する toleration とworkloadType=untrusted
ノードラベルのノード アフィニティ ルールを追加します。kind: Deployment apiVersion: apps/v1 metadata: name: my-app namespace: default labels: app: my-app spec: replicas: 1 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: tolerations: - key: workloadType operator: Equal value: untrusted effect: NoExecute affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: workloadType operator: In values: - "untrusted" containers: - name: my-app image: harbor-1.org-1.zone1.google.gdc.test/harborproject/my-app ports: - containerPort: 80 imagePullSecrets: - name: SECRET
コンテナ ワークロードを更新します。
kubectl apply -f deployment.yaml -n NAMESPACE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
次の変数を置き換えます。
NAMESPACE
: コンテナ ワークロードのプロジェクト Namespace。KUBERNETES_CLUSTER_KUBECONFIG
: Kubernetes クラスタの kubeconfig パス。
GDC は影響を受ける Pod を再作成します。ノード アフィニティ ルールにより、作成した専用ノードプールに Pod が強制移動されます。この toleration によって、それらの Pod のみをノードに配置できます。
分離が機能していることを確認する
指定した Pod がラベル付きノードプールで実行されていることを確認します。
指定された Namespace 内の Pod を一覧表示します。
kubectl get pods -o=wide -n NAMESPACE \ --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
次の変数を置き換えます。
NAMESPACE
: コンテナ ワークロードのプロジェクト Namespace。KUBERNETES_CLUSTER_KUBECONFIG
: Kubernetes クラスタの kubeconfig パス。
出力は次のようになります。
pod/kube-abc-12tyuj pod/kube-abc-39oplef pod/kube-abc-95rzkap
ワークロードが専用ノードプールで実行されていることを確認します。