AKS でネットワーク ポリシーを使用して、ポッド間のトラフィックをセキュリティ保護する

Kubernetes で最新のマイクロサービス ベースのアプリケーションを実行するときは、どのコンポーネントが互いに通信できるかを制御したいことがよくあります。 Azure Kubernetes Service (AKS) クラスター内のポッド間のトラフィック フローの制御には、最小特権の原則を適用する必要があります。 たとえば、バックエンド アプリケーションへの直接のトラフィックをブロックしたい場合があります。 Kubernetes のネットワーク ポリシー機能を使用すると、クラスター内のポッド間のイングレス トラフィックとエグレス トラフィックのルールを定義できます。

この記事では、ネットワーク ポリシー エンジンをインストールし、AKS 内のポッド間のトラフィック フローを制御するために Kubernetes ネットワーク ポリシーを作成する方法について説明します。 ネットワーク ポリシーを、AKS の Linux ベースまたは Windows ベースのノードとポッドに使用できます。

ネットワーク ポリシーの概要

既定では、AKS クラスター内のすべてのポッドが制限なしでトラフィックを送受信できます。 セキュリティを向上させるために、トラフィック フローを制御するルールを定義できます。 たとえば、バックエンド アプリケーションは多くの場合、必要なフロントエンド サービスにのみ公開されます。 または、データベース コンポーネントは、そこに接続するアプリケーション層からのみアクセスできます。

ネットワーク ポリシーは、ポッド間の通信のアクセス ポリシーを定義する Kubernetes の仕様です。 ネットワーク ポリシーを使用して、トラフィックを送受信するための順序付けされたルール セットを定義します。 1 つまたは複数のラベル セレクターに一致するポッドのコレクションにルールを適用します。

ネットワーク ポリシー ルールは、YAML マニフェストとして定義されます。 ネットワーク ポリシーは、デプロイまたはサービスも作成する、より広範囲のマニフェストの一部として含めることができます。

AKS でのネットワーク ポリシーのオプション

Azure には、ネットワーク ポリシーを適用するための 3 つのネットワーク ポリシー エンジンが用意されています。

  • Azure CNI Powered by Cilium を使用する AKS クラスターの Cilium
  • Azure ネットワーク ポリシー マネージャー
  • Calico: Tigera によって設立されたオープンソース ネットワークおよびネットワーク セキュリティ ソリューション。

Cilium は、推奨されるネットワーク ポリシー エンジンです。 Cilium は、"IPTables" に比べ全般により効率的な Linux のバークレイ パケット フィルター (BPF) を使用して、トラフィックにネットワーク ポリシーを適用します。 詳細については、Azure CNI Powered by Cilium のドキュメントを参照してください。
指定したポリシーを適用するために、Linux 用 Azure ネットワーク ポリシー マネージャーでは Linux IPTable が使われます。 Windows 用 Azure ネットワーク ポリシー マネージャーでは Host Network Service (HNS) ACLPolicies が使われます。 ポリシーは、許可される IP ペアと許可されない IP ペアのセットに変換されます。 その後、これらのペアは IPTable または HNS ACLPolicy フィルタ ルールとしてプログラミングされます。

ネットワーク ポリシー エンジンの違い: Cilium、Azure NPM、Calico

機能 Azure ネットワーク ポリシー マネージャー Calico Cilium
サポートされているプラットフォーム Linux、Windows Server 2022 (プレビュー)。 Linux、Windows Server 2019 および 2022。 Linux
サポートされているネットワーク オプション Azure Container Networking Interface (CNI)。 Azure CNI (Linux、Windows Server 2019 および 2022) と kubenet (Linux)。 Azure CNI。
Kubernetes 仕様の準拠 サポートされているすべてのポリシーの種類 すべてのポリシーの種類がサポートされています。 すべてのポリシーの種類がサポートされています。
その他の機能 なし。 グローバル ネットワーク ポリシー、グローバル ネットワーク セット、およびホスト エンドポイントで構成される拡張ポリシー モデル。 calicoctl CLI を使用した拡張機能の管理の詳細については、calicoctl ユーザー リファレンスを参照してください。 なし。
サポート Azure サポートとエンジニアリング チームによってサポートされています。 Azure サポートとエンジニアリング チームによってサポートされています。 Azure サポートとエンジニアリング チームによってサポートされています。

制限事項

Azure ネットワーク ポリシー マネージャーは IPv6 をサポートしていません。 それ以外については、Azure ネットワーク ポリシー マネージャーは Linux でのネットワーク ポリシーの仕様を完全サポートします。

Windows では、Azure ネットワーク ポリシー マネージャーは次をサポートしていません。

  • 名前付きポート。
  • ストリーム制御伝送プロトコル (SCTP)。
  • 負の一致ラベルまたは名前空間セレクター (例: debug=true を除くすべてのラベル)。
  • except クラスレス ドメイン間ルーティング (CIDR) ブロック (例外がある CIDR)。

