Google Cloud Platform

Kubernetes Engine 1.8 でのコンテナ セキュリティの強化

編集部注 : 1.7 リリースの場合、Kubernetes UI による管理アクセスはデフォルトでは有効になっていません。Kubernetes Engine を実行していない場合は、ダッシュボード用のアクセス制御に関するこちらのドキュメントをご覧ください。実行している場合は、それを無効にすることをお勧めします。

Kubernetes は開発のペースが速く、知っておくべき新しい機能やセキュリティ構成が頻繁に追加されます。この投稿では、Kubernetes Engine クラスタのセキュリティ強化に向けた Google の指針を実践的に紹介します。最新の動向をいち早くチェックしたいお客様のために、アルファ クラスタで試せる新しいセキュリティ機能(本番利用は推奨されていません)についても説明します。

Kubernetes クラスタにおけるセキュリティのベスト プラクティス

Kubernetes クラスタを実行する際にお勧めしたいベスト プラクティスは次のとおりです。

  • ノードでは最小権限のサービス アカウントを使用する。
  • Kubernetes のウェブ UI を無効にする。
  • レガシー権限付与を無効にする(Kubernetes 1.8 の新しいクラスタではデフォルトで無効になっている)。

これらを実践に移す前に、次のようにいくつかの環境変数を設定する必要があります。

  #Your project ID
PROJECT_ID=
#Your Zone. E.g. us-west1-c
ZONE=
#New service account we will create. Can be any string that isn't an existing service account. E.g. min-priv-sa
SA_NAME=
#Name for your cluster we will create or modify. E.g. example-secure-cluster
CLUSTER_NAME=
#Name for a node-pool we will create. Can be any string that isn't an existing node-pool. E.g. example-node-pool
NODE_POOL=

ノードでは最小権限のサービス アカウントを使用

最小権限の原則は、セキュリティ侵害が発生した場合の “爆発半径” を縮小するのに役立ちます。この原則のもとでは、各コンポーネントに対して、機能の実行に必要な最小限の権限しか付与しないからです。あるコンポーネントが侵害されても、最小限の権限しかなければ、攻撃の連鎖による権限昇格は非常に困難になります。

各 Kubernetes Engine ノードには、関連づけられたサービス アカウントがあります。サービス アカウント ユーザーは、Cloud Console の IAM セクションに “Compute Engine default service account”(Compute Engine のデフォルトのサービス アカウント)として表示されます。このアカウントはデフォルトで幅広いアクセス権を持ち、さまざまなアプリケーションで便利ですが、Kubernetes Engine クラスタの実行に必要な権限よりも多くの権限を有しています。

そのため、Compute Engine のデフォルトのサービス アカウントの代わりに、最小限の権限を持つサービス アカウントを作成、使用して Kubernetes Engine クラスタを実行することをお勧めします。

Kubernetes Engine は、サービス アカウントが少なくとも monitoring.viewermonitoring.metricWriterlogging.logWriter のロールを持つことを必要とします。

次のコマンドを実行することで、Kubernetes Engine の運用に必要な最小限の権限を持つサービス アカウントを作成できます。

  gcloud iam service-accounts create "${SA_NAME}" \
  --display-name="${SA_NAME}"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
  --member "serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role roles/logging.logWriter
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
  --member "serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role roles/monitoring.metricWriter
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
  --member "serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role roles/monitoring.viewer
#if your cluster already exists, you can now create a new node pool with this new service account.
gcloud container node-pools create "${NODE_POOL}" \
  --service-account="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --cluster="${CLUSTER_NAME}"

Kubernetes Engine クラスタが他の Google Cloud サービスにアクセスする必要がある場合は、このサービス アカウントを再利用するのではなく、追加のロールを作成し、Kubernetes シークレットでワークロードにプロビジョニングすることをお勧めします。

注 : Google は現在、Kubernetes クラスタでの Google Cloud Platform(GCP)資格情報の取得を大幅に容易にするシステムを設計しており、このワークフローを一新する予定です。この取り組みを共有したい方は Kubernetes Container Identity Working Group にご参加ください。

Kubernetes のウェブ UI を無効に

