KubernetesでApp Serviceを動かす!!

★★★ Live配信告知 ★★★ぜひお申込みください!
◆◇世界一わかりみの深いクラウドネイティブ on Azure◆◇
8/4(木) 19:00~ 第17回:コンテナをサーバーレスでラクラク実行 〜 Azure Container InstancesとDocker CLIで実現 〜 今回は、コンテナをサーバーレスで実行するテクノロジとDocker CLIとの連携を紹介します。
◆◇PS Live◆◇
8/5(金) 12:00~ 第18回:アウトプットはイイぞ 〜サイオステクノロジーLT大会〜 エンジニア初級者向けから、個人ネタまで、エンジニア脳を体感できるプログラムです。

こんにちは、サイオステクノロジー武井です。今回は、KubernetesでApp Serviceを動かすということをしてみたいと思います。

Azure Arcとは?

Azure以外のクラウドやオンプレミスで動作する仮想マシンその他のリソースを統合的に運用監視しましょうというサービスです。AWSで動作する仮想マシンであるEC2を管理する場合はCloud Watchを使いますし、GCPであればCloud Monitoring、AzureであればAzure Monitorといったところになります。マルチクラウドを考えた場合、Cloud Watch、Cloud Monitoring、Azure Monitorの3つのツールを使いこなすのはちょっと大変です。

Azure Arcを使うと、Azure以外(他のクラウドやオンプレミス)のリソースに専用のエージェントを入れることにより、Azure上のリソースとして登録し、Azure側で一括管理できてしまいます。先の例で言えば、AWSのEC2もGCPの仮想マシンも全て、Azure上のリソースとして見えるようになるのでAzure Monitorで管理出来るようになります。

Azure Arc enabled Kubernetes

Azure Arcは、Azure以外のKubernetes(他のクラウドやオンプレミスのKubernetes)をAzureのリソースとして管理することができます。私はAzure Arcの機能の中でこれが最もすごいと思っております。

今回ご紹介するApp ServiceをKubernetesで動かすぞという技術のベースには、このAzure Arc enabled Kubernetesが使われております。これはApp Serviceをコンテナ化(もしくはApp Serviceがそもそもコンテナベースで動いている???)して、Azure Arcによって、Kubernetesリソースとして登録されている別クラウド上のKubernetesにデプロイが可能になる技術です。

これは何がいいかというと、私個人の考えになりますが、クラウドネイティブかつマルチクラウドという相反するテクノロジーが共存出来るのかなと思っております。

例えばAzure FunctionsといったFaaSサービスを使うと、OSやアプリケーションフレームワークといったレイヤーの面倒を見なくてよく、簡単にアプリケーションを構築出来る反面、それはAzureネイティブな技術なので、他のクラウドに移植することが困難になります。つまりAzure Functionsで作ったアプリをマルチクラウドで展開する場合、そのアプリはほぼ作り直しになるのです。AWSでAzure Functionsはもちろん動きませんから、Lambdaあたりで再開発といったところになります。もちろんある程度の部品の流用はできると思いますが。

でも、Azure Arc enabled Kubernetesを使えば、App ServiceというAzureマネージドなクラウドネイティブな機能を他クラウドのKubernetes上で動作させることができ、そして万が一Azureが大規模障害で利用不能のになったとしても、他のクラウドでApp Serviceが動作するということが出来るのです。

ちなみに、この機能はMicrosoft Build2021でプレビューとなり、App Serviceだけではなく、Azure Functions、Logic Apps、Event Gridなどもその対象となります。

早速動かしてみよう!!

ということで、やってみましょう。といっても、すでにその方法は以下URLのMicrosoft Learnに掲載されており、その方法をベースにしております。

https://docs.microsoft.com/ja-jp/learn/modules/configure-application-kubernetes-arc/

Microsoft LearnではAzure Kubernetes Service上にApp Serviceをデプロイする方法が記載されていましたので、それに準拠します。オンプレミスや他のクラウドのKubernetesでも、、、動くのかしら?

ちなみにこの検証に必要なリソースは以下のリソースグループとリージョンに配置することとします。

  • リソースグループ:appservicewazurearc
  • リージョン:East US

