GKE(Google Kubernetes Engine)を単一クラスタで使う段階では、Deployment、Service、IngressなどのKubernetesリソースを理解することが中心になります。一方で、クラスタやチームが増えてくると、設定をどうそろえるか、危険な設定をどう防ぐか、Google Cloudリソースまで同じ運用モデルで扱うか、という論点が出てきます。
この記事では、『GKE Fleet・マルチクラスタGKE・MCSの関係まとめ』で見た複数クラスタ構成の続きとして、Config Sync、Policy Controller、Config Connectorの役割を整理します。これらの機能は単一クラスタでも使えますが、個別管理のずれや運用ルールのばらつきが目立ちやすいのは複数クラスタ構成です。そのため本記事では、複数クラスタ運用を主な文脈にして、同期、ポリシー制御、Google Cloudリソース管理の違いを見ていきます。
- Config Sync、Policy Controller、Config Connectorの役割の違い
- 3つがGKEやFleetの運用でどこに関係するか
- Config SyncとPolicy Controllerを組み合わせる理由
- Config ConnectorとTerraformの見方の違い
GKE運用統制におけるConfig Sync・Policy Controller・Config Connectorの立ち位置
Config Sync、Policy Controller、Config Connectorは、どれもGKEやKubernetesの文脈で出てくるため混ざりやすいです。ただし、見ている対象は違います。
| 仕組み | 主な管理対象 | 答える問い |
|---|---|---|
| Config Sync | Kubernetes設定 | Gitリポジトリなどに置いた設定を、どのクラスタへ反映するか |
| Policy Controller | Kubernetes APIに入るリソース | その設定や変更を、クラスタに入れてよいか |
| Config Connector | Google Cloudリソース | Cloud Storage bucketやPub/Sub topicなどを、Kubernetes経由で管理するか |
関係を図にすると次のようになります。
flowchart TB
Repo["Gitリポジトリ"]
ConfigSync["Config Sync"]
subgraph Fleet["Fleet"]
subgraph Cluster["GKEクラスタ"]
Policy["Policy Controller"]
K8s["Kubernetesリソース"]
CcResource["Config Connector用リソース"]
Connector["Config Connector"]
end
end
Cloud["Google Cloudリソース"]
Repo --> ConfigSync
ConfigSync -->|"同期"| K8s
ConfigSync -->|"同期"| CcResource
Policy -. "判定" .-> K8s
CcResource --> Connector
Connector -->|"Google Cloud API"| Cloud
図では、GitリポジトリからGKEクラスタへ設定を同期する役割がConfig Syncです。ここでいうKubernetesリソースは、Deployment、Service、Namespace、RBAC、NetworkPolicyなど、Kubernetes APIで管理する設定や管理対象を指します。Policy Controllerは、クラスタに入るKubernetesリソースがポリシーに違反していないかを判定します。
Google Cloudリソースは、Cloud Storage bucket、Pub/Sub topic、IAM設定など、Google Cloud APIで管理するリソースを指します。Config Connectorは、Kubernetes上に作られたConfig Connector用リソースをもとにGoogle Cloud APIを呼び出し、Google Cloudリソースを管理します。
つまり、3つは同じ「GKE運用」の話に見えても、設定を配るのか、設定を検査するのか、Google Cloudリソースを管理するのかで分かれます。
Config SyncはKubernetes設定をGitなどから同期する
Config Syncは、Gitリポジトリなどを設定の正とし、その内容をGKEクラスタへ同期する仕組みです。
GitOpsという考え方では、Gitのようなバージョン管理システムを設定の正として扱います。手元から各クラスタへ kubectl apply を繰り返すのではなく、レビュー済みの設定をリポジトリに置き、クラスタ側がその状態へ近づくようにします。
Config Syncの同期元には、GitリポジトリのほかにOCI image(Open Container Initiative形式のイメージ)やHelm chart(Kubernetes設定をパッケージ化する形式)も使えます。ただし、本記事では仕組みを理解しやすいように、Gitリポジトリを設定の正にする例で説明します。
Config Syncが役立つのは、クラスタが増えたときです。クラスタごとにnamespace、RBAC(Role-Based Access Control。Kubernetes上の権限制御)、NetworkPolicy、Policy Controllerの制約などを手作業で入れていると、設定の差分が見えにくくなります。あるクラスタだけ古い設定のまま残る、誰かが直接変更してGit上の定義とずれる、といった状態も起きます。
Config Syncを使うと、中央の設定を複数クラスタへ同期し、クラスタの状態が設定の正からずれたときに戻せます。ここでの中心は、Kubernetes設定の配布と差分の修正です。
Gitリポジトリには、たとえば次のようなKubernetes manifestを置きます。これは app というnamespaceを作る単純な例です。
apiVersion: v1
kind: Namespace
metadata:
name: app
labels:
team: backend
Config Syncで同期したくなる変更には、次のようなものがあります。
| 変更例 | 同期したい理由 |
|---|---|
| 全クラスタに共通namespaceを追加する | アプリ配置先や管理単位をクラスタ間でそろえるため |
| RBACのRoleやRoleBindingを更新する | チームごとの操作権限を手作業でばらつかせないため |
| NetworkPolicyを追加する | Pod間通信の許可範囲をクラスタ間でそろえるため |
| Policy Controllerの制約を配布する | 禁止したい設定や監査ルールを複数クラスタへ同じ形で入れるため |
Config Syncは、このようなmanifestを読み取り、対象クラスタのKubernetes APIへ適用します。その結果として、各クラスタ内にNamespaceなどのKubernetesリソースが作成・更新されます。
flowchart TB
Repo["Gitリポジトリ"]
Manifest["Kubernetes manifest"]
ConfigSync["Config Sync"]
subgraph Fleet["Fleet"]
subgraph ClusterA["GKEクラスタ A"]
ResA["Kubernetesリソース"]
end
subgraph ClusterB["GKEクラスタ B"]
ResB["Kubernetesリソース"]
end
end
Repo --> Manifest
Manifest --> ConfigSync
ConfigSync --> ResA
ConfigSync --> ResB
この図では、Gitリポジトリに置いたKubernetes manifestをConfig Syncが読み取り、複数のGKEクラスタへKubernetesリソースとして反映しています。Config Syncは、アプリケーションの通信制御そのものやGoogle Cloudリソース作成そのものを担当するのではなく、クラスタに適用するKubernetes設定をそろえる役割です。
Policy Controllerは入れてよい設定かを判定する
Policy Controllerは、Kubernetesクラスタに対してプログラム可能なポリシーを適用し、設定がルールに違反していないかを監査または強制する仕組みです。
Policy Controllerは、Open Policy Agent Gatekeeperをベースにしています。Open Policy Agentは、ポリシーをコードとして扱うためのオープンソースの仕組みです。Gatekeeperは、そのポリシー判定をKubernetes APIへの適用時や既存リソースの監査に組み込むためのプロジェクトです。
たとえば、次のようなルールをクラスタに適用したい場面があります。
- 特定のコンテナイメージレジストリ以外を使わせない
- privileged modeのコンテナを禁止する
- namespaceに必須ラベルを付けさせる
- Service Meshで必要な設定の抜け漏れを監査する
Config Syncが「設定をクラスタへ届ける」仕組みだとすると、Policy Controllerは「その設定を入れてよいか」を判定する仕組みです。ポリシー違反をすぐブロックする強制だけでなく、まず監査して違反を見つける使い方もできます。
Config Sync経由の場合、Pull RequestがマージされるとConfig Syncがmanifestをクラスタへ同期しようとします。そのmanifestがKubernetes APIに入る段階で、Policy ControllerがAdmission Controllerとして判定します。つまり、Policy ControllerがGitのPull Requestを直接ブロックするわけではないので注意が必要です。
たとえば、privileged modeのコンテナを禁止するポリシーがあるクラスタに、次のようなPod manifestを同期しようとするとします。
apiVersion: v1
kind: Pod
metadata:
name: privileged-sample
spec:
containers:
- name: app
image: nginx
securityContext:
privileged: true
このmanifestがConfig Syncで同期される場合、流れは次のようになります。
flowchart TB Pr["Pull Request"] Repo["Gitリポジトリ"] ConfigSync["Config Sync"] Api["Kubernetes API"] Policy["Policy Controller"] Cluster["GKEクラスタ"] Error["同期エラー"] Pr -->|"マージ"| Repo Repo --> ConfigSync ConfigSync -->|"manifestを適用"| Api Api -->|"Admission判定"| Policy Policy -->|"許可"| Cluster Policy -. "拒否" .-> Error
この図では、Pull Requestのマージ自体をPolicy Controllerが止めるわけではありません。止まるのは、Config SyncがmanifestをKubernetes APIへ適用しようとしたタイミングです。上のPod manifestは securityContext.privileged が true になっているため、privileged mode禁止のポリシーに違反します。そのため、強制モードではこのPodはクラスタに作成されず、Config Sync側では同期エラーとして見えます。
一方で、事前チェックをCIに組み込めば、Pull Request段階でポリシー違反を検出する運用もできます。ただし、それはCI側に検査を追加した場合の話です。Policy Controller本体の基本的な判定位置は、Kubernetes APIへの適用時と、既存リソースに対する監査です。
監査モードでは、違反したリソースをただちに拒否するのではなく、クラスタ内にあるリソースがルールに合っているかを検出します。既存クラスタにいきなり強制を入れると影響が大きい場合は、まず監査で違反状況を把握し、その後に強制へ進める使い方ができます。
Policy Controllerの制約自体もKubernetesリソースとして扱えるため、Config Syncで複数クラスタへ配布できます。つまり、Config SyncとPolicy Controllerは競合するものではなく、ポリシーを配る役割とポリシーで判定する役割として組み合わせられます。
Config ConnectorはGoogle CloudリソースをKubernetesから管理する
Config Connectorは、Google CloudリソースをKubernetes経由で管理するためのアドオンです。
Kubernetesには、Custom Resource Definition(CRD)という拡張の仕組みがあります。CRDは、Kubernetes APIに独自のリソース種類を追加するための仕組みです。Config Connectorはこの仕組みを使い、Cloud Storage bucket、Pub/Sub topic、IAM(Identity and Access Management。Google Cloudの権限管理)設定などのGoogle CloudリソースをKubernetesリソースとして表現します。
Config Connectorの中心は、Kubernetesの宣言とGoogle Cloud APIの橋渡しです。KubernetesにConfig Connector用のリソースを作ると、Config ConnectorのコントローラがGoogle Cloud APIを呼び出し、実際のGoogle Cloudリソースを作成・更新・削除します。
flowchart TB Manifest["Kubernetes manifest"] Api["Kubernetes API"] Connector["Config Connector"] Resource["Google Cloudリソース"] Manifest --> Api Api --> Connector Connector -->|"Google Cloud API"| Resource
この図では、利用者がKubernetes manifestを適用し、Config ConnectorがGoogle Cloud APIを通じてGoogle Cloudリソースを管理しています。GKE上のPodを増やす話ではなく、Google Cloud側のリソースをKubernetesの管理モデルに寄せる話です。
具体例: Kubernetes manifestからCloud Storage bucketを作る
たとえば、アプリケーションのログやアップロードファイルを置くCloud Storage bucketを、アプリのKubernetes設定と同じ流れで管理したい場面を考えます。通常はGoogle Cloud Console、gcloud、Terraformなどで作るリソースですが、Config Connectorを使うとKubernetes manifestとして宣言できます。
Cloud Storage bucketは、Config Connectorでは次のような StorageBucket リソースとして表現します。metadata.name はbucket名として使われるため、実際にはグローバルに一意な名前にします。以下は説明用の例です。
apiVersion: storage.cnrm.cloud.google.com/v1beta1
kind: StorageBucket
metadata:
name: example-app-logs-bucket
annotations:
cnrm.cloud.google.com/project-id: example-project-id
spec:
location: ASIA-NORTHEAST1
uniformBucketLevelAccess: true
このmanifestは、「example-project-id というGoogle Cloudプロジェクトに、example-app-logs-bucket というCloud Storage bucketを東京リージョンで作る」という宣言です。Kubernetes上では StorageBucket というリソースを追加する形ですが、実際に作られるものはGoogle Cloud側のCloud Storage bucketです。
このmanifestをKubernetes APIへ適用すると、Config Connectorがそれを監視し、Google Cloud APIを呼び出してCloud Storage bucketを作成します。manifestを変更すればbucket設定の更新、manifestを削除すれば対応するGoogle Cloudリソースの削除、というように、Kubernetesの宣言的な管理モデルでGoogle Cloudリソースを扱います。
注意点は、Google Cloud APIを呼び出す主体です。Config Connectorは、マニフェストを適用した人間ユーザーの権限ではなく、Config Connectorに割り当てたIAM Service Account(Google Cloud上の実行主体)の権限でGoogle Cloudリソースを変更します。そのため、Kubernetes上でConfig Connectorリソースを作れる人は、間接的にGoogle Cloudリソースを変更できることになります。
この性質はCI/CD(継続的インテグレーション/継続的デリバリー)と似ています。Gitリポジトリへマージできる人が、パイプラインの権限で本番へデプロイできるのと同じように、Config Connectorリソースを作れる人は、Config Connectorの権限でGoogle Cloudリソースを変更できます。したがって、Kubernetes RBACやリポジトリのレビュー権限を含めて管理する必要があります。
補足: 同じCloud Storage bucketをTerraformでもConfig Connectorでも作れる
直前のCloud Storage bucketは、Terraformでも作れます。たとえばTerraformでは、同じようなbucketを次のように宣言します。
resource "google_storage_bucket" "app_logs" {
name = "example-app-logs-bucket"
project = "example-project-id"
location = "ASIA-NORTHEAST1"
uniform_bucket_level_access = true
}
つまり、Cloud Storage bucketを作るだけなら、TerraformでもConfig Connectorでも実現できます。違いは、どこに宣言を書き、どの仕組みがGoogle Cloudへ反映するかです。
| 仕組み | 宣言を書く場所 | Google Cloudへ反映する方法 |
|---|---|---|
| Terraform | Terraformファイル | terraform apply を実行して反映する |
| Config Connector | Kubernetes manifest | Kubernetes APIに入ったmanifestをもとに、Config ConnectorのコントローラがGoogle Cloudへ反映する |
Terraformでは、Terraformファイルを変更し、terraform plan や terraform apply を実行してGoogle Cloudリソースへ反映します。そのとき、Terraform state(Terraformが管理対象の現在状態を記録する情報)を使って、どのリソースを作成・更新・削除するかを判断します。
Config Connectorでは、Kubernetes manifestをKubernetes APIへ適用します。Gitで管理している場合、変更の起点はPull Requestのマージです。マージ後にConfig SyncなどでmanifestがKubernetes APIへ入ると、Config ConnectorのコントローラがGoogle Cloudリソースへ反映します。
その後も、Config ConnectorのコントローラはGoogle Cloudリソースの状態を監視し、manifestで宣言した状態へ近づけ続けます。このように現在の状態を望ましい状態へ近づけ続ける制御ループをreconcileと呼びます。
使い分けとしては、そのGoogle Cloudリソースを基盤全体の設定として管理するのか、それともGKEアプリの設定に近いリソースとして管理するのかで考えると分かりやすいです。
| ユースケース | 選びやすい仕組み | 理由 |
|---|---|---|
| VPC、IAM、共有DBなど、複数アプリや環境の土台になるGoogle Cloudリソースを管理したい | Terraform | GKEに限らず、Google Cloud全体のIaC(Infrastructure as Code。インフラ設定をコードで管理する考え方)として使いやすいため |
| GKEアプリを追加・削除するタイミングで、そのアプリ専用のCloud Storage bucketやPub/Sub topicも一緒に作成・削除したい | Config Connector | アプリ用のKubernetesリソースと、アプリ専用のGoogle Cloudリソースを同じKubernetes API上で扱えるため |
| すでにTerraformで基盤管理が安定している | Terraformを継続 | 同じリソースを複数の仕組みで管理すると、どちらが正なのか分かりにくくなるため |
TerraformとConfig Connectorは、どちらか一方だけを使うものとは限りません。TerraformでネットワークやIAMなどの土台を管理し、Config Connectorで特定のGKEアプリ専用のbucketやtopicを管理する、という分け方もできます。
ただし、同じGoogle CloudリソースをTerraformとConfig Connectorの両方で管理しないようにします。どちらの宣言が正なのか分からなくなり、片方で変更した内容をもう片方が戻してしまう、といった混乱につながるためです。
Config Connectorに明確なデメリットがあるというより、管理責任の置き場所が変わる点に注意します。Kubernetes上でConfig Connectorリソースを作れる人が、間接的にGoogle Cloudリソースを変更できるため、Kubernetes RBACやレビュー権限の設計が重要になります。
すでにTerraformでGoogle Cloud基盤を管理しているなら、Config Connectorを無理に置き換えとして見る必要はありません。
3機能を組み合わせると役割分担がはっきりする
3つを組み合わせると、次のような役割分担になります。
flowchart TB
Repo["Gitリポジトリ"]
subgraph Cluster["GKEクラスタ"]
ConfigSync["Config Sync"]
Policy["Policy Controller"]
K8s["Kubernetesリソース"]
Connector["Config Connector"]
end
Cloud["Google Cloudリソース"]
Repo -->|"設定の正"| ConfigSync
ConfigSync -->|"同期"| K8s
Policy -. "判定" .-> K8s
K8s --> Connector
Connector --> Cloud
この図では、Gitリポジトリに置いたKubernetes設定をConfig Syncが同期します。同期された設定は、Policy Controllerのポリシーで監査または強制されます。その中にConfig Connector用のリソースがあれば、Config ConnectorがGoogle Cloudリソースを管理します。
同じGitリポジトリに置けるからといって、3つが同じ役割になるわけではありません。Config Syncは配布、Policy Controllerは判定、Config ConnectorはGoogle Cloud APIへの反映を担当します。
この役割分担を押さえると、設計時の問いも分けやすくなります。
| やりたいこと | 見る仕組み | 理由 |
|---|---|---|
| 複数クラスタのnamespaceやRBACをGitでそろえたい | Config Sync | Kubernetes設定を中央の正から同期するため |
| 危険なPod(Kubernetesでアプリケーションを動かす最小単位)設定や運用ルール違反を止めたい | Policy Controller | Kubernetes APIに入るリソースをポリシーで判定するため |
| Cloud Storage bucketやPub/Sub topicをKubernetes manifestで管理したい | Config Connector | Google CloudリソースをKubernetes API経由で管理するため |
まとめ
- Config Syncは、Gitリポジトリなどを設定の正としてKubernetes設定をGKEクラスタへ同期する
- Policy Controllerは、Kubernetesリソースがポリシーに違反していないかを監査または強制する
- Config Connectorは、Kubernetes APIを通じてGoogle Cloudリソースを管理する
- Config SyncとPolicy Controllerは、ポリシーを配る役割とポリシーで判定する役割として組み合わせられる
- Config ConnectorはGoogle Cloudリソース管理をKubernetes側へ寄せる仕組みであり、既存のTerraform管理を必ず置き換えるものではない
- 3つを混同しそうなときは、配布、判定、Google Cloud APIへの反映のどれをしたいのかで考える