Azure AKSを試す

## やったこと
* AKSをazure-cliで構築する。
* Golangのアプリをデプロイする。

## AKS構築

ログイン

```
$ az login
```

サブスクリプションを確認し、SubscriptionIdをセットする

```
$ az account list -o table

$ SUBSCRIPTION=<SubscriptionId>
```

リソースグループ作成

```
$ RESOURCEGROUP=MyResourceGroup
$ az group create -n $RESOURCEGROUP -l japaneast
```

サービスプリンシパルの作成

```
$ az ad sp create-for-rbac --skip-assignment --name $RESOURCEGROUP -o json
```

成功すると以下のjsonが返ってくる

```
{
  "appId": <appId>,
  "displayName": "MyResourceGroup",
  "password": <password>,
  "tenant": <tenantId>
}
```

上記のappIdとパスワードをセットする

```
$ SERVICE_PRINCIPAL=<appId>
$ CLIENT_SECRET=<password>
```

AKS作成

```
$ az aks create \
    --resource-group $RESOURCEGROUP \
    --name myAKSCluster \
    --node-count 1 \
    --service-principal $SERVICE_PRINCIPAL \
    --client-secret $CLIENT_SECRET
```

 AKS クラスターのアクセス資格情報を取得し、kubeconfig ファイルにマージする

```
$ az aks get-credentials -n myAKSCluster --resource-group $RESOURCEGROUP
```

確認

```
$ kubectl get node

NAME                                STATUS   ROLES   AGE    VERSION
aks-nodepool1-85062842-vmss000000   Ready    agent   2m9s   v1.22.6
```


## イメージ作成

以下の手順を実行する
* ACRの作成
* アプリをビルドしてプッシュ
* kubernetesのdeployment,serviceを作成


Azureのコンテナイメージを保管するACRを作成

```
$ ACR_NAME=<ACR名>
$ az acr create --resource-group $RESOURCEGROUP --name $ACR_NAME --sku Basic
```

AKSクラスターに接続し、AKSクラスターからACRのイメージをプルできるようにする。

```
$ az aks update -n myAKSCluster -g $RESOURCEGROUP --attach-acr $ACR_NAME
```

ACRにGoのアプリをビルド、プッシュする

アプリは以下のmain.goとDockerfileを利用
go modで初期化しておく

```go:main.go
package main

import (
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "Hello World!",
		})
	})
	r.Run(":8080")
}
```

```docker:Dockerfile
FROM golang:1.17-alpine

WORKDIR /app

COPY go.mod .
COPY go.sum .
RUN go mod download

COPY . ./

RUN go build -o /go-app

EXPOSE 8080

CMD [ "/go-app" ]
```


イメージを作成して、ACRにプッシュする

```
# ビルド 
$ docker build -t go-app .

# tag付け
$ docker tag go-app ${ACR_NAME}.azurecr.io/go-app

# ACRにログイン (Azure Portal > 「コンテナー レジストリ」　 > 「アクセスキー」で認証情報を取得する)
$ docker login ${ACR_NAME}.azurecr.io

# プッシュ
$ docker push ${ACR_NAME}.azurecr.io/go-app
```

# アプリをデプロイ

```deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-deployment
  labels:
    app: go-deployment
spec:
  selector:
    matchLabels:
      app: go-pod
  replicas: 3
  template:
    metadata:
      labels:
        app: go-pod
    spec:
      containers:
        - name: go-container
          image: <ACR名>.azurecr.io/go-app
          ports:
          - containerPort: 8080 
```

```service.yml
apiVersion: v1
kind: Service
metadata:
  name: go-svc
spec:
  selector:
    app: go-pod
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
  type: LoadBalancer
```

```
$ kubectl apply -f deployment.yml
$ kubectl apply -f service.yml
```

* 確認

サービスのEXTERNAL-IPからアクセスする

```
$ kubectl get svc go-svc

NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)          AGE
go-svc       LoadBalancer   10.0.248.227   20.210.21.12   8080:30157/TCP   2m34s
kubernetes   ClusterIP      10.0.0.1       <none>         443/TCP          40m

$ curl http://20.210.21.12:8080 
{"message":"Hello World!"}
```

# 削除

リソースグループを削除

```
az group delete -n $RESOURCEGROUP
```

参考

https://docs.microsoft.com/ja-jp/azure/aks/learn/quick-kubernetes-deploy-cli
https://docs.microsoft.com/ja-jp/azure/container-registry/container-registry-get-started-portal