🌊

Config Connectorを試してみる

2023/03/14に公開

クラウドエース SRE ディビジョンの松島です。
今回はGKEの追加機能である Config Connector について、調査及び動かしてみた結果を投稿します。

目次

  • Config Connector とは
  • Config Connector でできること
  • Config Connector を試してみる
  • Config Connector の使い所
  • 最後に

Config Connectorとは

Config Connector は、 Kubernetes を使用して Google Cloud リソースをするための Kubernetes アドオンです。

Config Connector でできること

Kubernetes 側の操作で Google Cloud リソースを作成できる

Pod などを作成するのと同じようなマニフェストで Google Cloud リソースを定義し、kubectl applyで作成することができます。
また、作成済みリソースの状態と Kubernetes 上の定義が異なる場合は、自動で Kubernetes 上で定義された状態に修正されます(手動で Google Cloud リソースの設定を変えても強制的にマニフェストで定義した設定に戻される)

既存の Google Cloud リソースを Kubernetes 側の制御下における

新規作成する場合と同じ手順で既存のリソースを指定した場合、そのリソースが Kubernetes 管理となります。
専用のツールで既存のリソースを Config Connector で使用する YAML 形式で出力可能で、それを利用すれば比較的容易に手動作成のリソースを取り込むことが可能となっています。

Config Connector を試してみる

構成概要

アプリケーションの機能として下図のようなものを想定して、構成を組んでみます。
(実際にはアプリケーション本体の実装は行わない)

  • DB として Cloud SQL を利用
  • Pub/Sub にメッセージを公開する
  • Workload Identity を利用して Google Cloud リソースの操作を行う

構成図

構成図内の Google Cloud 側のリソースを Config Connector で下記の通り管理します。

  • Config Connector で作成するもの
    • Pub/Sub トピック及びサブスクリプション
    • サービスアカウント及びIAM
    • Workload Identity の設定
  • 手動で作成して Config Connector 制御にするもの
    • Cloud SQL

構築

0. 下準備

下準備として下記を実施しておきます。(本筋とそれるので詳細は省略します。)

  • GKE クラスタ作成に必要なものを準備
    • VPC 、サブネット、GKE ノードに設定するサービスアカウントなど
  • Cloud SQL作成
    • 後で Config Connector に取り込むため、最初の時点では手動作成しておく

1. GKE クラスタ作成

まずは GKE クラスタを作成します。
この時、下記の操作を行うことで Config Connector を使用可能になります。

  • コンソールの場合は「Config Connector を有効にする」にチェックを入れる
  • コマンドの場合はgcloud オプションで--addons ConfigConnectorを指定する

コンソール有効化画面

ちなみに Config Connector を有効化してクラスタを作成すると、名前空間 cnrm-system に必要な Pod が複数作成されますが、それなりのリソース要求があるのでスペックの低いノードで試す際は注意が必要です。
私の手元では少なくとも2vcpu, メモリ3GBぐらいはないと必要なPodたちが起動しませんでした。

2. ConfigConnector を利用するための設定

こちらの手順に従って、下記の3ステップでConfig Connector を利用するための設定を実施していきます。

  • 3-1. Config Connector 用 Workload Identity の設定
  • 3-2. Config Connector コンポーネントをクラスタにインストール
  • 3-3. Config Connector リソースを作成する namespace の指定
2-1.Config Connector用Workload Identity の設定

まず Config Connector 用サービスアカウントを作成します。

gcloud iam service-accounts create {Config Connector用サービスアカウント名}  --project={プロジェクトID}

作成した Config Connector 用サービスアカウントにプロジェクト編集者権限を付与します。

gcloud projects add-iam-policy-binding {プロジェクトID} \
--member="serviceAccount:{Config Connector用サービスアカウント名}@{プロジェクトID}.iam.gserviceaccount.com" \
--role="roles/editor" \
--project="{プロジェクトID}"

サービス アカウントと、Config Connector が実行する事前定義された Kubernetes サービス アカウントの間の IAM ポリシー バインディングを設定します。

gcloud iam service-accounts add-iam-policy-binding {Config Connector用サービスアカウント名}@{プロジェクトID}.iam.gserviceaccount.com \
--member="serviceAccount:{プロジェクトID}.svc.id.goog[cnrm-system/cnrm-controller-manager]" \
--role="roles/iam.workloadIdentityUser" \
--project="{プロジェクトID}"
2-2.Config Connector コンポーネントをクラスタにインストール

下記の通り config_connector.yaml を作成し、kubectl apply -f config_connector.yamlを実行します。

config_connector.yaml
apiVersion: core.cnrm.cloud.google.com/v1beta1
kind: ConfigConnector
metadata:
  # the name is restricted to ensure that there is only one
  # ConfigConnector resource installed in your cluster
  name: configconnector.core.cnrm.cloud.google.com
spec:
 mode: cluster
 googleServiceAccount: "{Config Connector用サービスアカウント名}@{プロジェクトID}.iam.gserviceaccount.com"

すると必要なコンポーネントたちが起動します。

Workload
Workload

Serivce
Service

2-3.Config Connector リソースを作成するnamespace の指定

namespace に Google Cloud のプロジェクトを紐づけることで、リソースを作成するプロジェクトを指定します。
下記のとおり config_connector_ns.yaml を作成し、kubectl apply -fを実行します。

config_connector_ns.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: {プロジェクトを紐付けるnamespace名}
  annotations:
    cnrm.cloud.google.com/project-id: "{プロジェクトID}"