作業は全てAzure Cloud Shellで行います。

事前準備

まずApp ServiceをKubernetes上で動作するためのリソースプロバイダーと機能を有効にします。

$ az feature register --namespace Microsoft.Kubernetes --name previewAccess
$ az provider register --namespace Microsoft.Kubernetes --wait

$ az feature register --namespace Microsoft.KubernetesConfiguration --name extensions
$ az provider register --namespace Microsoft.KubernetesConfiguration --wait

$ az feature register --namespace Microsoft.ExtendedLocation --name CustomLocations-ppauto
$ az provider register --namespace Microsoft.ExtendedLocation --wait

$ az provider register --namespace Microsoft.Web --wait

 

次のコマンドを実行して、最新のAzure CLI拡張機能をインストールします。

$ az update

 

次のコマンドを実行して、connectedk8s および customlocation Azure CLI 拡張機能をインストールします。

$ az extension add --upgrade --yes -n connectedk8s
$ az extension add --upgrade --yes -n customlocation
$ az extension remove -n appservice-kube
$ az extension add --yes --source "https://aka.ms/appsvc/appservice_kube-latest-py2.py3-none-any.whl"

 

az -vコマンドを実行して、以下のモジュールが表示されることを確認します。バージョンは違うかもしれません。

$ az -v
connectedk8s 1.1.5
appservice-kube 0.1.20
customlocation 0.1.2

AKSクラスターの作成

AKSクラスターを作成するリソースグループ、クラスター名、リージョンなどを変数に定義します。

$ K8S_CLUSTER_RG_NAME=appservicewazurearc
$ K8S_CLUSTER_NAME=k8sAKS-c$RANDOM
$ LOCATION=eastus

 

AKSクラスターを作成します。ちょっと時間かかります。

$ az aks create -g $K8S_CLUSTER_RG_NAME -n $K8S_CLUSTER_NAME --enable-aad --generate-ssh-keys

 

クラスターから管理者資格情報を取得します。以下のNamespaceが取得できればOKです。

$ kubectl get ns
NAME STATUS AGE
default Active 3m46s
kube-node-lease Active 3m48s
kube-public Active 3m48s
kube-system Active 3m48s

 

AKSクラスターをAzure Arcに接続する

Azure  Arcのクラスターを作成するリソースグループとクラスター名を変数に定義します。

$ K8S_ARC_PREFIX=k8sArc
$ ARC_RG_NAME=appservicewazurearc
$ ARC_CLUSTER_NAME="${K8S_ARC_PREFIX}-cluster"

 

AKSクラスターをAzure Arcに接続します。2分程度かかります。出力結果のprovisioningState プロパティの値が Succeeded となっていることを確認します。

$ az connectedk8s connect -g $ARC_RG_NAME -n $ARC_CLUSTER_NAME

 

クラスター上に作成された Azure Arc ポッドを一覧表示します。clusterconnect-agent ポッドが含まれていることを確認してください。

$ kubectl get pods -n azure-arc
NAME READY STATUS RESTARTS AGE
cluster-metadata-operator-7cff574c4f-tzfm4 2/2 Running 0 3m38s
clusterconnect-agent-6dfd867c68-xdxrf 3/3 Running 0 3m38s
clusteridentityoperator-fd498bf96-r9mjk 2/2 Running 0 3m38s
config-agent-658f87845-tznm6 2/2 Running 0 3m38s
controller-manager-8676dcdc6-tbnnc 2/2 Running 0 3m38s
extension-manager-67b9965fb5-w5sm4 2/2 Running 0 3m38s
flux-logs-agent-6596f58c56-tdg52 1/1 Running 0 3m38s
kube-aad-proxy-d98bfc858-lcx26 2/2 Running 0 3m38s
metrics-agent-5b9b94754f-2pqm5 2/2 Running 0 3m38s
resource-sync-agent-f8c7c6b6b-jlm9w 2/2 Running 0 3m38s

Azure Arc上のAKSクラスターでApp Serviceを使えるようにする

AKSクラスターやAzure Arcのリソースグループ名などを変数に定義します。

