Azure Container Instances を Azure Container Registory からポートを複数持った状態でプロビジョンする

今日は、[Web App for Containers をハック](https://blogs.technet.microsoft.com/livedevopsinjapan/2017/10/13/migration-tips-from-iaas-to-web-app-for-containers-on-azure/)していたが、Web App なので、コンテナのポートを２つ以上公開することができない。その状況でもコンテナをデプロイするために、Azure Container Instances を使ってみた。時間がなかったので、３０分以内に終わらせるため、この方法を選んだ。

# コマンドラインでは複数ポートを指定できない

[Azure Container Instance](https://docs.microsoft.com/en-us/azure/container-instances/container-instances-overview) は、CLI, Portal, PowerShellの３つの方法がよく紹介されている。 [Azure Container Registry](https://docs.microsoft.com/en-us/azure/container-registry/) においているコンテナをプロビジョンするにはどうしたらいいのだろう。パスワードで保護されているし。`az` コマンドでは、Container Registry のパスワードを入力できるが、ポータルや、CLI だと、ポートの複数指定ができない。

# ARM テンプレートでデプロイする

ところが、Azure Container Instances REST-API を見るとどうやらできそう。具体的には、ARM テンプレートを使えば良い。

I upload the sample template on the gist. Please have a look. You can deploy it using az command.

* [Azure Container Instances deploy sample with two ports and ACR credential](https://gist.github.com/TsuyoshiUshio/0660ac26e043ea1afe9e782d7bdc25e9)


ポイントはいくつかで、まずは複数ポート。簡単に設定できる。

```json
                    "containers": [
                        {
                            "name": "kirinmq",
                            "properties": {
                                "image": "{YOUR_ACR_HOST_NAME}.azurecr.io/mq",
                                "ports": [
                                    {
                                        "port": "5555" 
                                    },
                                    {
                                        "port": "5556"
                                    }
                                ],
```

次に、ACR のクレデンシャル。そのままだ。ちなみにこのコンフィグをどこから見つけてきたかというと、ACI の REST API スペックから。

* [Container Groups - Create Or Update](https://docs.microsoft.com/en-us/rest/api/container-instances/ContainerGroups/CreateOrUpdate#definitions_imageregistrycredential)

```json
                "properties": {
                    "imageRegistryCredentials": [
                        {"password": "{YOUR_ACR_PASSWORD}",
                            "server": "{YOUR_ACR_HOST_NAME}.azurecr.io",
                            "username": "{YOUR_ACR_USER_NAME"}

                    ],
```

デプロイ。ちなみに、現在は使えるロケーションが限られてるので、注意。

```
az group create --name resourceGroupName --location westus
az group deployment create -n someDeploy --template-file azuredeploy.json -g resourceGroupName
```

# Rest API を観察する


* [Container Groups - Create Or Update](https://docs.microsoft.com/en-us/rest/api/container-instances/ContainerGroups/CreateOrUpdate#definitions_imageregistrycredential)

を観察して見ると色々面白い設定ができる。先の Gist にもしてあるが、コンテナで使う、CPUとか、メモリの確保とかができる。まるで、オーケストレータのようだ。Win/Linux の両方に対応している。マウントもできるようす。これは面白いね！

# コンテナグループ

ちなみに、アーキテクチャ的には、同じVMに乗っかるコンテナグループという概念がある様子。Kubernetes の pod に似た概念で、同じコンテナグループのコンテナはVMを共有する。

![container-groups-example.png](https://qiita-image-store.s3.amazonaws.com/0/3470/25b04f87-9aa9-1664-c6e7-008e450b9e6c.png)

コンテナインスタンスの課金を見ると、CPU、メモリとか、リクエスト単位みたい。とかそういうものなので、コンテナグループを分けると、別のVMであることを保証するなら、コンテナグループを作ると、基本的にVMを占有とか可能なのだろうか？

<img width="1156" alt="Screen Shot 2017-10-13 at 11.53.34 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/3470/e9903bdf-2764-8b84-5c21-d9fc836821c0.png">



# Debugの方法

さて、ハック時間内にできなかったことは、Debug の方法。やっぱコンテナはログが命。コンテナグループ、リソースグループ、コンテナ名を指定したらログが見える。

```
$ az container logs -n myContainerGroup -g resourceGroupName --container-name mq
Stopping nginx: [FAILED]
Starting nginx: [  OK  ]
Stopping sshd: [FAILED]
Generating SSH2 RSA host key: [  OK  ]
Generating SSH1 RSA host key: [  OK  ]
Generating SSH2 DSA host key: [  OK  ]
Starting sshd: [  OK  ]
```

おお、手元からログ見れた。[Migration tips from IaaS to Web App for Containers on Azure](https://blogs.technet.microsoft.com/livedevopsinjapan/2017/10/13/migration-tips-from-iaas-to-web-app-for-containers-on-azure/) の作戦で、シンボリックリンクを貼るとちゃんとデバッグできそう。また、コンテナ自身のコンフィグもみれる。先ほどの ARM テンプレートの実行結果みたいな感じ。

```
$ az container show -n myContainerGroup -g resourceGroupName
{
  "containers": [
    {
      "command": null,
      "environmentVariables": [],
      "image": "{YOUR_ACR_HOST_NAME}.azurecr.io/mq",
      "instanceView": {
        "currentState": {
          "detailStatus": "",
          "exitCode": null,
          "finishTime": null,
          "startTime": "2017-10-13T06:15:13+00:00",

```

* [Troubleshoot deployment issues with Azure Container Instances](https://docs.microsoft.com/en-us/azure/container-instances/container-instances-troubleshooting)
* [az container command](https://docs.microsoft.com/en-us/cli/azure/container?view=azure-cli-latest#az_container_logs)

見れない時は、`Activity Log` で。エラーはこんなのが書いてあった。

```
Error code
LocationNotAvailableForResourceType
Message
The provided location 'japaneast' is not available for resource type 'Microsoft.ContainerInstance/containerGroups'. List of available regions for the resource type is 'westus,eastus,westeurope'.
```

明らか！

削除もあるね

```
＄ az container delete -n mq -g resourceGroupName -y
$ az container list -g resourceGroupName
[]

```

うん、簡単だ！

# まとめ

ほんまこれサーバーレスよね。思ったより、細かく設定できそうなので、これは色々遊べそうだ！

* [Container Instances](https://azure.microsoft.com/en-us/services/container-instances/)
* [Azure Container Instances](https://github.com/seanmck/azure-quickstart-templates/tree/master/101-aci-linuxcontainer-public-ip-multiple-ports
)
* [Container Groups - Create Or Update](https://docs.microsoft.com/en-us/rest/api/container-instances/ContainerGroups/CreateOrUpdate#definitions_imageregistrycredential)