Container Engine for Kubernetesの保護

このトピックでは、Oracle Cloud InfrastructureContainer Engine for Kubernetes (OKEとも呼ばれる)を使用する場合のセキュリティの推奨事項について説明します。

マルチテナント・クラスタ

現時点では、同じクラスタ内で相互に分散したワークロードを実行することはお薦めしません。たとえば、同じクラスタ内で次のワークロードを実行しないでください:

  • 開発ワークロードと本番ワークロード
  • コントロール・プレーンとデータ・プレーン
  • 任意の顧客コードを実行するワークロード

また、同じクラスタに異なる信頼レベルでアクセスする複数のテナント、チームまたはユーザーが存在する場合は、別々のクラスタを使用することを検討する必要があります。以降の項で説明するように、KubernetesおよびOKEはワークロードを分離する方法を提供します。ただし、これらの方法は現在、ハード・マルチテナンシには十分ではありません。

ロールベースのアクセス制御(RBAC)

Kubernetesには、受信したユーザーまたはグループをロールにバンドルされた一連の権限と照合する統合ロールベース・アクセス制御(RBAC)コンポーネントが付属しています。これらの権限は、動詞(取得、作成、削除)とリソース(ポッド、サービス、ノード)を組み合せ、ネームスペースまたはクラスタにスコープを設定できます。クライアントが実行するアクションに応じて合理的なデフォルトの責任分担を提供する事前構成済ロールのセットが用意されています。

1つのオブジェクトの更新が他の場所でのアクションの原因になるしくみを理解しておくことが重要です。たとえば、ユーザーがポッドを直接作成することはできなくても、ユーザーにかわってポッドを作成するデプロイメントを作成できるようにすると、ユーザーはそれらのポッドを間接的に作成できるようになります。同様に、APIからノードを削除すると、そのノードにスケジュールされているポッドが終了し、他のノードで再作成されます。事前構成済ロールは柔軟性と一般的なユース・ケースとの間のバランスをとっていますが、権限のエスカレーションが間違って実行されないように、より制限されたロールを慎重に確認する必要があります。事前構成済ロールではニーズが満たされない場合は、ユース・ケースに固有のロールを作成できます。

必ず最小限の権限の原則に従って、ユーザーおよびKubernetesサービス・アカウントに必要な最小限の権限セットが確実に付与されるようにする必要があります。デフォルトでは、Oracle Cloud Infrastructure IAMまたはKubernetesサービス・アカウントでUSE CLUSTERアクセス権を持つユーザーは、検出ロールを除き、Kubernetes APIにアクセスできません。IAMをOKEと統合する方法を学習するには、アクセス制御とContainer Engine for Kubernetesについてを参照してください。

RBACバインディング(たとえば、ユーザーOCID、インスタンスOCID、サービス名)を作成するときは、プリンシパルのOCIDを使用する必要があります。

クラスタ・セキュリティ

クラスタのポッド・セキュリティ・ポリシーを設定して、Container Engine for Kubernetesで作成したクラスタでポッドが実行できる操作を制御できます。ポッド・セキュリティ・ポリシーは、ポッドがクラスタによって受け入れられる前に、セキュリティ関連の条件を満たすようにする手段です。たとえば、ポッド・セキュリティ・ポリシーを使用して次のことを実行できます:

  • ポッドで使用可能なストレージの選択肢を制限する
  • ポッドがアクセスできるホストのネットワーキングとポートを制限する
  • ポッドがルート・ユーザーとして実行されないようにする
  • ポッドが権限モードで実行されないようにする

クラスタにポッド・セキュリティ・ポリシーを定義している場合、ロールおよびバインディングを作成することで、リクエストしているユーザーまたはポッドによるポリシーの使用を認可する必要があります。クラスタに定義されたポッド・セキュリティ・ポリシーをクラスタに適用するかどうかは、クラスタのPodSecurityPolicyアドミッション・コントローラを有効にすることで指定できます。

詳細は、Container Engine for Kubernetesでのポッド・セキュリティ・ポリシーの使用を参照してください。

ノード・プール・セキュリティ

ノード・プール・コンパートメント

クラスタ内のノード・プールは、コンパートメントをまたがることができます。ただし、複数のコンパートメントを使用すると、ワーカー・ノードをグループ化して管理するのに便利ですが、クラスタ内のワーカー・ノード間の分離は実現されません。ワークロードは、コンパートメントに関係なく任意のノード・プールに対してスケジュールできます。ノード・プールでの複数のコンパートメントの使用に関する有効なユース・ケースは、ワーカー・ノードに対する動的グループおよびIAMポリシーを簡単に作成することです。複数のコンパートメントに関する無効なユース・ケースは、コンパートメントが一部のタイプのセキュリティ境界または分離を提供することを想定して、顧客ワークロードを実行している各ノード・プールを別々のコンパートメントに配置することです。

ノード・プールのサブネット

