IBM Cloud Docs
Kubernetes クラスターで実行されるアプリのシークレットの保護

Kubernetes クラスターで実行されるアプリのシークレットの保護

このチュートリアルでは、 外部シークレット・オペレーター ・オープン・ソース・ツールを使用して IBM Cloud Kubernetes Service クラスターを実行するアプリケーションのシークレットを管理するために IBM Cloud® Secrets Manager を使用する方法を学習します。

あるいは、 Kubernetes Service CLI プラグインを使用して、TLS シークレットと非 TLS シークレットを管理することもできます。 この方法について詳しくは、 Kubernetes Ingress のセットアップ を参照してください。

あなたは組織の開発者であり、あなたのチームは Kubernetes Service を使用して、 IBM Cloud 上にコンテナ化されたアプリケーションとサービスを展開しています。 現在のフローでは、 Kubernetes Secrets を使用して、クラスタで実行されるアプリやサービスで使用されるパスワードやAPIキーなどの機密データを保存しています。 アプリケーションのシークレットの制御を強化するには、外部のシークレット管理サービスにクラスターのシークレットを保管する機能を使用できます。このサービスでは、保存されたシークレットの暗号化シークレットのアクティビティーのモニタリングが可能で、さらにシークレットの管理も簡単になります。

Secrets Manager を使用すると、 Kubernetes クラスターで実行されるアプリケーションによって使用されるシークレットを集中させて保護できます。 デプロイ時にシークレットを投入するのではなく、実行時に Secrets Manager からシークレットを安全にリトリーブするようにアプリケーションを構成できます。 シークレットを置き換える時間がある場合は、Secrets Manager から可能です。 例えば、以下のシナリオがあるとします。

この図は、 Secrets Manager とお客様の Kubernetes クラスタ間の基本的な流れを示しています。
External Secrets flow

  1. デベロッパーとして、Secrets Manager を使用して、Kubernetes クラスターにデプロイしたいアプリケーションのシークレットを保管します。
  2. Secrets Manager がシークレットの ID を提供します。 このIDをアプリのExternalSecrets構成ファイルに記述して、その構成をクラスターに適用します。
  3. 外部シークレットコントローラーは、Kubernetes APIを使用して定義した構成ファイル内のExternalSecretsオブジェクトをフェッチします。
  4. アプリケーションの実行時に、コントローラーはSecrets Managerから秘密データを取得し、ExternalSecretsオブジェクトをクラスターのKubernetes秘密に変換します。

このシナリオは、Kubernetes クラスターで実行されるワークロードのコンプライアンスの準備に影響を及ぼす可能性のある、サード・パーティー・ツールを特徴としています。 コミュニティやサードパーティのツールを追加する場合は、アプリのコンプライアンスを維持する責任があることを念頭に置き、問題が発生した場合は適切なプロバイダーと協力してトラブルシューティングを行う必要があります。 詳細については、IBM Cloud Kubernetes Service 使用の際の責任を参照してください。

開始前に

開始する前に、アカウント資格情報を作成し、リソースをプロビジョニングできるように、必ず管理者プラットフォーム・アクセス権限 を使用するようにしてください。 以下の前提条件も必要です。

環境を設定する

Secrets Manager および Kubernetes Service を操作するには、IBM Cloud アカウントにクラスターと Secrets Manager インスタンスを作成する必要があります。 また、両方のサービスに対して操作を実行できるように許可を構成する必要もあります。

このステップでは、サービス ID と IBM Cloud API キーを作成して、アクセス環境をセットアップします。 これらのリソースが不要になった場合は、チュートリアルの終了時に簡単に削除できます。 あるいは、 信頼されたプロファイル を使用して、外部シークレット・オペレーターを許可することもできます。

サービス ID および API キーの作成

開始するには、Secrets Manager および Kubernetes Service に対して操作を実行するために必要なアカウント資格情報を作成します。

  1. IBM Cloud CLI を使用して、コマンド・ラインから IBM Cloud にログインします。

    ibmcloud login
    

    ログインに失敗した場合は、ibmcloud login --ssoコマンドを実行して再試行してください。 フェデレーテッドIDを使用してログインする場合は、--ssoパラメーターが必要です。 このオプションを使用する場合、CLI 出力にリストされているリンクに移動して、ワンタイム・パスコードを生成します。

  2. サービス ID を作成し、環境変数として設定します。

    export SERVICE_ID=`ibmcloud iam service-id-create kubernetes-secrets-tutorial --description "A service ID for testing ESO integration" --output json | jq -r ".id"`; echo $SERVICE_ID
    
  3. サービス ID 許可を割り当てて、Secrets Manager からシークレットを読み取ります。

    ibmcloud iam service-policy-create $SERVICE_ID --roles "SecretsReader" --service-name secrets-manager
    

    SecretsReader サービス・アクセスを割り当てると、Secrets Manager からシークレットを読み取り、Kubernetes クラスターに取り込むための正しいレベルのアクセス権限が外部シークレット・コントローラーに付与されます。

  4. サービス ID 用に IBM Cloud API キーを作成します。

    export IBM_CLOUD_API_KEY=`ibmcloud iam service-api-key-create kubernetes-secrets-tutorial $SERVICE_ID --description "An API key for testing ESO integration." --output json | jq -r ".apikey"`
    

    この API キーは、後でクラスター・デプロイメント用に Secrets Manager を構成する際に使用します。