$ K8S_CLUSTER_RG_NAME=appservicewazurearc
$ K8S_CLUSTER_NAME=$(az aks list -g $K8S_CLUSTER_RG_NAME --query "[0].name" -o tsv)
$ K8S_ARC_PREFIX=k8sArc
$ ARC_RG_NAME=appservicewazurearc
$ ARC_CLUSTER_NAME="${K8S_ARC_PREFIX}-cluster"

 

パブリックIPアドレスのリソースを作成して、その値を変数に格納します。

$ K8S_PIP_NAME=k8sAKS-cluster-pip
$ K8S_INFRA_RG_NAME=$(az aks show -g $K8S_CLUSTER_RG_NAME -n $K8S_CLUSTER_NAME --query nodeResourceGroup -o tsv)
$ az network public-ip create -g $K8S_INFRA_RG_NAME -n $K8S_PIP_NAME --sku STANDARD
$ K8S_PIP=$(az network public-ip show -g $K8S_INFRA_RG_NAME -n $K8S_PIP_NAME --query ipAddress -o tsv)

 

カスタムロケーションを定義します。カスタムロケーションはAzure Arcで管理されているリソースの場所を定義する仮想的な場所のことです。App ServiceをAzure Arcで管理されたKubernetes上に作成するときに、このカスタムロケーションの指定が必要になります。

$ CUSTOM_LOCATION_NAME="${K8S_ARC_PREFIX}-location"

 

Azure Arc に接続されたクラスターと、対応する Kubernetes 環境にインストールする拡張機能の名前を指定する変数の値を設定します。

$ EXTENSION_NAME="${K8S_ARC_PREFIX}-kube"
$ KUBE_ENV_NAME="${K8S_ARC_PREFIX}-env-$RANDOM"

 

App ServiceのPodが作成されるNamespace名を変数に格納します。

$ APP_SERVICE_NAMESPACE_NAME=appservice-ns

 

App Serviceのアプリケーションログを格納するLog Analyticsを作成します。

$ K8S_INFRA_RG_NAME=$(az aks show -g $K8S_CLUSTER_RG_NAME -n $K8S_CLUSTER_NAME --query nodeResourceGroup -o tsv)
$ LA_WORKSPACE_NAME=k8sAKS-workspace
$ az monitor log-analytics workspace create -g $K8S_INFRA_RG_NAME -n $LA_WORKSPACE_NAME

 

Log Analyticsの色々な設定情報を変数に格納します。

LA_WORKSPACE_NAME=k8sAKS-workspace
LA_WORKSPACE_ID=$(az monitor log-analytics workspace show --resource-group $K8S_INFRA_RG_NAME --workspace-name $LA_WORKSPACE_NAME --query "customerId" -o tsv)
LA_WORKSPACE_ID_ENC=$(printf %s $LA_WORKSPACE_ID | base64)
LA_WORKSPACE_KEY=$(az monitor log-analytics workspace get-shared-keys --resource-group $K8S_INFRA_RG_NAME --workspace-name $LA_WORKSPACE_NAME --query "secondarySharedKey" -o tsv)
LA_WORKSPACE_KEY_ENC_WITH_SPACE=$(printf %s $LA_WORKSPACE_KEY | base64)
LA_WORKSPACE_KEY_ENC=$(echo -n "${LA_WORKSPACE_KEY_ENC_WITH_SPACE//[[:space:]]/}")

 

App Service拡張機能をインストールします。

$ az k8s-extension create -g $ARC_RG_NAME --name $EXTENSION_NAME --cluster-type connectedClusters -c $ARC_CLUSTER_NAME --extension-type 'Microsoft.Web.Appservice' --release-train stable --auto-upgrade-minor-version true --scope cluster --release-namespace $APP_SERVICE_NAMESPACE_NAME --configuration-settings "Microsoft.CustomLocation.ServiceAccount=default" --configuration-settings "appsNamespace=${APP_SERVICE_NAMESPACE_NAME}" --configuration-settings "clusterName=${KUBE_ENV_NAME}" --configuration-settings "loadBalancerIp=${K8S_PIP}" --configuration-settings "buildService.storageClassName=default" --configuration-settings "buildService.storageAccessMode=ReadWriteOnce" --configuration-settings "envoy.annotations.service.beta.kubernetes.io/azure-load-balancer-resource-group=${K8S_CLUSTER_RG_NAME}" --configuration-settings "customConfigMap=${APP_SERVICE_NAMESPACE_NAME}/kube-environment-config" --configuration-settings "logProcessor.appLogs.destination=log-analytics" --configuration-protected-settings "logProcessor.appLogs.logAnalyticsConfig.customerId=${LA_WORKSPACE_ID_ENC}" --configuration-protected-settings "logProcessor.appLogs.logAnalyticsConfig.sharedKey=${LA_WORKSPACE_KEY_ENC}"

 

