めもめも

データエンジニアリング、機械学習について書いてます

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と言う名前で、中身に適当な文字列を入れます。 スクリーンショット 2022-03-18 1.15.38.png

サービスアカウントに権限付与

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に保存している情報と一致することを確認できました。

参考

https://github.com/external-secrets