はじめに
Azure Kubernetesを利用してwebサービスを立ち上げる。立ち上げまでにどのような事が必要なのか、どんな要素で構成されているのか、実装のコマンドや操作はどのようなものかを一通り試して学んでみる。最終イメージと主な操作を以下に示します。

環境構築
ACR(Azure Container Registry)
最初にイメージを格納するコンテナレジストリを作成します。azureではすべてのリソースはリソースグループという単位で管理されているので、まずはリソースグループを作成します。個人的にはリソースグループ名に日付を付けておくと、検証した環境一式を一度に消せるのでそうしてます。
リソースグループができたらイメージの格納場所であるACRを作成します。格納場所が出来たら、プログラムソースとDockerfileからイメージを作成します。プログラムソースやDockerファイルについてはここでは割愛します。azureだと、az acr buildでイメージが出来上がります。
# リソースグループの作成
az group create --resource-group rgp_2020_05_11 --location japaneast
# レジストリの作成
az acr create --resource-group rgp_2020_05_11 --name registry0511 --sku Standard --location japaneast
# Dockerfileのあるソースディレクトリへ移動
cd ~
# イメージのビルド(内部でdocker buildをコールしている)
az acr build --registry registry0511 --image web-image:v1.0 .
# 作成したイメージの確認
az acr repository list --name registry0511
[
"web-image"
]
AKS(Azure Kubernetes Service)
リソースの作成で、「Kubernetes」を選択します。

既存のリソースグループを選択し、クラスター名(ここではmyCluster)を入力、地域とバージョンはデフォルトのままにします。

ノードサイズは最低2コア4Gメモリを選択する必要がある。デフォルトでもよいが、安価な「B2s」を選択します。また無料試用版のサブスクリプションだとノード数は合計4コア以内の制約があるため、ここでは2ノードとします。すべて入力したら「確認および作成」ボタンを押します。

「作成」ボタンを押して10分程度すると、以下のような完了メッセージが表示されます。

以上でkubernetesは出来上がりです。
Kubernetesへの適用の準備
Azure cloud shellからkubeを操作できるように権限を付与します。(visual stdio codeからazureへログインすることもできます。こちら。)
# cloud Shell から kubectlを使えるようにする
az aks get-credentials --resource-group rgp_2020_05_11 --name myCluster
このコマンドで自分のホームディレクトリ下の.kube/configに接続するための証明書が追加されます。
kubenetesがACRにあるimageをPULLできるようにするために、まずはACRの管理者ユーザを有効にします。サービスプリンシパルを作成すればリソースに対する権限を細かく制御できますが、ここでは管理者ユーザを利用します。

管理者ユーザを有効にしたら、次のコマンドでsecretリソースを作成します。デプロイ用のマニフェストの中で、このsecretリソースを指定すれば、ACRからイメージをpullできるようになります。
$ kubectl create secret docker-registry acr-pull-key --docker-username=registry0511 --docker-password=<パスワード> --docker-server=registry0511.azurecr.io
# secret情報の確認
$ kubectl get secret
NAME TYPE DATA AGE
acr-pull-key kubernetes.io/dockerconfigjson 1 8m33s
これでkubernetesへの適用の準備が完了しました。あとは、マニフェストを作成してkubectl apply -f マニフェストでpodやserviceを立ち上げていきます。
マニフェストファイルの適用
ここまでの手順で、kubernetes上にnodeが立ち上がった状態になっているはずです。デプロイはしてないので、まだpodは立ち上がっていません。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
aks-agentpool-39326823-vmss000000 Ready agent 19m v1.15.10
aks-agentpool-39326823-vmss000001 Ready agent 19m v1.15.10
$ kubectl get pod
No resources found in default namespace.
ACRに保存されたイメージをもとにポッドを立ち上げます。適用するマニフェストファイルは次のとおり。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec: # ======================== Deploymentのスペック =========================
replicas: 4 # レプリカ数
selector:
matchLabels: # 検索条件
app: web-first
template: # ================== テンプレート =================================
metadata:
labels:
app: web-first
env: production
spec:
containers:
- image: registry0511.azurecr.io/web-image:v1.0 # コンテナイメージの場所
name: web-first-container # コンテナ名
ports:
- containerPort: 3000 # ポート番号
imagePullSecrets:
- name: acr-pull-key # コンテナレジストリのPULLキー
マニフェストファイル(web-deployment.yaml)を適用し、podの状態を確認します。
# デプロイ用のマニフェストファイルを適用します
$ kubectl apply -f web-deployment.yaml
deployment.apps/web-deployment created
# podの状態を確認します(立ち上げ中)
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
web-deployment-555cd7dff9-9m9th 0/1 ContainerCreating 0 17s
web-deployment-555cd7dff9-fv2sz 0/1 ContainerCreating 0 17s
web-deployment-555cd7dff9-jkb59 0/1 ContainerCreating 0 17s
web-deployment-555cd7dff9-mwb6g 0/1 ContainerCreating 0 17s
# podの状態を確認します(起動完了)
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
web-deployment-555cd7dff9-9m9th 1/1 Running 0 4m22s
web-deployment-555cd7dff9-fv2sz 1/1 Running 0 4m22s
web-deployment-555cd7dff9-jkb59 1/1 Running 0 4m22s
web-deployment-555cd7dff9-mwb6g 1/1 Running 0 4m22s
次にLoad Balancerを立ち上げます。適用するマニフェストファイルは次のとおり。
apiVersion: v1
kind: Service
metadata:
name: lb
spec: # ================= Serviceのスペック ===============================
type: LoadBalancer
ports:
- port: 80 # 自身が公開するポート番号
targetPort: 3000 # 接続先のポート番号
protocol: TCP
selector: # =========== 接続先(POD)の条件 =============================
app: web-first
上記のマニフェストファイル(lb-service.yaml)を適用し、サービスの起動を確認します。外部IPが割り当てられるまで十数秒待ちます。
$ kubectl apply -f lb-service.yaml
service/lb created
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 34m
lb LoadBalancer 10.0.226.244 <pending> 80:31716/TCP 6s
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 34m
lb LoadBalancer 10.0.226.244 20.44.171.157 80:31716/TCP 26s
ブラウザからhttp://<EXTERNAL-IP>へ接続すると、無事、コンテンツが表示されるはずです。今後はこれをベースに気になるところ、例えばIPでなくFQDNで、httpでなくhttpsでアクセスしたいなど、また試していこうかと思います。