AKS で asp.net core アプリケーション : アプリをデプロイ

[前回](https://qiita.com/kenakamu/items/f61ed635a77b673e8164)はローカルで Visual Studio 2019 のテンプレートを使って ASP.NET Core Web アプリケーションを作成しました。今回は作成したアプリを AKS 上で動かすほか、SQL が外部からアクセスできる状態を変更します。

# ACR へのアップロード

作成したアプリを AKS で使うためには、コンテナイメージを AKS がダウンロードできる必要があります。初回の記事で作成した ACR へアップロードします。

1\. 現在ローカルの環境はデバッグビルドとしてビルドされているため、Visual Studio よりリリースビルドを作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/c607a1c9-3f15-58a8-edac-ccce7070d404.png)

2\. プロジェクトを右クリックして「発行」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/17c7dc4b-217b-b950-6a4d-84cd27c5fc03.png)

3\.「コンテナーレジストリ」より「既存の Azure Container Registry を選択する」にチェックを入れて「プロファイルの作成」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/d0f10d41-191b-f7e8-9e71-3714102b082d.png)

4\. 任意のログイン、サブスクリプションを選択し、リソースグループよりアップロード先の ACR を選択。「OK」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/d6410adb-d867-e5da-ef9b-fde8d39b37e8.png)

5\. タグでバージョンを指定したいので、「イメージタグの編集」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/406b2f8c-ac78-5c70-fd0b-a08b21132e45.png)

6\.「発行時にタグを生成」を選択して「OK」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/6a2a492e-6160-7203-aeb8-14331ed14d36.png)

7\.「発行」をクリック。完了後 Azure ポータルからも確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/1ab609d9-2be6-f157-b9a0-f6bdac76b752.png)

8\. ローカルにもイメージが作成されている。

```shell
> docker images
REPOSITORY                               TAG                 IMAGE ID            CREATED             SIZE
<none>                                   <none>              1a0dfc93b4f6        10 minutes ago      923MB
<none>                                   <none>              e850b565c69e        17 minutes ago      923MB
core3webapp                              latest              2f23df6191c3        About an hour ago   226MB
kenakamuacr.azurecr.io:443/core3webapp   20191017061631      2f23df6191c3        About an hour ago   226MB
mcr.microsoft.com/dotnet/core/sdk        3.0-buster          170a7f2ec51a        7 hours ago         689MB
mcr.microsoft.com/dotnet/core/aspnet     3.0-buster-slim     930743cb4e19        15 hours ago        207MB
```

# AKS へのデプロイ

次に AKS にアプリをデプロイします。

1\. 以下 yaml ファイルを作成。

- container で ACR とイメージ名、タグを指定

```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:20191017061631
        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:
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 80
  selector:
    app: core3webapp
```

2\. **apply** を実行。

```shell
kubectl apply -f core3webapp.yaml
```

3\. 結果を確認。

```shell
> kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
core3webapp-58847975d4-4f4hk        1/1     Running   0          67s
mssql-deployment-5b74bdb6f7-755wh   1/1     Running   2          2d2h
> 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     72s
kubernetes         ClusterIP      10.0.0.1       <none>          443/TCP          2d2h
mssql-deployment   LoadBalancer   10.0.228.137   52.243.63.3     1433:30488/TCP   2d2h
```

4\. ブラウザで外部アドレスよりアプリに接続。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/028df797-0f05-2edc-4b45-4aedf00855ee.png)

5\. 登録済のアカウントでログイン。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/97393078-7551-5170-7586-595b611d2a08.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/5bc60087-c849-55c8-5817-77d172315a00.png)

# SQL 用 k8s サービスの変更

現在 SQL の接続は 2 つの問題があります。

- LoadBalancer タイプのため外部からアクセスできる
- appsettings.json で IP アドレス指定で接続している

## サービスのタイプ変更

