Azure Policy を使用して Azure Kubernetes Service (AKS) クラスターをセキュリティで保護する
Azure Policy を使用して、Azure Kubernetes Service (AKS) クラスターに組み込みのセキュリティ ポリシーを適用し実施することができます。 Azure Policy は、組織の標準を適用してコンプライアンスを大規模に評価するのに役立ちます。 AKS 用の Azure Policy アドオンをインストールした後、個々のポリシー定義またはイニシアチブ (policysets と呼ばれることもあります) と呼ばれるポリシー定義のグループをクラスターに適用できます。 AKS ポリシーの完全な一覧とイニシアチブの定義については、AKS 用の Azure Policy 組み込み定義に関するページを参照してください。
この記事では、ポリシー定義をクラスターに適用し、それらの割り当てが適用されていることを確認する方法について説明します。
前提条件
- この記事は、AKS クラスターがすでに存在していることを前提としています。 AKS クラスターが必要な場合は、Azure CLI、Azure PowerShell、または Azure portal を使用して作成できます。
- AKS クラスターにインストール済みの AKS 用の Azure Policy アドオンが必要です。
組み込みポリシー定義またはイニシアチブの割り当て
次の手順を使用して、Azure portal でポリシー定義またはイニシアチブを適用できます。
- Policy と呼ばれる、Azure portal での Azure Policy サービスに移動します。
- Azure Policy ページの左側のウィンドウで、 [定義] を選択します。
- [カテゴリ] で
Kubernetes
を選択します。 - 適用するポリシー定義またはイニシアチブを選択します。 この例では、[Linux ベースのワークロード用の Kubernetes クラスター ポッド セキュリティ ベースライン標準] イニシアチブを選択します。
- [割り当て] を選択します。
- [スコープ] には、Azure Policy アドオンが有効な AKS クラスターのリソース グループを設定します。
- [パラメーター] ページを選択し、 [効果] を
audit
からdeny
に更新して、ベースライン イニシアチブに違反している新しいデプロイをブロックします。 評価から除外する名前空間を追加することもできます。 この例では、規定値のままにしておきます。 - [確認と作成]>[作成] の順に選択して、ポリシーの割り当てを送信します。
カスタム ポリシー定義を作成して割り当てる
カスタム ポリシーを使用すると、Azure を使用する際の規則を定義することができます。 たとえば、次の種類のルールを適用できます。
- セキュリティの実行
- コスト管理
- 組織固有のルール (名前付けや場所など)
カスタム ポリシーを作成する前に、一般的なパターンとサンプルの一覧を確認して、該当するケースがすでにカバーされていないかどうかを確認してください。
カスタム ポリシー定義は JSON で記述されます。 カスタム ポリシーの作成について詳しくは、「Azure Policy の定義の構造」と「カスタム ポリシー定義の作成」を参照してください。
Note
Azure Policy では、templateInfo と呼ばれる新しいプロパティが利用され、制約テンプレートのソースの種類を定義できるようになっています。 ポリシー定義で templateInfo を定義するときに、constraintTemplate や constraint プロパティを定義する必要はありません。 その場合でも、apiGroups と kinds の定義は必要です。 詳細については、Azure Policy の効果についてのページを参照してください。
カスタム ポリシー定義を作成したら、「ポリシー定義の割り当て」に関するページを参照し、Kubernetes クラスターにポリシーを割り当てる手順を確認してください。
Azure Policy が実行されていることを検証する
次の
kubectl get
コマンドを使用して、ポリシーの割り当てがクラスターに適用されていることを確認します。kubectl get constrainttemplates
Note
ポリシーの割り当てが各クラスターに同期されるまでに最大 20 分かかる場合があります。
出力は次の出力例のようになります。
NAME AGE k8sazureallowedcapabilities 23m k8sazureallowedusersgroups 23m k8sazureblockhostnamespace 23m k8sazurecontainerallowedimages 23m k8sazurecontainerallowedports 23m k8sazurecontainerlimits 23m k8sazurecontainernoprivilege 23m k8sazurecontainernoprivilegeescalation 23m k8sazureenforceapparmor 23m k8sazurehostfilesystem 23m k8sazurehostnetworkingports 23m k8sazurereadonlyrootfilesystem 23m k8sazureserviceallowedports 23m
特権のあるポッドの拒否を検証する
まず、privileged: true
のセキュリティ コンテキストを持つポッドをスケジュールしたときに何が起こるかをテストしてみましょう。 このセキュリティ コンテキストは、ポッドの特権をエスカレートします。 イニシアチブでは特権のあるポッドが禁止されているため、要求は拒否されます。その結果、デプロイが拒否されます。
nginx-privileged.yaml
という名前のファイルを作成し、次の YAML マニフェストを貼り付けます。apiVersion: v1 kind: Pod metadata: name: nginx-privileged spec: containers: - name: nginx-privileged image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine securityContext: privileged: true
kubectl apply
コマンドを使用し、YAML マニフェストの名前を指定してポッドを作成します。kubectl apply -f nginx-privileged.yaml
次の出力例に示すように、このポッドは想定どおりスケジュールできません。
Error from server ([denied by azurepolicy-container-no-privilege-00edd87bf80f443fa51d10910255adbc4013d590bec3d290b4f48725d4dfbdf9] Privileged container is not allowed: nginx-privileged, securityContext: {"privileged": true}): error when creating "privileged.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by azurepolicy-container-no-privilege-00edd87bf80f443fa51d10910255adbc4013d590bec3d290b4f48725d4dfbdf9] Privileged container is not allowed: nginx-privileged, securityContext: {"privileged": true}
ポッドはスケジューリング段階に達しないため、続行する前に削除するリソースはありません。
特権のないポッドの作成をテストする
前の例では、コンテナー イメージは、自動的に root を使用して NGINX をポート 80 にバインドしようとしました。 ポリシー イニシアチブによりこの要求が拒否されるので、ポッドの起動が失敗します。 次に、特権アクセスなしで同じ NGINX ポッドを実行してみましょう。
nginx-unprivileged.yaml
という名前のファイルを作成し、次の YAML マニフェストを貼り付けます。apiVersion: v1 kind: Pod metadata: name: nginx-unprivileged spec: containers: - name: nginx-unprivileged image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine
kubectl apply
コマンドを使用し、YAML マニフェストの名前を指定してポッドを作成します。kubectl apply -f nginx-unprivileged.yaml
kubectl get pods
コマンドを使用して、ポッドの状態を確認します。kubectl get pods
出力は次の出力例のようになります。ここには、ポッドが正常にスケジュールされ、状態が [実行中] であることが示されています。
NAME READY STATUS RESTARTS AGE nginx-unprivileged 1/1 Running 0 18s
この例は、コレクション内のポリシーに違反するデプロイのみに影響するベースライン イニシアチブを示しています。 許可されたデプロイは引き続き機能します。
kubectl delete
コマンドを使用し、YAML マニフェストの名前を指定して、特権のない NGINX ポッドを削除します。kubectl delete -f nginx-unprivileged.yaml
ポリシーまたはイニシアチブを無効にする
次の手順を使用して、Azure portal でベースライン イニシアチブを削除できます。
- Azure portal の [Policy] ペインに移動します。
- [割り当て] を選択します。
- [Linux ベースのワークロード用の Kubernetes クラスター ポッド セキュリティ ベースライン標準] イニシアチブの横にある [...] ボタンを選択します。
- [割り当ての削除] を選択します。
次のステップ
Azure Policy のしくみについて詳しくは、次の記事をご覧ください。
Azure Kubernetes Service