📦

Azure Kubernetes Service (AKS) をプライベート構成にしたい

に公開

はじめに

Azure 上で Kubernetes サービスを提供する AKS に関して、最近活用が増えているためかプライベート構成の質問を受ける機会が増えています。私自身、Kubernetes に詳しいわけではないのですが App Service などの PaaS とは異なりプライベート構成とするためにはいくつか考慮すべきポイントがありますので、ドキュメントを参考にしつつ整理していこうと思います。

AKS の基本構成

ざっくりとした図ですが、AKS の構成要素は以下になります。

プライベート構成にする場合に検討すべきポイントは主に以下の 3 点かと思います。

  • Kubernetes API アクセスのプライベート化
  • 受信トラフィック (Ingress) のプライベート化
  • 送信トラフィック (Egress) の制御

上記についてぞれぞれ確認していきます。

Kubernetes API アクセスのプライベート化

こちらは AKS をプライベート クラスターとして作成することで実現可能です。
https://learn.microsoft.com/ja-jp/azure/aks/private-clusters?tabs=default-basic-networking%2Cazure-portal

こちらを設定することで、以下のようにプライベート エンドポイントが VNET 内に作成され、インターネットからのアクセスをブロックすることができます。この際、他の PaaS のプライベート エンドポイントと同様にプライベート DNS ゾーンとレコードが作成され、VNET にリンクされます。

プライベート クラスターの場合、インターネット側から利用者が API にアクセスできないため、ExpressRoute や VPN、Azure 内の VM からアクセスするなどの対処が必要です。なお、別 VNET の VM からアクセスする場合は AKS 用の VNET へのピアリングとプライベート DNS ゾーンの VNET リンクが必要です。

プライベート クラスター作成後のリソース グループを見ていくと、以下のようにプライベート DNS ゾーンやプライベート エンドポイントが作成されています。


実際にインターネット経由で Azure ポータルからワークロードを確認しようとすると以下のようになります。

なお、追加でパブリック FQDN を無効化することも可能になっています。
https://learn.microsoft.com/ja-jp/azure/aks/private-clusters?tabs=default-basic-networking%2Cazure-portal#disable-a-public-fqdn

受信トラフィック (Ingress) のプライベート化

API サーバーへの接続はプライベート構成にできましたが、一方でデータ プレーン側の受信トラフィック・送信トラフィックはパブリックのままになっています。次は受信トラフィックを確認していきます。

通常 AKS ではサービスを外部公開する場合、規定で作成されるパブリック ロードバランサーを使用することができます。
https://learn.microsoft.com/ja-jp/azure/aks/load-balancer-standard#use-the-public-standard-load-balancer

こちらを設定すると、パブリック IP が作成され、ロード バランサーにフロント エンド IP 構成、バックエンド プール、正常性プローブ、負荷分散規則が作成されます。





この場合 NSG でアクセス制御は可能ですが、基本的にインターネット側からアクセス可能な構成になっています。そのためプライベート化するために以下にある内部ロードランサーを使用します。
https://learn.microsoft.com/ja-jp/azure/aks/internal-lb?tabs=set-service-annotations

こちらをデプロイすると、内部ロード バランサーが作成され、フロントエンド IP 構成にプライベート IP が設定されます。


この構成でプライベート ネットワーク内で安全にサービスを公開することが可能になりました。
なお、この対処で既定で作成されるパブリック IP アドレスとパブリック ロード バランサーが不要となるかについては次の送信トラフィックの構成に関係します。

送信トラフィック (Egress) の制御

AKS の送信トラフィックは既定ではパブリック ロードバランサーの送信規則を利用して実現しています。この場合、特に NSG をカスタマイズしていない場合は制限なくインターネット アクセスが可能です。

こちらの送信トラフィックについてロード バランサの他にいくつか実現方法があります。なお、方法や条件によって作成時のみ設定可能、作成後に変更可能などがあります。

  • NAT ゲートウェイ
  • ユーザー定義ルート (UDR)
  • HTTP プロキシ

https://learn.microsoft.com/ja-jp/azure/aks/egress-outboundtype

NAT ゲートウェイを利用する場合

パブリック ロードバランサーが不要になるという利点があります。
一方で VNET を集約するケースを除き、引き続きパブリック IP がクラスターごとに必要になります。またアクセス制御という観点では、VMSS から直接インターネットに接続することになるため、NSG で制御する必要があります。
https://learn.microsoft.com/ja-jp/azure/aks/nat-gateway

ユーザー定義ルートを使用する場合

ネクスト ホップに Azure ファイアウォールや NVA などを配置することで URL ベースでのアクセス制御が可能になり、かつ クラスターに紐づくパブリック IP 利用を禁止することができます。ただし、事前に UDR が付与されているサブネットを準備しておくなど、クラスター作成時の難易度が高くなります。
https://learn.microsoft.com/ja-jp/azure/aks/egress-udr
https://learn.microsoft.com/ja-jp/azure/aks/limit-egress-traffic?tabs=aks-with-system-assigned-identities

HTTP プロキシを利用する場合

送信トラフィックを任意のプロキシサーバー経由とすることができるため、URL ベースでのアクセス制御が可能になります。こちらはクラスター作成時のみ指定可能です。
https://learn.microsoft.com/ja-jp/azure/aks/http-proxy

Azure ポリシーで制限をかける

ここまでプライベート構成について整理してきましたが、利用者がパブリック構成を利用しないように Azure ポリシーで制限をかける方法を考えてみます。

Kubernetes API アクセスのプライベート化

パブリックの AKS を作成しようとする場合に Deny するポリシーを設定すれば実現できそうです。

受信トラフィック (Ingress) のプライベート化

パブリック IP の作成を Deny したいところではありますが、そのようにポリシーをかけると送信トラフィックの構成で UDR 以外を選択できなくなってしまう (他の選択肢はパブリック IP が作成されるため) ので、事前に運用観点での整理や利用者への周知が必要です。
また、Kubernetes としては Azure ポリシーの制限は認識できないため、パブリック IP を使うサービスを展開した場合、明示的にエラーが出ない点も注意する必要があります。

送信トラフィック (Egress) の制御

こちらはデプロイ時に送信トラフィックの種類 (outboundType) をチェックするポリシーを設定すれば実現可能かと思います。

その他

プレビューではありますが、他にもネットワーク分離クラスターや API サーバー VNET 統合など新たな機能が提供されていますので、こちらもご確認ください。
(2025/4/3 追記) ネットワーク分離クラスターは GA となりました。
https://learn.microsoft.com/ja-jp/azure/aks/network-isolated?pivots=aks-managed-acr
https://learn.microsoft.com/ja-jp/azure/aks/api-server-vnet-integration

また Kubernetes レベルで制御する方法があるようですが、こちらは検証できていません。
https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/

Microsoft (有志)

Discussion