Note

サポートされていないポリシーが作成されると、Azure ネットワーク ポリシー マネージャーのポッド ログにエラーが記録されます。

スケール

Linux 用 Azure ネットワーク ポリシー マネージャーでは、250 ノードおよび 2 万ポッドを超えるスケーリングは許可されません。 これらの制限を超えてスケーリングしようとすると、"メモリ不足" (OOM) エラーが発生する場合があります。 メモリ上限を増やすには、サポート チケットを作成します。

開始する前に

Azure CLI バージョン 2.0.61 以降がインストールされて構成されている必要があります。 バージョンを確認するには、az --version を実行します。 インストールまたはアップグレードする必要がある場合は、Azure CLI のインストールに関するページを参照してください。

AKS クラスターを作成してネットワーク ポリシーを有効にする

ネットワーク ポリシーの動きを見るために、ネットワーク ポリシーをサポートする AKS クラスターを作成し、ポリシーの追加に取り組みます。

Azure ネットワーク ポリシー マネージャーを使うには、Azure CNI プラグインを使う必要があります。 Calico は、Azure CNI プラグインまたは Kubenet CNI プラグインで使用できます。

次のサンプル スクリプトでは、システム割り当て ID を使って AKS クラスターを作成し、Azure ネットワーク ポリシー マネージャーを使ってネットワーク ポリシーを有効にします。

Note

Calico は、--network-plugin azure または --network-plugin kubenet パラメーターと共に使用できます。

システム割り当て ID を使用する代わりに、ユーザー割り当て ID を使用することもできます。 詳細については、マネージド ID の使用に関するページを参照してください。

Azure ネットワーク ポリシー マネージャーが有効な AKS クラスターを作成する - Linux のみ

このセクションでは、Linux ノード プールを使用し Azure ネットワーク ポリシー マネージャーを有効にしてクラスターを作成します。

最初に、変数 $RESOURCE_GROUP_NAME および $CLUSTER_NAME の値を置き換えます。

$RESOURCE_GROUP_NAME=myResourceGroup-NP
$CLUSTER_NAME=myAKSCluster
$LOCATION=canadaeast

AKS クラスターを作成して、azurenetwork-pluginnetwork-policy に指定します。

クラスターを作成するには、次のコマンドを使用します。

az aks create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --node-count 1 \
    --network-plugin azure \
    --network-policy azure

Azure ネットワーク ポリシー マネージャーが有効な AKS クラスターを作成する - Windows Server 2022 (プレビュー)

このセクションでは、Windows ノード プールを使用し Azure ネットワーク ポリシー マネージャーを有効にしてクラスターを作成します。

Note

Windows ノードで Azure ネットワーク ポリシー マネージャーを使用できるのは、Windows Server 2022 だけです

aksプレビューの Azure CLI 拡張機能をインストールする

重要

AKS のプレビュー機能は、セルフサービスのオプトイン単位で利用できます。 プレビューは、"現状有姿" および "利用可能な限度" で提供され、サービス レベル アグリーメントおよび限定保証から除外されるものとします。 AKS プレビューは、ベストエフォート ベースでカスタマー サポートによって部分的にカバーされます。 そのため、これらの機能は、運用環境での使用を意図していません。 詳細については、次のサポート記事を参照してください。

aks-preview 拡張機能をインストールするには、次のコマンドを実行します。

az extension add --name aks-preview

リリースされた最新バージョンの拡張機能に更新するには、次のコマンドを実行します。

az extension update --name aks-preview

WindowsNetworkPolicyPreview 機能フラグを登録する

WindowsNetworkPolicyPreview 機能フラグは、次の例のとおり、WindowsNetworkPolicyPreview コマンドを使用して登録します。

az feature register --namespace "Microsoft.ContainerService" --name "WindowsNetworkPolicyPreview"

状態が [登録済み] と表示されるまでに数分かかります。 登録の状態は、az feature show コマンドで確認します。

az feature show --namespace "Microsoft.ContainerService" --name "WindowsNetworkPolicyPreview"

状態が [Registered] と表示されたら、az provider register コマンドを使用して Microsoft.ContainerService リソース プロバイダーの登録を最新の情報に更新します。

az provider register --namespace Microsoft.ContainerService

AKS クラスターを作成する

次に、変数 $RESOURCE_GROUP_NAME$CLUSTER_NAME$WINDOWS_USERNAME の値を置き換えます。

$RESOURCE_GROUP_NAME=myResourceGroup-NP
$CLUSTER_NAME=myAKSCluster
$WINDOWS_USERNAME=myWindowsUserName
$LOCATION=canadaeast

