Google Distributed Cloud(GDC)エアギャップの専用ノードプールを使用すると、コンテナ ワークロードを分離して Kubernetes クラスタのセキュリティを強化し、Pod の配置を制御できます。この分離により、権限昇格攻撃のリスクを軽減できます。専用プールを設定するには、taint とラベルを適用し、ワークロードの toleration とノード アフィニティ ルールに一致させて、スケジューリングを確認します。
このドキュメントは、Kubernetes クラスタを管理するプラットフォーム管理者グループの IT 管理者と、コンテナを実行するアプリケーション オペレーター グループのデベロッパーを対象としています。詳細については、ノード分離の概要と GDC エアギャップ ドキュメントの対象読者をご覧ください。
始める前に
このドキュメントのタスクを完了するには、必要な権限をリクエストして環境を準備する必要があります。
IAM ロールをリクエストする
Kubernetes クラスタでコンテナ ワークロードを分離するために必要な権限を取得するには、特定のロールが必要です。必要なロールは、組織スコープの共有クラスタとプロジェクト スコープの標準クラスタのどちらで作業しているかによって異なります。詳細については、Kubernetes クラスタの構成をご覧ください。
共有クラスタロール
共有クラスタ内のノードプールに taint とラベルを適用するには、IAM 組織管理者に連絡して、次のロールをリクエストしてください。
ユーザー クラスタ管理者(
user-cluster-admin): Management API サーバーでホストされている共有クラスタのリソースを作成、削除、編集、表示します。このロールは、共有クラスタのノードプールへのアクセス権を付与します。ユーザー クラスタ デベロッパー(
user-cluster-developer): 共有クラスタの作成、削除、編集、表示。このロールは、共有クラスタ内でホストされているデータプレーン API へのアクセス権を付与します。
これらのロールは Namespace にバインドされていません。
標準クラスタロール
IAM プロジェクト管理者に連絡して、Standard クラスタのノードプールに taint とラベルを適用するために、次のロールをリクエストします。
クラスタ管理者(
cluster-admin): 標準クラスタ内のすべてのリソースを作成、削除、編集、表示します。このロールは、クラスタのリソースを管理する標準クラスタ内でホストされているデータプレーン API へのアクセス権を付与します。クラスタ デベロッパー(
cluster-developer): 標準クラスタを作成、削除、編集、表示します。このロールは、クラスタを管理する標準クラスタ内でホストされているデータプレーン API へのアクセス権を付与します。標準クラスタ管理者(
standard-cluster-admin): 管理 API サーバーでホストされている標準クラスタのリソースを作成、削除、編集、表示します。このロールは、Standard クラスタのノードプールへのアクセス権を付与します。
これらのロールは、プロジェクトの Namespace にバインドされます。
環境を準備する
API を使用して Kubernetes クラスタに対してコマンドを実行するには、次のリソースがあることを確認してください。
これらの手順では、Kubernetes クラスタの kubeconfig パスを使用して
KUBERNETES_CLUSTER_KUBECONFIGを置き換えます。これらの手順では、
MANAGEMENT_API_SERVERを管理 API サーバーの kubeconfig パスに置き換えます。専用ノードプールに使用するノードラベルとノード taint 用に特定の名前を選択します。例:
workloadType=untrusted
新しいノードプールに taint とラベルを適用する
新しいノードプールに 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 キー部分。例:workloadTypeTAINT_VALUE: スケジュール設定TAINT_EFFECTに関連付けられた Key-Value ペアの taint 値部分。例:untrustedTAINT_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_SERVERMANAGEMENT_API_SERVERは、Kubernetes クラスタがホストされているゾーン API サーバーの kubeconfig パスに置き換えます。
既存のノードプールに taint とラベルを適用する
既存のノードプールに 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=untrustedTAINT_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セクションに次のセクションを追加します。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"次のように置き換えます。
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:NoExecutetaint の 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。共有クラスタの場合、これはプロジェクトの名前空間である必要があります。Standard クラスタの場合は、任意の 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。共有クラスタの場合、これはプロジェクトの名前空間である必要があります。Standard クラスタの場合は、任意の Namespace を指定できます。KUBERNETES_CLUSTER_KUBECONFIG: Kubernetes クラスタの kubeconfig パス。
出力は次のようになります。
pod/kube-abc-12tyuj pod/kube-abc-39oplef pod/kube-abc-95rzkapワークロードが専用ノードプールで実行されていることを確認します。