Parts Unlimited MRP Microservices を AKS + Helm で使ってみる ①

# はじめに
Parts Unlimited とは DevOps を学ぶためのバイブルとも言える 2013 年に刊行された " The Phenix Project" [邦題：The DevOps　逆転だ！　究極の継続的デリバリー](https://eb.store.nikkei.com/asp/ShowItemDetailStart.do?itemId=D2-00P85350B0)に出てくる架空の会社であるパーツアンリミテッド社の "Project Unicorn" にちなんだネーミングで、マイクロソフトが GitHub で公開している DevOps を学ぶためのサンプルソースコードやハンズオンラボのシリーズとなっています。ハンズオンの手順に従って作業をすると体系づけて要素技術の実装を学びながらデモ環境をつくることができるというものです。
この記事では、[Parts Unlimited MRP Microservices](https://microsoft.github.io/PartsUnlimitedMRPmicro/)を元に要点のみを__作業ログ__として残した記事となります。（抄訳、意訳ではなく作業ログです。引用参照文献はリンクを残しています。）
__本情報の内容（添付文書、リンク先などを含む）は、作成日時点でのものであり、予告なく変更される場合があります__

## キーになる技術
- Azure Container Service (以下 AKS ) とコンテナ化されたアプリケーション
- フロントエンドの Web サイト (Apache Tomcat, [Hystrix](https://github.com/Netflix/Hystrix), JSP)
- Java spring API, MongDB
- .Net Core API (C# 利用）

# 実際の手順
## AKS を Helm（kubernetes＝以下 K8S のパッケージマネージャ） を使用して作成する
### 全体の流れ
 1. AKS のクラスタ作成
 2. CosmosDB の作成と MongoDB API互換設定
 <<今回はここまで。続編で下記手順を行います。>>
 3. コンテナのビルド＆ACRへのPush 
 4. Helm のインストールとセットアップ
 5. Helm のチャート作成
 6. Parts Unlimited MRP を Helm を使用してデプロイ

### 準備（ACR＝Azure Container Registry）
ドキュメントの手順[Azure Portal を使用したコンテナー レジストリの作成](https://docs.microsoft.com/ja-jp/azure/container-registry/container-registry-get-started-portal)に従って作成します。
<img width="314" alt="Screen Shot 2018-03-05 at 15.09.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/135357/df8aa3d2-5df7-1050-c08d-be69232878c9.png">

コマンドラインでも[Azure CLI を使用したコンテナー レジストリの作成](https://docs.microsoft.com/ja-jp/azure/container-registry/container-registry-get-started-azure-cli)を参考に作成することができます。
az login をしてもいいですが、こちらの記事[Azure CLI をバッチで使用する方法](https://qiita.com/mihochannel/items/b297b07c826b631ba0ea)にあるようにサービスプリンシパルを設定していればコマンドラインのほうが楽です。

```bash
az acr create --resource-group arcRG --name myContainerRegistry007 --sku Basic
```

### 1. AKS のクラスタ作成
コマンドライン（Azure CLI)で実施します。
AKS を利用可能なリージョンを [リージョン別の利用可能な製品](https://azure.microsoft.com/ja-jp/regions/services/)で確認しておきます。
今回は米国中部を利用しました。
Azure CLI で指定する --location 以降のリージョン名は _az account list-locations_ の出力結果を適当に grep して探すとスペルが簡単に見つかります。

```bash
Mihos-MacBook:management miyamam$ az account list-locations | grep central
    "id": "/subscriptions/...snip.../locations/centralus",
    "name": "centralus",
    "id": "/subscriptions/...snip.../locations/northcentralus",
    "name": "northcentralus",
    "id": "/subscriptions/...snip.../locations/southcentralus",
    "name": "southcentralus",
    "id": "/subscriptions/...snip.../locations/centralindia",
    "name": "centralindia",
    "id": "/subscriptions/...snip.../locations/canadacentral",
    "name": "canadacentral",
    "id": "/subscriptions/...snip.../locations/westcentralus",
    "name": "westcentralus",
    "id": "/subscriptions/...snip.../locations/koreacentral",
    "name": "koreacentral",
```

もとのドキュメントでは　az acs コマンドを使用していますが、今回は az aks コマンドを使用します。

```bash
# AKS が利用可能かの確認
$az provider show -n Microsoft.ContainerService | grep Registered
"registrationState": "Registered",
# Registered に無い場合は登録
$az provider register -n Microsoft.ContainerService

# リソースグループの作成
$az group create --name=kube-res --location=centralus
{
  "id": "/subscriptions/...snip/resourceGroups/kube-res",
  "location": "centralus",
  "managedBy": null,
  "name": "kube-res",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null
}

#AKSのK8Sクラスタの作成
$az aks create --resource-group kube-res --name=kube-container --node-count=3
Mihos-MacBook:management miyamam$ az aks create --resource-group kube-res --name=kube-container --node-count=3

{
  "agentPoolProfiles": [
    {
      "count": 3,
      "dnsPrefix": null,
      "fqdn": null,
      "name": "nodepool1",
      "osDiskSizeGb": null,
      "osType": "Linux",
      "ports": null,
      "storageProfile": "ManagedDisks",
      "vmSize": "Standard_D1_v2",
      "vnetSubnetId": null
    }
  ],
  "dnsPrefix": "指定したプリフィクスを含んだなまえがつくよ",
  "fqdn": "dnsPrefixと同じなまえ.centralus.azmk8s.io",
  "id": "/subscriptions/...snip/resourcegroups/kube-res/providers/Microsoft.ContainerService/managedClusters/kube-container",
  "kubernetesVersion": "1.7.7",
  "linuxProfile": {
    "adminUsername": "azureuser",
    "ssh": {
      "publicKeys": [
        {
          "keyData": "ssh-rsa 自分のCLI操作した端末の証明書が入るよ。"
        }
      ]
    }
  },
  "location": "centralus",
  "name": "kube-container",
  "provisioningState": "Succeeded",
  "resourceGroup": "kube-res",
  "servicePrincipalProfile": {
    "clientId": "...snip...",
    "keyVaultSecretRef": null,
    "secret": null
  },
  "tags": null,
  "type": "Microsoft.ContainerService/ManagedClusters"
}
```

クラスタが作成されたら繋いでみましょう。

```bash
$ kubectl cluster-info
Kubernetes master is running at https://クラスターのなまえ.centralus.azmk8s.io:443

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Unable to connect to the server: dial tcp: lookup クラスターのなまえ.centralus.azmk8s.io on [2001:4898::1050:5050]:53: no such host
```


### 2. CosmosDB の作成と MongoDB API互換設定
元のチュートリルではざっくりと[Azure Cosmos DB への MongoDB アプリケーションの接続](https://docs.microsoft.com/ja-jp/azure/cosmos-db/connect-mongodb-account)を参考に接続文字列をつくるということだけ書かれていますが、DB作らないと接続文字列はもちろんつくれないので作業ログ残しておきます。
参考ドキュメントはこちら
[]()

```bash
# Central US リージョンに phoenixproject というリソースグループを作成
$ az group create --name phoenixproject --location centralus
{
  "id": "/subscriptions/...snip.../resourceGroups/phoenixproject",
  "location": "centralus",
  "managedBy": null,
  "name": "phoenixproject",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null
}

# Create a MongoDB API Cosmos DB account
$ az cosmosdb create --name pudb --kind MongoDB --locations "Central US"=0 "North Central US"=1 --resource-group phoenixproject --max-terval 10 --max-staleness-prefix 200
{
  "consistencyPolicy": {
    "defaultConsistencyLevel": "Session",
    "maxIntervalInSeconds": 5,
    "maxStalenessPrefix": 100
  },
  "databaseAccountOfferType": "Standard",
  "documentEndpoint": "https://..snip...documents.azure.com:443/",
  "enableAutomaticFailover": false,
  "failoverPolicies": [
    {
      "failoverPriority": 0,
      "id": "pudb-centralus",
      "locationName": "Central US"
    },
    {
      "failoverPriority": 1,
      "id": "pudb-northcentralus",
      "locationName": "North Central US"
    }
  ],
  "id": "/subscriptions/..snip../resourceGroups/phoenixproject/providers/Microsoft.DocumentDB/databaseAccounts/pudb",
  "ipRangeFilter": "",
  "kind": "MongoDB",
  "location": "Central US",
  "name": "pudb",
  "provisioningState": "Succeeded",
  "readLocations": [
    {
      "documentEndpoint": "https://..snip...documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "pudb-centralus",
      "locationName": "Central US",
      "provisioningState": "Succeeded"
    },
    {
      "documentEndpoint": "https://..snip...documents.azure.com:443/",
      "failoverPriority": 1,
      "id": "pudb-northcentralus",
      "locationName": "North Central US",
      "provisioningState": "Creating"
    }
  ],
  "resourceGroup": "phoenixproject",
  "tags": {},
  "type": "Microsoft.DocumentDB/databaseAccounts",
  "writeLocations": [
    {
      "documentEndpoint": "https://..snip...documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "pudb-centralus",
      "locationName": "Central US",
      "provisioningState": "Succeeded"
    }
  ]
}

# Create Database ：pudb という名前で、pudbnameという名前のDBを作成
$ az cosmosdb database create --name pudb --db-name pudbname --resource-group phoenixproject

{
  "_colls": "colls/",
  "_etag": "\"00003600-0000-0000-0000-5a9d533c0000\"",
  "_rid": "3d0kAA==",
  "_self": "dbs/3d0kAA==/",
  "_ts": 1520259900,
  "_users": "users/",
  "id": "pudbname"
}

# Create Collection collection1 という名前でコレクション作成
$ az cosmosdb collection create --collection-name collection1 --name pudb --db-name pudbname --resource-group phoenixproject
{
  "collection": {
    "_conflicts": "conflicts/",
    "_docs": "docs/",
    "_etag": "\"00003800-0000-0000-0000-5a9d538f0000\"",
    "_rid": "3d0kAJM4DQA=",
    "_self": "dbs/3d0kAA==/colls/3d0kAJM4DQA=/",
    "_sprocs": "sprocs/",
    "_triggers": "triggers/",
    "_ts": 1520259983,
    "_udfs": "udfs/",
    "id": "collection1",
    "indexingPolicy": {
      "automatic": true,
      "excludedPaths": [],
      "includedPaths": [
        {
          "indexes": [
            {
              "dataType": "String",
              "kind": "Range",
              "precision": -1
            },
            {
              "dataType": "Number",
              "kind": "Range",
              "precision": -1
            }
          ],
          "path": "/*"
        }
      ],
      "indexingMode": "consistent"
    }
  },
  "offer": {
    "_etag": "\"00003900-0000-0000-0000-5a9d538f0000\"",
    "_rid": "mo1L",
    "_self": "offers/mo1L/",
    "_ts": 1520259983,
    "content": {
      "offerIsRUPerMinuteThroughputEnabled": false,
      "offerThroughput": 400
    },
    "id": "mo1L",
    "offerResourceId": "...snip...",
    "offerType": "Invalid",
    "offerVersion": "V2",
    "resource": "dbs/3d0kAA==/colls/3d0kAJM4DQA=/"
  }
}


```

## 次回以降で記載
 3. コンテナのビルド＆ACRへのPush 
 4. Helm のインストールとセットアップ
 5. Helm のチャート作成
 6. Parts Unlimited MRP を Helm を使用してデプロイ

# 参考リンク
- [邦題：The DevOps　逆転だ！　究極の継続的デリバリー](https://eb.store.nikkei.com/asp/ShowItemDetailStart.do?itemId=D2-00P85350B0)
- [Parts Unlimited MRP Microservices](https://microsoft.github.io/PartsUnlimitedMRPmicro/)
- [Hystrix](https://github.com/Netflix/Hystrix)
- [Azure Portal を使用したコンテナー レジストリの作成](https://docs.microsoft.com/ja-jp/azure/container-registry/container-registry-get-started-portal)
- [Azure CLI を使用したコンテナー レジストリの作成](https://docs.microsoft.com/ja-jp/azure/container-registry/container-registry-get-started-azure-cli)
- [Azure Container Service (AKS) の概要](https://docs.microsoft.com/ja-jp/azure/aks/intro-kubernetes)
- [リージョン別の利用可能な製品](https://azure.microsoft.com/ja-jp/regions/services/)
- [Azure Container Service (AKS) クラスターのデプロイ](https://docs.microsoft.com/ja-jp/azure/aks/kubernetes-walkthrough)
- [Azure Cosmos DB への MongoDB アプリケーションの接続](https://docs.microsoft.com/ja-jp/azure/cosmos-db/connect-mongodb-account)
- [Azure Cosmos DB: Azure CLI を使用して MongoDB API アカウントを作成する](https://docs.microsoft.com/ja-jp/azure/cosmos-db/scripts/create-mongodb-database-account-cli?toc=%2fcli%2fazure%2ftoc.json)