クラスターの Windows Server コンテナーの管理者資格情報として使用するユーザー名を作成します。 次のコマンドを実行すると、ユーザー名の入力を求められます。 $WINDOWS_USERNAME に設定します。 この記事のコマンドは BASH シェルに入力するということに注意してください。

echo "Please enter the username to use as administrator credentials for Windows Server containers on your cluster: " && read WINDOWS_USERNAME

クラスターを作成するには、次のコマンドを使用します。

az aks create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --node-count 1 \
    --windows-admin-username $WINDOWS_USERNAME \
    --network-plugin azure \
    --network-policy azure

クラスターの作成には数分かかります。 既定では、クラスターは Linux ノード プールのみを使用して作成されます。 Windows ノード プールを使用する場合は、これを追加します。 次に例を示します。

az aks nodepool add \
    --resource-group $RESOURCE_GROUP_NAME \
    --cluster-name $CLUSTER_NAME \
    --os-type Windows \
    --name npwin \
    --node-count 1

Calico を有効にして AKS クラスターを作成する

AKS クラスターを作成し、--network-plugin azure--network-policy calicoを指定します。 --network-policy calico を指定すると、Linux ノード プールと Windows ノード プールの両方で Calico が有効になります。

クラスターに Windows ノード プールの追加を計画している場合は、Windows Server のパスワード要件を満たすパラメーター windows-admin-username および windows-admin-password を含める必要があります。

重要

現時点では、Kubernetes バージョン 1.20 以降と Calico 3.17.2 を使用して、Windows ノードを伴う Calico ネットワーク ポリシーを新しいクラスターで利用できます。この場合、Azure CNI ネットワークを使用する必要があります。 Calico が有効になっている AKS クラスターの Windows ノードでは、フローティング IP も既定で有効になっています。

以前のバージョンの Calico で Kubernetes 1.20 を実行している、Linux ノード プールのみを含むクラスターの場合、Calico バージョンは自動的に 3.17.2 にアップグレードされます。

クラスターの Windows Server コンテナーの管理者資格情報として使用するユーザー名を作成します。 次のコマンドを実行すると、ユーザー名の入力を求められます。 $WINDOWS_USERNAME に設定します。 この記事のコマンドは BASH シェルに入力するということに注意してください。

echo "Please enter the username to use as administrator credentials for Windows Server containers on your cluster: " && read WINDOWS_USERNAME
az aks create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --node-count 1 \
    --windows-admin-username $WINDOWS_USERNAME \
    --network-plugin azure \
    --network-policy calico

クラスターの作成には数分かかります。 既定では、クラスターは Linux ノード プールのみを使用して作成されます。 Windows ノード プールを使用する場合は、これを追加します。 次に例を示します。

az aks nodepool add \
    --resource-group $RESOURCE_GROUP_NAME \
    --cluster-name $CLUSTER_NAME \
    --os-type Windows \
    --name npwin \
    --node-count 1

既存のクラスターに Azure Network Policy Manager または Calico をインストールする

既存の AKS クラスターへの Azure Network Policy Manager または Calico のインストールもサポートされています。

警告

アップグレード プロセスにより、各ノード プールが同時に再イメージ化されます。 各ノード プールを個別にアップグレードすることはサポートされていません。 クラスター ネットワークのあらゆる中断は、ノード プール内の各ノードが再イメージ化される、ノード イメージのアップグレードまたは Kubernetes バージョンのアップグレードと似た形になります。

Azure Network Policy Manager をインストールするコマンドの例です。

az aks update
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --network-policy azure

Calico をインストールするコマンドの例です。

警告

この警告は、Calico が有効になっている Kubenet クラスターを、Calico が有効な Azure CNI オーバーレイにアップグレードする場合に適用されます。

  • Calico が有効になっている Kubenet クラスターでは、Calico は CNI とネットワーク ポリシー エンジンの両方として使用されます。
  • Azure CNI クラスターでは、Calico は CNI としてではなく、ネットワーク ポリシーの適用にのみ使用されます。 これにより、ポッドが起動してから、Calico がポッドからの送信トラフィックを許可するまでの間に、短い遅延が発生する可能性があります。

この問題を回避するには、Calico の代わりに Cilium を使用することをお勧めします。 Cilium の詳細については、「Azure CNI Powered by Cilium」を参照してください

az aks update
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --network-policy calico

Azure NPM または Calico がインストールされている既存のクラスターを、Azure CNI Powered by Cilium にアップグレードする

ネットワーク ポリシー エンジンがインストールされている既存のクラスターを Azure CNI Powered by Cilium にアップグレードするには、「既存のクラスターを Azure CNI Powered by Cilium にアップグレードする」を参照してください