正常にインストールされたかどうかを確認します。以下のコマンドを実行して、installState プロパティの値が Installedに変わることを確認します。変わるまで何度も実行してください。ちょっと時間かかります。

$ az k8s-extension show --cluster-type connectedClusters -c $ARC_CLUSTER_NAME -g $ARC_RG_NAME --name $EXTENSION_NAME

 

拡張機能のIDを変数に格納します。

$ EXTENSION_ID=$(az k8s-extension show --cluster-type connectedClusters -c $ARC_CLUSTER_NAME -g $ARC_RG_NAME --name $EXTENSION_NAME --query id -o tsv)

 

Azure Arc上で動作するKubernetesクラスターにカスタムの場所を作成します。これを行うことにより、App Serviceの作成場所として、このカスタムの場所を指定すると、Azure Arc上で動作するKubernetes上にApp Serviceが作成されます。

接続されているクラスターの id プロパティの値を変数に格納します。

$ CONNECTED_CLUSTER_ID=$(az connectedk8s show -n $ARC_CLUSTER_NAME -g $ARC_RG_NAME --query id -o tsv)

 

カスタムの場所を作成します。

$ az customlocation create -g $ARC_RG_NAME -n $CUSTOM_LOCATION_NAME --host-resource-id $CONNECTED_CLUSTER_ID --namespace $APP_SERVICE_NAMESPACE_NAME -c $EXTENSION_ID

 

カスタムの場所のIDを変数に格納します。

$ CUSTOM_LOCATION_ID=$(az customlocation show -g $ARC_RG_NAME -n $CUSTOM_LOCATION_NAME --query id -o tsv)

 

App Service Kubernetes 環境を作成します。

$ az appservice kube create -g $ARC_RG_NAME -n $KUBE_ENV_NAME --custom-location $CUSTOM_LOCATION_ID --static-ip $K8S_PIP

 

ちゃんとできているかどうかを以下のコマンドで確認します。ちょっと時間かかるので、provisioningState プロパティの値が Succeeded に変わるまでコマンドを何度も再実行します。

$ az appservice kube show -g $ARC_RG_NAME -n $KUBE_ENV_NAME

Azure Arc上のAKSクラスターでApp Serviceをデプロイする

App Service名を変数に格納します。

$ WEBAPP_NAME=k8sarcwebapp$RANDOM$RANDOM

 

App Serviceを作成します。このとき先程作成したカスタムの場所を–custom-locationの値として指定します。これが重要です。

$ az webapp create -g $ARC_RG_NAME -n $WEBAPP_NAME --custom-location $CUSTOM_LOCATION_ID --runtime "PHP|7.4"

 

以下のPHPファイルを作成します。

<?php
echo 'hoge';
?>

 

先のPHPファイルを含むZIPアーカイブを作成します。

$ zip -r app.zip .

 

App Serviceにデプロイします。

$ az webapp deployment source config-zip -g $ARC_RG_NAME -n $WEBAPP_NAME --src app.zip

 

しばらくしてApp Serivceのリソースの「概要」ブレードに表示される[URL]を確認して、「[URL]/test.php」にアクセスすると、ブラウザ上に「hoge」と表示されると思います。

AKS上にデプロイしたApp Serviceがちゃんと動きましたね!!ゴイスー。

Podを見てみましょう。一番下の「k8sarcwebapp264457290-7f95d7bf9d-cv2kq」っていう名前のPodがApp Serivceが稼働するPodです。

