ExternalSecretsでGKEのsecretをSecretManagerで管理してみた
GKEでsecretを使いたいときに,その管理方法に悩む方は多いかと思います.
ここではExternalSecretsを使用したsecretの管理方法についてご紹介いたします.
ExternalSecretsとは
ExternalSecretsはkubernetes clusterにおけるsecretを外部で管理できるソフトウェアツールです.
具体的には,cluster上にExternalSecretsのコントローラを設置することで,外部プロバイダからsecretデータを取得しcluster上にupsertします.
これにより,cluster上のpodは自由にsecretにアクセスすることができます.
ExternalSecretsを使うメリット
secretを外部で管理することでセキュリティ面を考慮しつつバージョニングを行うことができます.
GitHubで管理してしまうと,secretが漏洩してしまう可能性があり,こちらは避けたいところです.
また,cloudサービス上で管理することでconsoleから自由に追加や消去を行うことができるので,利便性も良いのではないかと考えられます.
実際に使ってみる
筆者は,実際にGKEのcluster上にExternalSecretsのコントローラを設置し,同じくGCPサービスであるSecretManagerで管理するsecretをupsertする方法を試してみました.
以下に必要な設定を記載します.
1.Workload Identityの有効化
cluster内のnodeからSecretManagerにアクセスする必要があるため,kubernetesサービスアカウントをGCPサービスアカウントと紐付ける必要があります.
この際に必要になるのが「Workload Identity」という機能です.
clusterのWorkload Identityを有効化するために以下のコマンドを使用します.
gcloud container clusters update $CLUSTER_NAME --workload-pool $PROJECT_NAME.svc.id.goog
また,node poolに対しても修正が必要になります.
gcloud container node-pools update $NODEPOOL_NAME --cluster=$CLUSTER_NAME --workload-metadata=GKE_METADATA
terraformを使用している場合
GKEのresourceにおいて,workload_identity_config.idnetity_namespace
およびnode_pool.node_config.workload_metadata_config
を加えることで有効化することができます.
resource "google_container_cluster" "CLUSTER_NAME" {
workload_identity_config {
identity_namespace = "<PROJECT_NAME>.svc.id.goog"
}
node_pool {
node_config {
workload_metadata_config {
node_metadata = "GKE_METADATA_SERVER"
}
}
}
}
2.manifestファイル生成
kubernetes-external-secretsをcloneします.
cloneしたリポジトリ内に移動し,helmを使用してkubernetesのmanifestファイルのtemplateを生成します.
helm template --output-dir <OUTPUT PATH> ./charts/kubernetes-external-secrets/
3.templateの修正
templateのmetadata等を修正していきます.
主にRELEASE-NAME
となっている項目を修正します.
例えばdeployment.yaml
のmetadata.name
はRELEASE-NAME-kubernetes-external-secrets
となっているので,RELEASE-NAME
の部分を修正します.
本記事ではmy-release-kubernetes-external-secrets
としますが,自由で問題ありません.
rbac.yaml
やserviceaccount.yaml
,service.yaml
も同様に修正します.
4.GSAとKSAの紐付け
GCPサービスアカウントとkubernetesサービスアカウントの紐付けを行います.
この際,1で説明したWorkload Identityの有効化が必要になりますのでご注意ください.
まず,2で生成したserviceaccount.yaml
においてmetadata.annotations
の項目を追加します.
metadata:
annotations:
iam.gke.io/gcp-service-account: <SERVICEACCOUNT_NAME>@<PROJECT_NAME>.iam.gserviceaccount.com
このときのSERVICEACCOUNT_NAME
は紐付けしたいGCPサービスアカウントの名前です.
このGCPサービスアカウントのロールにはsecretmanager.secretAccessor
が必要になります.
次に,serviceaccount.yaml
をGKEへapplyします.
また,bindingを完了するためにgcloudで以下のコマンドを実行します.
gcloud iam service-accounts add-iam-policy-binding \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:<PROJECT_NAME>.svc.id.goog[default/my-release-kubernetes-external-secrets]" \
<SERVICEACCOUNT_NAME>@<PROJECT_NAME>.iam.gserviceaccount.com
5.デプロイ
設定が終わったとこで他のmanifestファイルもapplyします.
これでExternalSecretsの設置は完了なので,実際にsecretをデプロイしてみます.
例えば以下のようなmanifestファイルを作成します.
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: example-secret
spec:
backendType: gcpSecretsManager
region: REGION-NAME
projectId: PROJECT-NAME
data:
- key: example-secret
name: example-secret
これにより,SecretManagerにおけるexample-secretがGKEのsecretとしてupsertされます.
終わりに
最後まで読んで頂きありがとうございました.
実装から時間が空いて記事を書いてしまったため,もし何か違うところがあれば教えていただけるとありがたいです.
また,READMEにAWS SecretManager等を使用する方法も書かれているので,ぜひ参考にしてみてください.
Discussion