GKEの機密情報を、SecretManagerでリモート管理する
概要
kubernetesには、パスワードなどの機密情報を管理するためのSecretというリソースが用意されているのですが、Secretに保存される情報は、単にBase64でエンコードされたものであり、安全性は高くありません。
そこで、GCPで機密情報を管理するためのストレージサービスであるSecret Managerを使って、機密情報をリモート管理します。
GKEから、SecreteManagerに保存された情報にアクセスするためには、External Secretsを使います。
External Secretsは、クラウドサービスなどの外部から、機密情報を取得し、それをSecretとして保存するkubernetesのリソースです。
External Secrets を使うことで、機密情報をkubernetesの定義ファイル内に直接書く必要がなくなるため、安全性が上がります。
前提
GKEクラスタがある前提です。
標準モードでも、Autopilotモードでも構いません。
手順
Secret Managerに機密情報を保存
まずは、Secret Manager に機密情報を保存します。
今回は、external-secrets-testと言う名前で、中身に適当な文字列を入れます。
サービスアカウントに権限付与
GKEがSecret Managerにアクセスできるように、GKEのノードに紐づくサービスアカウントに、「Secret Manager のシークレットアクセサー」というロールを付与します。
External Secretsを作成
いきなりExternal Secretsオブジェクトを作成することはできません。
なぜなら、External SecretsというリソースがGKEに存在していないからです。
まずは、kubernetesのCustom Resource Definitionという機能を使って、External Secretsというカスタムリソースを作成します。
1. helmのインストール
マニフェストを生成するためにhelmを使用します。
インストール方法は、ググるとたくさん出てきます。
2.git clone
kubernetes-external-secretsにExternal Secretsのためのマニフェストファイルがまとめられているので、git cloneします。
git clone https://github.com/external-secrets/kubernetes-external-secrets
3.マニフェスト生成
helmを使用して、マニフェストを生成します。
helm template --include-crds --output-dir output-dir ./charts/kubernetes-external-secrets/
4.マニフェストapply
kubectl apply -f output-dir/kubernetes-external-secrets -R
これで、External SecretsというカスタムリソースがGKEに作成されました。
External Secretsをデプロイ
以下のようなマニフェストファイルを作成して、External Secretsをデプロイしましょう。
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: example-secret # key name in the k8s secret
spec:
backendType: gcpSecretsManager
data:
- key: external-secrets-test # name of the GCP secret
name: external-secrets-test
kubectl apply -f external-secrets.yaml
これで、SecretManagerに保存した情報が、kubernetesのSecretとして、保存されました。
External Secretsを作ると、Secretとして保存されます。
確認
Secret Managerに保存している情報が取れるか確認します。
$ kubectl get secret example-secret -o=yaml
apiVersion: v1
data:
external-secrets-test: ZjEwaGU3RDM0eGw=
kind: Secret
metadata:
creationTimestamp: "2022-03-18T08:14:23Z"
name: example-secret
namespace: default
ownerReferences:
- apiVersion: kubernetes-client.io/v1
controller: true
kind: ExternalSecret
name: example-secret
uid: 804a71f3-b1db-47e0-a818-91c62eb18cf9
resourceVersion: "341207"
uid: 51be1466-507b-4f33-a143-41075f947f65
type: Opaque
dataに保存された文字列をデコードしてみます。
$ echo ZjEwaGU3RDM0eGw= | base64 --decode
f10he7D34xl
Secret Managerに保存している情報と一致することを確認できました。
参考
Discussion