はじめに

このエントリでは、最新の Photon Controller のソースコードからビルドした devbox を使い、仮想マシンをデプロイ出来るようにするところまでの手順を示します。あくまで “できるようにする” ための Dirty Hack 的な手順もありますので、Github 上の Wiki に “まともな” 手順が掲載された場合には、そちらを参照してください。

この記事はソースコードと実際の動作から得られた情報をまとめているため、誤っている可能性もありますのでご容赦下さい。

Dirty Hack 概要

devbox のビルドは、前回のエントリーにあるように “vagrant up” 一発で完了します。しかしながら、この devbox のままでは、Photon Machine (ここでは ESXi) を Photon Controller に対して登録することすらできません。

Deployer のコードを眺めると分かります (特に com.vmware.photon.controller.deployer.dcp.workflow パッケージ) が、Photon Controller の Control Plane は、Photon Controller デプロイ用の VM の Deployer が管理者が作成した yaml ファイルに従ってデプロイされます。

しかしながら、今回は MacBookPro 上の Oracle VirtualBox と VMware Fusion で Photon Controller/ESXi を動かすので、そんなに潤沢にメモリがありません。限られた MacBookPro のリソースで Photon Controller を動かすため、ビルドされた Devbox をデプロイ済みの Photon Controller に無理やり変化させます。

Dirty Hack の手がかり

今回のエントリーの手順は、ソースコードから追ったモノもありますが、基本的には Getting Started 向けの Photon Controller VM の CloudStore の中身を curl で探りながら編み出しました。

Dirty Hack 詳細

以下の細工を施すと、devbox の Photon Controller で仮想マシンをデプロイ出来る下地が整います。

  1. deployment を curl -X POST で作成
  2. ESXi ホストを Photon Controller に登録
  3. テナントの作成
  4. リソース チケットの作成
  5. プロジェクトの作成

photon-cli を多用したいところではあるのですが、JSON 形式で結果を出力できません。スクリプト化が難しいため、Photon Controller のデータストアである CloudStore や API FrontEnd に直接 POST/GET/PATCH して Hack しています。

以下、devbox の IP アドレスを 22.31.1.1 としていますので、ご自身の環境で試す場合は適宜置き換えてください。

deployment を curl -X POST で作成

CloudStore 内の deployment のエンティティは、Photon Controller の Control Plane のデプロイそのものを表します。

POST 時に必要なパラメーターは以下の通りです。state、imageDataStoreNames、chairmanServerList がキーとなるパラメーターになります。

    {
        "state": "READY",
        "imageDataStoreNames": [
            "datastore1"
        ],
        "imageDataStoreUsedForVMs": true,
        "oAuthEnabled": false,
        "chairmanServerList": [
            "22.33.1.1:13000"
        ],
        "loadBalancerEnabled": true,
        "documentKind": "com:vmware:photon:controller:cloudstore:dcp:entity:DeploymentService:State"
    }
キー 説明
state deployment の状態。正常に動作する Control Plane の deployment は READY
imageDataStoreNames 仮想ディスクのイメージを保存するデータストア名
imageDataStoreUsedForVMs 上記の imageDataStoreNames にあるデータストアに、Photon Controller でデプロイされる仮想マシンを配置するかどうか。MacBookPro 上にエコに環境構築するため、ここは true 一択。
oAuthEnabled 認証に VMware Lightwave を利用するかどうか。まずはシンプルさを優先し、今回は flase。
chairmanServerList この Photon Controller の Chairman の IP アドレスとポート。devbox は一つの Photon OS 上に全てのコンポーネントのコンテナが起動するため、devbox の IP アドレスと Chairman のデフォルトポート番号とします。ESXi に Agent を PUSH でインストールする際に、Agent に ChairmanServerList の IP アドレス、ポート番号が設定されます。Agent は起動されると Chairman と通信するため、この ChairmanServerList の設定は必須ものもとなります。
loadBalancerEnabled Photon Controller の Control Plane を複数台の VM に分散すると haproxy が利用される。ここではとりあえず true としているが、false でも影響は無さそう…
documentKind deployment のエンティティを表現する Xenon の Service Document クラス。Java のパッケージ名におけるピリオドをコロンに置き換えて記述します

