Azure Kubernetes Service (AKS) with Azure CNI の環境を構築してみました


## 概要

AKS の仮想ネットワークには Kubenetネットワーク（基本）と Azure CNI（高度）の2種類がありますが、Azureが推奨する Azure CNI を用いて AKS の環境を構築し、そこで Pod と Node に割り振られるIPアドレスを確認してみます。[このドキュメント](https://docs.microsoft.com/ja-jp/azure/aks/concepts-network)も参照ください。

### ローカル環境

macOS Big Sur 11.3 
python 3.8.3

### 前提条件

1. Azure環境がすでに用意されていること（テナント/サブスクリプション）。
2. ローカル環境に「azure cli」がインストールされていること。

### 事前準備

- [この記事](https://qiita.com/turupon/items/88ca03fe2668d8ad4498) にある 「ACR（Azure Container Registry）のレジストリ作成」を完了していること。

- ローカルの環境変数に以下を定義しておきます。
  - ACR_NAME=acr0ituru
  - ACR_RES_GROUP=rg_ituru_acr
  - AKS_CLUSTER_NAME=ituruAKSCNICluster
  - AKS_RES_GROUP=rg_ituru_cni
  - SP_NAME=sp_ituru_cni

---

## AKS と ACR のデプロイ連携

### AKS リソースグループの作成

```
az group create --name $AKS_RES_GROUP --location japaneast
```

### 既存の ACR のリソースIDを取得

```
ACR_ID=$(az acr show --name $ACR_NAME --query id --output tsv)
```

### サービスプリンシパルの作成 とシークレット情報の取得

```
SP_PASSWD=$(az ad sp create-for-rbac --name $SP_NAME --skip-assignment --query password --output tsv)
```

### サービスプリンシパルの appIDの取得

```
APP_ID=$(az ad sp list --display-name $SP_NAME --query '[].{ID:appId}' --output tsv)
```

### 作成したサービスプリンシパルに ACR の contributor権限を付与

```
az role assignment create --assignee $APP_ID --scope $ACR_ID --role contributor
```

---

## AKS と Azure CNI のデプロイ連携　

### AKS クラスタを構築するための仮想ネットワークを作成

```
az network vnet create -g $AKS_RES_GROUP -n vnet_ituru_akscp --address-prefix 10.0.0.0/16 --subnet-name akscpsubnet1 --subnet-prefix 10.0.1.0/24
```

### 仮想ネットワークサブネットのリソースIDを取得

```
CP_SUBNET_ID=$(az network vnet subnet list -g $AKS_RES_GROUP --vnet-name vnet_ituru_akscp --query "[0].id" --output tsv)
```

### 作成したサービスプリンシパルに、仮想ネットワークサブネットのネットワーク共同作成者権限を付与

```
az role assignment create --assignee $APP_ID --scope $CP_SUBNET_ID --role "network contributor"
```

### AKS クラスターの作成

クラスターを 3ノードで作成します。AKSとACR連携/AKSとCNI連携 のためのパラーメータも定義します。 作成完了まで数分かかります。

```
az aks create \
  --name $AKS_CLUSTER_NAME \
  --resource-group $AKS_RES_GROUP \
  --node-count 3 \
  --service-principal $APP_ID \
  --client-secret $SP_PASSWD \
  --enable-addons monitoring \
  --node-vm-size Standard_DS2_v2 \
  --vm-set-type VirtualMachineScaleSets \
  --load-balancer-sku standard \
  --network-plugin azure \
  --vnet-subnet-id $CP_SUBNET_ID \
  --docker-bridge-address 172.17.0.1/16 \
  --dns-service-ip 10.1.0.10 \
  --service-cidr 10.1.0.0/24 \
  --generate-ssh-keys
```

### Kubernetesクラスタ接続のための認証情報の取得

```
az aks get-credentials --resource-group $AKS_RES_GROUP --name $AKS_CLUSTER_NAME
```

.kube/configファイルに接続情報を書き込むことで、ローカルからクラスタ操作できるようになります。


---

## Pod / Node の IPアドレス確認　

### Pod の起動

[この記事](https://qiita.com/turupon/items/88ca03fe2668d8ad4498) で ACRにプッシュしたコンテナを、作成したAKSクラスタで稼働させます。

マニフェストを以下のように定義します。

```IoTDataGen.yaml
apiVersion: v1
kind: Pod
metadata:
  name: iotdatagen
spec:
  containers:
  - name: iotdatagen
    image: acr0ituru.azurecr.io/iotdatagen:5.0
    command:
      - sh
      - -c
      - "exec tail -f /dev/null"
```

Podを起動させます

```
## namespaceの作成
kubectl create namespace akscp02

## Pod の起動
kubectl apply -f IoTDataGen.yaml -n akscp02
```

### IPアドレス確認

node と Pod のIPアドレスに vNet の subnet ネットワークアドレスレンジのIPがアサインされていることを確認します。

```
## node（INTERNAL-IPを確認）
$ kubectl get nodes -o wide
NAME                                STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
aks-nodepool1-83327242-vmss000000   Ready    agent   29h   v1.20.9   10.0.1.4      <none>        Ubuntu 18.04.5 LTS   5.4.0-1055-azure   containerd://1.4.8+azure
aks-nodepool1-83327242-vmss000001   Ready    agent   29h   v1.20.9   10.0.1.35     <none>        Ubuntu 18.04.5 LTS   5.4.0-1055-azure   containerd://1.4.8+azure
aks-nodepool1-83327242-vmss000002   Ready    agent   29h   v1.20.9   10.0.1.66     <none>        Ubuntu 18.04.5 LTS   5.4.0-1055-azure   containerd://1.4.8+azure

## Pod（IPを確認）
$ kubectl get pod -n akscp02 -o wide
NAME           READY   STATUS    RESTARTS   AGE     IP          NODE                                NOMINATED NODE   READINESS GATES
iotdatagen     1/1     Running   0          16h     10.0.1.82   aks-nodepool1-83327242-vmss000002   <none>           <none>
```

ついでに、DNS として 「10.1.0.10」 を使用されていることの確認

```
## Pod に接続
$ kubectl exec -it iotdatagen -n akscp02 -- /bin/bash
root@iotdatagen:/opt/app# 

## 名前解決の実行
root@iotdatagen:/opt/app# nslookup www.networld.co.jp
Server:		10.1.0.10
Address:	10.1.0.10#53

Non-authoritative answer:
Name:	www.networld.co.jp
Address: 52.68.155.102
```

### まとめ

AKS with Azure CNI として構築手順を確認できました。

---

## 参考記事
以下の記事を参考にさせていただきました。感謝申し上げます。

[AKSのネットワーク構成](https://hyoublog.com/2020/10/26/aks%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF/)
[Azure CNI ネットワーク と Application Gateway](https://qiita.com/kenakamu/items/f4c0fabea8044a6b28cb)
[Azure Kubernetes Service(AKS)を構成するAzureリソース](https://qiita.com/n_mikuni/items/a164dad07780ba6ed2ac)
[プライベート Azure Kubernetes Service クラスターを作成する](https://github.com/MicrosoftDocs/azure-docs.ja-jp/blob/master/articles/aks/private-clusters.md)