ノード・プールにはプライベート・サブネットのみを使用することをお薦めします。サービス・ゲートウェイは、Oracle Cloud Infrastructureサービスへのアクセスを提供するように構成する必要があります。サブネットがインターネット・ゲートウェイを使用してパブリックになっている場合は、サービス・ゲートウェイを使用できません。プライベート・サブネットがインターネットへのアクセスを必要とする場合は、NATゲートウェイを使用します。

ポッドがアクセスできるノードの制御

デフォルトでは、ポッドはクラスタ内のどのノードでもスケジュールできます。Kubernetesには、ノードへのポッドの配置を制御するための豊富なポリシー・セットと、エンド・ユーザーが使用できるテイント・ベースのポッドの配置とエビクションが用意されています。多くのクラスタで、これらのポリシーを使用したワークロードの分離は、作成者がツールを使用して採用または適用する規則にすることができます。これらの配置コントロールは、デプロイメント機能を持つユーザーが信頼できない場合、マルチテナント環境では適切ではありません。信頼できないユーザーがコードをデプロイしている場合は、信頼できないグループごとにクラスタを検討する必要があります。

インスタンス・プリンシパルに付与されるアクセスの制限

デフォルトでは、ノード上のすべてのポッドは、インスタンス・メタデータ・エンドポイントを使用してインスタンス・プリンシパル証明書にアクセスできます。インスタンス・プリンシパル経由での権限のエスカレーションを防ぐために、特定のノード・プールのポッドが機能するために必要な最小限の権限セットを持つように、異なる動的グループを使用してノード・プール間でワークロードを分離する必要があります。

たとえば、次の2つのワークロードがあり、両方に異なるアクセス権が必要であるとします:

  • LogArchiver - オブジェクト・ストレージ内のバケットおよびオブジェクトを管理するためのアクセス権が必要です
  • HostMonitor - インスタンスを管理するためにコンピュートAPIにアクセスする必要があります

最も簡単な方法は、これらを同じノード・プール内でスケジューリングし、すべての必要なアクセス権を持つインスタンス・プリンシパルを提供することです。ただし、このようにすると、ワークロードの1つが危険にさらされた場合の影響が大きくなります。よりよい方法は、インスタンス・プリンシパルが適用可能なワークロードに必要とする限定されたアクセス権のセットを使用して、個々のノード・プールにワークロードをスケジュールすることです。

インスタンス・メタデータへのコンテナ・アクセスのブロック

アクセスをブロックする優先方法は、デフォルトの「すべてを拒否」ポリシーを持つネットワーク・ポリシー・プラグインを使用することです。その後、ラベル・セレクタを介して、KubernetesのNetworkPolicyリソースを使用してポッドおよびネットワークへのアクセス権を明示的に付与します。ネットワーク・ポリシー・プラグインがインストールされていない場合は、IPTablesルールを使用してホストのすべてのポッドからのアクセスを制限できます。この方法は、ホスト上のポッドのサブセットをブロックする場合には使用しないことをお薦めします。

重要: NetworkPolicysおよび次のIPTableルールは、ポッド・オーバーレイ・ネットワークのコンテナにのみ適用されます。ホスト・ネットワークで実行中のコンテナおよびサービスは、次のいずれのオプションにも影響を受けません:

iptables --insert FORWARD 1 --in-interface veth+ --destination 169.254.0.0/16 --jump DROP

ネットワーク・セキュリティ

OKEクラスタで実行されるポッドは、多くの場合、クラスタ内の他のポッドやクラスタ外部のサービスと通信する必要があります。Container Engine for Kubernetesには、クラスタ内のワークロードとの間の通信を保護するために複数のオプションが用意されています。ネットワーク・セキュリティを最適な状態にするためには、ネットワーク・ポリシー(ポッドレベルのネットワーク通信を保護するため)とセキュリティ・リスト(ホストレベルのネットワーク通信を保護するため)の組合せを使用して評価する必要があります。

ネットワーク・ポリシー

Kubernetesのネットワーク・ポリシーにより、管理者はポッドのグループがクラスタ内の他のポッドとどのように通信できるかを定義できます。さらに、ネットワーク・ポリシーを使用すると、ポッドのグループがクラスタ外部のサービス(たとえば、Oracle Cloud Infrastructureサービス)とどのように通信できるかを定義できます。

ネットワーク・ポリシーを使用してアクセスを制限するには、ネットワーク・プラグインをインストールする必要があります。ネットワーク・プラグインは、Kubernetesで定義されているネットワーク・ポリシーを構成して適用します。数多くのネットワーク・プラグイン・オプションがあります。ここに示す手順に従って、クラスタ内にCalicoをインストールして構成します。ネットワーク・ポリシー・プラグインは、ホスト上のアクセスを制限することで機能します。OKEへのCalicoのインストールの詳細は、例: Calicoのインストールおよびネットワーク・ポリシーの設定を参照してください。

ノード・プール・セキュリティ・リスト

