Kubernetes の Secret リソースでマニフェストで作成するとき、Secret として秘匿したいデータを Base 64 でエンコードして指定します。
ただ、Base 64は単なるエンコードなので、そのままでマニフェストを保存することは、セキュリティ上避けたいですよね。そのため、Secret のデータの暗号化や復号を行う kubesec や SealedSecrets などのツールが提供されています。
これまで「kubesecとか使えば暗号化や復号はできるよね」と頭でしか理解してなかったんですが、kubesec を実際に触ってみようと思い立ったので、そのときのメモをここに書いておきたいと思います。
なお、今回は 下図のように AWS KMS のキーを使用して暗号化・復号する前提とします。
目次
1. AWS KMS のキーの作成
今回、暗号化や復号に必要なキーを AWS KMS を使用して生成しますので、AWS KMSにアクセスできるようにする必要があります。そのため、使用しているAWS IAM のユーザーまたはロールに、AWS IAM のポリシーを設定します。
今回は、使用している AWS IAM のユーザーに AWSKeyManagementServicePowerUser という管理ポリシーを設定する前提としますが、実際に使用する際は最小権限の原則に基づいて設定して下さい。
AWS KMS を操作する上での AWS IAM のポリシーについては次のドキュメントに例があるので参考にしましょう。
AWS KMS キーの作成は AWS マネジメントコンソールからでも行えますが、今回は AWS CLI のコマンドで作成してみます。
aws kms create-key --description "demo for kubesec"
--description
オプションで指定する文字列の値は任意です。
キー作成が完了すると、次のような 出力が表示されるので、この中の Arn の値をメモしておきましょう。
{ "KeyMetadata": { "AWSAccountId": "000000000000", "KeyId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "Arn": "arn:aws:kms:ap-northeast-1:000000000000:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "CreationDate": "2023-03-25T09:31:57.061000+00:00", "Enabled": true, "Description": "demo for kubesec", "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "Enabled", "Origin": "AWS_KMS", "KeyManager": "CUSTOMER", "CustomerMasterKeySpec": "SYMMETRIC_DEFAULT", "KeySpec": "SYMMETRIC_DEFAULT", "EncryptionAlgorithms": [ "SYMMETRIC_DEFAULT" ], "MultiRegion": false } }
2. kubesec のインストール
kubesec のインストール方法などについては、下記を参考にしました。
今回は Linux の環境にインストールしますので、次のコマンドを実行します。
curl -sSL https://github.com/shyiko/kubesec/releases/download/0.9.2/kubesec-0.9.2-linux-amd64 \ -o kubesec && chmod a+x kubesec && sudo mv kubesec /usr/local/bin/
その後、確認のため次のコマンドを実行します。
kubesec --version
0.9.2
のようにバージョン ID が出力されれば OK です。
3. Secret のマニフェストの暗号化
ではいよいよ、Secret のマニフェストを暗号化してみます。
今回は、次の内容を secret.yaml として保存して使用します。
apiVersion: v1 kind: Secret metadata: name: my-secret type: Opaque data: username: YWRtaW4= password: YWRtaW4xMjM0
kubesec で AWS KMS のキーを使用して暗号化するときは、--key
オプションに キーの ARN を指定します。
次の例では、secret.yaml を暗号化したマニフェストを 標準出力 に表示します。
kubesec encrypt --key=aws:<ARN of AWS KMS key> secret.yaml
実行すると次のような内容が表示されます。
apiVersion: v1 data: password: (暗号化された値) username: (暗号化された値) kind: Secret metadata: name: my-secret type: Opaque # kubesec:v:3 # kubesec:aws:arn:aws:kms:ap-northeast-1:0000000000001:key/xxxxx # kubesec:mac:xxxxx
data:
以下の username
や password
の値が暗号化されていることを確認できました。
また、-i
オプションを付けると、指定したマニフェストファイルに暗号化した値を直接変更します。
kubesec encrypt -i --key=aws:<ARN of AWS KMS key> secret.yaml
上記を実行すると、secret.yaml の data:
以下の username
や password
の値が直接変更されたことが確認できます。
4. Secret のマニフェストの復号
暗号化されたマニフェストを復号する場合は、decrypt
を使用します。
次の例では、暗号化されている secret.yaml を復号して標準出力に表示します。
kubesec decrypt secret.yaml
実行すると次のような内容が表示されます。
apiVersion: v1 data: password: YWRtaW4xMjM0 username: YWRtaW4= kind: Secret metadata: name: my-secret type: Opaque
また、暗号化と同じように -i
オプションを付けると、暗号化されたファイルに復号した値を直接変更します。
kubesec decrypt -i secret.yaml
上記を実行すると、暗号化された secret.yaml の data:
以下の username
や password
の値が直接変更されたことが確認できます。
5.今回の所感
kubesec と AWS KMS のキーを使用して Secret の値を暗号化・復号する仕組み自体は、とてもシンプルです。
GitOps のように Kubernetes のマニフェストを Git リポジトリに保存・管理してデプロイする場合は、Secret は kubesec のようなツールを使い、暗号化して保存し、Kubernetes クラスタに適用する際に自動的に復号するような仕組みを考えたいと思いました。
一方で、AWS KMS のキーの権限の管理は厳格に行う必要があります。キーを作成できる権限、キーを使用して暗号化・復号できる権限などは IAMのユーザーまたはロールごとに最小権限の原則に基づいて設定する必要があるので、その管理や運用を漏れなく実施する必要性を強く感じました。
今回は 暗号化・復号のツールとして kubesec を使ってみましたが、他にも SealedSecrets といった便利なツールもあるので、また別の機会に触ってみたいです!