つばろぐ

主に C#, .NET, Azure の備忘録です。たまに日記。

Tye のコンテナーレジストリーに Azure Container Registry (ACR) を使用する

過去記事では AKS に Tye のサンプルアプリケーションをデプロイする際、コンテナーレジストリーには DockerHub を使用していました。
Tye では DockerHub の他に Azure Container Registry (ACR) を使用することができるため、今回は ACR を使ってみようと思います。

ドキュメントでいうとこのあたりになります。
https://github.com/dotnet/tye/blob/master/docs/reference/schema.md#registry-string

サンプルアプリケーションはこちら。

github.com

Azure Container Registry の作成

ポータルや CLI を使って ACR のリソースを作成します。
管理者ユーザーは無効のままで大丈夫です。

docs.microsoft.com

docs.microsoft.com

tye.yaml を変更する

tye.yamlregistry を書き換えて、コンテナーレジストリーに ACR を使うようにします。

変更前

name: microservice
registry: tsubakimoto
services:
- name: backend
  project: backend\backend.csproj
- name: frontend
  project: frontend\frontend.csproj
- name: redis
  image: redis
  bindings:
  - port: 6379
    connectionString: "${host}:${port}"
- name: redis-cli
  image: redis
  args: "redis-cli -h redis MONITOR"

変更後

name: microservice
registry: acrprojecttye.azurecr.io
services:
- name: backend
  project: backend\backend.csproj
- name: frontend
  project: frontend\frontend.csproj
- name: redis
  image: redis
  bindings:
  - port: 6379
    connectionString: "${host}:${port}"
- name: redis-cli
  image: redis
  args: "redis-cli -h redis MONITOR"

AKS にデプロイしてみる

アプリケーションには何も変更を加えずに AKS にデプロイしてみましょう。
AKS にデプロイするにはセットアップが必要なので、以前の記事を参考にしてください。

tsubalog.hatenablog.com

$ kubectl apply -f https://raw.githubusercontent.com/dotnet/tye/master/docs/tutorials/hello-tye/redis.yaml
deployment.apps/redis created
service/redis created

$ tye deploy --interactive
Loading Application Details...
Verifying kubectl installation...
Verifying kubectl connection to cluster...
Processing Service 'backend'...
    Applying container defaults...
    Compiling Services...
    Publishing Project...
    Building Docker Image...
        Created Docker Image: 'acrprojecttye.azurecr.io/backend:1.0.0'
    Pushing Docker Image...
            unauthorized: authentication required, visit https://aka.ms/acr/authorization for more information.
Drats! 'deploy' failed:
        'docker push' failed.

ACR へ認証を行う

AKS へのデプロイに失敗しました。理由は認証エラーですね。
ビルドしたコンテナーイメージをプッシュしようとしている ACR の認証をしていないためです。

エラーログにもある https://aka.ms/acr/authorization は ACR の認証に関するドキュメントです。

docs.microsoft.com

$ az acr login -n acrprojecttye
Login Succeeded

再度デプロイ

ACR にログインしたので改めてデプロイを実行します。

$ tye deploy --interactive
Loading Application Details...
Verifying kubectl installation...
Verifying kubectl connection to cluster...
Processing Service 'backend'...
    Applying container defaults...
    Compiling Services...
    Publishing Project...
    Building Docker Image...
        Created Docker Image: 'acrprojecttye.azurecr.io/backend:1.0.0'
    Pushing Docker Image...
        Pushed docker image: 'acrprojecttye.azurecr.io/backend:1.0.0'
    Validating Secrets...
        Enter the connection string to use for service 'redis': redis:6379
        Created secret 'binding-production-redis-secret'.
    Generating Manifests...
Processing Service 'frontend'...
    Applying container defaults...
    Compiling Services...
    Publishing Project...
    Building Docker Image...
        Created Docker Image: 'acrprojecttye.azurecr.io/frontend:1.0.0'
    Pushing Docker Image...
        Pushed docker image: 'acrprojecttye.azurecr.io/frontend:1.0.0'
    Validating Secrets...
    Generating Manifests...
Processing Service 'redis'...
    Applying container defaults...
        Service 'redis' does not have a project associated. Skipping.
    Compiling Services...
    Publishing Project...
        Service 'redis' does not have a project associated. Skipping.
    Building Docker Image...
        Service 'redis' does not have a project associated. Skipping.
    Pushing Docker Image...
        Service 'redis' does not have a project associated. Skipping.
    Validating Secrets...
    Generating Manifests...
        Service 'redis' does not have a container. Skipping.
Processing Service 'redis-cli'...
    Applying container defaults...
        Service 'redis-cli' does not have a project associated. Skipping.
    Compiling Services...
    Publishing Project...
        Service 'redis-cli' does not have a project associated. Skipping.
    Building Docker Image...
        Service 'redis-cli' does not have a project associated. Skipping.
    Pushing Docker Image...
        Service 'redis-cli' does not have a project associated. Skipping.
    Validating Secrets...
    Generating Manifests...
        Service 'redis-cli' does not have a container. Skipping.
Deploying Application Manifests...

        Verifying kubectl installation...
        Verifying kubectl connection to cluster...
        Writing output to '/tmp/tmpKE7MrI.tmp'.
        Deployed application 'microservice'.
Time Elapsed: 00:00:34:51

デプロイに成功しました。 Azure ポータルで ACR の状態を見るとイメージがプッシュされていることが分かります。