Kubernetes クラスターと Secrets Manager インスタンスを作成します。

Kubernetes クラスタと Secrets Manager のインスタンスを IBM Cloud アカウント内に作成します。

IBM Cloud アカウントあたり、1 つの空き Kubernetes クラスターと Secrets Manager サービス・インスタンスを作成できます。 両方のリソースがご使用のアカウントに既にある場合は、既存の空きクラスターおよび Secrets Manager インスタンスを使用してチュートリアルを完了できます。

  1. コマンド・ラインから、Secrets Manager サービス・インスタンスを作成するアカウント、リージョン、リソース・グループを選択します。

    このチュートリアルでは、ダラス地域と対話します。 別の地域にログインしている場合は、次のコマンドを実行して、ダラスをターゲット地域に設定してください。

    ibmcloud target -r us-south -g default
    
  2. Kubernetes クラスターを作成します。

    ibmcloud ks cluster create classic --zone dal10 --flavor free --name my-test-cluster
    
  3. Secrets Manager インスタンスを作成します。

    ibmcloud resource service-instance-create my-secrets-manager secrets-manager trial us-south
    

    Secrets Manager とご使用の Kubernetes クラスターの両方のプロビジョニング完了には 5 分から 15 分かかります。

  4. 次のステップに進む前に、クラスタと Secrets Manager インスタンスが正しくプロビジョニングされたことを確認してください。

    1. ワーカー・ノードのデプロイメントが完了していることを確認します。

      ibmcloud ks worker ls --cluster my-test-cluster
      

      ワーカー・ノードがプロビジョニングを終了すると、ステータスは 「レディー」 に変わります。

      ID                                                       Public IP       Private IP      Flavor   State          Status                Zone    Version
      kube-c39pf4ld0m87o3fv1utg-mytestclust-default-000000dd   169.xx.xx.xxx   10.xxx.xx.xxx   free     normal   Ready   mex01   1.20.7_1543
      
    2. 次に、Secrets Manager インスタンスが正常にプロビジョニングされたことを確認します。

      ibmcloud resource service-instance my-secrets-manager
      

      インスタンスがプロビジョニングを終了すると、ステータスは 「アクティブ」 に変わります。

      Name:                  my-secrets-manager
      ID:                    crn:v1:bluemix:public:secrets-manager:us-south:a/f047b55a3362ac06afad8a3f2f5586ea:fe06948b-0c6b-4183-8d4b-e6c1d38ff65f::
      GUID:                  fe06948b-0c6b-4183-8d4b-e6c1d38ff65f
      Location:              us-south
      Service Name:          secrets-manager
      Service Plan Name:     trial
      Resource Group Name:   default
      State:                 active
      Type:                  service_instance
      Sub Type:
      Created at:            2021-01-06T17:11:32Z
      Created by:            zara@example.com
      Updated at:            2021-03-31T02:33:26Z
      
  5. CLI で、Kubernetes クラスターのコンテキストを設定します。

    ibmcloud ks cluster config --cluster my-test-cluster
    
  6. kubectlコマンドが正しく実行され、Kubernetesコンテキストがクラスターに設定されていることを確認します。

    kubectl config current-context
    

    出力例:

    my-test-cluster/<your_cluster_ID>
    

トラステッド・プロファイルの作成