上記 JSON ファイルを /tmp/tmp.json などに保存して、CloudStore に POST します。

    curl -s -S -H "Content-Type:application/json" -X POST http://22.31.1.1:19000/photon/cloudstore/deployments -d @/tmp/tmp.json

Photon Controller の仕組みとしては API FrontEnd に REST で POST すべきなのですが、chairmanServerList は API FrontEnd の REST API からは操作することが出来ません。本来は Control Plane をデプロイする際に、Photon Controller 内部で設定される値なので、Dirty Hack らしく CloudStore に直接データを叩き込みます。この手順以降は、CLI をそのまま使うので、Dirty といえる手順はここだけですかね…。

ESXi ホストを Photon Controller に登録

ESXi を Photon Controller に登録すると、Photon Controller の Agent Vib が ESXi にインストールされ、Agent は Zookeeper や Chairman と通信を開始します。curl で実行できなくはないのですが、少々長い処理になっているため、POST の Response に含まれる Task の完了をポーリングして待機しなければなりません。面倒なので、その辺の WAIT 処理が含まれている CLI から実行します。

今回の環境では、VMware Fusion 上に ESXi 6.0u1 をインストールし、Software Acceptance Level を CommunitySupported に予め変更しています。

    % photon-cli target set http://22.31.1.1:9000
    API target set to 'http://22.31.1.1:9000'
    % photon-cli host create --username root --password VMware1! --address 22.31.1.101 --tag "CLOUD" --metadata '{"key": "value"}'
    Using target 'http://22.31.1.1:9000'
    Host with ip '22.31.1.101' created: ID = f9a8d926-02f5-4acd-b991-46f91c3ea622
    %
パラメーター 説明
username ESXi に Vib をインストールする際に利用するユーザー。root を使用します。
password username に対するパスワード。GA 版ではもう少しセキュリティに配慮した仕組みが欲しいところ。
address ESXi の管理ポートの IP アドレス
tag ESXi の役割。CLOUD と MGMT がある。CLOUD は仮想マシンを作成するリソースプールとしての役割を ESXi に適用。MGMT は Photon Controller の Control Plane がデプロイされる役割を ESXi に適用。CLOUD、MGMT を両方割り当てることも可能。
metadata ALLOWED_DATASTORE など、様々なパラメータはあるものの、単純な環境では指定しなくともある程度は動作はします。しかし CLI が metadata 必須のため key:value というやっつけの値をとりあえず入力します。

まず、photon target set コマンドで、CLI のエンドポイントを指定します。ここでは API FrontEnd のポート 9000 を指定しています。haproxy が設定された環境であれば 443 に対して HTTPS 接続することができます。

ESXi ホストの追加が終わったら、photon host list コマンドで確認します。

    % photon-cli host list
    Using target 'http://22.31.1.1:9000'
    2016/02/10 14:00:54 Error: esxcloud: { HTTP status: '404', code: 'NotFound', message: '', data: 'map[]' }

お”、確認できない…Orz。log/management_api/management_api.log を見てみると dropwizard のログには確かに GET /hosts がありません。流石にこれはないと思い、Github を追ってみると PROMOTE-3800 で com.vmware.photon.controller.apife.resources.HostsResource が削除されていました。理由は以下の Commit ログのとおり。

APIFE & Ruby CLI: Removing hosts listing api from HostsResource.