f:id:tech-tsubaki:20200912162931p:plain

AKS から ACR への認証

デプロイは成功しましたが Pod の状態はエラーになっています。
どうやらコンテナーレジストリーからイメージをプルできていないようです。

$ kubectl get po
NAME                        READY   STATUS         RESTARTS   AGE
backend-55cc974776-7kjwx    0/1     ErrImagePull   0          35s
frontend-59b55b7b94-pk5l2   0/1     ErrImagePull   0          35s
redis-58897bf8c-kdqd8       1/1     Running        0          2m8s

これも認証の問題で、今度は AKS から ACR への認証を設定する必要があります。
ドキュメントに沿って設定を行います。

docs.microsoft.com

$ az aks update -n aks-project-tye -g rg-project-tye --attach-acr acrprojecttye
{- Finished ..
  "aadProfile": null,
  "addonProfiles": {
    "httpapplicationrouting": {
      "config": {},
      "enabled": false,
      "identity": null
    },
    "kubedashboard": {
      "config": {},
      "enabled": true,
      "identity": null
    }
  },
  "agentPoolProfiles": [
    {
      "availabilityZones": null,
      "count": 1,
      "enableAutoScaling": null,
      "enableNodePublicIp": null,
      "maxCount": null,
      "maxPods": 110,
      "minCount": null,
      "mode": "System",
      "name": "agentpool",
      "nodeLabels": {},
      "nodeTaints": null,
      "orchestratorVersion": "1.16.10",
      "osDiskSizeGb": 128,
      "osType": "Linux",
      "provisioningState": "Succeeded",
      "scaleSetEvictionPolicy": null,
      "scaleSetPriority": null,
      "spotMaxPrice": null,
      "tags": null,
      "type": "VirtualMachineScaleSets",
      "vmSize": "Standard_DS2_v2",
      "vnetSubnetId": null
    }
  ],
  "apiServerAccessProfile": {
    "authorizedIpRanges": null,
    "enablePrivateCluster": false
  },
  "autoScalerProfile": null,
  "diskEncryptionSetId": null,
  "dnsPrefix": "aks-project-tye-dns",
  "enablePodSecurityPolicy": null,
  "enableRbac": true,
  "fqdn": "aks-project-tye-dns-04d99eee.hcp.japaneast.azmk8s.io",
  "id": "/subscriptions/1df1e3be-e3ae-4e0e-8c9a-742b8d0b8dfd/resourcegroups/rg-project-tye/providers/Microsoft.ContainerService/managedClusters/aks-project-tye",
  "identity": null,
  "identityProfile": null,
  "kubernetesVersion": "1.16.13",
  "linuxProfile": null,
  "location": "japaneast",
  "maxAgentPools": 10,
  "name": "aks-project-tye",
  "networkProfile": {
    "dnsServiceIp": "10.0.0.10",
    "dockerBridgeCidr": "172.17.0.1/16",
    "loadBalancerProfile": {
      "allocatedOutboundPorts": null,
      "effectiveOutboundIps": [
        {
          "id": "/subscriptions/1df1e3be-e3ae-4e0e-8c9a-742b8d0b8dfd/resourceGroups/MC_rg-project-tye_aks-project-tye_japaneast/providers/Microsoft.Network/publicIPAddresses/c9a695e4-4b80-40e6-bb16-05df8d207912",
          "resourceGroup": "MC_rg-project-tye_aks-project-tye_japaneast"
        }
      ],
      "idleTimeoutInMinutes": null,
      "managedOutboundIps": {
        "count": 1
      },
      "outboundIpPrefixes": null,
      "outboundIps": null
    },
    "loadBalancerSku": "Standard",
    "networkMode": null,
    "networkPlugin": "kubenet",
    "networkPolicy": null,
    "outboundType": "loadBalancer",
    "podCidr": "10.244.0.0/16",
    "serviceCidr": "10.0.0.0/16"
  },
  "nodeResourceGroup": "MC_rg-project-tye_aks-project-tye_japaneast",
  "privateFqdn": null,
  "provisioningState": "Succeeded",
  "resourceGroup": "rg-project-tye",
  "servicePrincipalProfile": {
    "clientId": "fbba54b1-22e7-4072-8a41-9767bb23d41f",
    "secret": null
  },
  "sku": {
    "name": "Basic",
    "tier": "Free"
  },
  "tags": null,
  "type": "Microsoft.ContainerService/ManagedClusters",
  "windowsProfile": null
}

動作確認

AKS から ACR に正しく認証できたのでもう一度デプロイしてみます。ログは代わり映えしないので省略します。
イメージもプルできているためポートフォワードを設定して確認してみます。

$ kubectl get po
NAME                        READY   STATUS    RESTARTS   AGE
backend-55cc974776-lphwb    1/1     Running   0          66s
frontend-59b55b7b94-gql2d   1/1     Running   0          65s
redis-58897bf8c-5dg7b       1/1     Running   0          96s

$ kubectl port-forward svc/frontend 5000:80
Forwarding from 127.0.0.1:5000 -> 80
Forwarding from [::1]:5000 -> 80

f:id:tech-tsubaki:20200912162918p:plain

アプリケーションが動作していることが分かります。
Azure を使うならコンテナーレジストリーも ACR を使うことが多いと思いますが、 Tye もちゃんと ACR に対応しているため使い勝手が良さそうです。