ネットワーク管理者は、ノード・プール・サブネット上でセキュリティ・リスト・ルールを定義して、ワーカー・ノードとの間のアクセスを制限できます。セキュリティ・リスト・ルールを定義すると、管理者はクラスタ内のホスト上でオーバーライドできないネットワーク制限を適用できます。

すべてのポッド間通信がワーカー・ノードのVXLANオーバーレイ・ネットワークで発生するため、セキュリティ・リスト・ルールを使用してポッド間通信を制限することはできません。ただし、セキュリティ・リストを使用して、ワーカー・ノードとの間のアクセスを制限できます。

重要: クラスタが機能できるように、ノード・プール・サブネットに存在する必要があるセキュリティ・リスト・ルールの最小セットがあります。セキュリティ・リスト・ルールを変更する前のセキュリティ・リスト・ルールの最小セットの詳細は、ネットワーク・リソース構成の例を参照してください。

ワークロード・セキュリティのベストプラクティス

タグのかわりにイメージ・ダイジェストを使用する

タグを使用してイメージをプルせずに、イメージ・ダイジェストを使用したイメージのプルのみを行うことをお薦めします(イメージ・タグは可変であるため)。イメージ・ダイジェストは、イメージのsha256ダイジェストです。これにより、ダウンロードされたイメージが予想どおりであることをDockerが検証できます。

イメージ・ダイジェストIDの例:

sha256:77af4d6b9913e693e8d0b4b294fa62ade6054e6b2f1ffb617ac955dd63fb0182

次の例に示すように、イメージをプルします:

docker pull acme@sha256:77af4d6b9913e693e8d0b4b294fa62ade6054e6b2f1ffb617ac955dd63fb0182

次のコマンドを使用して、ローカル・イメージのすべてのダイジェストを表示できます:

docker images --digests

リソース使用率の制限

リソース割当て制限は、ネームスペースに付与されるリソースの数または容量を制限します。これは、名前空間が割り当てることのできるCPU、メモリーまたは永続ディスクの量を制限するために最も頻繁に使用されますが、各ネームスペースに存在するポッド、サービスまたはボリュームの数も制御できます。

制限範囲は、メモリーなどの一般的に予約されているリソースについてユーザーが不当に高い値または低い値をリクエストするのを防ぐため、または何も指定しない場合にデフォルトの制限を提供するために、前述のリソースの一部の最大または最小サイズを制限します。

リソースの割当て制限へのアクセスは、KubernetesのRBACポリシーを介して制限できます。これにより、管理者は、クラスタのユーザーが、アクセス権を持たないリソースを使用できないようにすることができます。詳細は、Kubernetesのドキュメントのクラスタでのリソース使用率の制限を参照してください。

Tillerアドオンの無効化

OKEにはオプションのTillerアドオンが用意されています。これにより、Helm+Tillerのインストールおよび使用を簡単に行うことができ、Kubernetesのプロビジョニングおよび実行を迅速に行うことができます。Tillerに関連するセキュリティ・リスクがあるため、本番クラスタにこのアドオンを使用することはお薦めしません。Tillerにプロビジョニングされたクラスタには、Tillerに対して行われたAPIコールの認証または認可がないため、リクエストの属性を提供できません。したがって、Tillerに接続できるすべての演算子またはサービスは、Tillerアクセスを使用してそのAPIを起動できます。

Tillerに関連するセキュリティの問題を解決するために、Helm V3が開発されました。Helm V3リリースでは、HelmからTillerが完全に削除されました。Helm+Tillerで提供される機能を利用する場合は、Helm V3の使用を検討することをお薦めします。

ノート

既存のクラスタでTillerのアドオンを無効にするには、Oracle Supportに連絡してください。

Kubernetes Dashboardアドオンの無効化

OKEはオプションのKubernetes Dashboardアドオンを提供し、Kubernetes Dashboardを簡単にインストールする方法を用意しています。Kubernetes Dashboardは、OKEによって、実行に必要な最小限の権限セットとともにインストールされます。追加の資格証明を提供せずにダッシュボードを使用することはできません。詳細は、「Kubernetesダッシュボードを使用したクラスタへのアクセス」を参照してください。

ダッシュボードは、特にKubernetesの新規ユーザーに役立ちます。ただし、拡張可能な認証サポートがないため、このアドオンを本番クラスタにインストールすることはお薦めしません。したがって、コンソールを使用してクラスタを作成するときに、Kubernetesダッシュボードをインストールするように指定することはできません。Kubernetesダッシュボードをインストールする場合は、APIを使用してクラスタを作成し、isKubernetesDashboardEnabled属性をtrueに設定します。

Kubernetes Dashboardをインストールする場合は、ロード・バランサまたはイングレス・コントローラを介して外部に公開するのではなく、クラスタ内でアクセスを制限することをお薦めします。Kubernetes Dashboardは、Kubernetesクラスタへのアクセスの取得に使用される一般的な攻撃ベクトルです。

ノート

既存のクラスタでKubernetes Dashboardアドオンを無効にするには、Oracle Supportに連絡してください。