k8s Secretとは?設定例とセキュリティ対策

Kubernetes Secret徹底解説:設定例とセキュリティ対策

Kubernetes(以下、k8s)におけるSecretは、パスワード、APIキー、証明書などの機密情報を安全に管理するためのオブジェクトです。Podの定義ファイルやイメージに直接機密情報を記述する代わりに、Secretオブジェクトに格納し、必要な時にPodから参照することで、セキュリティリスクを軽減し、機密情報の管理を効率化します。本記事では、k8s Secretの基本的な概念から、具体的な設定例、セキュリティ対策までを詳細に解説します。

1. Secretとは

k8s Secretは、機密情報を安全に格納し、Podに提供するためのオブジェクトです。具体的には、以下のような情報を格納するために使用されます。

  • パスワード: データベース、外部サービス、APIのエンドポイントなどにアクセスするための認証情報。
  • APIキー: 外部サービスやAPIを利用するための認証トークン。
  • 証明書: TLS/SSL通信を確立するための証明書と秘密鍵。
  • その他機密情報: 設定ファイル、SSHキー、暗号化キーなど、アプリケーションの動作に必要な機密性の高い情報。

1.1 Secretの重要性

Secretを使用する主な理由は以下の通りです。

  • セキュリティ向上: Podの定義ファイルやイメージに機密情報を記述することを避け、ソースコードリポジトリに機密情報が漏洩するリスクを軽減します。
  • 機密情報の集中管理: 機密情報をSecretオブジェクトとして一元的に管理することで、管理の手間を軽減し、機密情報の更新やローテーションを容易にします。
  • アクセス制御: SecretオブジェクトへのアクセスをRBAC(Role-Based Access Control)で制御することで、承認されたユーザーやサービスアカウントのみが機密情報にアクセスできるように制限します。
  • Podの可搬性向上: Podの定義ファイルから機密情報を分離することで、Podを異なる環境に簡単にデプロイできます。
  • 監査可能性: Secretオブジェクトの作成、更新、削除などの操作は、k8sの監査ログに記録されるため、機密情報の利用状況を追跡できます。

1.2 Secretの種類

k8sには、いくつかの組み込みのSecretタイプがあります。

  • Opaque: 最も一般的なSecretタイプで、任意の形式の機密情報を格納できます。Base64エンコードされたkey-valueペアとしてデータを格納します。
  • kubernetes.io/dockerconfigjson: Dockerレジストリへの認証情報を格納するためのSecretタイプ。.dockerconfigjsonファイルの内容を格納します。
  • kubernetes.io/service-account-token: サービスアカウントに関連付けられたトークンを格納するためのSecretタイプ。Podがk8s APIサーバーにアクセスするために使用されます。
  • kubernetes.io/tls: TLS/SSL証明書と秘密鍵を格納するためのSecretタイプ。TLS/SSL通信を確立するために使用されます。
  • bootstrap.kubernetes.io/token: ノードのブートストラップに使用されるトークンを格納するためのSecretタイプ。

これらのSecretタイプに加えて、カスタムSecretタイプを定義することも可能です。

2. Secretの設定方法

Secretを設定するには、kubectlコマンドラインツールまたはYAMLファイルを使用します。

2.1 kubectlコマンドによるSecret作成

kubectl create secretコマンドを使用して、コマンドラインからSecretを作成できます。

bash
kubectl create secret generic my-secret \
--from-literal=username=admin \
--from-literal=password=secretpassword

このコマンドは、my-secretという名前のOpaqueタイプのSecretを作成し、usernamepasswordという2つのkey-valueペアを格納します。--from-literalオプションは、コマンドラインから直接値を指定するために使用されます。

別の方法として、ファイルからSecretを作成することもできます。

bash
kubectl create secret generic my-secret \
--from-file=username=./username.txt \
--from-file=password=./password.txt

このコマンドは、username.txtファイルとpassword.txtファイルの内容をそれぞれusernamepasswordというキーに対応する値として格納します。

2.2 YAMLファイルによるSecret作成

YAMLファイルを使用してSecretを定義することもできます。

yaml
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
username: YWRtaW4=
password: c2VjcmV0cGFzc3dvcmQ=

このYAMLファイルは、my-secretという名前のOpaqueタイプのSecretを定義し、usernamepasswordという2つのkey-valueペアを格納します。dataフィールドには、Base64エンコードされた値が含まれていることに注意してください。