$ kubectl get pods -n appservice-ns
NAME READY STATUS RESTARTS AGE
k8sarc-kube-k8se-activator-75c9599557-8sls7 1/1 Running 0 18m
k8sarc-kube-k8se-app-controller-7b5944fd8c-hnhn9 1/1 Running 0 18m
k8sarc-kube-k8se-build-service-866454fd66-llxq6 1/1 Running 0 25m
k8sarc-kube-k8se-envoy-7687cb74bd-66vw5 1/1 Running 0 25m
k8sarc-kube-k8se-envoy-7687cb74bd-ft9sb 1/1 Running 0 25m
k8sarc-kube-k8se-envoy-7687cb74bd-hbr49 1/1 Running 0 25m
k8sarc-kube-k8se-https-scaler-86cf76cc65-hhgtp 1/1 Running 0 25m
k8sarc-kube-k8se-img-cacher-dlbsk 1/1 Running 0 25m
k8sarc-kube-k8se-img-cacher-v6dn4 1/1 Running 0 25m
k8sarc-kube-k8se-img-cacher-vsvqt 1/1 Running 0 25m
k8sarc-kube-k8se-log-processor-6jhrb 1/1 Running 3 25m
k8sarc-kube-k8se-log-processor-jsm9f 1/1 Running 3 25m
k8sarc-kube-k8se-log-processor-vnw6r 1/1 Running 1 25m
k8sarcwebapp264457290-7f95d7bf9d-cv2kq 1/1 Running 0 68s

 

さっきのPodに入ってみましょう。

$ kubectl exec -it k8sarcwebapp264457290-7f95d7bf9d-cv2kq /bin/bash -n appservice-ns
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
Defaulted container "https" out of: https, app-init (init)
# cat /home/site/wwwroot/test.php
<?php
echo 'hoge';
?>

 

確かにtest.phpをデプロイしたApp SerivceのPodですね!!

ここでAzureポータルのApp Serivceの画面からスケールアウトしてみましょう。「最大インスタンス数」を2にしてみます。

 

Podの数を確認してみるとたしかに2つに増えてます!!「k8sarcwebapp・・・」っていう名称のPodが2つありますよね!!スケールアウトされました。

$ kubectl get pods -n appservice-ns
NAME READY STATUS RESTARTS AGE
k8sarc-kube-k8se-activator-75c9599557-8sls7 1/1 Running 0 5h35m
k8sarc-kube-k8se-app-controller-7b5944fd8c-hnhn9 1/1 Running 0 5h35m
k8sarc-kube-k8se-build-service-866454fd66-llxq6 1/1 Running 0 5h43m
k8sarc-kube-k8se-envoy-7687cb74bd-66vw5 1/1 Running 0 5h43m
k8sarc-kube-k8se-envoy-7687cb74bd-ft9sb 1/1 Running 0 5h43m
k8sarc-kube-k8se-envoy-7687cb74bd-hbr49 1/1 Running 0 5h43m
k8sarc-kube-k8se-https-scaler-86cf76cc65-hhgtp 1/1 Running 0 5h43m
k8sarc-kube-k8se-img-cacher-dlbsk 1/1 Running 0 5h43m
k8sarc-kube-k8se-img-cacher-v6dn4 1/1 Running 0 5h43m
k8sarc-kube-k8se-img-cacher-vsvqt 1/1 Running 0 5h43m
k8sarc-kube-k8se-log-processor-6jhrb 1/1 Running 3 5h43m
k8sarc-kube-k8se-log-processor-jsm9f 1/1 Running 3 5h43m
k8sarc-kube-k8se-log-processor-vnw6r 1/1 Running 1 5h43m
k8sarcwebapp264457290-7f95d7bf9d-6hz8c 1/1 Running 0 5h8m
k8sarcwebapp264457290-7f95d7bf9d-cv2kq 1/1 Running 0 5h18m

まとめ

Kubernetes上でApp Serivceが動きましたね!!なんかとっても未来を感じます。ドラえもんはすぐそこまで来ているって感じです。





ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!


ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

Be the first to comment

Leave a Reply

Your email address will not be published.


*