Nutanix KarbonをAzure Arc対応Kubernetesとして接続してみる

![スクリーンショット 2021-12-19 9.25.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/c57fcb5f-02ef-a229-2e17-e076ea2a1320.png)
本記事は、Nutanix Advent Calendar 2021の19日目、12月19日分としての投稿になります。当初、Nutanix Community Editionの何かとAdvent Calendarに予告してたのに、諸般の都合で商用のNutanixでの記事となりました（ごめんなさい）。

**本記事の内容は、この日付時点の情報に基づいています。そのため，今後新しいバージョンが提供された場合に，当該記載と矛盾が生じる場合がありますのでご注意ください。**

# はじめに
ここ数年、Qiitaにアウトプットを出すのがAdvent Calendar時期のみになっている @hanakara_milk です、こんばんは。今回は、Azure Arc対応KubernetesとしてNutanix Karbonが対応しているので、とりあえず「やってみた」系ですが、Azure Arcに繋いでみる、と言う記事になります。

本来は、Nutanix Community Edition（以下、CE）でやりたかったのですが、Nutanix KarbonがAzure Arc対応KubernetesとしてCertifiedされたのが、つい最近で、残念ながらCEのバージョン（AOS 5.18相当時期のKarbon 2.0.x系）だと、時間の都合もありうまく繋がるかを含めてハマる可能性があったため日和って商用のNutanixで検証しています。

Nutanix側の構成は以下のとおりです。

* AOS：5.15.7
* Prism Central：pc.2021.9.0.2
* Karbon：2.3.0

:::note warn
なお、MicrosoftのドキュメントのAzure Arc対応KubernetesとしてのCertifiedはKarbonのバージョン2.2.1
:::
https://docs.microsoft.com/ja-jp/azure/azure-arc/kubernetes/validation-program#validated-distributions

# Azure Arc対応Kubernetesについて
Azure Arc対応Kubernetesでは、単にAzureからCertifiedされた任意のKubernetesをAzureのポータルやAzure CLIでマネージできると言うだけでなく、Azure Arcを一元的な管理プレーンとして位置付け、任意のインフラにAzureのサービスを展開し、Azureの一部として利用できると言う側面も持っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/5aa4c580-10ea-6a23-580c-189a53ce70f7.png)
例えば、本来パブリッククラウドのAzureは、それ自身が所有するAzureのインフラ上に様々なサービスを展開しますが、オンプレミスのKubernetesクラスターをAzure Arcに接続すると、Azure Arc対応データサービスのためのコントローラーをそのKubernetesクラスターにデプロイし、そのコントローラーを介して、そのKubernetesクラスター上にAzureが提供するサービスの1つであるAzure Arc対応SQL Managed Instanceなどをデプロイすることができるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/7b5c888d-3736-3f79-cd31-0c7591398920.png)

つまり、オンプレミスのKubernetesが、Azureのカスタマイズされた特定用途専用リージョンの1つのように扱えるようになります。
最終的にはAzureのARM（Azure Resource Manager）でAzureが管理している様々なリソースがオンプレミスを含む任意の場所に展開できるようにするぞーと言った野心的な？仕組みです。

今回は、時間の都合上、そこまで試せていませんが、オンプレミスにあるNutanix KarbonでデプロイされたKubernetesクラスターをAzure Arcに接続して、Azure Portal上から少し触ってみるところまでやってみます。

# Azure Arc対応Kubernetesに接続するための準備
今回は、いくつかの準備作業について、本記事中では省略していますが、以下の下準備が必要となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/cb678e8c-38cd-b620-4294-dae7c6d6e851.png)

:::note warn
本記事はLinuxを作業端末（VM）として利用することを前提とした内容
:::

* Nutanix KarbonからのKubernetesクラスターのデプロイ
* コマンドでAzureやKubernetesを操作する作業用端末（または作業用VMなど）
* 各種ツールのインストール（kubectl, Azure CLI, helm3）
 
https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-linux?pivots=dnf

https://kubernetes.io/ja/docs/tasks/tools/install-kubectl/#install-kubectl-on-linux

https://helm.sh/ja/docs/intro/install/

:::note warn
作業用端末または作業用VMは、KarbonのKubernetesクラスターにアクセスできる必要があります
:::

:::note warn
この端末には、KarbonからデプロイされたKubernetesクラスターへアクセスするためのkubeconfigをAzure CLIで作業を行うTerminalなどに環境変数として登録する必要があります
:::

# Azure Arcへの接続
## Azure CLIにconnectedk8s extensionを追加
Azure CLIにAzure ArcにKubernetesクラスターを接続するための拡張コマンドセットを追加します。

```bash
az extension add --name connectedk8s
```
:::note warn
こちらの作業はAzure CLIが既にインストールされている前提です
:::


