このハンズオンでは Anthos Config Management の導入、設定を通じて基礎的な機能を学習します。
ACM を使うことで以下の 2 つのことが実現できます。
ACM は複数のコンポーネントで構成されています。
本ハンズオンは、Billing が有効な Google Cloud プロジェクトで行うこと、また各種コマンドは Cloud Shell で実行することを前提としています。環境がない場合は、事前に Google Cloud プロジェクトをご用意ください。
Google Cloud コンソール から Google Cloud Console にブラウザでアクセスします。
各種コマンドを実行するための CLI 環境である Cloud Shell を開きます。下図の中のリンクをクリックし、Cloud Shell を開きます。
ハンズオンを実行する対象の Google Cloud プロジェクトを設定します。コマンドの XXXXXXXX
の部分を実際のプロジェクト ID に置き換えて実行します。プロジェクト ID はダッシュボード画面のプロジェクト情報カードから確認ができます。
export PROJECT_ID=XXXXXXXX
gcloud config set project ${PROJECT_ID}
実行後、確認メッセージがでてきた場合は承認ボタンをクリックします。
コマンド実行後に以下の様に Cloud Shell のプロンプトに、黄色の文字でプロジェクト ID が表示されていることを確認します。
ハンズオン用のディレクトリを作成し、そちらに移動します。
export HANDSON_DIR=${HOME}/acm-handson-${PROJECT_ID}
mkdir -p ${HANDSON_DIR} && cd ${HANDSON_DIR}
Google Cloud では以下のような各種機能を API として提供しており、Google Cloud プロジェクトの作成直後は、ほぼすべての機能が無効化されております。そのため、使いたい機能は事前に有効化する必要があります。ここではアプリケーションをデプロイする対象の GKE、Config Controller に必要な機能群を有効化します。
gcloud services enable container.googleapis.com \
monitoring.googleapis.com \
cloudtrace.googleapis.com \
clouddebugger.googleapis.com \
cloudprofiler.googleapis.com \
sourcerepo.googleapis.com \
krmapihosting.googleapis.com \
container.googleapis.com \
cloudresourcemanager.googleapis.com \
&& gcloud beta container hub config-management enable
以下のような環境を順を追って構築していきます。
この環境のポイントは以下になります。
本手順のゴールイメージ
開発環境用の GKE クラスタを 1 つ、本番環境用の GKE クラスタを 2 つ作成します。
for cluster_name in dev-cluster01 prod-cluster01 prod-cluster02
do
gcloud container clusters create ${cluster_name} \
--workload-pool ${PROJECT_ID}.svc.id.goog \
--release-channel regular \
--logging=SYSTEM,WORKLOAD \
--monitoring=SYSTEM \
--machine-type e2-medium \
--zone asia-northeast1-b \
--async
done
Kubernetes Engine から GUI で確認できます。
6.1 のコマンドは非同期実行のためのオプションがついているため、コマンドの成功失敗に関わらず、すぐ結果が返ってきます。
3 つのクラスタの作成が完了し、稼働状態 (RUNNING) になるまで待ちます。
watch -n 5 gcloud container clusters list --format "value\(name,status\)"
すべてのクラスタが RUNNING になったら、Ctrl-C
でコマンドを終了させます。
Kubernetes の操作には kubectl
という CLI を使います。kubectl
から作成したクラスタを操作するために認証情報を取得します。
for cluster_name in dev-cluster01 prod-cluster01 prod-cluster02
do
gcloud container clusters get-credentials ${cluster_name} --zone=asia-northeast1-b
done
kubectl
では操作対象のクラスタを認証情報も合わせ、コンテキストというもので管理しています。デフォルトでは長いコンテキスト名が付いてしまうため、以降の手順で簡単に指定できるように短い名称に変えます。
kubectl config rename-context gke_${PROJECT_ID}_asia-northeast1-b_dev-cluster01 dev01
kubectl config rename-context gke_${PROJECT_ID}_asia-northeast1-b_prod-cluster01 prod01
kubectl config rename-context gke_${PROJECT_ID}_asia-northeast1-b_prod-cluster02 prod02
フリートとはクラスタを論理的に編成するための Google Cloud のコンセプトです。これを使うことでマルチクラスタ機能の使用と管理、複数のシステム間での一貫したポリシーの適用が可能になります。
for cluster_name in dev-cluster01 prod-cluster01 prod-cluster02
do
gcloud container hub memberships register ${cluster_name} \
--gke-cluster=asia-northeast1-b/${cluster_name} \
--enable-workload-identity
done
クラスタに適用する設定 (マニフェスト) は GitOps の形で集中管理します。そこでマニフェストを格納するための Git リポジトリの作成、権限の設定を行います。
本手順のゴールイメージ
マニフェストを格納するための Git リポジトリを Cloud Source Repositories に作成します。
gcloud source repos create acm-repo
作成した Git リポジトリは空になっています。後ほどマニフェストを格納するために main ブランチに README ファイル を作成しておきます。
cd ${HANDSON_DIR} \
&& gcloud source repos clone acm-repo \
&& cd acm-repo \
&& git checkout -b main \
&& echo "# Repository for ACM" > README.md \
&& git add . \
&& git commit -m 'add readme' \
&& git push origin main \
&& cd ..
下記コマンドで出力された URL から GUI にアクセスできます。
echo https://source.cloud.google.com/${PROJECT_ID}/acm-repo/+/main
Config Sync は Cloud Source Repositories からマニフェストを読み取るために権限が必要です。ここでは専用のサービスアカウントを作成します。
gcloud iam service-accounts create acm-sync \
--description="Service account for Config Sync" \
--display-name="acm-sync"
サービスアカウントは作成しただけでは権限を持っていません。Cloud Source Repositories への読み取り権限を付与します。
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:acm-sync@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/source.reader"
Workload Identity を使い、先程作成したサービスアカウントを Config Sync が利用する Kubernetes サービスアカウントと紐付けます。これにより、Config Sync が Cloud Source Repositories にあるマニフェストを読み取ることができるようになります。
gcloud iam service-accounts add-iam-policy-binding \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:${PROJECT_ID}.svc.id.goog[config-management-system/root-reconciler]" \
acm-sync@${PROJECT_ID}.iam.gserviceaccount.com
本手順のゴールイメージ
Config Sync, Policy Controller は設定ファイルを使い、クラスタごとにインストールします。どのような設定ができるかは、gcloud apply spec フィールド をご確認ください。
cd ${HANDSON_DIR} \
&& cat << EOF > apply-spec.yaml
applySpecVersion: 1
spec:
configSync:
# Config Sync の有効化
enabled: true
# Git リポジトリ内のコード形式 (非構造化)
sourceFormat: unstructured
# Sync 対象の Git リポジトリ
syncRepo: https://source.developers.google.com/p/${PROJECT_ID}/r/acm-repo
# Sync 対象のブランチ名
syncBranch: main
# Sync 対象のリビジョン
syncRev: HEAD
# Git リポジトリとの認証方法 (Workload Identity から Service Account を利用)
secretType: gcpserviceaccount
# Service Account のメールアドレスを指定
gcpServiceAccountEmail: acm-sync@${PROJECT_ID}.iam.gserviceaccount.com
# Sync 対象のディレクトリ
policyDir: /
# Config Sync により設定されたリソースの上書きを許可するか (デフォルトは False)
preventDrift: false
policyController:
# Policy Controller の有効化
enabled: true
# 全ての拒否動作と Dryrun での失敗をログ対象とするか (デフォルトは False)
logDeniesEnabled: true
EOF
3 つのクラスタ全てで同じ設定を使い、Config Sync、Policy Controller をインストールします。
for cluster_name in dev-cluster01 prod-cluster01 prod-cluster02
do
gcloud beta container hub config-management apply \
--membership=${cluster_name} \
--config=./apply-spec.yaml
done
Config Sync, Policy Controller がインストールされ、稼働状態になるまで待ちます。
watch -n 5 gcloud beta container hub config-management status
すべてのクラスタの Status が SYNCED、Policy_Controller が INSTALLED になったら、Ctrl-C
でコマンドを終了させます。 Kubernetes Engine - 構成管理 から GUI でも確認できます。
本手順のゴールイメージ
cd ${HANDSON_DIR}/acm-repo
accountservice という名前空間、またその名前空間内の Pod を閲覧する権限、それを Google グループに付与する設定を作成します。
cat << EOF > namespace.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: accountservice
EOF
cat << EOF > accountservice.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: accountservice
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader-binding
namespace: accountservice
subjects:
# Google Group
- kind: Group
name: accountservice-ro-group@example.com
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
EOF
作成した設定ファイルを Git リポジトリにプッシュします。
git add . && git commit -m 'add accountservice.yaml' && git push origin main
開発用クラスタの名前空間一覧を確認します。accountservice が作成されるまで待ちます。
kubectl get namespace --context dev01 --watch
名前空間 accountservice が作られたら Ctrl-C
でコマンドを終了させます。
--context
の引数を本番クラスタ (prod01, prod02) の指定に変え、実行してみてください。開発クラスタと同じように名前空間が作られているはずです。
ACM では複数のクラスタを管理する CLI として nomos
が用意されています。これを使うことで、複数のクラスタの状況、Config Sync により管理されているリソースを一覧化して見ることができます。
以下のコマンドは、3 クラスタすべての情報を 1 秒おきに表示します。
nomos status --contexts dev01,prod01,prod02 --poll 1s
確認後 Ctrl-C
でコマンドを終了させます。
kubectl delete -f accountservice.yaml --context dev01 \
&& nomos status --contexts dev01,prod01,prod02 --poll 1s
Git で定義されているあるべき状態と、現在の差分が検出され、自動的に修正 (削除したものが再作成) されます。確認後 Ctrl-C
でコマンドを終了させます。
Git から名前空間を除くリソースを削除します。すべてのクラスタからリソースが削除されることを確認します。
git rm accountservice.yaml && git commit -m 'delete accountservice.yaml' && git push origin main \
&& nomos status --contexts dev01,prod01,prod02 --poll 1s
確認後 Ctrl-C
でコマンドを終了させます。
Config Sync ではリソースの誤削除を防ぐため、一度のコミットですべての名前空間、リソースを削除することができないようになっています。そのため、本手順でリソースを、次の手順で名前空間を削除するようにしています。KNV2006: Config Management Erros
Git から名前空間リソースを削除します。すべてのクラスタから名前空間が削除されることを確認します。
git rm namespace.yaml && git commit -m 'delete namespace.yaml' && git push origin main \
&& nomos status --contexts dev01,prod01,prod02 --poll 1s
確認後 Ctrl-C
でコマンドを終了させます。
ここまで 3 クラスタすべてが同じ Git リポジトリ、ブランチを参照しており、同じ設定が適用されていました。現実では本番、開発では異なる設定となることがほとんどです。
今回のハンズオンでは Git リポジトリは同じものを参照し、ブランチで本番、開発を区別することとします。
本手順のゴールイメージ
参照するブランチを prod, dev に修正したファイルを作成します。
cd ${HANDSON_DIR}
cat apply-spec.yaml | sed -e 's/syncBranch: main/syncBranch: prod/' -e 's/preventDrift: false/preventDrift: true/' -e '5s/enabled: true/enabled: false/' > apply-spec-prod.yaml
cat apply-spec.yaml | sed -e 's/syncBranch: main/syncBranch: dev/' > apply-spec-dev.yaml
Git リポジトリにはまだ参照するブランチが作成されていません。prod, dev のブランチを作成します。
cd acm-repo \
&& git checkout -b prod \
&& git push origin prod \
&& git checkout -b dev \
&& git push origin dev \
&& cd ..
先程作成した、本番用、開発用で参照するブランチを分けた設定ファイルを適用します。
本番用クラスタ (Config Sync を一度停止する)
for num in 01 02
do
gcloud beta container hub config-management apply \
--membership=prod-cluster${num} \
--config=./apply-spec-prod.yaml
done
開発用クラスタ
gcloud beta container hub config-management apply \
--membership=dev-cluster01 \
--config=./apply-spec-dev.yaml
注: 本番環境では 構成ファイルのドリフト防止 機能を有効化しようとしています。有効化には一度 Config Sync を止め、再度起動させる必要があります。
sed -i -e 's/enabled: false/enabled: true' apply-spec-prod.yaml
for num in 01 02
do
gcloud beta container hub config-management apply \
--membership=prod-cluster${num} \
--config=./apply-spec-prod.yaml
done
参照ブランチが変わったことを nomos
コマンドで確認します。
nomos status --contexts dev01,prod01,prod02 --poll 1s
確認後 Ctrl-C
でコマンドを終了させます。
本番用に 2 クラスタありますが、同じブランチを参照しており、Git リポジトリが更新されるとすぐに設定が反映されます (デフォルトで HEAD が指定されているため)。ここではより安全に参照する リビジョン を指定することで Git リポジトリの更新とは分けて、クラスタ設定を管理します。
本手順のゴールイメージ
cd ${HANDSON_DIR}/acm-repo && git checkout prod
今 Sync されているリビジョン (HEAD) のハッシュ値を取得します。
REVISION=$(git rev-parse HEAD)
リビジョンを固定した設定ファイルを作成します。
cd ${HANDSON_DIR} && cat apply-spec-prod.yaml \
| sed -e "s/syncRev: HEAD/syncRev: ${REVISION}/" \
> apply-spec-prod-rev.yaml
Config Sync の設定を更新し、本番クラスタの参照リビジョンを固定します。
for num in 01 02
do
gcloud beta container hub config-management apply \
--membership=prod-cluster${num} \
--config=./apply-spec-prod-rev.yaml
done
参照リビジョンが変わったことを nomos
コマンドで確認します。
nomos status --contexts prod01,prod02 --poll 1s
確認後 Ctrl-C
でコマンドを終了させます。
これで本番用クラスタ 01, 02 が特定のリビジョンに固定されました。こうすることで Git リポジトリに反映された設定をクラスタ個別に反映させることが可能になりました。
本手順のゴールイメージ
productionservice という名前空間を作成します。
cd ${HANDSON_DIR}/acm-repo \
&& cat << EOF > accountservice.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: accountservice
EOF
作成した設定ファイルを Git リポジトリにプッシュします。
git add . && git commit -m 'add accountservice.yaml' \
&& git push origin prod
最新のリビジョン (HEAD) のハッシュ値を取得します。
REVISION=$(git rev-parse HEAD)
設定ファイルに記載されている参照リビジョンを更新します。
cd ${HANDSON_DIR} && \
sed -i -e "s/syncRev: .*$/syncRev: ${REVISION}/" apply-spec-prod-rev.yaml
Config Sync の設定を更新し、本番クラスタ 01 のみ参照リビジョンを固定します。
gcloud beta container hub config-management apply \
--membership=prod-cluster01 \
--config=./apply-spec-prod-rev.yaml \
&& nomos status --contexts prod01,prod02 --poll 1s
本番用クラスタ 01, 02 で異なるリビジョンが適用されることを確認します。確認後 Ctrl-C
でコマンドを終了させます。
Config Sync で作成されたリソースを手動で削除します。
kubectl delete namespace accountservice --context prod01
Config Sync で管理されているリソースを修正しようとしたので、拒否されるはずです。 これは Config Sync の Admission Webhook により実現されています。
開発用のクラスタでは preventDrift のパラメータが false に設定していたため、手動での操作自体は拒否されず、操作後自動的に修正されていました。
今回は開発、本番の 2 環境、そしてそれぞれの環境は設定が同一という前提で以下の要素を使い、クラスタ設定を制御しました。
Git, Config Sync では上記に加え下記のような要素を使い、クラスタに適用する設定を制御することができます。
また今回は 1 クラスタが参照する Git リポジトリが 1 つでしたが、複数のリポジトリ (正しくは、クラスタ全体設定用に 1 つ、各名前空間ごとに 1 つずつ) を参照するように構成することも可能です。詳しくは 名前空間リポジトリからの同期を構成する をご確認ください。
それぞれの要素の使い分けなどは Anthos Config Management を使用した安全なロールアウト をご確認ください。
Policy Controller は、Kubernetes の API に対する操作に対しポリシーを設定することができます。
Config Sync により GitOps でリソースの一元管理を実現できましたが、リソースをどのように作るべきか、何を作らせるべきかなどの制限は入っていませんでした。そのような各種制限を設定、そして強制する機能が Policy Controller で「セキュリティガードレール」として機能します。
この機能を利用することで以下のようなことが可能になります。
手順 8 で Policy Controller は各クラスタにインストール済みです。その中で自動的に有用なポリシーテンプレートも導入されます。インストールされるテンプレート一覧は 制約テンプレートライブラリ をご確認ください。
ここではそれらのテンプレートを活用して、3 つセキュリティガードレールを追加します。
テンプレートライブラリで提供されている K8sReplicaLimits を利用して、開発用クラスタでのレプリカ数上限を 3 に設定します。
cd ${HANDSON_DIR}/acm-repo && git checkout dev
cat << EOF > replica_limit.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sReplicaLimits
metadata:
name: replica-limits
spec:
enforcementAction: dryrun
match:
kinds:
- apiGroups:
- apps
kinds:
- Deployment
parameters:
ranges:
- max_replicas: 3
EOF
作成したポリシーを Git リポジトリにプッシュし、反映を確認します。
git add . && git commit -m 'add replica limit policy for development' && git push origin dev \
&& nomos status --contexts dev01 --poll 1s
反映を確認後 Ctrl-C
でコマンドを終了させます。
kubectl create deployment nginx-4 --image nginx --replicas 4 --context dev01
手順 15.3 で作成したポリシーは dryrun モード (enforcementAction 項目) で設定していました。そのためポリシー違反の設定は拒否ではなく、監視されます。ポリシー違反が検出されているかを確認します。
kubectl get K8sReplicaLimits replica-limits -o yaml --context dev01
出力結果の最下部に violations としてポリシー違反の Deployment が表示されていることを確認します。
K8sRectrictNamespaces ポリシーを使うことで、名前空間の利用を制限できます。
ここではサービスで通常利用しないほうが良い default の名前空間の利用を制限します。
cd ${HANDSON_DIR}/acm-repo && git checkout prod
cat << EOF > restrict-default-namespace.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRestrictNamespaces
metadata:
name: restrict-default-namespace
spec:
match:
kinds:
- apiGroups: ["apps"]
kinds: ["Deployment","Pod","ReplicaSet"]
enforcementAction: deny
parameters:
restrictedNamespaces:
- default
EOF
作成したポリシーを Git リポジトリにプッシュします。
git add . && git commit -m 'restrict default namespace for production' \
&& git push origin prod
更新が含まれているリビジョン (HEAD) のハッシュ値を取得します。
REVISION=$(git rev-parse HEAD)
リビジョンを固定した設定ファイルを作成します。
cd ${HANDSON_DIR} && cat apply-spec-prod-rev.yaml \
| sed -e "s/syncRev: .*$/syncRev: ${REVISION}/" \
> apply-spec-prod-rev-17.yaml
Config Sync の設定を更新し、本番クラスタ 01 にポリシーを反映します。
gcloud beta container hub config-management apply \
--membership=prod-cluster01 \
--config=./apply-spec-prod-rev-17.yaml \
&& nomos status --contexts prod01 --poll 1s
restrict-default-namespace リソースが Sync されたら、Ctrl-C
でコマンドを終了させます。
kubectl create deployment nginx --image nginx --replicas 4 --context prod01
K8sRequiredProbes ポリシーを使うことで、Pod に readiness Probe または liveness Probe の利用を強制できます。本番用サービスでは、アプリケーションに合わせた Probe を適切に設定することが良いプラクティスです。
ここでは両方の Probe が設定されていない Pod の作成を制限します。
cd ${HANDSON_DIR}/acm-repo \
&& cat << EOF > must-have-probes.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredProbes
metadata:
name: must-have-probes
spec:
enforcementAction: deny
match:
kinds:
- apiGroups:
- ""
kinds:
- Pod
parameters:
probeTypes:
- tcpSocket
- httpGet
- exec
probes:
- readinessProbe
- livenessProbe
EOF
作成したポリシーを Git リポジトリにプッシュします。
git add . && git commit -m 'restrict workloads without probes for production' \
&& git push origin prod
更新が含まれているリビジョン (HEAD) のハッシュ値を取得します。
REVISION=$(git rev-parse HEAD)
リビジョンを固定した設定ファイルを作成します。
cd ${HANDSON_DIR} && cat apply-spec-prod-rev-16.yaml \
| sed -e "s/syncRev: .*$/syncRev: ${REVISION}/" \
> apply-spec-prod-rev-18.yaml
Config Sync の設定を更新し、本番クラスタ 01 にポリシーを反映します。
gcloud beta container hub config-management apply \
--membership=prod-cluster01 \
--config=./apply-spec-prod-rev-18.yaml \
&& nomos status --contexts prod01 --poll 1s
must-have-probes リソースが Sync されたら、Ctrl-C
でコマンドを終了させます。
kubectl create namespace service1 --context prod01 \
&& kubectl run nginx-without-probes --image nginx -n service1 --context prod01
Config Controller は Google Cloud リソースのプロビジョニングとオーケストレーション (わかりやすく言うと IaC を実現します) を行うホスト型サービスです。本サービスにより、Google Cloud の環境を Kubernetes Resource Model で構築、管理できます。
Config Controller は下記 3 つのコンポーネントで構築されています。
Config Connector が KRM を Google Cloud のリソースに変換し作成する機能を担っています。Config Sync, Policy Controller により、Google Cloud のリソース管理機能に、GitOps、セキュリティガードレールが追加されています。
gcloud anthos config controller create config-controller01 \
--location=us-central1 --async
watch -n 5 gcloud anthos config controller list --location us-central1
作成が完了 (STATE が RUNNING) したら、Ctrl-C
でコマンドを終了させます。
Config Controller は GKE クラスタにホストされた形で提供されます。作成したクラスタを CLI (kubectl) から操作するために認証情報を取得します。
gcloud anthos config controller get-credentials config-controller01 \
--location us-central1
Config Controller は Google Cloud のリソースを作成、管理します。そのため、それらを実行するための権限を付与する必要があります。
export SA_EMAIL="$(kubectl get ConfigConnectorContext -n config-control \
-o jsonpath='{.items[0].spec.googleServiceAccount}' 2> /dev/null)"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member "serviceAccount:${SA_EMAIL}" \
--role "roles/owner"
Config Controller には Config Sync が含まれており、簡単に GitOps でリソースを管理することができます。
cd ${HANDSON_DIR} \
&& cat << EOF > cc-repo.yaml
apiVersion: sourcerepo.cnrm.cloud.google.com/v1beta1
kind: SourceRepoRepository
metadata:
name: config-controller-repo
namespace: config-control
EOF
kubectl apply -f cc-repo.yaml
作成した Git リポジトリは空になっています。後ほどマニフェストを格納するために main ブランチに README ファイル を作成しておきます。
gcloud source repos clone config-controller-repo \
&& cd config-controller-repo \
&& git checkout -b main \
&& echo "# Repository for Config Controller" > README.md \
&& git add . \
&& git commit -m 'add readme' \
&& git push origin main
cd ${HANDSON_DIR} \
&& cat << EOF > gitops-iam.yaml
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMServiceAccount
metadata:
name: config-sync-sa
namespace: config-control
spec:
displayName: ConfigSync
---
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: config-sync-wi
namespace: config-control
spec:
member: serviceAccount:${PROJECT_ID}.svc.id.goog[config-management-system/root-reconciler]
role: roles/iam.workloadIdentityUser
resourceRef:
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMServiceAccount
name: config-sync-sa
---
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: allow-configsync-sa-read-csr
namespace: config-control
spec:
member: serviceAccount:config-sync-sa@${PROJECT_ID}.iam.gserviceaccount.com
role: roles/source.reader
resourceRef:
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
kind: Project
external: projects/${PROJECT_ID}
EOF
kubectl apply -f gitops-iam.yaml
cat << EOF > apply-spec-config-controller.yaml
apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
name: config-management
spec:
enableMultiRepo: true
enableLegacyFields: true
policyController:
enabled: true
clusterName: krmapihost-config-controller01
git:
policyDir: /
secretType: gcpserviceaccount
gcpServiceAccountEmail: config-sync-sa@${PROJECT_ID}.iam.gserviceaccount.com
syncBranch: main
syncRepo: https://source.developers.google.com/p/${PROJECT_ID}/r/config-controller-repo
sourceFormat: unstructured
EOF
kubectl apply -f apply-spec-config-controller.yaml
Config Sync, Policy Controller がインストールされ、稼働状態になるまで待ちます。
nomos status --contexts $(kubectl config current-context) --poll 5s
クラスタの状態が SYNCED になったらCtrl-C
でコマンドを終了させます。
cd ${HANDSON_DIR}/config-controller-repo \
&& cat << EOF > storage-bucket-tokyo.yaml
apiVersion: storage.cnrm.cloud.google.com/v1beta1
kind: StorageBucket
metadata:
annotations:
cnrm.cloud.google.com/force-destroy: "false"
name: ${PROJECT_ID}-bucket-tokyo
namespace: config-control
spec:
storageClass: STANDARD
location: asia-northeast1
versioning:
enabled: true
uniformBucketLevelAccess: true
EOF
作成したリソース用マニフェストを Git リポジトリにプッシュします。
git add . && git commit -m 'create a storage bucket in Tokyo' \
&& git push origin main \
&& nomos status --contexts $(kubectl config current-context) --poll 1s
Cloud Storage が作られたら Ctrl-C
でコマンドを終了させます。
Cloud Storage 管理画面 から GUI で確認できます。
cat << EOF > gcs-tokyo-only.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: GCPStorageLocationConstraintV1
metadata:
name: tokyo-only
spec:
enforcementAction: deny
match:
kinds:
- apiGroups:
- storage.cnrm.cloud.google.com
kinds:
- StorageBucket
parameters:
locations:
- asia-northeast1
EOF
作成したポリシーを Git リポジトリにプッシュします。
git add . && git commit -m 'restrict bucket creation only in Tokyo' \
&& git push origin main \
&& nomos status --contexts $(kubectl config current-context) --poll 1s
tokyo-only というポリシーが作られたら Ctrl-C
でコマンドを終了させます。
cat << EOF > storage-bucket-tokyo.yaml
apiVersion: storage.cnrm.cloud.google.com/v1beta1
kind: StorageBucket
metadata:
annotations:
cnrm.cloud.google.com/force-destroy: "false"
name: ${PROJECT_ID}-bucket-osaka
namespace: config-control
spec:
storageClass: STANDARD
location: asia-northeast2
versioning:
enabled: true
uniformBucketLevelAccess: true
EOF
作成したリソース用マニフェストを Git リポジトリにプッシュします。
git add . && git commit -m 'create a storage bucket in Osaka' \
&& git push origin main \
&& nomos status --contexts $(kubectl config current-context) --poll 1s
Tokyo リージョンのみ作成可能なポリシーが設定済みなため、作成に失敗しエラーが出力されます。エラーが確認できたら Ctrl-C
でコマンドを終了させます。
環境のクリーンアップを行います。
最も簡単な方法は Google Cloud プロジェクトごと削除する方法です。
gcloud projects delete ${PROJECT_ID} --quiet