ack-secret-manager は、CloudOps Orchestration Service (OOS) から暗号化パラメーターを取得し、ACK クラスター内に Kubernetes Secrets として同期します。アプリケーションは、これらの Secrets をファイルシステムからマウントするか、環境変数として参照することで、手動介入なしに OOS 暗号化パラメーターを最新の状態に保つことができます。
セキュリティに関する注意事項
シークレットの同期を有効化する前に、以下のリスクを評価してください。
ファイルシステムへの露出:ファイルシステムからシークレットを読み取るアプリケーションは、攻撃者が CVE 脆弱性を悪用してクラスター内のディレクトリを走査した場合、シークレットを漏洩させる可能性があります。
環境変数による漏洩:環境変数経由でシークレットを参照することは、デバッグブレークポイントやログ権限の設定ミスなどにより不適切な動作を引き起こす可能性があるため、セキュリティ上推奨されません。この方法は避けてください。
過剰なアクセス権限:シークレットの同期時に付与されるアクセス権限は、最小権限の原則に従い、必要最低限に制限してください。
アプリケーションでシークレットを永続化する必要がない場合は、RRSA を使用して最小限の権限で Pod に権限を付与する方法を採用し、その後、GetSecretParameter API を直接呼び出します。これにより、Pod ファイルシステムや Kubernetes Secrets 内で暗号化パラメーターが公開されるのを回避できます。
前提条件
開始する前に、以下の条件を満たしていることを確認してください。
OOS サービスと同じリージョンに ACK クラスターが存在すること。対応するクラスタータイプ:ACK マネージドクラスター、ACK 専用クラスター、登録済みクラスター、ACK Serverless クラスター。詳細については、「ACK マネージドクラスターの作成」「ACK One 登録済みクラスターの作成」「ACK Serverless クラスターの作成」をご参照ください。
OOS 暗号化パラメーターが存在すること。詳細については、「暗号化パラメーターの作成」および「CreateSecretParameter」をご参照ください。
クラスターの kubeconfig ファイルおよび正常に動作する
kubectl接続が利用可能であること。詳細については、「クラスターの kubeconfig を取得し、kubectl を使用してクラスターに接続」をご参照ください。
仕組み
ack-secret-manager は、OOS 暗号化パラメーターをクラスターに同期するために、以下の 2 つのカスタムリソースを使用します。
SecretStore — OOS への認証およびアクセス方法を指定
ExternalSecret — OOS からフェッチする対象および同期先となる Kubernetes Secret を指定
設定後、ack-secret-manager は設定された間隔で OOS に対してポーリングを行い、対象の Kubernetes Secret を最新の状態に保ちます。
ステップ 1:ack-secret-manager のインストール
ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスター] ページで、管理対象のクラスター名をクリックします。クラスターの詳細ページ左側のペインで、[アプリケーション] > [Helm] を選択します。
[Helm] ページで、[デプロイ] をクリックします。[チャート] セクションの [デプロイ] パネルで、[ack-secret-manager] を検索・選択し、[次へ] をクリックします。デフォルトでは、ack-secret-manager は
kube-system名前空間にインストールされます。カスタムのアプリケーション名または名前空間を使用する場合は、[アプリケーション名] および [名前空間] を [基本情報] ステップで設定してください。[パラメーター] ステップで、最新のチャートバージョンを選択し、必要に応じて以下のパラメーターを設定して、[OK] をクリックします。インストール完了後、ack-secret-manager ページにリダイレクトされます。以下のリソースが作成された場合、インストールは成功しています。

RRSA 認証:RAM Roles for Service Accounts (RRSA) を使用する場合は、
rrsa.enableを true に設定します。
定期同期:暗号化パラメーターの自動回転を有効化するには、以下を設定します。

パラメーター 説明 command.disablePolling自動パラメーター回転を有効化するには、 falseを設定しますcommand.pollingInterval同期頻度(秒単位)。デフォルト値: 120(2 分ごと)速度制限:クラスターに多数の ExternalSecret が存在する場合、OOS または RAM API の速度制限を回避するために、以下を設定します。