まずは SQL のサービスを LoadBalancer から ClusterIP に変更します。
[Azure Kubernetes Service (AKS) でのアプリケーションに対するネットワークの概念](https://docs.microsoft.com/ja-jp/azure/aks/concepts-network)を参照すると、サービスの種類として以下のように記述があります。

**クラスター IP** - AKS クラスター内で使用する内部 IP アドレスを作成します。 クラスター内で他のワークロードをサポートする内部専用アプリケーションに適しています。
AKS クラスター内のクラスター IP トラフィック フローを示す図
![](https://docs.microsoft.com/ja-jp/azure/aks/media/concepts-network/aks-clusterip.png)

**NodePort** - ノード IP アドレスとポートによるアプリケーションへの直接アクセスを許可する、基になるノード上にポート マッピングを作成します。
AKS クラスターでの NodePort トラフィック フローを示す図
![](https://docs.microsoft.com/ja-jp/azure/aks/media/concepts-network/aks-nodeport.png)

**LoadBalancer** - Azure ロード バランサー リソースを作成し、外部 IP アドレスを構成し、要求されたポッドをロード バランサーのバックエンド プールに接続します。 顧客のトラフィックによるアプリケーションへのアクセスを許可するために、目的のポート上に負荷分散規則が作成されます。
![](https://docs.microsoft.com/ja-jp/azure/aks/media/concepts-network/aks-loadbalancer.png)
制御と受信トラフィックのルーティングを追加するため、イングレス コントローラーを代わりに使用できます。

**ExternalName** - 特定の DNS エントリを作成して、アプリケーションに簡単にアクセスできるようにします。

ここでは内部からのアクセスが必要なだけのため、クラスターIP を使います。

1\. sql2017.yaml のサービス定義から、一番最後の ```type: LoadBalancer``` を削除する。

```yaml:sql2017.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
     name: azure-disk
provisioner: kubernetes.io/azure-disk
parameters:
  storageaccounttype: Premium_LRS
  kind: Managed
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mssql-data
  annotations:
    volume.beta.kubernetes.io/storage-class: azure-disk
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
---
apiVersion: v1
kind: Secret
metadata:
  name: mssql
type: Opaque
data:
  SA_PASSWORD: "TXlDMG05bCZ4UEBzc3cwcmQ="
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: mssql-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: mssql
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: mssql
        image: mcr.microsoft.com/mssql/server:2017-latest
        ports:
        - containerPort: 1433
        env:
        - name: MSSQL_PID
          value: "Developer"
        - name: ACCEPT_EULA
          value: "Y"
        - name: MSSQL_SA_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mssql
              key: SA_PASSWORD 
        volumeMounts:
        - name: mssqldb
          mountPath: /var/opt/mssql
      volumes:
      - name: mssqldb
        persistentVolumeClaim:
          claimName: mssql-data
---
apiVersion: v1
kind: Service
metadata:
  name: mssql-deployment
spec:
  selector:
    app: mssql
  ports:
    - protocol: TCP
      port: 1433
      targetPort: 1433
```

2\. apply を実行。

- バージョンによって --force コマンドが無いとエラーになる

```shell
kubectl apply -f sql2017.yaml --force
```
3\. サービスの mssql-deployment で EXTERNAL-IP がアサインされないことを確認。

```shell_session
> 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   25m
kubernetes         ClusterIP      10.0.0.1      <none>          443/TCP        2d3h
mssql-deployment   ClusterIP      10.0.138.88   <none>          1433/TCP       10s
```

## appsettings.json の変更

AKS クラスタ内部の名前解決は、設定した名前で自動的に行うことができるようになっています。よってここでは SQL への接続は ```mssql-deployment``` を使います。

1\. Visual Studio 2019 より appsettings.json を開いて接続文字列を変更。

```json:appsettings.json
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=mssql-deployment;Database=Users;User Id=sa;Password=MyC0m9l&xP@ssw0rd;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}
```

2\. すべてを保存後、プロジェクトを右クリックして発行を実行。新しいバージョンを確認。

```shell
u> docker images
REPOSITORY                               TAG                 IMAGE ID            CREATED             SIZE
core3webapp                              latest              1c4252eb3ac9        26 minutes ago      226MB
kenakamuacr.azurecr.io:443/core3webapp   20191017063305      1c4252eb3ac9        26 minutes ago      226MB
...
```

3\. core3webapp.yaml でイメージのバージョンを変更後、apply を実行。describe コマンドでデプロイされたポッドの詳細を表示し、Containers の Image より指定したバージョンであることを確認。

```shell
> kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
core3webapp-678c7b89f4-lmd4b        1/1     Running   0          27m
mssql-deployment-5b74bdb6f7-755wh   1/1     Running   2          2d3h
> kubectl describe pods core3webapp-678c7b89f4-lmd4b
Name:               core3webapp-678c7b89f4-lmd4b
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               aks-nodepool1-23705949-1/10.240.0.5
Start Time:         Fri, 18 Oct 2019 03:33:33 +0900
Labels:             app=core3webapp
                    pod-template-hash=678c7b89f4
Annotations:        <none>
Status:             Running
IP:                 10.244.0.23
Controlled By:      ReplicaSet/core3webapp-678c7b89f4
Containers:
  core3webapp:
    Container ID:   docker://626a673c7f83ea89470c199ce13b57e6776e2c2604f12b7c28046303edc777e7
    Image:          kenakamuacr.azurecr.io/core3webapp:20191017063305
    Image ID:       docker-pullable://kenakamuacr.azurecr.io/core3webapp@sha256:ed67905e33163d8c95b771676524be76496f2284d9e6e2816c5f94909bd07e9d
```

4\. 再度外部からアプリにアクセスして、ログインやログオフなどデータベースに接続する処理が行えることを確認。

# まとめ

今回は AKS へアプリをデプロイするとともに、SQL のアクセスを内部にするなど運用上必要な設定を行いました。次回はネットワークの考察とアプリの複数台構成を見ていきます。

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