信頼できるプロファイルにより、外部シークレット・オペレーターは、サービス ID を作成したり API キーを管理したりすることなく、 Secrets Managerから読み取ることができます。

  1. Secrets Manager インスタンスおよび Kubernetes クラスターの CRN を取得します。

    CLUSTER_CRN=$(ibmcloud ks cluster get --cluster my-test-cluster --output json | jq -r '.crn')
    SECRETS_MANAGER_CRN=$(ibmcloud resource service-instance my-secrets-manager --output JSON | jq -r '.[0].crn')
    
  2. プロファイルを作成します。

    ibmcloud iam trusted-profile-create 'External Secrets'
    
  3. 信頼できるプロファイルを使用する権限を Kubernetes クラスターに付与します。

    Kubernetes

    ibmcloud iam trusted-profile-rule-create 'External Secrets' --name kubernetes --type Profile-CR --conditions claim:namespace,operator:EQUALS,value:external-secrets --conditions claim:name,operator:EQUALS,value:external-secrets --conditions claim:crn,operator:EQUALS,value:$CLUSTER_CRN --cr-type IKS_SA
    

    OpenShift

    ibmcloud iam trusted-profile-rule-create 'External Secrets' --name kubernetes --type Profile-CR --conditions claim:namespace,operator:EQUALS,value:external-secrets-operator --conditions claim:name,operator:EQUALS,value:cluster-external-secrets --conditions claim:crn,operator:EQUALS,value:$CLUSTER_CRN --cr-type IKS_SA
    
  4. トラステッド・プロファイルが Secrets Manager インスタンスからシークレットを読み取ることを許可するアクセス・ポリシーを作成します。

    ibmcloud iam trusted-profile-policy-create 'External Secrets' --roles SecretsReader --service-instance $SECRETS_MANAGER_CRN --service-name secrets-manager
    

Secrets Manager インスタンスの準備

最後に、シークレットの処理を開始できるように、Secrets Manager インスタンスを構成します。

  1. コマンドラインから、Secrets Manager CLI プラグインにアクセスできることを確認します。

    ibmcloud secrets-manager --help
    

    まだプラグインをお持ちでないですか? Secrets ManagerCLIプラグインをインストールするには、ibmcloud plugin install secrets-managerを実行します。

  2. 固有の Secrets Manager API エンドポイント URLを使用して、環境変数をエクスポートします。

    export SECRETS_MANAGER_URL=`ibmcloud resource service-instance my-secrets-manager --output json | jq -r '.[].dashboard_url | .[0:-3]'`; echo $SECRETS_MANAGER_URL
    
  3. インスタンスのシークレット・グループを作成します。

    シークレット・グループ は、インスタンス内の特定の機密情報にアクセスできるチーム内のユーザーを編成、制御するための方法です。 IBM Cloud CLI からシークレット・グループを作成するには、ibmcloud secrets-manager secret-group-create コマンドを使用します。 以下のコマンドを実行して、シークレット・グループを作成し、その ID を環境変数として保管します。

    export SECRET_GROUP_ID=`ibmcloud secrets-manager secret-group-create --name my-test-secret-group --description "Read and write to my test app" --output json --service-url $SECRETS_MANAGER_URL | jq -r '.id'`; echo $SECRET_GROUP_ID
    

    Windows™コマンド・プロンプト(cmd.exe)またはPowerShellを使用していますか? コマンド・ラインで JSON コンテンツを渡す際にエラーが発生する場合、ご使用のオペレーティング・システムに固有の引用符のエスケープ要件に応じて、ストリングを調整する必要がある場合があります。 詳細については、IBM Cloud CLI の文字列の引用符の使用を参照してください。

    成功! これで、Kubernetes クラスターにデータを取り込むためのシークレットを Secrets Manager に保管できるようになりました。 次のステップに進んでください。

Secrets Manager にシークレットを作成する

シークレットはアプリケーション固有であり、シークレットを必要とする個別のアプリまたはサービスによって異なります。 シークレットは、ユーザー名、パスワード、API キー、またはその他のタイプの資格情報で構成される場合があります。

Secrets Manager は、サービスで作成および管理できるさまざまなシークレットのタイプをサポートしています。 例えば、IBM Cloud IAM 認証で保護されているアプリ用の API キーを管理する必要がある場合は、IAM 資格情報を作成できます。 または、不特定型の構造化データまたは非構造化データを保持できるシークレットを管理する必要がある場合は、任意シークレットを作成できます。

このチュートリアルでは、例として、ユーザー名およびパスワードを作成します。 IBM Cloud CLI からシークレットを作成するには、ibmcloud secrets-manager secret-create コマンドを使用します。 以下のコマンドを実行して、シークレットを作成し、その ID を環境変数として保管します。

export SECRET_ID=`ibmcloud secrets-manager secret-create --secret-type=username_password --secret-name example_username_password --username-password-username user123 --username-password-password cloudy-rainy-coffee-book --secret-labels "my-test-cluster, tutorial" --secret-group-id $SECRET_GROUP_ID --output json $SECRETS_MANAGER_URL | jq -r '.id'`; echo $SECRET_ID

必ず、 instance_id および region をご使用のものに更新してください。

