AKSのインフラを学ぶ - Azureリソース編

# 本記事について
## Azureインフラエンジニアの視点でAKSを学ぶ
私は普段AzureのIaaSやネットワークを主に扱っているのですが、AKSに手を出すにあたり困惑することが多くありました。
この記事ではAKSのインフラ（主にネットワーク）を構築しながら確認した内容を記録しておきます。

以下の3点について整理していきます。本記事は1の内容にフォーカスしています。
1. AKSとAzureリソース
2. AKSのネットワーク構成
3. インフラ観点のトラブルシューティング用Tips

## AKSとAzureリソース
Azure環境の設計をする際にはサブスクリプションが決まった後、まずはリソースグループの構成を定義して、
それぞれのリソースグループにどのようなリソースを構築するかを決めていきます。
例えば仮想マシンを実行するシステムを設計する際にはネットワーク等の共通インフラリソースを管理するリソースグループと
仮想マシンリソースを管理するリソースグループを分けるかもしれません。
また、仮想マシンも複数のサブシステムに分かれる場合はサブシステムごとにリソースグループを分けることもあるでしょう。

加えて、仮想マシンを構築すると仮想マシンリソースだけではなく、ネットワークインターフェースや、
OSディスク、データディスク、場合によってはパブリックIPアドレスや拡張機能といったリソースも作成されます。
また、前提として仮想マシンを利用するにはVNetがあることが前提となっています。
**設計の段階でリソースを把握しておくことでランニングコストの算出など全体像を理解できます。**

AKSにおいても同様に**事前に構築されるリソースについて把握しておきたい**というのがこの記事のモチベーションです。
特にAKSでは仮想マシン等に比べると複雑なリソース構造になりますので、しっかり把握してAKSを構築できるようにしておきたいと思います。
AKSの基本的な構成や一般的なシナリオで想定されるリソース構成を確認していきます。