/deployments/{id}/hosts と同一機能なので削除、とのこと。ここで使っている photon-cli は 10 月時点のものなので /hosts にアクセスしに行ったため弾かれているようです。curl を使って、まず deployment の ID を取得して /deployments/{id}/hosts に対して GET を掛けます。

    % curl -s -S -X GET http://22.31.1.1:9000/deployments/5af14868-5e34-4664-ad75-9d0a65be583c/hosts | jq .
    {
      "items": [
        {
          "id": "f9a8d926-02f5-4acd-b991-46f91c3ea622",
          "selfLink": "http://22.31.1.1:9000/hosts/f9a8d926-02f5-4acd-b991-46f91c3ea622",
          "kind": "host",
          "address": "22.31.1.101",
          "username": "root",
          "password": "VMware1!",
          "metadata": {
            "key": "value"
          },
          "usageTags": [
            "CLOUD"
          ],
          "esxVersion": "6.0.0",
          "state": "READY"
        }
      ],
      "nextPageLink": "/deployments/5af14868-5e34-4664-ad75-9d0a65be583c/hosts?pageLink=L2NvcmUvbm9kZS1zZWxlY3RvcnMvZGVmYXVsdC9mb3J3YXJkaW5nP3BlZXI9MmQ3MjUxZGMtNTM0OS00NTBiLWFiZGItNmFlZWNjNWMyODliJnBhdGg9L2NvcmUvYnJvYWRjYXN0LXF1ZXJ5LXBhZ2UvMTQ1NTA4MzIzODYxODAwNiZxdWVyeT0mdGFyZ2V0PVBFRVJfSUQ=",
      "previousPageLink": null
    }
    % curl -s -S -X GET http://22.31.1.1:9000/deployments/5af14868-5e34-4664-ad75-9d0a65be583c/hosts | jq .
    {
      "items": [
        {
          "id": "f9a8d926-02f5-4acd-b991-46f91c3ea622",
          "selfLink": "http://22.31.1.1:9000/hosts/f9a8d926-02f5-4acd-b991-46f91c3ea622",
          "kind": "host",
          "address": "22.31.1.101",
          "username": "root",
          "password": "VMware1!",
          "metadata": {
            "key": "value"
          },
          "usageTags": [
            "CLOUD"
          ],
          "esxVersion": "6.0.0",
          "state": "READY"
        }
      ],
      "nextPageLink": "/deployments/5af14868-5e34-4664-ad75-9d0a65be583c/hosts?pageLink=L2NvcmUvbm9kZS1zZWxlY3RvcnMvZGVmYXVsdC9mb3J3YXJkaW5nP3BlZXI9MmQ3MjUxZGMtNTM0OS00NTBiLWFiZGItNmFlZWNjNWMyODliJnBhdGg9L2NvcmUvYnJvYWRjYXN0LXF1ZXJ5LXBhZ2UvMTQ1NTA4MzI0MDg4NjAwMSZxdWVyeT0mdGFyZ2V0PVBFRVJfSUQ=",
      "previousPageLink": null
    }

無事 ESXi ホストが Photon Controller の配下に加わったことを確認できました。

テナントの作成

Photon Controller はマルチテナントに対応しているので、まずは tenant を作成する必要があります。

    % photon-cli tenant create demo
    Using target 'http://22.31.1.1:9000'
    Created tenant 'demo' ID: 65494fc9-de8c-4e48-8024-4e59e99c94db
    % photon-cli tenant list
    Using target 'http://22.31.1.1:9000'
    ID                                    Name
    65494fc9-de8c-4e48-8024-4e59e99c94db  demo
    
    Total: 1
    %

上記コマンドでは demo という名前のテナントを作成しています。

リソース チケットの作成

テナントを作成したら、次にテナントに割り当てるリソースを指定します。コマンドラインで以下のように行います。

    % photon-cli tenant set demo
    Using target 'http://22.31.1.1:9000'
    Tenant set to 'demo'
    % photon-cli resource-ticket create --name dev-ticket --limits "vm.memory 100 GB, vm 100 COUNT"
    Using target 'http://22.31.1.1:9000'
    
    Tenant name: demo
    Creating resource ticket name: dev-ticket
    
    Please make sure limits below are correct:
    1: vm.memory, 100, GB
    2: vm, 100, COUNT
    Are you sure [y/n]? y
    Resource ticket created: ID = e9bb8c09-b6de-49fc-98b5-aa9a985785d1
    [ mohisa@pollux:~/tmp/devbox/photon-controller/devbox-photon/log/ ]
    % photon-cli resource-ticket list
    Using target 'http://22.31.1.1:9000'
    ID                                    Name        Limit
    e9bb8c09-b6de-49fc-98b5-aa9a985785d1  dev-ticket  vm.memory 100 GB
                                                      vm 100 COUNT
    
    Total resource tickets: 1
    %