## Azure Arc対応Kubernetes 用のプロバイダーを登録する
Azure CLI環境に、Azure Arcに接続するためのプロバイダー定義などを追加します。こちらは追加の完了までに少し時間がかかります。

```bash
az provider register --namespace Microsoft.Kubernetes
az provider register --namespace Microsoft.KubernetesConfiguration
az provider register --namespace Microsoft.ExtendedLocation
```

## Azure Arc対応Kubernetes用のリソースグループの作成
Azure ArcにKubernetesクラスターを接続し管理するためのリソースグループを作成します（Azure CLIを使わずにAzure PortalのUIからでも実行可能）。既存のリソースグループを利用する場合は、この作業は不要です。

```bash:コマンド例
az group create --name {YOUR_RESOUCE_GROUP_NAME} --location {RG_ROCATION} --output table
```
:::note info
引数：
{YOUR_RESOUCE_GROUP_NAME}は、作成するリソースグループ名（例：rg-karbon）
{RG_ROCATION}は、リソースグループを配置するロケーション（例：japaneast）
:::

```bash:今回の実行例
az group create --name rg-karbon --location japaneast --output table
```
当たり前ですが、Azure CLIで作成した```rg-karbon```と言う名前のリソースグループがAzure Portal上でも表示されています。
![スクリーンショット 2021-12-19 9.24.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/9ae404a7-331f-b86a-6708-75b6a9036ec7.png)

### KubernetesクラスターをAzure Arcに接続
KarbonでデプロイしたKubernetesクラスターをAzure Arcに接続に接続します（Azure CLIを使わずにAzure PortalのUIからでも実行可能）。この作業の際に指定する、```--name```は、準備時の登録してあるKUBECONFIG内のKubernetesクラスター名を指定する必要があります。

```bash:コマンド例
az connectedk8s connect --name {KARBON_K8S_CLUSTER_NAME} --resource-group {YOUR_RESOUCE_GROUP_NAME}
```

:::note info
引数：
{KARBON_K8S_CLUSTER_NAME}は、KarbonでデプロイしたKubernetesクラスター名
{YOUR_RESOUCE_GROUP_NAME}は、先ほど作成したリソースグループ名
:::
```bash:今回の実行例
az connectedk8s connect --name milk01 --resource-group rg-karbon
```
上記コマンド実行すると、```This operation might take a while...```と表示後、結果がずらずらっと表示されます。この時点で、Azure ArcからオンプレミスのNutanix KarbonでデプロイしたKubernetesクラスターが見えるようになります。
![スクリーンショット 2021-12-19 9.25.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/b0f3c7e2-1599-c6bb-dd36-5023c6592af5.png)

ただし、この時点では、Azure PortalからKarbonでデプロイしたKubernetesクラスターが見えるだけで、実際にワークロードに対する操作等、実際の管理操作ができない、制限付きRead Onlyのような状態です。そのため、今度はこの接続されたKubernetesクラスターに対して、Azure Arcを介して管理操作が可能な状態にもっていきます。

# Azure ArcからKubernetes管理機能を有効にする
Azure ArcからKarbonでデプロイしたKubernetesクラスターを管理できるようにするには、cluster-adminに近い権限を付与する必要があります。Azure Portalから接続したKubernetesクラスターを見ると、Kubernetesリソースすらまだ見れない状態です。
![スクリーンショット 2021-12-19 9.37.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/aa6d034f-a098-292c-abbe-9622933b1b88.png)

## クラスター接続機能（cluster-connect）を有効にする
**サービスアカウント ベアラー トークン**を生成し、Azure Portal側からKarbonでデプロイしたKubernetesクラスターに書き込み権限のあるログインをできるようにします（Azure CLIを使わずにAzure PortalのUIからでも実行可能）。まずはクラスター接続機能（cluster-connect）の有効化です。

```bash:コマンド例
az connectedk8s enable-features --features cluster-connect -n {KARBON_K8S_CLUSTER_NAME} -g {YOUR_RESOUCE_GROUP_NAME}
```

```bash:今回の実行例
az connectedk8s enable-features --features cluster-connect -n milk01 -g rg-karbon
```

## クラスター接続機能（cluster-connect）のための認証
次にAzure Arc側からKubernetesクラスターを操作できるようにサービスアカウントの追加とロールバインディングを設定します。
サービスアカウントの追加とロールバインディングを設定とあるとおり、KarbonでデプロイしたKubernetesクラスターに対する作業となるため、今回の例では```milk01```のKUBECONFIGが登録され、```milk01```クラスターにアクセス可能なTerminalで作業します。

```bash
kubectl create serviceaccount admin-user
kubectl create clusterrolebinding admin-user-binding --clusterrole cluster-admin --serviceaccount default:admin-user
```

サービスアカウントの追加とロールバインディングの設定が完了したら、サービス アカウントのトークンを取得します。次の工程でこのトークンを使って、Azure ArcによるKubernetes管理操作用のKUBECONFIGを作成します。

:::note info
メモ：
この作業はサービスアカウントでの認証の代わりにAzure AD連携によって代替可能
:::

https://docs.microsoft.com/ja-jp/azure/azure-arc/kubernetes/cluster-connect#azure-active-directory-authentication-option

```bash
SECRET_NAME=$(kubectl get serviceaccount admin-user -o jsonpath='{$.secrets[0].name}')
TOKEN=$(kubectl get secret ${SECRET_NAME} -o jsonpath='{$.data.token}' | base64 -d | sed $'s/$/\\\n/g')
```

先ほど作成したトークンを使って、Azure ArcによるKubernetes管理操作用のKUBECONFIGを作成するほか、一時的にProxyを立てて、Azure PortalのAzure Arcから```milk01```クラスターにアクセス可能かの確認も実施します。

```bash:コマンド例
az connectedk8s proxy -n $CLUSTER_NAME -g $RESOURCE_GROUP --token $TOKEN
```

```bash:今回の実行例と実行結果
az connectedk8s proxy -n milk01 -g rg-karbon --token $TOKEN

Setting up environment for first time use. This can take few minutes...
Proxy is listening on port 47011
Merged "milk01" as current context in /root/.kube/config
Start sending kubectl requests on 'milk01' context using kubeconfig at /root/.kube/config
Press Ctrl+C to close proxy.
```

実行結果のメッセージに記載されているように、KUBECONFIGに、先ほど追加したサービスアカウントとロールバインディングの設定で作成したトークンが、```/root/.kube/config```にマージされ、新しいKUBECONFIGができあがっています。
既に先に実行したコマンドで```$TOKEN```に格納した内容、またはマージされた```/root/.kube/config```の```token:```の内容が**サービスアカウント ベアラー トークン**となります。
![スクリーンショット 2021-12-19 9.46.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/5bcadf0a-457b-8378-3b33-2b229ce47c5c.png)
```$TOKEN```に格納した内容を```echo```するか、マージされた```/root/.kube/config```の```token:```の内容を```cat```したものをAzure Portal上Azure Arcから管理操作するために必要な認証として、**サービスアカウント ベアラー トークン**を貼り付けて「サインイン」をクリックすると、Azure Arcからの管理操作が可能となります。
![スクリーンショット 2021-12-19 9.50.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/e7d6ab01-61d3-b265-5dbe-a514fe6347e8.png)
これで、先ほどまでAzure Portal上で接続したKubernetesクラスターのリソースを選択しても「サインインしてKubernetesリソースを表示します」と表示され見ることができなかったものが、表示されるようになりました。

# Azure ArcによるKarbonでデプロイされたKubernetesクラスターの管理
やっとAzure Arcによる管理操作の準備が完了したところで、さっそく触れてみます。

## Azure Portal上からKubernetesリソース確認
左ペインのメニューから「Kubernetesクラスターのリソース（プレビュー）を選択して、デプロイ（deployment）を名前空間（namespace）でフィルタして確認してみます。

KarbonでデプロイされたKubernetesクラスターは、当然ながら当初はkube-systemとntnx-systemのnamespaceでデプロイされたリソースしかありません。しかし、Azure Arc対応Kubernetesとして接続したことで、Azure Arc由来のリソースが増えています。
![スクリーンショット 2021-12-19 9.50.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/b3cedad1-d984-5929-ecd0-8547d5bdc908.png)

## Azure Portal上からKubernetesリソース追加
次に、Azure Arc側からKarbonでデプロイされたKubernetesクラスターにリソースを追加や変更できるか確認してみます。名前空間（namespace）の```default```には画面のとおり何もリソースがありません。このダッシュボードから「追加」をクリックしてデプロイ（deployment）を登録していきます。
![スクリーンショット 2021-12-19 9.56.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/1cdb1f0f-0e82-0555-7ed5-58ab453bb290.png)

簡単なdeploymentと言うことで、お馴染みのnginxベースでpod名を表示するだけのpodをAzure Portalからyamlで登録します。
![スクリーンショット 2021-12-19 9.56.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/fea88b4a-e1d1-1fe0-0f1b-fff968b7f70e.png)

（わざわざコードに載せるほどでもないですが）

```yaml:サンプルアプリ
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp-color
spec:
  selector:
    matchLabels:
      run: webapp-color
      #  strategy:
      #    rollingUpdate:
      #      maxSurge: 1
      #      maxUnavailable: 0
  replicas: 4
  template:
    metadata:
      labels:
        run: webapp-color
      annotations:
        kubernetes.io/change-cause: Initial release webapp-color version.1
    spec:
      containers:
      - name: webapp-color
        image: detteiu/karbon-training02:v1
        ports:
        - containerPort: 8080
```