# AKSの基本アーキテクチャとAKSリソースの管理
## 基本アーキテクチャ
まず、Azureに限定せずKubernetesそのものの基本的なアーキテクチャを見ると、大きくコントロールプレーンとノードから構成されています。
コントロールプレーンではAPIサーバなどのクラスター自体を管理する複数のコンポーネントが実行され、
ノードではユーザーのアプリケーションが実行されるという構造です。
[Kubernete | Kubernetesのコンポーネント](https://kubernetes.io/ja/docs/concepts/overview/components/)

AKSではどうなるかというと、コントロールプレーンがAzureによるマネージドで提供され、ユーザーは原則としてノードのみを管理するという構造になります。
ネイティブなKubernetesに比べてコントロールプレーンを管理しなくてよいのがパブリッククラウドでKubernetesを扱う大きなメリットの1つではないでしょうか。
[MS Learn | AKSの中心概念](https://learn.microsoft.com/ja-jp/azure/aks/core-aks-concepts)

また、最近ではAKS Automaticというノード部分についてもAzureによる推奨構成で事前に設定されたAKSのモードもプレビューで出てきています。
ノードのスケーリング管理や監視、セキュリティなどが推奨構成で展開できるというものですが、本記事では触れません。

## AKSリソースの基本
AKSリソースでは**AKSクラスターそのものを示すリソース**に加えて**ノードリソースグループ**と呼ばれる
AKSにより管理されるマネージドのリソースグループが作成されます。
名前の通りノードを実行するために必要なAzureリソースが作成されるリソースグループになります。

デフォルトではという以下の名前で自動的に作成され、AKSクラスターリソースのプロパティ画面から確認できます。
- MC\_"AKSのリソースグループ名"\_"AKSクラスター名"\_"リージョン名"

また、このリソースグループやリソースに対してユーザーが直接変更を加えることはサポートされず、
AKS（Kubernetes）に対する操作により間接的に変更を加えます。
なお、AKSクラスターリソースを削除することで自動的にこのリソースグループも削除されます。

では実際にAKSを構築して作成されるリソースを見ていきましょう。

# AKSリソース
## Azureポータルからデプロイした基本構成
まずはAzureポータルから最小構成をデプロイした際に構築されるAzureリソースを確認してみます。
### 構築手順
Azureポータルで構築する際の設定をタブごとに確認して設定していきます。
1. Basic
ここではAKSクラスターリソースの構築先リソースグループやリソース名を指定するのに加えて、[クラスターのプリセット構成]というものを選んでいます。
これはAzure側で用意されているいくつかの設定のセットを選択できるものです。今回は一番シンプルな"Dev/Test"のプリセットを選択しています。
![01-portal-default-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/512d3746-23fd-4957-945c-6773303d1a3e.png)

2. ノードプール
ここではノードプールを設定します。
デフォルトでは"agentpool"という名前のシステムノードプール（モードが"System"）のみが設定されています。
ノードのVMサイズやノード数も設定できます。今回は最小のVMサイズでノード数も1ノードに設定しています（AシリーズやBシリーズは利用できないので注意）。
![01-portal-default-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/2e5b7abb-08ad-4668-ba2b-835dc2f7e22f.png)

3. ネットワーク
ここではクラスターのネットワーク構成を決めていきます。
今回はデフォルトのままで特に設定は変更しませんので、パブリッククラスターでAzure CNIオーバレイというネットワーク構成になります。
また、ロードバランサーは"Standard"となっており、削除することや変更することはできません。
![01-portal-default-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/8d3b1b21-be41-48c4-aa31-b60ab5a377ec.png)
![01-portal-default-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/d8d67d6c-6d96-48ed-a2a6-f6906390180f.png)

4. 統合
ここではACRとの接続やAzure Policyの設定などがおこなえますが、デフォルトではすべて無効になっていますので、そのままにします。
![01-portal-default-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/13c3a06c-b52a-433a-9d4d-59a4b3a0da7c.png)

5. 監視中
ここではAKSクラスターの監視について設定できます。
デフォルトではAzure MonitorのマネージドPrometheusと推奨のアラートルールが有効になっています。
今回はインフラ構成にフォーカスして検証していきますので、リソースの差異がわかりやすいよう監視の設定はすべてオフにしておきます。
   - 変更前（デフォルト）
![01-portal-default-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/ad0c7287-7f8b-4bd6-ad31-29de5d5ea427.png)
![01-portal-default-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/3429a936-e950-4a8f-b21c-e7216e64be68.png)

   - 変更後
![01-portal-default-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/b07085e8-04ea-470e-89da-1e458ef572f5.png)
![01-portal-default-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/d80eced2-cfac-40ca-9a30-20967cfe0fc9.png)

6. セキュリティ
ここではセキュリティに関する設定がおこなえます。今回はデフォルトのままにしています。
![01-portal-default-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/40325a87-290f-4138-b93d-ab250352077a.png)

7. 詳細
最後に詳細設定ではノードリソースグループの名称を設定できます。既定のままにしておきます。
![01-portal-default-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/bac6ab7e-fb8e-4f49-880e-b21cb708f99e.png)

### 作成されたリソース
以上の設定で構築をおこなうと、AKSクラスター以外にノードリソースグループが作成され、ノードリソースグループには以下のリソースが作成されました。
![01-portal-default-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/353f8315-95c1-42c2-b3eb-21b3041fda94.png)

上から順に作成されたリソースを見ていきます。
- 仮想マシンスケールセット
AKSクラスターを作成する際に指定したシステムノードプール（必須）に対応する仮想マシンスケールセットです。
なお、ユーザーノードプールも追加で作成すると別で仮想マシンスケールセットが作成されます。
- NSG
ノードプールの仮想マシンスケールセットがデプロイされている仮想ネットワークのサブネットに紐づけられています。
既定の状態ではNSGはデフォルトルールのみが登録されています。
![01-portal-default-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/37fe7735-b406-47a6-bd9d-8e4393eba324.png)

- マネージドID
ノードプールに対応したマネージドIDです。
AKSではクラスターリソースでもシステムマネージドIDを有効化することができますが、こちらはノードプール用のものです。
使い分けは以下のドキュメントに解説がありますが、Azure Container Repository（ACR）からイメージをプルする際の認証に使用するものです。
[MS Learn | AKSで使用されるマネージドIDの概要](https://learn.microsoft.com/ja-jp/azure/aks/use-managed-identity#summary-of-managed-identities-used-by-aks)
- 仮想ネットワーク
ノードプールがデプロイされている仮想ネットワークです。
デフォルトではアドレス空間は"10.224.0.0/12"が割り当てられ、"aks-subnet"が"10.224.0.0/16"で作成されています。
- パブリックIPアドレス
ロードバランサーに紐づけられたパブリックIPアドレスです。
ノードプールがAzure外部にアクセスする際のIPアドレスになります。
- ロードバランサー
外部ロードバランサー（Standard SKU）が作成されます。
これは送信規則を利用してノードプールが外部へアクセスするために利用されるとともに、
KubernetesのLoadBalancerサービスを構築した際にも利用されます。
※LoadBalancerサービスの詳細は別記事で触れます。

### ノードプールの追加
ついでに構築した環境にユーザーノードプールを作成するとどうなるかも確認しておきましょう。
ノードリソースグループを見ると仮想マシンスケールセットが追加されていることがわかります。
![01-portal-default-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/8e1775cc-ad47-4d46-b62c-0cb7ceb9003a.png)

## BYO VNetを利用したパブリッククラスター
ネットワーク環境は既存の環境があり、それを利用したいというケースはよくあると思います。
ということで次は既存VNetにAKSクラスターをデプロイした場合のAzureリソースを確認してみます。
と言っても単に既存VNet内にデプロイするだけではAzureリソースはVNetが不要になるのみです。
**ここでは既存VNetにインターネットアクセスのためのAzure FirewallやNVA、NATゲートウェイなどが展開されていることを想定して、
既存VNetのNATゲートウェイを利用したインターネットアクセスの構成（外部ロードバランサーなし）を試してみます。**
### 構築手順
先ほどの手順で見た通り外部ロードバランサーをAzureポータルからのデプロイでは外すことができません。
そのためAzure CLIを利用してデプロイしていきます。
Azure CLIでデプロイする際に既設のNATゲートウェイを利用するようにオプションを設定します。

```
az aks create `
--name "aks-public-01" `
--resource-group "rg-aks-public-01" `
--enable-managed-identity `
--generate-ssh-keys `
--network-plugin azure `
--network-plugin-mode overlay `
--service-cidr "172.17.0.0/20" `
--dns-service-ip "172.17.0.10" `
--outbound-type userAssignedNATGateway `
--vnet-subnet-id "<サブネットのリソースID>" `
--node-count 1 `
--os-sku Ubuntu `
--node-vm-size Standard_D2pls_v6
```
### 作成されたリソース
Azureポータルからデプロイした時との差異として仮想ネットワークはもちろん、外部ロードバランサー（と外部ロードバランサーのPIP）がなくなっていることが確認できます。
インターネットアクセスにNATゲートウェイを利用するよう設定したことで外部ロードバランサーが作成されなくなりました。
![01-portal-default-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/a5529c3e-6a06-4a3b-b3f0-069ef3b75f94.png)

ただし、ロードバランサーはクラスターへのインバウンド通信でも利用されます。
実際にKubernetesの**LoadBalancerサービスをデプロイするとロードバランサーが作成されます。**
- kubectlコマンドでLoadBalancerサービスをデプロイした後のリソースグループ

![01-portal-default-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/bad806a7-e266-44cc-8b0b-76a6e067eaa6.png)

## BYO VNetを利用したプライベートクラスター
最後に、コントロールプレーンへのアクセスをプライベートネットワークに閉じたプライベートクラスター構成を試してみます。
こちらも既存のVNetを利用する前提で構築していきます。
### 構築手順
こちらもAzure CLIを利用してデプロイしていきます。
プライベートクラスターを有効化するオプションを指定しています。

```
az aks create `
--name "aks-private-01" `
--resource-group "rg-aks-private-01" `
--enable-managed-identity `
--enable-private-cluster `
--private-dns-zone system `
--disable-public-fqdn `
--generate-ssh-keys `
--network-plugin azure `
--network-plugin-mode overlay `
--service-cidr "172.17.0.0/20" `
--dns-service-ip "172.17.0.10" `
--outbound-type userAssignedNATGateway `
--vnet-subnet-id "<サブネットのリソースID>" `
--node-count 1 `
--os-sku Ubuntu `
--node-vm-size Standard_D2pls_v6
```
### 作成されたリソース
先ほどの例に比べて、コントロールプレーンのAPIサーバへのアクセスがプライベート化されたことで、APIサーバのプライベートエンドポイントと
ネットワークインターフェース、プライベートエンドポイントの名前解決のためのプライベートDNSゾーンが作成されていることがわかります。
![01-portal-default-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/872c084e-0acd-43f0-849c-02f020fd6aa4.png)

# まとめ
本記事ではAKSを構築した際に自動で作成されるノードリソースグループのリソースについて確認してきました。
既定のネットワーク構成ではインターネットアクセスに外部ロードバランサーが使用されることや、ノードプールごとに仮想マシンスケールセットが作成される様子などが確認できました。
また、BYO VNetのシナリオではユーザーが事前に用意した環境でAKSを実行したり、またプライベートクラスターのシナリオでは
一般的なAzureサービスと同様のプライベートエンドポイントの仕組みが使われていることが確認できました。
次回は今回構築したプライベートクラスターを中心にネットワーク構成を確認したいと思います。