Kubernetes Engine を使用する際は、Kubernetes のウェブ UI を無効にすることをお勧めします。Kubernetes のウェブ UI(Kubernetes ダッシュボード)は、高度な権限を持つ Kubernetes サービス アカウントに依存するからです。Cloud Console が同様の機能を提供しますので、Kubernetes Engine を使用するときは、そうした権限は不要になります。

次のコマンドで Kubernetes のウェブ UI を無効にできます。

  gcloud container clusters update "${CLUSTER_NAME}" \
    --update-addons=KubernetesDashboard=DISABLED

レガシー権限付与を無効に

Kubernetes 1.8 から、属性ベースのアクセス制御(ABAC)が Kubernetes Engine ではデフォルトで無効になっています。Kubernetes 1.6 でロール ベースのアクセス制御(RBAC)がベータ リリースされ、ユーザーの移行時間を確保するために ABAC は 1.8 まで有効になっていました。RBAC はセキュリティの面で大きなメリットがあり、現在では安定していますので、ABAC を無効にしても問題はありません。

まだ ABAC を使用している場合は、RBAC を使用するうえでの前提条件を確認してください。クラスタを旧バージョンからアップグレードして ABAC を使用している場合は、次のように、アクセス制御構成を更新しなければなりません。

  gcloud container clusters update "${CLUSTER_NAME}" \
  --no-enable-legacy-authorization

以上のすべての推奨事項に従って新しいクラスタを作成するには、次のコマンドを実行します。

  gcloud container clusters create "${CLUSTER_NAME}" \
  --service-account="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --no-enable-legacy-authorization \
  --disable-addons=KubernetesDashboard

クラスタ ネットワーク ポリシーを作成

上述のベスト プラクティスに加えて、クラスタのポッドおよびサービス間の通信を制御するネットワーク ポリシーを作成することもお勧めします。現在ベータ段階にある Kubernetes Engine のネットワーク ポリシー強制機能により、クラスタ内における攻撃の増幅が非常に難しくなるからです。

また、Kubernetes Network Policy API を使用すれば、Kubernetes Engine のポッド レベルでのファイアウォール ルールを作成することも可能です。このファイアウォール ルールは、クラスタ内でどのポッドとサービスが相互にアクセスできるかを規定します。

新しいクラスタの作成時にネットワーク ポリシー強制機能を有効にするには、gcloud beta を使って --enable-network-policy フラグを指定します。

  gcloud beta container clusters create "${CLUSTER_NAME}" \
  --project="${PROJECT_ID}" \
  --zone="${ZONE}" \
  --enable-network-policy

ネットワーク ポリシーを有効にしたら、実際にポリシーを定義する必要がありますが、これはお客様のトポロジに固有となりますので、ここでは具体的に説明しません。ちなみに、Kubernetes のドキュメントでは、ネットワーク ポリシーの概要と、シンプルな nginx 環境に即した定義の手順が的確に解説されています。

注 : Kubernetes Engine の Network Policy API のような機能は、GKE API の有意義なセキュリティ強化につながります。ただし、こうした機能は現時点ではアルファやベータゆえに、SLA やサポート終了予定ポリシーの対象ではなく、将来のリリースにおいて、下位互換性のない方法で変更される可能性があります。したがって、これらの機能を本番クラスタで使用することはお勧めしません。

まとめ

従来の情報セキュリティから学んだ教訓の多くはコンテナや Kubernetes、Kubernetes Engine にも当てはまりますが、こうした教訓を Google は新しい方法で活用しています。これらの教訓には、最小権限の原則の徹底、レガシー機能や不要な機能の無効化による攻撃対象領域の最小化、そして最も伝統的な教訓である、適切なファイアウォール ポリシーの作成などが含まれています。

詳細については Kubernetes Engine のウェブ ページドキュメントをご覧ください。コンテナや Google Cloud Platform を初めてお使いになる方は、ぜひ無料トライアルにお申し込みください。

* この投稿は米国時間 11 月 30 日、Google Kubernetes Engine の Product Manager である Aaron Small と、Software Engineer である Ike McCreery によって投稿されたもの(投稿はこちら)の抄訳です。

- By Aaron Small, Product Manager, Google Kubernetes Engine and Ike McCreery, Software Engineer, Google Kubernetes Engine