出力には、新しく作成されたシークレットの ID が表示されます。 以下に例を示します。

e0246cea-d668-aba7-eef2-58ca11ad3707

外部シークレット・オペレーターのセットアップ

アプリケーションの秘密が分かったので、クラスタに External Secrets Operatorツールを設定することができます。 このパッケージは、アプリケーションのKubernetesシークレットに変換されるExternalSecretsオブジェクトを作成することで、Secrets Managerとクラスターの間の接続を構成します。

外部シークレット・オペレーターは、IBM によって保守されないオープン・ソース・ツールです。 このツールの詳細や問題のトラブルシューティングについては、 プロジェクトのドキュメントを参照してください。

クラスターの外部シークレット・オペレーターの構成

Kubernetes

まず、公式のHelmチャートをインストールして、external-secretsリソースをクラスターに追加します。 インストール・オプションについて詳しくは、 入門ガイドを参照してください。

  1. 外部 Secrets Operator Helm リポジトリーをインストールするには、以下のコマンドを実行します。

    helm repo add external-secrets https://charts.external-secrets.io
    
  2. 外部 Secrets Operator と Secrets Managerの間の認証を構成します。

    認証にサービス ID を使用している場合は、以下のようにします。

    kubectl -n default create secret generic secret-api-key --from-literal=apikey=$IBM_CLOUD_API_KEY
    helm install external-secrets external-secrets/external-secrets -n external-secrets --create-namespace --set installCRDs=true
    

    信頼できるプロファイルを使用して認証を行っている場合は、以下のようにします。

    echo '
    installCRDs: true
    extraVolumes:
    - name: sa-token
      projected:
        defaultMode: 420
        sources:
        - serviceAccountToken:
            path: sa-token
            expirationSeconds: 3600
            audience: iam
    extraVolumeMounts:
    - mountPath: /var/run/secrets/tokens
      name: sa-token
    webhook:
      extraVolumes:
      - name: sa-token
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              path: sa-token
              expirationSeconds: 3600
              audience: iam
      extraVolumeMounts:
      - mountPath: /var/run/secrets/tokens
        name: sa-token' >values.yml
    helm install external-secrets external-secrets/external-secrets -n external-secrets --create-namespace -f values.yml
    

OpenShift

  1. External Secrets Operator をインストールするには、以下のリソースを作成します。

    echo '
    apiVersion: v1
    kind: Namespace
    metadata:
      name: external-secrets-operator
    ---
    apiVersion: operators.coreos.com/v1
    kind: OperatorGroup
    metadata:
      name: external-secrets-operator
      namespace: external-secrets-operator
    spec:
      targetNamespaces:
        - external-secrets-operator
    ---
    apiVersion: operators.coreos.com/v1alpha1
    kind: Subscription
    metadata:
      name: external-secrets-operator
      namespace: external-secrets-operator
    spec:
      channel: stable
      installPlanApproval: Automatic
      name: external-secrets-operator
      source: community-operators
      sourceNamespace: openshift-marketplace
    ' | oc create -f-
    
  2. 外部 Secrets Operator と Secrets Managerの間の認証を構成します。

    認証にサービス ID を使用している場合は、以下のようにします。

    echo "
    apiVersion: operator.external-secrets.io/v1alpha1
    kind: OperatorConfig
    metadata:
      name: cluster
      namespace: external-secrets-operator
    spec: {}
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-api-key
      namespace: default
    type: Opaque
    stringData:
      apikey: $IBM_CLOUD_API_KEY
    " | oc create -f-
    

    信頼できるプロファイルを使用して認証を行っている場合は、以下のようにします。

    echo '
    apiVersion: operator.external-secrets.io/v1alpha1
    kind: OperatorConfig
    metadata:
      name: cluster
      namespace: external-secrets-operator
    spec:
      extraVolumeMounts:
      - mountPath: /var/run/secrets/tokens
        name: sa-token
      extraVolumes:
      - name: sa-token
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              audience: iam
              expirationSeconds: 3600
              path: sa-token
      webhook:
        extraVolumeMounts:
        - mountPath: /var/run/secrets/tokens
          name: sa-token
        extraVolumes:
        - name: sa-token
          projected:
            defaultMode: 420
            sources:
            - serviceAccountToken:
                audience: iam
                expirationSeconds: 3600
                path: sa-token
    ' | oc create -f-
    

アプリ構成の更新

