保存時に既に暗号化されている機密データを復号化する

Kubernetesにおいて、永続的なAPIリソースデータの書き込みが可能なすべてのAPIは、保存時の暗号化をサポートしています。 例えば、シークレットに対して保存時の暗号化を有効にできます。 保存時暗号化は、etcdクラスターまたはkube-apiserverを実行しているホスト上のファイルシステムに対するシステムレベルの暗号化に加えて行われます。

このページでは、保存時のAPIデータの暗号化を無効にして、APIデータを暗号化せずに保存する方法を説明します。 パフォーマンス向上のためにこれが必要になる場合もありますが、通常は、暗号化する必要があると判断したデータは、暗号化したままにしておくことが適切です。

始める前に

  • Kubernetesクラスターが必要、かつそのクラスターと通信するためにkubectlコマンドラインツールが設定されている必要があります。 このチュートリアルは、コントロールプレーンのホストとして動作していない少なくとも2つのノードを持つクラスターで実行することをおすすめします。 まだクラスターがない場合、minikubeを使って作成するか、 以下のいずれかのKubernetesプレイグラウンドも使用できます:

  • このタスクでは、各コントロールプレーンノードで、Kubernetes APIサーバーがstatic Podとして実行されていることを前提とします。

  • クラスターのコントロールプレーンは、etcd v3.x(メジャーバージョン3、マイナーバージョンは任意)の使用が必須です。

  • カスタムリソースを暗号化するには、クラスターがKubernetes v1.26以降を実行している必要があります。

  • 既に暗号化されたAPIデータが存在している必要があります。

バージョンを確認するには次のコマンドを実行してください: kubectl version.

保存時の暗号化が既に有効かどうかを確認する

デフォルトでは、APIサーバーはリソースの平文表現を保存するidentityプロバイダーを使用します。 デフォルトのidentityプロバイダーは、いかなる機密性保護も提供しません。

kube-apiserverプロセスは、設定ファイルへのパスを指定する引数--encryption-provider-configを受け入れます。このファイルを指定すると、その内容に基づき、etcdでのKubernetes APIデータの暗号化方式が制御されます。 指定されていない場合、保存時の暗号化は有効になりません。

この設定ファイルはYAML形式で、EncryptionConfigurationという種類の設定APIを表します。 設定の例はEncryption at rest configurationで確認できます。

--encryption-provider-configが指定されている場合は、どのリソース(例: secrets)が暗号化対象として設定されているか、またどのプロバイダーが利用されているかを確認してください。 そのリソースタイプで優先されているプロバイダーがidentityではないことを確認します。 保存時の暗号化を無効にする場合のみ、identity(暗号化なし)をデフォルトとして設定します。

リソースで最初にリストされているプロバイダーがidentity以外であることを確認してください。 もしそう設定されていれば、そのリソースに書き込まれる新しいデータはすべて、設定に従って暗号化されます。 もし最初にリストされているプロバイダーがidentityである場合、そのリソースは暗号化されずにetcdへ書き込まれています。

すべてのデータを復号化する

この例では、保存時のSecret APIの暗号化を停止する方法を示します。 他の種類のAPIを暗号化している場合は、必要に応じて手順を調整してください。

暗号化設定ファイルを特定する

まず、APIサーバーの設定ファイルを特定します。各コントロールプレーンノードでは、kube-apiserver用のstatic Podマニフェストが、コマンドライン引数--encryption-provider-configを指定しています。 このファイルは、hostPathボリュームマウントを使用してstatic Podにマウントされていることが多いです。 ボリュームの場所を確認し、ノードのファイルシステム上でファイルを見つけて内容を確認します。

APIサーバーを設定してオブジェクトを復号化する

保存時の暗号化を無効にするには、暗号化設定ファイルの最初のエントリとしてidentityプロバイダーを追加します。

以下が既存のEncryptionConfigurationファイルの例です。

---
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            # 下記は例であり有効なキーではないので、暗号化に使わないでください。
            - name: example
              secret: 2KfZgdiq2K0g2YrYpyDYs9mF2LPZhQ==

次のように変更します。

---
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - identity: {} # この行を追加してください。
      - aescbc:
          keys:
            - name: example
              secret: 2KfZgdiq2K0g2YrYpyDYs9mF2LPZhQ==

このノードでkube-apiserver Podを再起動します。

他のコントロールプレーンホストを再設定する

クラスター内に複数のAPIサーバーがある場合、変更を各APIサーバーに順番にデプロイする必要があります。 各コントロールプレーンホストが同一の暗号化設定を使用していることを確認してください。

強制的に復号化する

次に、以下のコマンドを実行して、すべてのSecretを強制的に復号化します。

# 異なる種類のオブジェクトを復号化する場合は、一致するように「secrets」を変更します。
kubectl get secrets --all-namespaces -o json | kubectl replace -f -

既存の暗号化済みリソースをすべて、暗号化を使用しないデータとして書き換えたら、kube-apiserverから暗号化設定を削除できます。

削除するコマンドラインオプションは次のとおりです。

  • --encryption-provider-config
  • --encryption-provider-config-automatic-reload

変更を反映するには、kube-apiserver Podを再起動します。

他のコントロールプレーンホストを再設定する

クラスター内に複数のAPIサーバーがある場合は、各APIサーバーに順番に変更をデプロイする必要があります。

各コントロールプレーンホストで同じ暗号化設定を使用していることを確認してください。

次の項目