まず、コマンドラインの対象となるテナントを photon-cli tenant set コマンドで指定します。そして photon-cli resource-ticket create コマンドでリソース チケットを作成します。

リソースとして利用できるアイテムの一覧はそのうち…

しかし、スクリプト化する際に空白の扱いが面倒なので、API FrontEnd (CloudStore ではなく) に POST する方法も合わせて併記します。POST の BODY は以下になります。

    {
        "name": "dev-ticket",
        "limits": [
          {
            "key": "vm.memory",
            "value": 100,
            "unit": "GB"
          },
          {
            "key": "vm",
            "value": 100,
            "unit": "COUNT"
          }
        ]
    }

これを /tmp/tmp.json に保存し、以下の curl で POST します。テナントの ID が必要になるため、POST するまえに GET でテナントの ID を確認します。

    % curl -s -S -H "Content-Type:application/json" -X GET http://22.31.1.1:9000/tenants
    % curl -s -S -H "Content-Type:application/json" -X POST http://22.31.1.1:9000/tenants/{id}/resource-tikcets -d @/tmp/tmp.json

プロジェクトの作成

テナントにリソース チケットを割り当てたら、プロジェクトを作成します。仮想マシンやコンテナ クラスタは、このプロジェクトの下にぶら下がります。プロジェクトもリソース制御されるため、プロジェクト作成時にテナントのリソース チケットからプロジェクト用のリソースチケットを切り出します。以下のコマンドでプロジェクトを作成します。

    % photon-cli project create --name dev-project --resource-ticket dev-ticket --name dev-project --limits "vm.memory 75 GB, vm 80 COUNT"
    Using target 'http://22.31.1.1:9000'
    
    Tenant name: demo
    Resource ticket name: dev-ticket
    Creating project name: dev-project
    
    Please make sure limits below are correct:
    1: vm.memory, 75, GB
    2: vm, 80, COUNT
    Are you sure [y/n]? y
    Project created: ID = 8b86b511-8e32-46e8-a62c-b26d86c080bd
    % photon-cli project list
    Using target 'http://22.31.1.1:9000'
    ID                                    Name         Limit            Usage
    8b86b511-8e32-46e8-a62c-b26d86c080bd  dev-project  vm.memory 75 GB  vm.memory 0 GB
                                                       vm 80 COUNT      vm 0 COUNT
    
    Total projects: 1

プロジェクトを作成する際は、テナントに割り当てられたリソースチケットから、どの程度リソースを切り出すのかを指定します。ここでは、メモリ 75 GB、仮想マシン数 80 個までの制限をリソースとして切り出しています。

以下のコマンドで現在のリソースの状況を見てみます。photon-cli resource-ticket list コマンドで使用量まで見ることが出来ないため、photon-cli resource-ticket show コマンドを利用します。

photon-cli resource-ticket show だけ何故 UUID を使わないのかは謎…

    % photon-cli resource-ticket list
    Using target 'http://22.31.1.1:9000'
    ID                                    Name        Limit
    e9bb8c09-b6de-49fc-98b5-aa9a985785d1  dev-ticket  vm.memory 100 GB
                                                      vm 100 COUNT
    
    Total resource tickets: 1
    % photon-cli resource-ticket show dev-ticket
    Using target 'http://22.31.1.1:9000'
    ID                                    Name        Limit             Usage
    e9bb8c09-b6de-49fc-98b5-aa9a985785d1  dev-ticket  vm.memory 100 GB  vm.memory 75 GB
                                                      vm 100 COUNT      vm 80 COUNT
    %

おわりに

ここまでの手順で、仮想マシンを作成する下地が整いました。次回以降のエントリでは、仮想マシンのデプロイ、コンテナクラスタのデプロイを行います。

チート

仮想マシン作成前までの手順をスクリプト化した Gist は以下になります。