Google Kubernetes Engine(GKE)ComputeClasses を使用すると、さまざまなワークロード要件を 満たすノードを作成できます。Pod は ComputeClass を使用してハードウェアを作成できます。ComputeClass によって、そのハードウェアは需要が高く、可用性が制限されているか、企業にとって比較的高価になる可能性があります。この チュートリアルでは、Kubernetes RBAC と ValidatingAdmissionPolicies を使用して、ComputeClass の作成、削除、 変更、選択を制限する方法について説明します。
これらの制限は、次のような状況を防ぐのに役立ちます。
- GPU や TPU などの特殊なハードウェアを必要としない Pod が、そのハードウェアをリクエストする ComputeClass を選択する。
- 不正なエンティティが、重要なワークロード用に予約されているハードウェアにアクセスするために、ComputeClass を作成または変更する。
このドキュメントでは、ワイルドカード ComputeClass 許容や、許可されていない特定の ComputeClass の選択など、一般的な不正使用をブロックする ValidatingAdmissionPolicy の例を使用します。ValidatingAdmissionPolicy を変更して、特定のチームのワークロードが ComputeClass を使用できないようにするなど、組織に固有の要件を満たすことができます。
目標
- ValidatingAdmissionPolicy を使用して、各 Namespace で Pod が選択できる ComputeClass を承認済みリストに制限する。
- ロールベース アクセス制御(RBAC)を使用して、クラスタ内の ComputeClass を作成、変更、削除できるユーザーを制限する。
費用
このドキュメントでは、課金対象である次のコンポーネントを使用します。 Google Cloud
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
- アカウントにログインします。 Google Cloud を初めて使用する場合は、 アカウントを作成して、 実際のシナリオでプロダクトがどのように機能するかを評価してください。 Google Cloud新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
-
Google Cloud CLI をインストールします。
-
外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。
-
gcloud CLI を初期化するには、次のコマンドを実行します:
gcloud init -
プロジェクトを作成または選択します Google Cloud 。
プロジェクトを選択または作成するために必要なロール
- プロジェクトを選択する: プロジェクトの選択に特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトを選択できます。
-
プロジェクトを作成する: プロジェクトを作成するには、プロジェクト作成者ロール
(
roles/resourcemanager.projectCreator)が必要です。これにはresourcemanager.projects.create権限が含まれています。詳しくは、ロールを付与する方法をご覧ください。
-
プロジェクトを作成します。 Google Cloud
gcloud projects create PROJECT_ID
PROJECT_IDは、作成する Google Cloud プロジェクトの名前に置き換えます。 -
作成した Google Cloud プロジェクトを選択します。
gcloud config set project PROJECT_ID
PROJECT_IDは、 Google Cloud プロジェクトの名前に置き換えます。
-
このガイドで既存のプロジェクトを使用する場合は、 このガイドを完了するために必要な権限があることを 確認します。新しいプロジェクトを作成した場合は、 必要な権限がすでに付与されています。
Kubernetes Engine API を有効にします。
API を有効にするために必要なロール
API を有効にするには、 権限を含む Service Usage 管理者 IAM ロール(
roles/serviceusage.serviceUsageAdmin)が必要です。serviceusage.services.enable詳しくは、ロールを付与する方法をご覧ください。gcloud services enable container.googleapis.com
-
Google Cloud CLI をインストールします。
-
外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。
-
gcloud CLI を初期化するには、次のコマンドを実行します:
gcloud init -
プロジェクトを作成または選択します Google Cloud 。
プロジェクトを選択または作成するために必要なロール
- プロジェクトを選択する: プロジェクトの選択に特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトを選択できます。
-
プロジェクトを作成する: プロジェクトを作成するには、プロジェクト作成者ロール
(
roles/resourcemanager.projectCreator)が必要です。これにはresourcemanager.projects.create権限が含まれています。詳しくは、ロールを付与する方法をご覧ください。
-
プロジェクトを作成します。 Google Cloud
gcloud projects create PROJECT_ID
PROJECT_IDは、作成する Google Cloud プロジェクトの名前に置き換えます。 -
作成した Google Cloud プロジェクトを選択します。
gcloud config set project PROJECT_ID
PROJECT_IDは、 Google Cloud プロジェクトの名前に置き換えます。
-
このガイドで既存のプロジェクトを使用する場合は、 このガイドを完了するために必要な権限があることを 確認します。新しいプロジェクトを作成した場合は、 必要な権限がすでに付与されています。
Kubernetes Engine API を有効にします。
API を有効にするために必要なロール
API を有効にするには、 権限を含む Service Usage 管理者 IAM ロール(
roles/serviceusage.serviceUsageAdmin)が必要です。serviceusage.services.enable詳しくは、ロールを付与する方法をご覧ください。gcloud services enable container.googleapis.com
- ローカルシェルを使用する場合は、
kubectlコンポーネントをインストールします。gcloud components install kubectl
- バージョン 1.30 以降を使用する GKE クラスタがあることを確認します。このチュートリアルでは、 Autopilot クラスタ を作成することもできます。
- RBAC 向け Google グループを使用するようにクラスタを構成します。
- ドメインに
gke-security-groupsグループを設定します。 - クラスタで RBAC 向け Google グループを有効にします。
詳細については、 Google グループを設定するをご覧ください。
- ドメインに
必要なロール
クラスタで RBAC ポリシーと Kubernetes オブジェクトを作成するために必要な権限を取得するには、プロジェクトに対する Kubernetes Engine 管理者(role/container.admin)IAM ロールを付与するよう管理者に依頼してください。ロールの付与については、プロジェクト、フォルダ、組織へのアクセスを管理するをご覧ください。
環境を準備する
このチュートリアルの作成タスクと検証タスクのためにクラスタを準備する手順は次のとおりです。
クラスタに接続します。
gcloud container clusters get-credentials CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION次のように置き換えます。
CLUSTER_NAME: クラスタの名前。CONTROL_PLANE_LOCATION: クラスタ コントロール プレーンのリージョンまたは ゾーン(例:us-central1、us-central1-a)。
このチュートリアルで使用する Namespace を作成します。クラスタ内の既存の Namespace を使用することもできます。
kubectl create namespace computeclass-vap-tutorialValidatingAdmissionPolicies と ValidatingAdmissionPolicyBindings の管理アクセス権を付与する RBAC ポリシーを作成します。
次のマニフェストを
validatingadmissionpolicy-editor.yamlとして保存します。apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: validatingadmissionpolicy-editor rules: - apiGroups: ["admissionregistration.k8s.io"] resources: ["validatingadmissionpolicies","validatingadmissionpolicybindings"] verbs: ["get", "list", "create", "update", "patch", "delete"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: edit-validatingadmissionpolicies subjects: - kind: User name: USER_ACCOUNT apiGroup: rbac.authorization.k8s.io roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: validatingadmissionpolicy-editorUSER_ACCOUNTは、ユーザー アカウントのメールアドレスに置き換えます。RBAC ポリシーを作成します。
kubectl apply -f validatingadmissionpolicy-editor.yaml
クラスタに ComputeClass を作成します。クラスタに ComputeClass がすでに存在する場合は、この手順をスキップします。
次のマニフェストを
access-computeclass.yamlとして保存します。apiVersion: cloud.google.com/v1 kind: ComputeClass metadata: name: access-restriction-class spec: priorities: - machineFamily: e2 nodePoolAutoCreation: enabled: true whenUnsatisfiable: ScaleUpAnywayComputeClass を作成します。
kubectl apply -f access-computeclass.yaml
ValidatingAdmissionPolicy を作成する
Pod が選択できる ComputeClass を制限するには、ValidatingAdmissionPolicy を作成して、特定の Namespace に適用します。ValidatingAdmissionPolicy 仕様を使用して、Pod が ComputeClass を選択する方法を制御します。このポリシーを作成して適用する手順は次のとおりです。
次の ValidatingAdmissionPolicy マニフェストを
restrict-computeclass-usage-vap.yamlとして保存します。apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: name: restrict-computeclass-usage spec: failurePolicy: Fail # If an internal error occurs, deny the request. variables: # Check whether the admission request is for a Deployment. - name: isDeployment expression: "object.kind == 'Deployment'" # Get the Pod specification from the admission request by reading the # spec.template.spec field for Deployments or the spec field for static Pods. - name: podSpec expression: "variables.isDeployment ? object.spec.template.spec : object.spec" # Check whether a node selector or an affinity rule that explicitly requests a # disallowed ComputeClass. - name: hasForbiddenNodeSelectorOrAffinity expression: >- (has(variables.podSpec.nodeSelector) && variables.podSpec.nodeSelector['cloud.google.com/compute-class'] == 'COMPUTECLASS_NAME') || (has(variables.podSpec.affinity) && has(variables.podSpec.affinity.nodeAffinity) && has(variables.podSpec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution) && variables.podSpec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.exists(term, has(term.matchExpressions) && term.matchExpressions.exists( exp, exp.key == 'cloud.google.com/compute-class' && exp.operator == 'In' && exp.values.exists(v, v == 'COMPUTECLASS_NAME') ) )) # Check whether the Pod has a toleration for the taint that corresponds to a # disallowed ComputeClass. - name: hasForbiddenComputeClassToleration expression: >- has(variables.podSpec.tolerations) && variables.podSpec.tolerations.exists(t, t.key == 'cloud.google.com/compute-class' && (t.operator == 'Exists' || (t.operator == 'Equal' && t.value == 'COMPUTECLASS_NAME')) && has(t.effect) && t.effect == 'NoSchedule') # Check whether the Pod has a toleration that could match any taint. - name: hasWildcardToleration expression: >- has(variables.podSpec.tolerations) && variables.podSpec.tolerations.exists(t, (t.operator == 'Exists' && !(has(t.key) && t.key != '')) ) # Trigger the ValidatingAdmissionPolicy when Pods or Deployments are created or # updated. matchConstraints: resourceRules: - apiGroups: [""] apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["pods"] - apiGroups: ["apps"] apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["deployments"] # Validate whether any of the expressions in the variables section evaluate to # true. validations: - expression: >- !(variables.hasForbiddenNodeSelectorOrAffinity || variables.hasForbiddenComputeClassToleration || variables.hasWildcardToleration) message: >- Pods and Deployments in this namespace cannot request ComputeClass COMPUTECLASS_NAME or use wildcard tolerations.COMPUTECLASS_NAMEは、Pod が選択できないようにする ComputeClass の名前に置き換えます。この ValidatingAdmissionPolicy には次のプロパティがあります。
- 静的 Pod または Deployment 内の Pod のトリガー。
次のいずれかを行う Pod を検索します。
- ノードセレクタまたはノード アフィニティ ルールを使用して、許可されていない特定の ComputeClass を明示的に選択する。
- 許可されていない特定の ComputeClass のノードテイントに対応する 許容 を使用する 。
- クラスタ内のすべてのノードテイントに一致する許容を使用する。
この ValidatingAdmissionPolicy は一例です。式を使用すると、特定のラベルを持つ Pod が特定の ComputeClass を選択できないようにするなど、独自の条件に基づいてポリシーをトリガーできます。
ValidatingAdmissionPolicy を作成します。
kubectl apply -f restrict-computeclass-usage-vap.yaml次の ValidatingAdmissionPolicyBinding を
restrict-computeclass-usage-binding.yamlとして保存します。apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: name: restrict-computeclass-usage-binding spec: policyName: restrict-computeclass-usage validationActions: ["Deny","Audit"] matchResources: namespaceSelector: matchLabels: kubernetes.io/metadata.name: computeclass-vap-tutorial # Replace with the name of any namespace in the cluster.この ValidatingAdmissionPolicyBinding は、前の手順の ValidatingAdmissionPolicy を
computeclass-vap-tutorialNamespace に適用します。validationActionsフィールドの値は、ValidatingAdmissionPolicy に違反する Pod または Deployment を拒否し、Kubernetes 監査ログにエントリを追加します。ValidatingAdmissionPolicyBinding を作成します。
kubectl apply -f restrict-computeclass-usage-binding.yaml
RBAC ポリシーを構成する
ValidatingAdmissionPolicy を使用してワークロードが特定の ComputeClass を使用できないようにするだけでなく、RBAC を使用して、許可されていないプリンシパルがクラスタ内の ComputeClass を作成および変更できないようにします。次の手順では、RBAC 向け Google グループを使用して、特定のユーザー グループに ComputeClass へのアクセス権を付与する方法について説明します。
ComputeClass エディタのグループを作成します。
Google 管理コンソールで、[グループ] ページに移動します。
[グループを作成] をクリックします。
[グループの詳細] ページで、次の操作を行います。
- [グループ名] フィールドに「
computeclass-editors」と入力します。 - [グループのメールアドレス] フィールドに「
computeclass-editors」と入力します。 - [セキュリティ] チェックボックスをオンにします。
- [次へ] をクリックします。
- [グループ名] フィールドに「
[アクセスタイプ] ページの [グループ メンバー] 列で、[メンバーを閲覧できるユーザー] チェックボックスがオンになっていることを確認します。
[グループを作成] をクリックします。
ナビゲーション メニューで、[ディレクトリ] [>] [グループ] をクリックします。
[gke-security-groups] 行にカーソルを合わせ、[メンバーを追加] をクリックします。
[gke-security-groups にメンバーを追加] ダイアログで、「
computeclass-editors」と入力し、結果からそのグループを選択します。[グループに追加] をクリックします。
承認されたユーザーのメールアドレスを
computeclass-editorsグループに追加します。次の ClusterRole を
computeclass-editor-clusterrole.yamlとして保存します。apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: computeclass-editor rules: - apiGroups: ["cloud.google.com"] resources: ["computeclasses"] verbs: ["create","update"]ClusterRole を作成します。
kubectl apply -f computeclass-editor-clusterrole.yaml次の ClusterRoleBinding を
computeclass-editor-role-binding.yamlとして保存します。apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: computeclass-editor-role-binding subjects: - kind: Group name: computeclass-editors@GROUP_DOMAIN apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: computeclass-editor apiGroup: rbac.authorization.k8s.io # Required for role referencesGROUP_DOMAINは、computeclass-editorsグループのドメイン名に置き換えます。ClusterRoleBinding を作成します。
kubectl apply -f computeclass-editor-role-binding.yaml
制限を確認する
以降のセクションでは、前のセクションで構成した制限が想定どおりに機能することを確認する方法について説明します。ValidatingAdmissionPolicies または RBAC ポリシーで独自の制限を構成する場合は、これらのポリシーに違反するワークロードを作成して制限をテストします。
ValidatingAdmissionPolicy を確認する
次のいずれかのマニフェストを保存します。各マニフェストは、ValidatingAdmissionPolicy の異なる条件に違反しています。
ノードセレクタを使用して、許可されていない ComputeClass を選択する Deployment:
apiVersion: apps/v1 kind: Deployment metadata: name: disallowed-computeclass-deployment namespace: computeclass-vap-tutorial spec: replicas: 1 selector: matchLabels: app: forbidden-selector-app template: metadata: labels: app: forbidden-selector-app spec: containers: - name: my-app-container image: nginx:latest # The node selector triggers the policy. nodeSelector: cloud.google.com/compute-class: COMPUTECLASS_NAME許可されていない ComputeClass の許容を持つ Deployment:
apiVersion: apps/v1 kind: Deployment metadata: name: disallowed-computeclass-deployment-toleration namespace: computeclass-vap-tutorial spec: replicas: 1 selector: matchLabels: app: forbidden-selector-app template: metadata: labels: app: forbidden-selector-app spec: containers: - name: my-app-container image: nginx:latest tolerations: - key: cloud.google.com/compute-class operator: Equal value: COMPUTECLASS_NAME effect: NoSchedule許可されていない ComputeClass のノード アフィニティ ルールを持つ Deployment:
apiVersion: apps/v1 kind: Deployment metadata: name: disallowed-computeclass-deployment-toleration namespace: computeclass-vap-tutorial spec: replicas: 1 selector: matchLabels: app: forbidden-selector-app template: metadata: labels: app: forbidden-selector-app spec: containers: - name: my-app-container image: nginx:latest affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: cloud.google.com/compute-class operator: In values: - COMPUTECLASS_NAMEクラスタ内の任意のノードテイントの許容を持つ Pod:
apiVersion: v1 kind: Pod metadata: name: disallowed-computeclass-deployment-toleration namespace: computeclass-vap-tutorial spec: containers: - name: my-app-container image: nginx:latest tolerations: - operator: Exists effect: NoSchedule
テスト ワークロードを作成します。
kubectl apply -f PATH_TO_WORKLOAD_MANIFEST出力は次のようになります。
Error from server (BadRequest): admission webhook "validation-policy.kubernetes.io" denied the request: Pods and Deployments in this namespace cannot request ComputeClass COMPUTECLASS_NAME or use wildcard tolerations.
RBAC 構成を確認する
RBAC 構成を確認する手順は次のとおりです。
computeclass-editorsグループのメンバーであるユーザーの認証情報を使用して、クラスタに対して認証を行います。ユーザーが ComputeClass を作成できるかどうかを確認します。
kubectl auth can-i create computeclasses.cloud.google.com \ --as=MEMBER_USERMEMBER_USERは、グループのメンバーであるユーザーのメールアドレスに置き換えます。出力は
yesです。computeclass-editorsグループのメンバーではないユーザーの認証情報を使用して、クラスタに対して認証を行います。ユーザーが ComputeClass を作成できるかどうかを確認します。
kubectl auth can-i create computeclasses.cloud.google.com \ --as=NON_MEMBER_USERNON_MEMBER_USERは、グループのメンバーではないユーザーのメールアドレスに置き換えます。出力は
noです。
グループのメンバーではないユーザーに対して kubectl auth can-i コマンドの出力が yes の場合は、次のことを確認します。
computeclass-editorsグループがgke-security-groupsグループのメンバーである。- ClusterRoleBinding のグループのメールアドレスが、グループの正確なメールアドレス(
computeclass-editors@example.comなど)である。
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
このチュートリアルの ValidatingAdmissionPolicy と RBAC ポリシーを本番環境クラスタにデプロイすると、GKE はポリシーに違反する受信 Pod と API リクエストをブロックします。これらのポリシーを有効にするには、このセクションをスキップしてください。以降のセクションでは、学習環境またはテスト環境でこのチュートリアルを実施した場合に、プロジェクトまたは個々のリソースを削除する方法について説明します。
プロジェクトの削除
プロジェクトを削除します。 Google Cloud
gcloud projects delete PROJECT_ID
リソースを個別に削除する
作成した ComputeClass を削除します。
kubectl delete computeclass access-restriction-classValidatingAdmissionPolicy と ValidatingAdmissionPolicyBinding を削除します。
kubectl delete validatingadmissionpolicy restrict-computeclass-usage kubectl delete validatingadmissionpolicybinding restrict-computeclass-usage-bindingClusterRole と ClusterRoleBinding を削除します。
kubectl delete clusterroles \ computeclass-editor validatingadmissionpolicy-editor kubectl delete clusterrolebindings \ computeclass-editor-role-binding edit-validatingadmissionpoliciesサンプル Namespace を削除します。
kubectl delete namespace computeclass-vap-tutorial
次のステップ
- クラスタ セキュリティのベスト プラクティスを確認する
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。 Cloud アーキテクチャ センターをご覧ください。