YAMLファイルを使用してSecretを作成するには、kubectl applyコマンドを使用します。

bash
kubectl apply -f my-secret.yaml

2.3 Dockerconfigjson Secretの作成

Dockerレジストリへの認証情報を格納するためのkubernetes.io/dockerconfigjsonタイプのSecretを作成するには、.dockerconfigjsonファイルが必要です。

bash
kubectl create secret docker-registry my-docker-secret \
--docker-server=YOUR_REGISTRY_SERVER \
--docker-username=YOUR_USERNAME \
--docker-password=YOUR_PASSWORD \
--docker-email=YOUR_EMAIL

このコマンドは、my-docker-secretという名前のkubernetes.io/dockerconfigjsonタイプのSecretを作成し、指定されたDockerレジストリの認証情報を格納します。

2.4 TLS Secretの作成

TLS/SSL証明書と秘密鍵を格納するためのkubernetes.io/tlsタイプのSecretを作成するには、証明書ファイルと秘密鍵ファイルが必要です。

bash
kubectl create secret tls my-tls-secret \
--cert=path/to/tls.crt \
--key=path/to/tls.key

このコマンドは、my-tls-secretという名前のkubernetes.io/tlsタイプのSecretを作成し、指定された証明書と秘密鍵を格納します。

3. Secretの使用方法

Secretを作成したら、Podで使用できます。SecretをPodで使用する方法はいくつかあります。

  • 環境変数として: Secretの値をPodの環境変数として設定します。
  • ボリュームとして: Secretの内容をPodのファイルシステムにマウントします。
  • イメージプルシークレットとして: Dockerレジストリからイメージをプルするための認証情報として使用します。

3.1 環境変数としてSecretを使用する

Secretの値をPodの環境変数として設定するには、Podの定義ファイルでenvフィールドを使用します。

yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: my-secret
key: username
- name: PASSWORD
valueFrom:
secretKeyRef:
name: my-secret
key: password

この例では、my-podという名前のPodのmy-containerという名前のコンテナに対して、USERNAMEPASSWORDという2つの環境変数を設定しています。valueFromフィールドを使用して、my-secretという名前のSecretからそれぞれの値を取得しています。secretKeyRefフィールドは、Secretの名前と、環境変数の値として使用するSecret内のキーを指定します。

3.2 ボリュームとしてSecretを使用する

Secretの内容をPodのファイルシステムにマウントするには、Podの定義ファイルでvolumesvolumeMountsフィールドを使用します。

yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: my-secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: my-secret-volume
secret:
secretName: my-secret

この例では、my-podという名前のPodのmy-containerという名前のコンテナに対して、my-secret-volumeという名前のボリュームを/etc/secretsディレクトリにマウントしています。volumesフィールドで、my-secret-volumeという名前のボリュームを定義し、secretフィールドを使用して、my-secretという名前のSecretを参照しています。readOnly: trueを指定することで、コンテナがSecretの内容を変更できないようにしています。

Secretをボリュームとしてマウントすると、Secret内の各key-valueペアが、マウントされたディレクトリ内のファイルとして表現されます。例えば、my-secret Secretにusernamepasswordという2つのキーが含まれている場合、/etc/secretsディレクトリには、usernameファイルとpasswordファイルが作成されます。

3.3 イメージプルシークレットとしてSecretを使用する

Dockerレジストリからイメージをプルするための認証情報としてSecretを使用するには、Podの定義ファイルでimagePullSecretsフィールドを使用します。

yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: your-registry/your-image:latest
imagePullSecrets:
- name: my-docker-secret

この例では、my-podという名前のPodは、your-registry/your-image:latestというイメージをプルするために、my-docker-secretという名前のSecretを使用します。imagePullSecretsフィールドは、イメージをプルするために使用するSecretの名前を指定します。

4. Secretのセキュリティ対策

Secretには機密情報が含まれているため、適切なセキュリティ対策を講じることが重要です。

4.1 RBACによるアクセス制御

RBAC(Role-Based Access Control)を使用して、Secretオブジェクトへのアクセスを制御します。承認されたユーザーやサービスアカウントのみがSecretを作成、更新、削除、および参照できるように制限します。

