はじめに
kubernetes には機密情報を管理する手段として Secret リソースが存在しますが、
base64エンコードされたデータを manifest に記載する必要があり、
デコードが容易な点からコードリポジトリで管理することがセキュリティ上好ましくありません。
この問題に対し、GoDaddy社製のkubernetes-external-secretsというツールを使用しており
ExternalSecret リソースを定義することで、AWS SecretsManager (以下 SecretsManager) で管理する機密情報を Kubernetes の Secret リソースに格納することが可能となります。 1
external-secrets を使った運用で懸念されたこと
external-secrets はデフォルト設定では 10000ms(10s) 間隔で SecretsManager を polling し、
機密情報に変更があった場合 Secret リソースを 更新します。
Pod のコンテナイメージ と Secrets を同時に更新する必要がある場合、
Deployment のコンテナイメージ更新で実施される rollout restart タイミングと、Secret リソース更新タイミングを合わせることが難しいと懸念されました。
そこで、external-secrets の Secret リソース更新を任意のタイミングで実施できないか調査しました。
その方法について記載します。
任意のタイミングで Secrets を更新する方法
polling を disable にする
external-secrets コントローラーの Deployment リソースの env にDISABLE_POLLING: true
を追加します。
これによって polling が停止します。
※ true
は任意の値でよい
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-secrets
labels:
app.kubernetes.io/name: external-secrets
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: external-secrets
template:
metadata:
labels:
app.kubernetes.io/name: external-secrets
spec:
serviceAccountName: external-secrets
containers:
- name: external-secrets
image: "godaddy/kubernetes-external-secrets:latest"
imagePullPolicy: IfNotPresent
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
env:
- name: "AWS_REGION"
value: "ap-northeast-1"
- name: "DISABLE_POLLING"
value: "true"
ExternalSecret リソースの annotation を更新する
Secret リソースを更新したい場合
ExternalSecret リソースの spec.template.metadata.annotations
に適当な key-value を追加・上書きします。
annotations が更新されると external-secrets は1度だけ SecretsManager に polling を行い
変更があった場合 Secret リソースを 更新します。
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: secrets
spec:
backendType: secretsManager
data:
- key: SecretsManager_key
name: sample_secret
template:
metadata:
annotations:
timestamp: "202006181000"
結果
上記の方法で任意のタイミングで Secrets リソース更新することができます。
external-secrets をこの運用に変え
イメージを更新した Deployment と annotation を更新した ExternalSecret の manifest を同時に apply することで
Deployment のコンテナイメージ更新で実施される rollout restart タイミングと、Secret リソース更新タイミングを合わせることができます。
ただし、external-secrets の Secret リソース更新が何かしらの理由で遅延するなどした場合
更新前の Secret で Pod が起動してしまう可能性はありえると考えております。
このあたりは他により良い方法がないか、引き続き考えていこうと思っています。
(external-secrets に限らず、この問題に対し良い方法をご存知の方がおりましたらコメントいただけますと幸いです。)
まとめ
external-secrets を使い任意のタイミングで Secret リソースを更新する方法を共有しました。
この方法を使うことで、Pod のコンテナイメージ と Secrets を ほぼ 同時に更新することができます。
external-secrets は簡単に機密情報管理サービスから kubernetes に機密情報を注入できます。
GCP や Alibaba Cloud をサポートするなど活発に更新が行われていますので
ご興味ありましたら一度お試しください。