3. リソースの構築

3-1. リソース構築

下記のマニフェストたちをkubectl applyすると対象リソースが作成されます。
xxxRefという名前のプロパティが含まれていますが、Config Connector ではこの値によってリース間の依存関係を決定し、依存先のリソースの作成を待ってから対象のリソースを作成するような制御が行われます。

pubsub.yaml
apiVersion: pubsub.cnrm.cloud.google.com/v1beta1
kind: PubSubTopic
metadata:
  name: test-topic
  namespace: {プロジェクトを紐付けたnamespace名}
---
apiVersion: pubsub.cnrm.cloud.google.com/v1beta1
kind: PubSubSubscription
metadata:
  name: test-subscription
  namespace: {プロジェクトを紐付けたnamespace名}
spec:
  ackDeadlineSeconds: 15
  messageRetentionDuration: 86400s
  retainAckedMessages: false
  topicRef: # 紐付け先のトピックを指定
    name: test-topic
serviceaccount.yaml
# Pod 用 Kubernetes サービスアカウント
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {Kubernetes サービスアカウント名}
  namespace: {プロジェクトを紐付けたnamespace名}
  annotations:
    iam.gke.io/gcp-service-account: {Google Cloud サービスアカウント名}@{プロジェクトID}.iam.gserviceaccount.com
---
# Pod 用 Google Cloud サービスアカウント
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMServiceAccount
metadata:
  name: gsa-for-app
  namespace: {プロジェクトを紐付けたnamespace名}
spec:
  displayName: {Google Cloud サービスアカウント名}
---
# KSA と GSA のバインディング
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicy
metadata:
  name: iampolicy-workload-identity
  namespace: {プロジェクトを紐付けたnamespace名}
spec:
  resourceRef: # 権限付与先のリソースを指定
    apiVersion: iam.cnrm.cloud.google.com/v1beta1
    kind: IAMServiceAccount
    name: gsa-for-app
  bindings:
    - role: roles/iam.workloadIdentityUser
      members:
        - serviceAccount:{プロジェクトID}.svc.id.goog[{プロジェクトを紐付けたnamespace名}/{Kubernetes サービスアカウント名}]
---
# Pub/Sub メッセージパブリッシュ権限
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicy
metadata:
  name: gsa-for-app-pubusub-role
  namespace: {プロジェクトを紐付けたnamespace名}
spec:
  resourceRef: # 権限付与先のリソースを指定
    apiVersion: pubsub.cnrm.cloud.google.com/v1beta1
    kind: PubSubTopic
    name: test-topic
  bindings:
    - role: roles/pubsub.publisher
      members:
        - serviceAccount:{Google Cloudサービスアカウント名}@{プロジェクトID}.iam.gserviceaccount.com
3-3. Cloud SQL のインポート

Cloud SQL は既に手動構築済なので、公式ドキュメントに記載の手順でリソースをインポートして GKE 支配下に置きます。

まずは必要なツールをローカルにインストールします(M1 mac の場合の手順なので、適宜読み替えてください)。

gsutil cp gs://cnrm/latest/cli.tar.gz .
tar zxf cli.tar.gz
sudo mv darwin/arm64/config-connector /usr/local/bin # 利用するファイルは実行環境に合わせて変更

次に手動作成した CloudSQL の情報をyamlファイルとして取得します。
下記の通りリソースのフルネームを指定してconfig-connector exportコマンドを実行すると、対象リソースを Config Connector でそのまま使用できるyaml形式で出力してくれるので、中身を cloud_sql.yaml にリダイレクトしてyamlファイルを作成します。

config-connector export //sqladmin.googleapis.com/sql/v1beta4/projects/{プロジェクト名}/instances/{Cloud SQLインスタンス名} > cloud_sql.yaml

このままだと namespace が指定されていないので、yamlファイルに2-3でプロジェクトと紐付けた namespace を書き足してプロジェクトを指定します。

cloud_sql.yaml
apiVersion: sql.cnrm.cloud.google.com/v1beta1
kind: SQLInstance
metadata:
  annotations:
    cnrm.cloud.google.com/project-id: {プロジェクトID}
  name: {Cloud SQLインスタンス名}
  namespace: {2-3で作成したnamespaceを指定} # これを書き足す
  ...

最後に cloud_sql.yaml をkubectl applyすれば手動作成した CloudSQL が Config Connector 配下に入ります。

4. 完了

これで目標リソースの作成及び、リソースを Config Connector 管理とする作業が完了しました。

Config Connector の使い所

Config Connector の使い所を考えてみます。

1. Google Cloudの構成管理ツールとして使う

Terraform と同じように構成管理ツールとしてに使用する、というのがぱっと思いつく使い方です。
ただし、今回試してみた範囲だと Config Connector が Terraform に比べて圧倒的に優れているとも考えにくく、GKE を使わないプロジェクトであえてこちらを使用する理由は薄いと思われます。
あくまで GKE を使用する場合の選択肢の一つとするのが妥当と考えます。

2. アプリケーション + Google Cloud リソースをパッケージ化して複製する

アプリケーション本体用の Deployment や Service と合わせて周辺の Google Cloud リソースをマニフェストで定義し、helmなど でパッケージ化しておくと、環境複製が楽になるかと思います。

最後に

本記事では Config Connector の機能紹介と簡単なハンズオンを実施しました。
その他こんな使い方もあるよ、などあればぜひ教えていただければと思います。

参考

Discussion