顧客管理の暗号鍵(CMEK)を使用する


このページでは、Google Kubernetes Engine(GKE)で顧客管理の暗号鍵(CMEK)を使用する方法について説明します。鍵の管理を制御する必要がある場合は、Cloud Key Management Service と CMEK を使用することで、GKE クラスタ内の接続された永続ディスクとカスタム ブートディスクを保護することができます。

概要

Google Cloud では、デフォルトで保存されている顧客コンテンツを暗号化し、GKE が自動的に暗号化の管理を行います。

暗号鍵のローテーションを自身で管理する場合は、CMEK を使用します。これらの鍵は、データの暗号化に使用するデータ暗号鍵を暗号化します。詳細については、鍵管理をご覧ください。

また、自身で管理する鍵を使用してクラスタの Secret を暗号化することもできます。詳細については、アプリケーション レイヤでの Secret の暗号化をご覧ください。

GKE では、CMEK を使用することによって、ノード ブートディスクとアタッチされたディスクの 2 種類のストレージ ディスクのデータを保護できます。

ノード ブートディスク
ノード ブートディスクは、クラスタのノードプールの一部です。クラスタとノードプールを作成するときに、CMEK で暗号化されたノード ブートディスクを作成できます。
アタッチされたディスク
アタッチされたディスクは、耐久性の高いストレージ用に Pod で使用される PersistentVolume です。CMEK で暗号化され、アタッチされた永続ディスクは、動的にプロビジョニングされる PersistentVolume として GKE で使用できます。

ストレージ ディスクの詳細については、ストレージ オプションをご覧ください。GKE コントロール プレーンに使用するコントロール プレーン ディスクは、CMEK では保護できません。

始める前に

  1. このトピックの演習を行うには、2 つの Google Cloud プロジェクトが必要です。

    • 鍵プロジェクト: 暗号鍵の作成先。

    • クラスタ プロジェクト: CMEK を有効にするクラスタの作成先。

  2. 鍵プロジェクトで、Cloud KMS API が有効になっていることを確認します。

    Cloud KMS API の有効化

  3. 鍵プロジェクトで、キーリングと鍵を作成するユーザーには次の IAM 権限が必要になります。

    • cloudkms.keyRings.getIamPolicy
    • cloudkms.keyRings.setIamPolicy

    これらの権限は、事前定義された roles/cloudkms.admin Identity and Access Management ロールに付与されています。鍵を管理するための権限の付与に関する詳細については、Cloud KMS のドキュメントをご覧ください。

  4. クラスタ プロジェクトで Cloud KMS API が有効になっていることを確認します。

    Cloud KMS API の有効化

  5. gcloud CLI がインストール済みであることを確認します。

  6. gcloud を最新バージョンに更新します。

    gcloud components update
    

Cloud KMS 鍵を作成する

CMEK でノード ブートディスクまたはアタッチされたディスクを保護する前に、Cloud KMS のキーリングと鍵が必要です。

キーリングと鍵の要件は次のとおりです。

  • 鍵には対称暗号化を使用する必要があります。

  • 鍵を使用するには、GKE サービス アカウントに権限を付与する必要があります。

  • キーリングには、GKE クラスタのロケーションと一致するロケーションが必要です。

    • ゾーンクラスタは、スーパーセット ロケーションからのキーリングを使用する必要があります。たとえば、ゾーン us-central1-a のクラスタは、リージョン us-central1 の鍵のみを使用できます。

    • リージョン クラスタは、同じロケーションからのキーリングを使用する必要があります。たとえば、asia-northeast1 リージョンのクラスタは、asia-northeast1 リージョンのキーリングで保護する必要があります。

    • GKE では、Cloud KMS の global リージョンの使用はサポートされていません。

キーリングと鍵を作成する方法については、対称鍵の作成をご覧ください。

鍵を使用する権限を付与する

クラスタのノードで使用する Compute Engine サービス アカウントには、Cloud KMS 暗号鍵の暗号化 / 復号のロールを割り当てる必要があります。これは、GKE 永続ディスクが暗号鍵にアクセスして使用する際に必要になります。

Compute Engine サービス アカウントの名前は次の形式です。

service-PROJECT_NUMBER@compute-system.iam.gserviceaccount.com

PROJECT_NUMBER は、クラスタのプロジェクト番号に置き換えます。

サービス アカウントにアクセス権を付与するには、gcloud コマンドまたは Google Cloud Console を使用します。

gcloud

Compute Engine サービス アカウントに、Cloud KMS 暗号鍵の暗号化 / 復号のロールを付与します。

gcloud kms keys add-iam-policy-binding KEY_NAME \
    --location LOCATION \
    --keyring RING_NAME \
    --member serviceAccount:SERVICE_ACCOUNT \
    --role roles/cloudkms.cryptoKeyEncrypterDecrypter \
    --project KEY_PROJECT_ID

次のように置き換えます。

  • KEY_NAME: 鍵の名前。
  • LOCATION: キーリングを作成したリージョン。
  • RING_NAME: キーリングの名前。
  • SERVICE_ACCOUNT: Compute Engine サービス アカウントの名前。
  • KEY_PROJECT_ID: 鍵プロジェクト ID。

Console

Compute Engine サービス アカウントに、Cloud KMS 暗号鍵の暗号化 / 復号のロールを付与します。

  1. Google Cloud Console で Cloud Key Management Service 鍵ブラウザを開きます。
    Cloud KMS 鍵のブラウザを開く
  2. 目的の鍵を含むキーリングの名前をクリックします。

  3. 使用する鍵のチェックボックスをオンにします。

    右側のウィンドウの [権限] タブが有効になります。

  4. [メンバーの追加] ダイアログで、アクセス権を付与する Compute Engine サービス アカウントのメールアドレスを指定します。

  5. [役割を選択] プルダウンで、[クラウド KMS 暗号鍵の暗号化 / 復号化] を選択します。

  6. [保存] をクリックします。

CMEK で保護されたノード ブートディスクを使用する

このセクションでは、CMEK で保護されたブートディスクが含まれる新しいクラスタまたはノードプールを作成します。

既存のクラスタまたはノードプールのブートディスクの種類は変更できないため、既存のクラスタではノード ブートディスクの顧客管理の暗号化を有効にすることはできません。ただし、クラスタ用の新しいノードプールを作成し、そこで顧客管理の暗号化を有効にし、以前のノードプールを削除することは可能です。

また、既存のクラスタまたは既存のノードプールで、ノード ブートディスク用の顧客管理の暗号化を無効にすることもできません。ただし、クラスタ用の新しいノードプールを作成し、そこで顧客管理の暗号化を無効にし、以前のノードプールを削除することは可能です。

CMEK で保護されたノード ブートディスクが含まれるクラスタを作成する

CMEK で保護されたノード ブートディスクが含まれるクラスタを作成するには、gcloud CLI または Google Cloud Console を使用します。

標準クラスタの場合、CMEK 鍵で暗号化できるのは標準永続ディスク(pd-standard)または SSD 永続ディスク(pd-ssd)のみです。

gcloud

ブートディスクが CMEK 鍵で暗号化されたクラスタを作成するには、クラスタ作成コマンドで --boot-disk-kms-key パラメータの値を指定します。

標準クラスタを作成する

ブートディスクが CMEK 鍵で暗号化されている標準クラスタを作成するには、次のコマンドを使用します。

gcloud container clusters create CLUSTER_NAME \
    --cluster-version=latest \
    --region COMPUTE_REGION \
    --boot-disk-kms-key projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME \
    --project CLUSTER_PROJECT_ID \
    --disk-type DISK_TYPE

Autopilot クラスタの作成

ブートディスクが CMEK 鍵で暗号化されている Autopilot クラスタを作成するには、次のコマンドを使用します。

gcloud container clusters create-auto CLUSTER_NAME \
    --cluster-version=latest \
    --region COMPUTE_REGION \
    --boot-disk-kms-key projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME \
    --project CLUSTER_PROJECT_ID

次のように置き換えます。

  • CLUSTER_NAME: 新しいクラスタ用の名前。
  • COMPUTE_REGION: クラスタ コントロール プレーンのコンピューティング リージョン
  • KEY_PROJECT_ID: 鍵プロジェクト ID。
  • LOCATION: キーリングのロケーション。
  • RING_NAME: キーリングの名前。
  • KEY_NAME: 鍵の名前。
  • CLUSTER_PROJECT_ID は、クラスタ プロジェクト ID です。
  • DISK_TYPE: pd-standard(デフォルト)または pd-ssd

Console

標準クラスタを作成する

ブートディスクが CMEK 鍵で暗号化されている標準クラスタを作成するには、次の手順を行います。

  1. Google Cloud コンソールで [Google Kubernetes Engine] ページに移動します。

    Google Kubernetes Engine に移動

  2. [ 作成] をクリックします。

  3. [Standard] セクションで [構成] をクリックします。

  4. 必要に応じてクラスタを構成します。

  5. ナビゲーション パネルで、[ノードプール] の下の [ノード] をクリックします。

  6. [ブートディスクの種類] プルダウン リストで、[標準永続ディスク] または [SSD 永続ディスク] を選択します。

  7. [ブートディスクの顧客管理の暗号化を有効にする] チェックボックスをオンにし、以前に作成した Cloud KMS 暗号鍵を選択します。

  8. [作成] をクリックします。

Autopilot クラスタの作成

ブートディスクが CMEK 鍵で暗号化されている Autopilot クラスタを作成するには、次の手順を行います。

  1. Google Cloud コンソールで [Google Kubernetes Engine] ページに移動します。

    Google Kubernetes Engine に移動

  2. [ 作成] をクリックします。

  3. [Autopilot] セクションで、[構成] をクリックします。

  4. 必要に応じてクラスタを構成します。

  5. [詳細オプション] セクションを展開し、[セキュリティ] オプションを見つけます。

  6. [ブートディスクの顧客管理の暗号化を有効にする] チェックボックスをオンにし、以前に作成した Cloud KMS 暗号鍵を選択します。

  7. [作成] をクリックします。

CMEK で保護されたノード ブートディスクが含まれる新しいノードプールを作成する

既存の標準クラスタで CMEK を有効にして新しいノードプールを作成するには、gcloud CLI または Google Cloud Console を使用します。

gcloud

ノード ブートディスクに対して顧客管理の暗号化が適用されるノードプールを作成するには、作成コマンドで --boot-disk-kms-key パラメータの値を指定します。

gcloud container node-pools create NODE_POOL_NAME \
    --region COMPUTE_REGION \
    --disk-type DISK_TYPE \
    --boot-disk-kms-key projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME \
    --project CLUSTER_PROJECT_ID \
    --cluster CLUSTER_NAME

次のように置き換えます。

  • NODE_POOL_NAME: ノードプールに付ける名前。
  • COMPUTE_REGION: クラスタ コントロール プレーンのコンピューティング リージョン
  • DISK_TYPE: pd-standard(デフォルト)または pd-ssd
  • KEY_PROJECT_ID: 鍵プロジェクト ID。
  • LOCATION: キーリングのロケーション。
  • RING_NAME: キーリングの名前。
  • KEY_NAME: 鍵の名前。
  • CLUSTER_PROJECT_ID: クラスタ プロジェクト ID。
  • CLUSTER_NAME: 前の手順で作成した標準クラスタの名前。

Console

  1. Google Cloud コンソールで [Google Kubernetes Engine] ページに移動します。

    Google Kubernetes Engine に移動

  2. クラスタのリストで、変更するクラスタの名前をクリックします。

  3. [ノードプールを追加] をクリックします。

  4. ナビゲーション パネルで [ノード] をクリックします。

  5. [マシンの構成] セクションで、[ブートディスクの種類] が [標準永続ディスク] または [SSD 永続ディスク] であることを確認します。

  6. [ブートディスクの顧客管理の暗号化を有効にする] チェックボックスをオンにし、作成した Cloud KMS 暗号鍵を選択します。

  7. [作成] をクリックします。

CMEK で保護された Filestore インスタンスまたは Persistent Disk を使用する

以下の情報では、新しく作成された Filestore インスタンスまたは Persistent Disk を暗号化する方法について説明します。新規または既存のクラスタで、Cloud KMS の新規または既存の鍵を使用して CMEK を有効にできます。

これらの手順は、GKE クラスタごとに 1 度実行する必要があります。

Cloud KMS 鍵を参照する StorageClass を作成する

  1. 以下の内容を cmek-sc.yaml という名前の YAML ファイルにコピーします。この構成では、暗号化されたボリュームの動的なプロビジョニングが可能です。

    Filestore インスタンス

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: csi-filestore-cmek
    provisioner: filestore.csi.storage.gke.io
    allowVolumeExpansion: true
    parameters:
      tier: enterprise
      instance-encryption-kms-key: projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME
    
    • instance-encryption-kms-key フィールドは、新しい Filestore インスタンスの暗号化に使用する鍵の完全修飾リソース識別子である必要があります。
    • instance-encryption-kms-key の値では大文字と小文字が区別されます(例: keyRingscryptoKeys)。新しいボリュームを不正な値でプロビジョニングすると、invalidResourceUsage エラーが発生します。
    • instance-encryption-kms-key パラメータの既存の StorageClass オブジェクトへの追加はできません。ただし、StorageClass オブジェクトを削除し、同じ名前で別のパラメータ セットを含むオブジェクトを再作成することは可能です。

    永続ディスク

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: csi-gce-pd-cmek
    provisioner: pd.csi.storage.gke.io
    volumeBindingMode: "WaitForFirstConsumer"
    allowVolumeExpansion: true
    parameters:
      type: pd-standard
      disk-encryption-kms-key: projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME
    
    • disk-encryption-kms-key フィールドは、新しいディスクの暗号化に使用する鍵の完全修飾リソース識別子である必要があります。
    • disk-encryption-kms-key の値では大文字と小文字が区別されます(例: keyRingscryptoKeys)。新しいボリュームを不正な値でプロビジョニングすると、invalidResourceUsage エラーが発生します。
    • disk-encryption-kms-key パラメータの既存の StorageClass オブジェクトへの追加はできません。ただし、StorageClass オブジェクトを削除し、同じ名前で別のパラメータ セットを含むオブジェクトを再作成することは可能です。既存のクラスのプロビジョナーが pd.csi.storage.gke.io であることを確認してください。

    デフォルトの StorageClass を設定できます。

  2. kubectl を使用して、GKE クラスタに StorageClass をデプロイします。

    kubectl apply -f cmek-sc.yaml
    
  3. StorageClass が Compute Engine Filestore または永続ディスク CSI ドライバを使用し、鍵の ID が含まれていることを確認します。

    Filestore インスタンス

    kubectl describe storageclass csi-filestore-cmek
    

    コマンドの出力で、次のことを確認します。

    • プロビジョナーの設定が filestore.csi.storage.gke.io になっている。
    • 鍵の ID が instance-encryption-kms-key の後にある。
    Name:                  csi-filestore-cmek
    IsDefaultClass:        No
    Annotations:           None
    Provisioner:           filestore.csi.storage.gke.io
    Parameters:            instance-encryption-kms-key=projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME,type=pd-standard
    AllowVolumeExpansion:  true
    MountOptions:          none
    ReclaimPolicy:         Delete
    VolumeBindingMode:     WaitForFirstConsumer
    Events:                none
    

    永続ディスク

    kubectl describe storageclass csi-gce-pd-cmek
    

    コマンドの出力で、次のことを確認します。

    • プロビジョナーが pd.csi.storage.gke.io に設定されている。
    • 鍵の ID が disk-encryption-kms-key の形式になっている。
    Name:                  csi-gce-pd-cmek
    IsDefaultClass:        No
    Annotations:           None
    Provisioner:           pd.csi.storage.gke.io
    Parameters:            disk-encryption-kms-key=projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME,type=pd-standard
    AllowVolumeExpansion:  unset
    MountOptions:          none
    ReclaimPolicy:         Delete
    VolumeBindingMode:     WaitForFirstConsumer
    Events:                none
    

GKE に暗号化されたストレージ ボリュームを作成する

このセクションでは、新しい StorageClass と Cloud KMS 鍵によって暗号化された Kubernetes ストレージ ボリュームを動的にプロビジョニングします。

  1. 次の内容を pvc.yaml という名前の新しいファイルにコピーし、storageClassName の値が StorageClass オブジェクトの名前と一致していることを確認します。

    Filestore インスタンス

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: podpvc
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: csi-filestore-cmek
      resources:
        requests:
          storage: 1Ti
    

    永続ディスク

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: podpvc
    spec:
      accessModes:
        - ReadWriteOnce
      storageClassName: csi-gce-pd-cmek
      resources:
        requests:
          storage: 6Gi
    
  2. GKE クラスタに PersistentVolumeClaim(PVC)を適用します。

    kubectl apply -f pvc.yaml
    
  3. StorageClassvolumeBindingMode フィールドが WaitForFirstConsumer に設定されている場合、PVC を使用する Pod を作成してから確認する必要があります。次の内容を pod.yaml という名前の新しいファイルにコピーし、claimName の値が PersistentVolumeClaim オブジェクトの名前と一致していることを確認します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: web-server
    spec:
      containers:
       - name: web-server
         image: nginx
         volumeMounts:
           - mountPath: /var/lib/www/html
             name: mypvc
      volumes:
       - name: mypvc
         persistentVolumeClaim:
           claimName: podpvc
           readOnly: false
    
  4. GKE クラスタに Pod を適用します。

    kubectl apply -f pod.yaml
    
  5. クラスタの PersistentVolumeClaim のステータスを取得して、PVC が作成されていて、新しくプロビジョニングされた PersistentVolume にバインドされていることを確認します。

    Filestore インスタンス

    kubectl get pvc
    

    出力は次のようになります。

    NAME      STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS     AGE
    podpvc    Bound     pvc-e36abf50-84f3-11e8-8538-42010a800002   1Ti        RWO            csi-filestore-cmek  9s
    

    永続ディスク

    kubectl get pvc
    

    出力は次のようになります。

    NAME      STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS     AGE
    podpvc    Bound     pvc-e36abf50-84f3-11e8-8538-42010a800002   6Gi       RWO            csi-gce-pd-cmek  9s
    

これで、CMEK で保護された永続ディスクが GKE クラスタで使用できるようになります。

CMEK による保護の削除

永続ディスクで CMEK による保護を終了するには、Compute Engine のドキュメントの指示に従います。

CMEK 暗号化は、Filestore インスタンスからの削除はできません。

GKE と CMEK に関する組織のポリシー

GKE は、CMEK 保護を要求でき、CMEK 保護に使用できる Cloud KMS 鍵を制限できる CMEK 組織ポリシー(プレビュー)をサポートします。

container.googleapis.comconstraints/gcp.restrictNonCmekServices 制約のサービスの Deny ポリシーリストにある場合は、CMEK 保護を有効にしなければ GKE により次のリソースの作成が拒否されます。

  • 新しいクラスタとノードプール
  • 新しい Filestore インスタンスと Persistent Disk

組織のポリシーで constraints/gcp.restrictNonCmekCryptoKeyProjects 制約が構成されている場合、GKE は、許可されたプロジェクト、フォルダ、または組織の暗号鍵を使用して CMEK 保護リソースを作成します。

次のステップ