#はじめに
セゾン情報システムズ Advent Calendar 2020
2日目を担当させていただきます。よろしくお願いいたします!
本記事では、以下を使用することで、機密情報をマニフェストファイルに記載することなく安全に管理する方法を紹介いたします。
-
Amazon EKS
AWS で Kubernetes を簡単に実行できるマネージド型の Kubernetes サービス
https://aws.amazon.com/jp/eks/ -
ExternalSecret
kubernetesのSecretを安全に管理するためのオープンソースソフトウェア
https://github.com/external-secrets/kubernetes-external-secrets -
AWS Secrets Manager
秘匿情報をAWS上に保管し、APIコールで取得できるサービス
https://aws.amazon.com/jp/secrets-manager/
#概要
kubernetes上に作成されたExternalSecretリソースが、外部のSecretManagerに登録されている情報を読み取り、Secretリソースを作成します。
Secretリソースとして登録するKey名と、外部のSecretManagerに登録されているデータの参照情報で秘匿情報を取得できるため、
機密情報をマニフェストファイルに記載する必要はありません!
#手順
AWS Secrets Managerに登録されている秘匿情報を取得する手順を記載いたします。
##サービスアカウントへのIAM権限付与設定
AWSリソースへアクセスするための権限をpod単位で付与したかったので、「IAM Roles for Service Accounts」の仕組みを使用
###IAM IDプロバイダ作成
Kubernetes サービスアカウントでIAMロールの権限を使用するために、まずは以下のコマンドでOIDC IDプロバイダを作成
eksctl utils associate-iam-oidc-provider --cluster {CLUSTER_NAME} --approve --region ap-northeast-1
###IAMロール作成
既存のAWSのポリシーに「SecretsManagerReadWrite」があるので、そのポリシーを付与したIAMロールを作成し、
上記で作成したOIDC IDプロバイダのIDを信頼関係に設定
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::{AWS_ACCOUNT_ID}:oidc-provider/oidc.eks.ap-northeast-1.amazonaws.com/id/{PROVIDER_ID}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.ap-northeast-1.amazonaws.com/id/{PROVIDER_ID}:aud": "sts.amazonaws.com"
},
"StringLike": {
"oidc.eks.ap-northeast-1.amazonaws.com/id/{PROVIDER_ID}:sub": "system:serviceaccount:default:*"
}
}
}
]
}
※「*」を使用する場合は、「StringEquals」ではなく「StringLike」を使用する必要あり!
##AWS Secrets Managerで秘匿情報登録
e.g.
シークレット名:test-credentials
値:{"username":"admin","password":"admin123"}
以下のようにAWS CLIで作成
aws secretsmanager create-secret --region ap-northeast-1 --name test-credentials --secret-string '{"username":"admin","password":"admin123"}'
##ExternalSecretリソース作成
helmでExternalSecretのリポジトリを追加
(リポジトリは最近移動したらしい -> 関連記事)
helm repo add external-secrets https://external-secrets.github.io/kubernetes-external-secrets/
helm installでExternalSecretリソースを作成
helm install {RELEASE_NAME} external-secrets/kubernetes-external-secrets --skip-crds \
--set securityContext.fsGroup=65534 \
--set nodeSelector."alpha\.eksctl\.io/nodegroup-name"={NODE_GROUP_NAME} \
--set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"='arn:aws:iam::{AWS_ACCOUNT_ID}:role/{ROLE_NAME}' \
--set env.AWS_REGION='ap-northeast-1' \
--set env.AWS_DEFAULT_REGION='ap-northeast-1'
securityContext.fsGroup=65534 :
シークレット情報にアクセスするためのtokenファイルに、rootユーザー以外のユーザーがアクセスできるようにするための設定
(起動したpodのユーザーはrootではないため必要な設定)
nodeSelector :
指定したNodeにpodを起動させたかったので設定
serviceAccount.annotations :
サービスアカウントでIAMロールの権限を使用するための設定、上記で作成したIAMロールを指定
その他オプション等については以下参照
https://artifacthub.io/packages/helm/external-secrets/kubernetes-external-secrets
##Secret Managerから秘匿情報取得
以下のyamlをkubectlでapply
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: test-external-secret
spec:
backendType: secretsManager
data:
- key: test-credentials #SecretManagerのシークレット名
name: username #変数名
property: username #取得したい値のキー
$ kubeclt apply -f externalSecret.yaml
$ kubectl get externalsecret
NAME LAST SYNC STATUS AGE
test-external-secret 2s SUCCESS 34h
以下のコマンドで取得した秘匿情報の確認も可能
↓結果抜粋↓(値はbase64でエンコードされてます)
$ kubectl get secret test-external-secret -o yaml
data:
username: YWRtaW4K
password: YWRtaW4xMjMK
:
上記の秘匿情報を使用する場合は以下のようにyamlに環境変数を定義することで使用可能
env:
- name: TEST_VALUE
valueFrom:
secretKeyRef:
name: test-external-secret #ExternalSecretのmetadata.name
key: username #ExternalSecretのspec.data.name