セキュリティの概要

このページでは、暗号化やノード構成など、GKE on Azure のセキュリティ アーキテクチャについて説明します。

GKE クラスタには、コンテナ イメージのコンテンツ、コンテナのランタイム、クラスタ ネットワーク、クラスタ API サーバーへのアクセスなど、ワークロードの保護に役立つ機能があります。

GKE クラスタを使用すると、クラスタの特定の責任を担うことに同意したことになります。詳細については、GKE クラスタの責任の共有をご覧ください。

保存中のデータの暗号化

保存中のデータの暗号化は、転送中のデータとは異なり、保存されたデータの暗号化です。GKE on Azure は、デフォルトで Azure プラットフォーム マネージド鍵を使用して、etcd およびストレージ ボリューム内の保存データを暗号化します。

GKE on Azure クラスタは、Azure Disk ボリュームにデータを保存します。これらのボリュームは、Azure Key Vault 鍵を使用して、保存時に常に暗号化されます。クラスタとノードプールを作成する際には、クラスタの基盤となる Disk ボリュームを暗号化するために顧客管理の Key Vault 鍵を指定できます。鍵を指定しない場合、Azure では、クラスタが稼働している Azure リージョン内でデフォルトの Azure マネージド鍵が使用されます。

また、すべての GKE クラスタでは、etcd に保存されている Kubernetes Secret オブジェクトなどの機密データ用に、アプリケーション レイヤでの Secret の暗号化が有効になっています。etcd データが保存されている基盤となるボリュームに攻撃者がアクセスしたとしても、これらのデータは暗号化されます。

クラスタを作成する際に、--database-encryption-kms-key-arn パラメータで Azure Key Vault 鍵を指定できます。この鍵はアプリケーション データの暗号化に使用されます。クラスタの作成時に鍵を指定しない場合、GKE on Azure によってクラスタ用の鍵が自動的に作成されます。このリソース フィールドは不変であり、クラスタの作成後に変更することはできません。

Key Vault 鍵を手動で作成するか、ハードウェア セキュリティ モジュール(HSM)で、お客様所有の鍵(BYOK)を使用することもできます。詳細については、お客様所有の鍵の使用をご覧ください。

アプリケーション レベルの暗号化の仕組み

Kubernetes では、エンベロープ暗号化と呼ばれる手法でアプリケーション レベルの暗号化が行われます。ローカル鍵(一般にデータ暗号鍵、DEKと呼ばれます)は、Secret を暗号化するために使用されます。次に、DEK 自体が鍵暗号鍵(KEK)と呼ばれる第二の鍵で暗号化されます。KEK は Kubernetes に保存されません。新しい Kubernetes Secret を作成すると、クラスタでは次の処理が行われます。

  1. Kubernetes API サーバーは乱数生成ツールを使用して、Secret に一意の DEK を生成します。

  2. Kubernetes API サーバーが、DEK を使用して Secret をローカルに暗号化します。

  3. Kubernetes API サーバーが、DEK を暗号化するために Azure Key Vault に送信します。

  4. Azure Key Vault が、事前に生成された KEK を使用して DEK を暗号化し、暗号化された DEK を Kubernetes API サーバーの Azure Key Vault プラグインに返します。

  5. Kubernetes API サーバーは暗号化された Secret と暗号化された DEK を etcd に保存します。平文の DEK はディスクに保存されません。

  6. Kubernetes API サーバーは、メモリ内のキャッシュ エントリを作成して暗号化された DEK を平文の DEK にマッピングします。これにより、API サーバーは Azure Key Vault をクエリせずに、最近アクセスされた Secret を復号できます。

クライアントが Kubernetes API サーバーから Secret をリクエストすると、次の処理が実行されます。

  1. Kubernetes API サーバーは、暗号化された Secret と暗号化された DEK を etcd から取得します。

  2. Kubernetes API サーバーは、キャッシュに既存のマップエントリがあるかチェックし、見つかった場合はそれで Secret を復号します。

  3. 一致するキャッシュ エントリがない場合、API サーバーは、KEK を使用して復号するため DEK を Azure Key Vault に送信します。復号された DEK を使用して Secret が復号されます。

  4. Kubernetes API サーバーが、復号された Secret をクライアントに返します。

Key Vault ファイアウォールによる構成ファイルの暗号化

暗号化のために公開鍵を渡す場合、サービス プリンシパルに暗号化の権限は必要ありませんが、ロールの割り当てを管理する権限が必要です。その最も簡単な方法は、Azure の User Access Administrator 組み込みロールをサービス プリンシパルに割り当てることです。

Azure Key Vault の保護をさらに強化するには、Azure Key Vault ファイアウォールを有効にします。これにより、GKE on Azure では、暗号化に公開鍵を使用して Key Vault へのネットワーク アクセスを回避できます。

ファイアウォールを構成するには、Azure CLI を使用して Key Vault 鍵をダウンロードします。この鍵は、Google Cloud CLI でクラスタを作成するときに --config-encryption-public-key へ渡します。

すべてのサブネットで、クラスタに使用される Key Vault のサービス エンドポイントを有効にする必要があります。詳細については、Azure Key Vault の仮想ネットワーク サービス エンドポイントをご覧ください。

鍵のローテーション