RoleとRoleBindingを使用して、特定のネームスペース内のSecretに対するアクセス権を定義できます。ClusterRoleとClusterRoleBindingを使用して、クラスター全体のSecretに対するアクセス権を定義できます。

例えば、以下のRoleは、my-namespaceネームスペース内のすべてのSecretに対する読み取りアクセス権を付与します。

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: secret-reader
namespace: my-namespace
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch"]

以下のRoleBindingは、my-service-accountという名前のサービスアカウントに、上記のRoleを割り当てます。

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: secret-reader-binding
namespace: my-namespace
subjects:
- kind: ServiceAccount
name: my-service-account
namespace: my-namespace
roleRef:
kind: Role
name: secret-reader
apiGroup: rbac.authorization.k8s.io

4.2 暗号化された保存

k8s APIサーバーは、etcdという分散キーバリューストアにすべてのクラスタデータを格納します。デフォルトでは、etcdに格納されたSecretは暗号化されていません。そのため、etcdへのアクセス権を持つ人は誰でもSecretの内容を読み取ることができます。

Secretを安全に保管するために、etcdに格納されるSecretを暗号化することをお勧めします。k8sでは、Encryption Configurationを使用して、etcdに格納されるSecretを暗号化できます。

Encryption Configurationファイルは、暗号化プロバイダーと暗号化キーを指定します。k8sは、Encryption Configurationファイルに基づいて、etcdに格納されるSecretを自動的に暗号化および復号化します。

4.3 Secretのローテーション

Secretの内容は定期的にローテーションすることをお勧めします。Secretのローテーションは、セキュリティ侵害が発生した場合の影響を軽減し、機密情報の有効期間を制限します。

Secretのローテーションは、手動で行うことも、自動化することもできます。手動でSecretをローテーションするには、新しいSecretを作成し、古いSecretを使用しているPodを更新します。自動化されたSecretローテーションには、Sealed Secrets、HashiCorp Vaultなどのツールを使用できます。

4.4 Secretの監査

k8sの監査ログを有効にして、Secretの作成、更新、削除などの操作を追跡します。監査ログを分析することで、Secretへの不正アクセスや不正使用を検出できます。

4.5 Secretの最小権限の原則

Podに必要なSecretのみを提供し、不要なSecretへのアクセスを制限します。最小権限の原則に従うことで、セキュリティ侵害が発生した場合の影響を軽減できます。

4.6 Sealed Secretsによる安全な保管

Sealed Secretsは、Secretを暗号化し、GitHubなどのパブリックリポジトリに安全に保管できるようにするk8sコントローラーです。Sealed Secretsを使用すると、機密情報をソースコードリポジトリにコミットするリスクを軽減できます。

Sealed Secretsは、マスター公開鍵とマスター秘密鍵を使用してSecretを暗号化します。マスター公開鍵は誰でも利用できますが、マスター秘密鍵はクラスター管理者のみがアクセスできます。Sealed Secretsコントローラーは、マスター秘密鍵を使用して、クラスターにデプロイされたSecretを復号化します。

4.7 HashiCorp Vaultとの連携

HashiCorp Vaultは、機密情報を安全に保管、アクセス、および配布するためのツールです。k8sとHashiCorp Vaultを連携させることで、SecretをVaultに保管し、PodからVaultにアクセスしてSecretを取得できます。

Vaultには、アクセス制御、監査、ローテーションなどの機能が組み込まれており、Secretのセキュリティを向上させることができます。

5. まとめ

k8s Secretは、パスワード、APIキー、証明書などの機密情報を安全に管理するための重要なオブジェクトです。Secretを使用することで、セキュリティリスクを軽減し、機密情報の管理を効率化できます。

本記事では、k8s Secretの基本的な概念から、具体的な設定例、セキュリティ対策までを詳細に解説しました。これらの情報を活用して、安全で効率的なk8s環境を構築してください。

今後の学習

  • Secret Generator: Secretを自動的に生成する仕組みを理解する。
  • External Secrets Operator: 外部のSecret管理システム(AWS Secrets Manager、Azure Key Vaultなど)と連携する。
  • Kustomize: Secretを含むYAMLファイルをカスタマイズする。
  • Helm: SecretをHelmチャートで管理する。

これらのトピックを学ぶことで、k8s Secretの理解をさらに深め、より高度なセキュリティ対策を講じることができます。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール