AKS で asp.net core アプリケーション : イングレスとアプリ複数ポッド構成

[前回](https://qiita.com/kenakamu/items/c1ff282992bfc778000d#%E3%81%BE%E3%81%A8%E3%82%81)は asp.net core アプリを AKS 上にデプロイしましたが、まだ一台構成のままです。また外部からのアクセスは IP アドレスを行っているため、この記事ではネットワークの考察とイングレスおよび名前解決、およびアプリの複数台構成についてみていきます。

# イングレスとは

[こちらの記事](https://docs.microsoft.com/ja-jp/azure/aks/ingress-basic)から説明を抜粋すると、「イングレス コントローラーは、リバース プロキシ、構成可能なトラフィック ルーティング、および Kubernetes サービスの TLS 終端を提供するソフトウェア」です。

# Azure ロードバランサ―と k8s サービス

AKS で k8s サービスをロードバランスとして作成した場合、裏では Azure ロードバランサーが構成されます。以下で具体的に確認してみます。

1\. コマンドプロンプトよりロードバランサ―のアドレスを確認。

```shell
>kubectl get svc
NAME               TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)        AGE
core3webapp        LoadBalancer   10.0.23.19    40.115.179.34   80:30242/TCP   10d
kubernetes         ClusterIP      10.0.0.1      <none>          443/TCP        12d
mssql-deployment   ClusterIP      10.0.138.88   <none>          1433/TCP       10d
```

2\. [Azure ポータル](https://portal.azure.com)より、ロードバランサ―が存在することを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/fbdb6c2b-621b-ec79-0178-6914c67240c4.png)

3\. ロードバランサ―リソースを開き、フロントエンド IP 構成から IP アドレスが手順 1 で確認したものと同じであることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/1212c728-c79d-8234-0ee0-da4e8952ae7d.png)

4\. バックエンドプールで、ノードとなる VM が設定されていることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/f5e55388-0f69-1a22-8528-7cc52837637b.png)

このロードバランサ―の IP アドレスに DNS 名を追加すると名前解決ができますが、レイヤー 4 で動作するため、パスによるルーティングなどはできません。

# HTTP アプリケーションルーティング アドオン

開発時に簡単にアプリケーションルーティングなど、レイヤー 7 の機能を試せるよう、AKS ではアドオンを用意しています。

[参考:HTTP アプリケーション ルーティング](https://docs.microsoft.com/ja-jp/azure/aks/http-application-routing)

このページの注意事項に 「このアドオンを運用環境で使用することはお勧めできません。」 とあるためあくまで開発環境向けではありますが、今回はこの機能を試してみます。

## アドオンのインストール

アドオンは AKS クラスタ新規構築時と、既存クラスタへの追加の両方をサポートしています。今回はすでに存在する環境に対して追加していきます。またアドオンをインストールすると、自動的に DNS リソースも追加されます。

1\. コマンドプロンプトより以下コマンドを実行。

```shell
az aks enable-addons -g netcoresample -n myaks --addons http_application_routing
```
2\. アドオンのインストールが完了したら、登録されている DNS ゾーン名を取得。

```shell
>az aks show -g netcoresample -n myaks --query addonProfiles.httpApplicationRouting.config.HTTPApplicationRoutingZoneName -o table
Result
----------------------------------------
15d7f373484d4e04917f.japaneast.aksapp.io
```
3\. Azure 上に DNS リソースが追加されているので確認。リソースグループはノードが追加されている方のグループ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/0845bab6-f2c4-fa09-dce3-ccf9b80a888d.png)

## イングレスリソースの追加

追加したアドオンを利用するため、イングレスの追加と、サービスのタイプを変更します。

1\. core3webapp.yaml を以下に書き換え。

- サービスから Type: LoadBalancer を削除 (既定の ClusterIP になる)
- イングレスの追加: DNS 名は上記で確認したゾーンを利用
- ルーティングのパスは、ルート (/) を使用

```yaml:core3webapp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: core3webapp
  namespace: default
  labels:
    app: core3webapp
spec:
  replicas: 1
  selector:
    matchLabels:
        app: core3webapp
  template:
    metadata:
      name: core3webapp
      labels:
        app: core3webapp
    spec:
      containers:
      - name: core3webapp
        image: kenakamuacr.azurecr.io/core3webapp:20191017063305
        resources: 
          requests:
            cpu: "250m"
            memory: "512Mi"
          limits:
            cpu: "500m"
            memory: "1Gi"
        imagePullPolicy: Always
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  name: core3webapp
  labels:
    app: core3webapp
spec:
  ports:
  - protocol: TCP
    port: 80
  selector:
    app: core3webapp
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: core3webapp
  annotations:
    kubernetes.io/ingress.class: addon-http-application-routing
spec:
  rules:
  - host: core3webapp.15d7f373484d4e04917f.japaneast.aksapp.io
    http:
      paths:
      - backend:
          serviceName: core3webapp
          servicePort: 80
        path: /
```

2\. kubectl apply でデプロイを実行。

- --force をつけている理由は ClusterIP の場合に失敗する不具合があるため

```shell
kubectrl apply -f core3webapp.yaml --force
```

3\. サービスを取得して EXTERNAL-IP がないことを確認。

```shell
>kubectl get svc
NAME               TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
core3webapp        ClusterIP   10.0.92.73    <none>        80/TCP     5m56s
kubernetes         ClusterIP   10.0.0.1      <none>        443/TCP    12d
mssql-deployment   ClusterIP   10.0.138.88   <none>        1433/TCP   10d
```

4\. イングレスを取得してホスト名を確認。

```shell
>kubectl get ingress
NAME          HOSTS                                                  ADDRESS          PORTS   AGE
core3webapp   core3webapp.15d7f373484d4e04917f.japaneast.aksapp.io   40.115.246.205   80      6m58s
```
5\. ブラウザでホスト名でアクセス。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/82357d4c-8257-b1c6-3b7b-9ba7b9f64eaf.png)