先ほどの画面で「追加」をクリックすると、無事にAzure Portalからの操作で、オンプレミスのNutanixのKarbonでデプロイしたKubernetesクラスターに対してdeploymentが登録されました。
![スクリーンショット 2021-12-19 9.57.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/a2cdee3f-e07c-af1d-f816-b222255cfbd6.png)
![スクリーンショット 2021-12-19 9.57.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/a5297b0d-6845-2cc8-5733-04ce4954b5e7.png)

## Azure Portal上からKubernetesモニタリング
次にAzure Portal上からオンプレミスのNutanixのKarbonでデプロイしたKubernetesクラスターのモニタリングを見ていきます。こちらは、LogAnalyticsやAzure Monitor for containerなどを構成することで利用可能になります。

:::note warn
注意：
LogAnalyticsやAzure Monitorの構成時には、ロギングやモニタリングのために必要なデータの取得が行われ、データ量に応じて課金が発生する
:::

左ペインのメニュー「監視」から「分析情報」を選択すると、LogAnalyticsが構成されていない場合、以下のような画面が表示されます。こちらの監視を利用するには、Azure Monitorの構成も構成が必要なため、画面の指示にそってウィザードを進めます。
![スクリーンショット 2021-12-19 18.34.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/642f6bf2-0794-0581-3e5e-7929c8e792ec.png)

数分待つと、ログやメトリックなどが取れはじめます。（よくあるPrometheus＋GrafanaやElasticSerch＋Fluentbit＋Kibanaなどでのロギング・モニタリングはデフォルトのテンプレートなどで完成済みのダッシュボードなどもよくシェアされているので、それと比較すると）AzureのLogAnalyticsやAzure Monitorだと、自分がクエリの作り方がよく分かってないのもあり、まだうまく監視に必要な情報を選べてませんが、Azure Arcの機能使って、場所を問わず任意のKubernetesの監視が可能になるようです。
![スクリーンショット 2021-12-19 18.49.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/c53d8e85-7f2f-cc44-3574-0fadf420714c.png)
![スクリーンショット 2021-12-19 18.53.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/978d1170-f487-e814-5af2-f9e101a606a7.png)
![スクリーンショット 2021-12-19 18.59.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/205c844a-1306-ac42-052d-7cb4b652e0a6.png)

# お試し後のお掃除
クラウドあるあるですが、LogAnalyticsやAzure Monitorの構成、それに利用するWorkspaceを含むリソースグループを削除しないとゴリゴリと課金が続きます。Azure Arc対応Kubernetes用にリソースグループを作成している場合は、関連するAzure Arc絡みのリソースグループを根こそぎ、そしてLogAnalyticsやAzure Monitorで利用したWorkspaceやリソースグループも忘れずに削除します。

# まとめ
今回のNutanix Advent Calendar 2021は、Azure Arc対応KubernetesにNutanix KarbonでデプロイしたKubernetesクラスターを接続してみた、と言う内容でした。

今回は時間切れでしたが、引き続きカスタムの場所でKarbon上のKubernetesをAzure Arc対応データサービスのリソースとして使ったりとか試してみたいと思います。
![スクリーンショット 2021-12-19 11.52.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84474/1e672120-67ac-f2ae-966f-5e7ef04892e9.png)

Google Anthosしかり、このAzure Arcしかり、接続するのに若干手間は掛かりますが、パブリッククラウド上のKubernetesもオンプレミス上のKubernetesも、そしてパブリッククラウドが提供するサービスのインフラリソースの一部としてオンプレを使いたいし、それらを一元的に管理したい、と言う場合の未来の選択肢の一つになるかもしれません。

ただ、現時点でKubernetesの運用は様々なKubernetesエコシステムを組み合わせて運用しているケースが多く、それらのインターフェースやダッシュボードでの管理を行っている場合に、運用の一元化のための代替インターフェースやそれらエコシステムの代替の機能までは提供できないため、Kubernetesの管理や運用を完全に一元化と言うのも、そう簡単ではない気がしています。

とは言うものの、単にオンプレミスを含む任意のKubernetesをパブリッククラウドから管理できると言うだけではなく、オンプレミスのインフラをパブリッククラウドが利用可能なインフラの1つとして扱えるようになる機能は、クラウドシフト潮流の荒波に晒され始めている日本企業のよくあるシステム要件事情からすると、現実的な落とし所の1つとして議論の俎上にのってきそうです。

もちろん逆パターン、つまりパブリッククラウドのインフラをオンプレミスのNutanixの拡張先のリソースとして利用可能な、Nutanixがパブリッククラウドでそのまま使えるNutanix Clusters on AWSやon Azureなんかのパターンでは、Lift＆Shiftに必要な学習コストがあまり必要ないことやオンプレミス運用時のPrismによる運用そのままなのでシンプル化を図れると言う意味では、これも有効な一手になるかと思います。