パラメーター 説明 デフォルト command.maxConcurrentOosSecretPulls1 秒あたりに同期する OOS 暗号化パラメーターの最大数 10
ステップ 2:ack-secret-manager の OOS 暗号化パラメーターへのアクセス権限付与
OOS からの読み取りを許可するための SecretStore を作成します。SecretStore が存在しない場合、コンポーネントは暗号化パラメーターを同期できません。
クラスタータイプに応じて、以下の権限付与方法のいずれかを選択してください。
| 方法 | 対応するクラスタータイプ | 備考 |
|---|---|---|
| RRSA | ACK マネージドクラスター、ACK Serverless クラスター(Kubernetes 1.22+) | 推奨。Pod 単位で権限を分離可能。AccessKey は不要 |
| ワーカー RAM ロール | ACK マネージドクラスター、ACK 専用クラスター、登録済みクラスター | ACK Serverless クラスターではサポートされていません |
| AccessKey ペア(RAM ロールの偽装) | すべての ACK クラスタータイプ | RRSA が利用できない場合に使用 |
RRSA を使用した権限付与
RRSA は、Pod レベルで権限を分離し、AccessKey の漏洩リスクを回避します。この方法は、ACK マネージドクラスターおよび Kubernetes 1.22 以降を実行する ACK Serverless クラスターに適用可能です。
ACK コンソールで、ACK クラスターの RRSA を有効化します。「RRSA の有効化」をご参照ください。
ack-secret-manager のインストール時に、RRSA を有効化するには
rrsa.enableを true に設定します。ack-secret-manager の OIDC ID プロバイダー(IdP)を信頼エンティティとする RAM ロールを作成します。「OIDC IdP 用の RAM ロールの作成」をご参照ください。以下の主要パラメーターを設定します。
パラメーター 値 ID プロバイダータイプ OIDC ID プロバイダー ack-rrsa-<cluster_id>という名前の IdP を選択します。<cluster_id>は、ご利用のクラスター ID です条件 — oidc:issデフォルト値を使用 条件 — oidc:audデフォルト値を使用 条件 — oidc:sub手動で追加:キー = oidc:sub、演算子 =StringEquals、値 =system:serviceaccount:<namespace>:<serviceAccountName>。ack-secret-manager をkube-system以外の名前空間にインストールした場合は、kube-systemを実際の名前空間に置き換えてください。以下の内容を含むカスタム RAM ポリシーを作成し、RAM ロールにアタッチします。「カスタムポリシーの作成」および「RAM ロールへの権限付与」をご参照ください。
{ "Action": [ "oos:GetSecretParameter", "kms:GetSecretValue" ], "Resource": [ "*" ], "Effect": "Allow" }SecretStore を作成します。プレースホルダーを置き換え、以下の内容を
secretstore-rrsa.yamlとして保存します。プレースホルダー 説明 {accountID}OOS 暗号化パラメーターの同期に使用する Alibaba Cloud アカウントの ID {clusterID}ご利用の ACK クラスターの ID {roleName}上記の手順で作成した RAM ロールの名前 apiVersion: 'alibabacloud.com/v1alpha1' kind: SecretStore metadata: name: scdemo-rrsa spec: OOS: OOSAuth: oidcProviderARN: "acs:ram::{accountID}:oidc-provider/ack-rrsa-{clusterID}" ramRoleARN: "acs:ram::{accountID}:role/{roleName}"ファイルを適用します。
kubectl apply -f secretstore-rrsa.yaml
ワーカー RAM ロールへの権限付与
この方法は、ACK マネージドクラスター、ACK 専用クラスター、登録済みクラスターに適用可能です。ACK Serverless クラスターにはワーカー RAM ロールが存在しないため、この方法はサポートされていません。
以下の内容を含むカスタム RAM ポリシーを作成します。「カスタムポリシーの作成」をご参照ください。
{ "Action": [ "oos:GetSecretParameter", "kms:GetSecretValue" ], "Resource": [ "*" ], "Effect": "Allow" }このポリシーをクラスターのワーカー RAM ロールにアタッチします。「ステップ 2:カスタムポリシーをワーカー RAM ロールにアタッチ」セクションをご参照ください。
AccessKey ペアを使用した RAM ロールの偽装
この方法は、すべての ACK クラスタータイプで動作します。
信頼できるエンティティが Alibaba Cloud アカウントである RAM ロールを作成します。「信頼できる Alibaba Cloud アカウント用の RAM ロールの作成」をご参照ください。
以下の内容を含むカスタム RAM ポリシーを作成し、上記の RAM ロールにアタッチします。「カスタムポリシーの作成」および「RAM ロールへの権限付与」をご参照ください。
{ "Action": [ "oos:GetSecretParameter", "kms:GetSecretValue" ], "Resource": [ "*" ], "Effect": "Allow" }上記の RAM ロールに対する
sts:AssumeRole権限を付与するカスタム RAM ポリシーを作成し、使用する RAM ユーザーにアタッチします。「カスタムポリシーの作成」および「RAM ユーザーへの権限付与」をご参照ください。acs:ram::*:role/**を、上記の手順で作成した RAM ロールの Alibaba Cloud リソースネーム(ARN)に置き換えてください。{ "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": "acs:ram::***:role/****" } ], "Version": "1" }RAM ユーザーの AccessKey ペアを格納する Kubernetes Secret を作成します。プレースホルダーを Base64 エンコード済みの値に置き換え、
ramuser.yamlとして保存し、適用します。apiVersion: v1 data: accessKey: {AccessKey ID encoded in Base64} accessKeySecret: {AccessKey secret encoded in Base64} kind: Secret metadata: name: ramuser namespace: kube-system type: Opaquekubectl apply -f ramuser.yamlSecretStore を作成します。プレースホルダーを置き換え、以下の内容を
secretstore-ramrole.yamlとして保存します。プレースホルダー 説明 {accountID}OOS 暗号化パラメーターの同期に使用する Alibaba Cloud アカウントの ID {roleName}ステップ 1 で作成した RAM ロールの名前 {secretName}AccessKey ペアを格納する Secret の名前 {secretNamespace}Secret の名前空間 {secretKey}AccessKey ペアを格納するシークレットを入力します {roleSessionName}ロールセッション名のカスタム文字列 apiVersion: 'alibabacloud.com/v1alpha1' kind: SecretStore metadata: name: scdemo-ramrole spec: OOS: OOSAuth: accessKey: name: {secretName} namespace: {secretNamespace} key: {secretKey} accessKeySecret: name: {secretName} namespace: {secretNamespace} key: {secretKey} ramRoleARN: "acs:ram::{accountID}:role/{roleName}" ramRoleSessionName: {roleSessionName}ファイルを適用します。
kubectl apply -f secretstore-ramrole.yaml
ステップ 3:同期設定の指定
認証の構成が完了したら、ExternalSecret を作成して、同期対象の OOS 暗号化パラメーターおよび保存先を指定します。
ack-secret-manager によって作成される Kubernetes Secret は、ExternalSecret と同じ名前空間および同じ名前を持ちます。
ExternalSecret を作成します。以下のテンプレートのプレースホルダーを置き換え、
external.yamlとして保存します。プレースホルダー 説明 {OOS parameter name}必須。同期対象の OOS 暗号化パラメーターの名前 {Kubernetes secret key}必須。対象 Kubernetes Secret 内のキー名 {secret store name}任意。ステップ 2 で作成した SecretStore の名前。ワーカー RAM ロール方式を使用する場合は空白のままにしてください {secret store namespace}任意。SecretStore の名前空間。ワーカー RAM ロール方式を使用する場合は空白のままにしてください apiVersion: 'alibabacloud.com/v1alpha1' kind: ExternalSecret metadata: name: esdemo spec: provider: oos # OOS 暗号化パラメーターの場合は "oos" を設定。デフォルトは "kms" data: - key: {OOS parameter name} name: {Kubernetes secret key} secretStoreRef: # ワーカー RAM ロール方式を使用する場合は空白のままにしてください name: {secret store name} namespace: {secret store namespace}ファイルを適用します。
kubectl apply -f external.yamlack-secret-manager が Kubernetes Secret を作成したことを確認します。
kubectl get secret esdemoSecret が存在する場合、OOS 暗号化パラメーターの同期は正常に完了しています。
高度な構成
クロスアカウントでの暗号化パラメーター同期
OOS インスタンスと ACK クラスターが異なる Alibaba Cloud アカウントに属している場合、ack-secret-manager はクロスアカウント同期をサポートします。以下の例では、アカウント A の OOS 暗号化パラメーターを、アカウント B の ACK クラスターに RRSA を使用して同期します。
アカウント A の構成
アカウント A を使用して、信頼エンティティがアカウント B である RAM ロールを作成します。信頼アカウントを選択する際は、[他の Alibaba Cloud アカウント] を選択し、アカウント B の ID を入力します。「信頼できる Alibaba Cloud アカウント用の RAM ロールの作成」をご参照ください。
重要[他の Alibaba Cloud アカウント] を選択し、アカウント B の ID を入力します。
以下の内容を含むカスタム RAM ポリシーを作成し、RAM ロールにアタッチします。「カスタムポリシーの作成」および「RAM ロールへの権限付与」をご参照ください。
{ "Action": [ "oos:GetSecretParameter", "kms:GetSecretValue" ], "Resource": [ "*" ], "Effect": "Allow" }
アカウント B の構成
ACK コンソールで、ACK クラスターの RRSA を有効化します。「RRSA の有効化」をご参照ください。
ack-secret-manager のインストール時に、RRSA を有効化するには
rrsa.enableを true に設定します。ack-secret-manager の OIDC ID プロバイダー(IdP)を信頼エンティティとする RAM ロールを作成します。上記の [RRSA 方式] で説明した主要パラメーターを同様に使用します。「OIDC IdP 用の RAM ロールの作成」をご参照ください。
アカウント A の RAM ロールに対する
sts:AssumeRole権限を付与するカスタム RAM ポリシーを作成し、アカウント B の RAM ロールにアタッチします。「カスタムポリシーの作成」および「RAM ロールへの権限付与」をご参照ください。Resourceには、アカウント A で作成した RAM ロールの ARN を設定します。ロールの ARN を表示するには、「RAM ロールの ARN を表示する方法」をご参照ください。<account-id>:アカウント A の ID<role-name>:アカウント A で作成した RAM ロールの名前
{ "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": "acs:ram:*:<account-id>:role/<role-name>" } ], "Version": "1" }以下に示す通り:
クロスアカウントアクセス用の SecretStore を作成します。プレースホルダーを置き換え、以下の内容を
secretstore-ramrole.yamlとして保存します。プレースホルダー 説明 {ACK-accountID}アカウント B の ID {clusterID}ご利用の ACK クラスターの ID {ACK-roleName}アカウント B で作成した RAM ロールの名前 {OOS-accountID}アカウント A の ID {OOS-roleName}アカウント A で作成した RAM ロールの名前 {roleSessionName}ロールセッション名のカスタム文字列 apiVersion: 'alibabacloud.com/v1alpha1' kind: SecretStore metadata: name: scdemo-cross-account spec: OOS: OOSAuth: oidcProviderARN: "acs:ram::{ACK-accountID}:oidc-provider/ack-rrsa-{clusterID}" ramRoleARN: "acs:ram::{ACK-accountID}:role/{ACK-roleName}" remoteRamRoleARN: "acs:ram::{OOS-accountID}:role/{OOS-roleName}" remoteRamRoleSessionName: {roleSessionName}ステップ 3:同期設定の指定で説明した通り、ExternalSecret を作成します。
JSON および YAML 形式の暗号化パラメーターの解析
OOS 暗号化パラメーターの値が JSON または YAML 形式である場合、ack-secret-manager は特定のフィールドを抽出し、それらを Kubernetes Secret 内の個別のキーと値のペアとして格納できます。
jmesPath を使用した特定フィールドの抽出
jmesPath パラメーターを使用すると、JMESPath 式を用いて JSON または YAML パラメーターから特定のフィールドを抽出できます。
JSON の例
OOS に格納されている以下の JSON を想定します。
{"name":"tom","friends":[{"name":"lily"},{"name":"mark"}]}以下の ExternalSecret は、2 つのフィールドを抽出します。path の各行には、抽出された値がコメントとして記載されています。
apiVersion: 'alibabacloud.com/v1alpha1'
kind: ExternalSecret
metadata:
name: es-json-demo
spec:
provider: oos
data:
- key: {OOS parameter name}
secretStoreRef:
name: {secret store name}
namespace: {secret store namespace}
jmesPath:
- path: "name" # 抽出結果:"tom"
objectAlias: "myname"
- path: "friends[0].name" # 抽出結果:"lily"
objectAlias: "friendname"YAML の例
OOS に格納されている以下の YAML を想定します。
name: tom
friends:
- name: lily
- name: markExternalSecret の構造は、上記の JSON の例と同じです。JMESPath 式は、YAML 形式のパラメーターに対しても同一の動作をします。
apiVersion: 'alibabacloud.com/v1alpha1'
kind: ExternalSecret
metadata:
name: es-yaml-demo
spec:
provider: oos
data:
- key: {OOS parameter name}
secretStoreRef:
name: {secret store name}
namespace: {secret store namespace}
jmesPath:
- path: "name" # 抽出結果:"tom"
objectAlias: "myname"
- path: "friends[0].name" # 抽出結果:"lily"
objectAlias: "friendname"dataProcess.extract を使用した自動解析
OOS パラメーターの構造が不明な場合、dataProcess.extract を使用して、JSON または YAML 値全体を自動的に解析できます。各トップレベルのキーは、Kubernetes Secret 内の個別のキーと値のペアになります。
dataProcess.replaceRule を使用して、Kubernetes Secret のキー要件を満たさないキー名をサニタイズします(例: / で始まるまたは終わるキー)。
JSON の例
OOS に格納されている以下の JSON を想定します。
{"/name-invalid":"lily","name-invalid/":[{"name":"mark"}]}以下の ExternalSecret は、値全体を解析し、無効なキー名を再命名します。
apiVersion: 'alibabacloud.com/v1alpha1'
kind: ExternalSecret
metadata:
name: extract-secret
spec:
provider: oos
dataProcess:
- extract:
key: {OOS parameter name}
secretStoreRef:
name: {secret store name}
namespace: {secret store namespace}
replaceRule:
- source: "^/.*d$" # `/` で始まり `d` で終わるキー → 「tom」に再命名
target: "tom"
- source: "^n.*/$" # `n` で始まり `/` で終わるキー → 「mark」に再命名
target: "mark"YAML の例
OOS に格納されている以下の YAML を想定します。
/name-invalid: lily
name-invalid/:
- name: markExternalSecret の構造は、上記の JSON の例と同じです。replaceRule のパターンも同様に適用します。
apiVersion: 'alibabacloud.com/v1alpha1'
kind: ExternalSecret
metadata:
name: extract-secret
spec:
provider: oos
dataProcess:
- extract:
key: {OOS parameter name}
secretStoreRef:
name: {secret store name}
namespace: {secret store namespace}
replaceRule:
- source: "^/.*d$" # `/` で始まり `d` で終わるキー → 「tom」に再命名
target: "tom"
- source: "^n.*/$" # `n` で始まり `/` で終わるキー → 「mark」に再命名
target: "mark"次のステップ
OOS から同期された Kubernetes Secrets および ACK クラスター内にキャッシュされた Secrets を保護するには、シークレット暗号化機能を有効化します。「KMS を使用した Kubernetes Secrets の暗号化」をご参照ください。