6\. Azure ロードバランサ―の設定も自動で変更される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/a805c102-8a17-235f-bcac-4039aa35695d.png)

7\. DNS ゾーンに指定した名前が追加される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/877ba4b2-f59c-8286-9aeb-2c537b9ef180.png)

# アプリケーションの複数台構成

次に複数台構成を試します。

1\. 異なるポッドにアクセスしている様子がわかるように、アプリを改修。Visual Studio で Views | Home | Index.cshtml を以下のコードと差し替え。

- @Environment.MachineName で実行中のポッド名を表示

```html:index.cshtml
@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <h3>@Environment.MachineName</h3>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
```

2\. プロジェクトを右クリックして発行を実行。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/222c75ef-410b-5f7a-40f8-b66cf0385261.png)

3\. ACR よりタグを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/49f0db6c-7cec-3280-e5c9-2e040c812ab0.png)

4\. core3webapp.yaml の Deployment のみを以下に変更。

- イメージのタグを変更
- レプリカで 2 を指定

```yaml:core3webapp.yaml
kind: Deployment
metadata:
  name: core3webapp
  namespace: default
  labels:
    app: core3webapp
spec:
  replicas: 2
  selector:
    matchLabels:
        app: core3webapp
  template:
    metadata:
      name: core3webapp
      labels:
        app: core3webapp
    spec:
      containers:
      - name: core3webapp
        image: kenakamuacr.azurecr.io/core3webapp:20191028123417
        resources: 
          requests:
            cpu: "250m"
            memory: "512Mi"
          limits:
            cpu: "500m"
            memory: "1Gi"
        imagePullPolicy: Always
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
```

5\. デプロイを適用。

```shell
kubectrl apply -f core3webapp.yaml --force
```

6\. ポッドを確認。アプリのポッドが 2 つになっていることを確認。

```shell
>kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
core3webapp-6d5b8fcb5-f29gc         1/1     Running   0          25s
core3webapp-6d5b8fcb5-tqnrb         1/1     Running   0          20s
mssql-deployment-5b74bdb6f7-5tk9k   1/1     Running   0          21h
```

7\. ブラウザよりアプリにアクセス。F5 で更新してポッド名が変わることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/cbebaa8b-23d7-c952-33ca-3693e59c9522.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/dcbea16e-9628-25ef-ab53-a22670b5c097.png)

# まとめ

今回はイングレスを使った構成および名前解決の作成を行ったほか、レプリカセットを使ってアプリを 2 台構成にしました。次回は SQL サーバーと Web アプリの配置について詳細を見ていきます。

[次の記事へ](https://qiita.com/kenakamu/items/aee6748b6d15b8aab34f)
[目次へ戻る](https://qiita.com/kenakamu/items/e155740aa60c85a3d867)

# 参考情報

[Azure Kubernetes Service (AKS) で Standard SKU ロード バランサーを使用する](https://docs.microsoft.com/ja-jp/azure/aks/load-balancer-standard)