ネットワーク ポリシーのセットアップを検証する

クラスターの準備ができたら、az aks get-credentials コマンドを使用して、Kubernetes クラスターに接続するように kubectl を構成します。 このコマンドは、資格情報をダウンロードし、それを使用するように Kubernetes CLI を構成します。

az aks get-credentials --resource-group $RESOURCE_GROUP_NAME --name $CLUSTER_NAME

ネットワーク ポリシーの検証を開始するために、サンプル アプリケーションを作成し、トラフィック ルールを設定します。

最初に、ポッドの例を実行するための demo という名前の名前空間を作成します。

kubectl create namespace demo

次に、clientserver という名前の 2 つのポッドをクラスターに作成します。

Note

クライアントまたはサーバーを特定のノードでスケジュールしたい場合は、ポッド作成 kubectl run コマンドで --command 引数の前に次のビットを追加します。

--overrides='{"spec": { "nodeSelector": {"kubernetes.io/os": "linux|windows"}}}'

server ポッドを作成します。 このポッドは TCP ポート 80 で機能します。

kubectl run server -n demo --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 --labels="app=server" --port=80 --command -- /agnhost serve-hostname --tcp --http=false --port "80"

client ポッドを作成します。 次のコマンドは、client ポッドで BASH を実行します。

kubectl run -it client -n demo --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 --command -- bash

別のウィンドウで、次のコマンドを実行してサーバー IP を取得します。

kubectl get pod --output=wide -n demo

出力は次のようになります。

NAME     READY   STATUS    RESTARTS   AGE   IP            NODE             NOMINATED NODE   READINESS GATES
server   1/1     Running   0          30s   10.224.0.72   akswin22000001   <none>           <none>

ネットワーク ポリシーなしで接続をテストする

クライアントのシェルで、次のコマンドを実行して、サーバーとの接続を検証します。 server-ip を、前のコマンドを実行した出力の中の IP を使用して置き換えます。 接続が成功した場合は、出力がありません。

/agnhost connect <server-ip>:80 --timeout=3s --protocol=tcp

ネットワーク ポリシーを使用して接続をテストする

ネットワーク ポリシーを追加するには、demo-policy.yaml という名前のファイルを作成し、次の YAML マニフェストを貼り付けます。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: demo-policy
  namespace: demo
spec:
  podSelector:
    matchLabels:
      app: server
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: client
    ports:
    - port: 80
      protocol: TCP

YAML マニフェストの名前を指定し、kubectl apply を使用して適用します。

kubectl apply –f demo-policy.yaml

ここで、クライアントのシェルで、次の /agnhost コマンドを実行して、サーバーとの接続を検証します。

/agnhost connect <server-ip>:80 --timeout=3s --protocol=tcp

トラフィックとの接続がブロックされるのは、サーバーには app=server というラベルが付いているけれども、クライアントにはラベルが付いていないからです。 上記の connect コマンドでは、次の結果が出力されます。

TIMEOUT

次のコマンドを実行して client にラベルを付けて、サーバーとの接続を検証します。 出力では何も返されません。

kubectl label pod client -n demo app=client

Azure Network Policy Manager または Calico をアンインストールする (プレビュー)

要件:

Note

  • アンインストール プロセスでは、Calico で使用されるカスタム リソース定義 (CRD) とカスタム リソース (CR) は削除されません。 これらの CRD と CR はすべて、"projectcalico.org" または "tigera.io" で終わる名前を持っています。 Calico が正常にアンインストールされた後に、これらの CRD と関連する CR を手動で削除できます (Calico を削除する前に CRD を削除すると、クラスターが破損します)。
  • アップグレードでは、クラスター内の NetworkPolicy リソースは一切削除されませんが、アンインストール後にこれらのポリシーは適用されなくなります。

警告

アップグレード プロセスにより、各ノード プールが同時に再イメージ化されます。 各ノード プールを個別にアップグレードすることはサポートされていません。 クラスター ネットワークのあらゆる中断は、ノード プール内の各ノードが再イメージ化される、ノード イメージのアップグレードまたは Kubernetes バージョンのアップグレードと似た形になります。

クラスターから Azure Network Policy Manager または Calico を削除するには、次のコマンドを実行します。

az aks update
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --network-policy none

リソースをクリーンアップする

この記事では、名前空間と 2 つのポッドを作成して、ネットワーク ポリシーを適用しました。 これらのリソースをクリーンアップするには、kubectl delete コマンドを使用し、リソース名を指定します。

kubectl delete namespace demo

次のステップ

ネットワーク リソースの詳細については、「Azure Kubernetes Service (AKS) でのアプリケーションに対するネットワークの概念」を参照してください。

ポリシーの詳細については、Kubernetes ネットワーク ポリシーに関するページを参照してください。