外部シークレット・オペレーターをクラスターにインストールした後、アプリケーションのシークレット・バックエンドとして Secrets Manager を定義できます。 開始するには、Secrets Manager で使用したいシークレットをターゲットとする構成ファイルを作成します。

  1. アプリケーションのルート・ディレクトリーに、external-secrets-example.ymlファイルを作成します。

    touch external-secrets-example.yml
    
  2. ファイルを修正して、Secrets Manager インスタンスから取り出すシークレットに関する情報を含めます。

    apiVersion: external-secrets.io/v1beta1
    kind: SecretStore
    metadata:
      name: ibmcloud-secrets-manager-example
    spec:
      provider:
        ibm:
          serviceUrl: <endpoint_url>
          auth:
            secretRef:
              secretApiKeySecretRef:
                name: secret-api-key
                key: apikey
    ---
    apiVersion: external-secrets.io/v1beta1
    kind: ExternalSecret
    metadata:
      name: ibmcloud-secrets-manager-example
    spec:
      secretStoreRef:
        name: ibmcloud-secrets-manager-example
        kind: SecretStore
      target:
        name: ibmcloud-secrets-manager-example
      data:
      - secretKey: username
        remoteRef:
          property: username
          key: username_password/<SECRET_ID>
      - secretKey: password
        remoteRef:
          property: password
          key: username_password/<SECRET_ID>
    

    シークレット ID またはシークレット名の 2 つのモードで作業することを選択できます。 シークレット名を選択すると、形式が secret_type/secret_id から secret_group/secret_type/secret_name に変わります。

    <endpoint_url>を、Secrets Manager 取得したエンドポイント URL 以前に置き換えます。 <SECRET_ID>を、前のステップで作成したシークレットの固有 ID に置き換えます。

    トラステッド・プロファイルを使用して認証を行っている場合は、 auth ブロックを以下のスニペットに置き換えます。

          auth:
            containerAuth:
              profile: "External Secrets"
              iamEndpoint: https://iam.cloud.ibm.com
              tokenLocation: /var/run/secrets/tokens/sa-token
    
  3. クラスターに構成を適用します。

    kubectl apply -f external-secrets-example.yml
    
  4. 外部シークレット・オペレーターが、Secrets Manager インスタンスに保管されているシークレットをフェッチできることを確認します。

    kubectl get secret ibmcloud-secrets-manager-example -o json | jq '.data | map_values(@base64d)'
    

    出力例:

    {
        "password": "cloudy-rainy-coffee-book",
        "username": "user123"
    }
    

    成功! これで、Secrets Manager インスタンスに保管されているシークレット・データをフェッチできるようになりました。 次のステップに進んでください。

クラスターへのアプリのデプロイ

最後に、external-secret-example.ymlファイルで定義した Secrets Managerシークレットを使用するアプリケーションをクラスターにデプロイできます。 アプリケーション実行時に、Secrets Manager からフェッチされたシークレット・データは、クラスターで使用できる Kubernetes シークレットに変換されます。

アプリのデプロイ方法の例をお探しですか? アプリの単一インスタンスのデプロイについて詳しくは、 クラスターでの Kubernetesネイティブ・アプリのデプロイ を参照してください。

(オプション) リソースのクリーンアップ

本チュートリアルで作成したリソースが今後不要な場合は、以下の手順を実行して、アカウントからリソースを削除できます。

  1. テスト Kubernetes クラスターを削除します。

    ibmcloud ks cluster rm --cluster my-test-cluster
    
  2. テスト Secrets Manager インスタンスを削除します。

    ibmcloud resource service-instance-delete my-secrets-manager
    
  3. 許可を削除します。

    サービス ID を使用している場合。

    ibmcloud iam service-id-delete $SERVICE_ID
    

    信頼できるプロファイルで作業している場合。

    ibmcloud iam trusted-profile-delete 'External Secrets'
    

特記事項

YAML文書 を構築する際には、データセクションの各キーは、 Secrets Manager インスタンスからRESTを使用して定期的にポーリングされることを念頭に置いてください。 以下の点にご注意ください。

  1. デフォルトでは、ポーリング間隔は1時間に設定されており、この値を設定するのが望ましい。 この値は、External Secretsテンプレートで spec.refreshInterval を使用することで変更できます。 間隔は、 sm、または h の単位で表すことができます。
  2. Secrets Manager シークレットを ID (keyByName: true) ではなく名前でフェッチするように YAML を設定した場合、関連するシークレット ID をフェッチするために ESO によって追加の呼び出しが行われます。 詳しくは、外部シークレット資料をご覧ください。

次のステップ

お疲れさまでした。 このチュートリアルでは、Secrets Manager をセットアップして、アプリケーションのシークレットをクラスターに安全に取り込む方法を学習しました。 Secrets Manager の開始に役立つリソースをさらにチェックしてください。