証明書のローテーションとは対照的に、鍵のローテーションは、鍵暗号鍵(KEK)に含まれる基盤となる暗号マテリアルを変更する動作です。このオペレーションは、スケジュール設定されたローテーションの一環として自動的にトリガーできます。また、鍵が不正使用された可能性があるセキュリティ インシデントの後に手動で行うこともできます。鍵のローテーションによって、暗号鍵と復号鍵の元データを含む鍵の単一フィールドのみが置き換えられます。

詳細については、鍵のローテーションをご覧ください。

クラスタの信頼性

すべてのクラスタ通信では、Transport Layer Security(TLS)が使用されます。各クラスタには、次の主要な自己署名ルート認証局(CA)がプロビジョニングされています。

  • クラスタルート CA は、API サーバーに送信されたリクエストの検証に使用されます。
  • etcd ルート CA は、etcd レプリカに送信されたリクエストの検証に使用されます。

クラスタにはそれぞれ一意のルート CA があります。あるクラスタの CA の信頼が損なわれても、他のクラスタの CA は影響を受けません。ルート CA の有効期間はすべて 30 年です。

ノードのセキュリティ

GKE on Azure は、Azure VM インスタンスのノードプールにワークロードをデプロイします。次のセクションでは、ノードのセキュリティ機能について説明します。

Ubuntu

ノードは、Kubernetes コントロール プレーンとノードを実行するために、最適化されたバージョンの Ubuntu OS を実行します。詳細については、Ubuntu ドキュメントのセキュリティ機能をご覧ください。

GKE クラスタは、次のようないくつかのセキュリティ機能を実装しています。

  • 最適化されたパッケージのセット

  • Google Cloud 向けにカスタマイズされた Linux カーネル

  • 制限付きユーザー アカウントと root ログインの無効化

Ubuntu には、次のような別のセキュリティ ガイドも用意されています。

ワークロードを保護する

Kubernetes では、コンテナベースのワークロードのプロビジョニング、スケーリング、更新を迅速に行うことができます。このセクションでは、クラスタと Google Cloud サービスでコンテナを実行する場合の副作用を制限する方法について説明します。

Pod コンテナのプロセス権限を制限する

コンテナ化されたプロセスの権限を制限することは、クラスタのセキュリティにとって重要です。セキュリティ関連のオプションは、セキュリティ コンテキストを使用して設定できます。これらの設定により、次のようなプロセスのセキュリティ設定を変更できます。

  • プロセスを実行しているユーザーとグループ。
  • 利用可能な Linux 機能
  • 権限昇格

GKE on Azure ノードのデフォルトのオペレーティング システムである Ubuntu は、すべてのコンテナに対してデフォルトの Docker AppArmor セキュリティ ポリシーを使用します。プロファイルのテンプレートは GitHub で確認できます。特に、このプロファイルではコンテナの以下の機能が拒否されます。

  • プロセス ID ディレクトリ(/proc/)で直接ファイルに書き込む
  • /proc/ にないファイルに書き込む
  • /proc/sys 内に存在する /proc/sys/kernel/shm* 以外のファイルに書き込む
  • ファイル システムをマウントする

ワークロードの自己変更機能を制限する

特定の Kubernetes ワークロード(特にシステム ワークロード)には、自己変更の権限があります。たとえば、一部のワークロードは垂直方向に自動スケーリングされます。これは便利ですが、すでにノードを不正使用した攻撃者がクラスタ内でさらにエスカレーションする可能性があります。たとえば、攻撃者がノード上のワークロード自体を変更して、同じ Namespace 内に存在する、より権限の高いサービス アカウントとして実行するおそれがあります。

理想的には、ワークロードにはそもそも自己変更機能を付与するべきではありません。自己変更が必要な場合は、クラスタに Policy Controller または Gatekeeper をインストールして、オープンソースの Gatekeeper ライブラリのいくつかの有用なセキュリティ ポリシーを提供する NoUpdateServiceAccount などの制約を適用することで、権限を制限できます。

ポリシーをデプロイする場合、通常はクラスタのライフサイクルを管理するコントローラがポリシーをバイパスできるようにする必要があります。これは、コントローラがクラスタに変更を加える(クラスタのアップグレードを適用するなど)ことができるようにするために必要です。たとえば、GKE on Azure に NoUpdateServiceAccount ポリシーをデプロイする場合は、Constraint で次のパラメータを設定する必要があります。

parameters:
  allowedGroups: []
  allowedUsers:
  - service-PROJECT_NUMBER@gcp-sa-gkemulticloud.iam.gserviceaccount.com

PROJECT_NUMBER は、クラスタをホストするプロジェクトの番号(ID ではありません)に置き換えます。

専用ノードプールでワークロードを分離する

Kubernetes の taint と toleration を使用して、特定タイプのワークロードを実行する特定のノードプールを指定できます。たとえば、ほとんどのシステム マネージド ワークロードとは別のユーザー ワークロードをスケジュールすることや、信頼レベルの異なるワークロードを各ノードプールに配置するよう GKE on Azure に指示できます。

taint と toleration を使用したワークロードの分離は、保証されたセキュリティ対策ではありません。これは、GKE on Azure が提供する他の強化策と併用する場合のみ使用してください。

詳細については、専用ノードプールにワークロードを分離するをご覧ください。

次のステップ