tl;dr

Stable 扱いでは無く、絶賛開発中の LXD の Rest API を触ってみて、目的別に整理してみた。

はじめに

注意

LXD の REST API は絶賛開発中とのことですので、ここに書いてある内容は本記事を書いた時点の内容となりますのでご注意くださいませ。

参考

lxd - Daemon based on liblxc offering a REST API to manage containers

github.com

LXD でリモートの LXD ホストのコンテナを操作してみる LXD 0.1 がリリースされたのでLXD を試してみた続..

d.hatena.ne.jp

メモ

前提

  • ホスト OS
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS"
  • LXD バージョン
$ lxd --version
0.25
  • コンテナイメージ
$ lxc image list
+--------------------+--------------+--------+-----------------------+--------+----------+------------------------------+
|       ALIAS        | FINGERPRINT  | PUBLIC |      DESCRIPTION      |  ARCH  |   SIZE   |         UPLOAD DATE          |
+--------------------+--------------+--------+-----------------------+--------+----------+------------------------------+
| oreno-ubuntu-image | 1b9ba7cb50ac | no     |                       | x86_64 | 126.72MB | Dec 27, 2015 at 8:10am (JST) |
|                    | 4712c42e3fca | no     | Ubuntu trusty (amd64) | x86_64 | 64.43MB  | Dec 27, 2015 at 8:00am (JST) |
+--------------------+--------------+--------+-----------------------+--------+----------+------------------------------+

もちろん、API でも確認できる。

$ curl -s -k --cert $HOME/.config/lxc/client.crt --key $HOME/.config/lxc/client.key https://127.0.0.1:8443/1.0/images | jq .
{
  "operation": "",
  "metadata": [
    "/1.0/images/1b9ba7cb50acxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "/1.0/images/4712c42e3fcaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  ],
  "status_code": 200,
  "status": "Success",
  "type": "sync"
}

REST API で操作出来るようにする

$ lxc config set core.trust_password ${password}
$ lxc config set core.https_address [::]
$ lxc remote add oreno-local 127.0.0.1:8443

以下のように出力される。

Certificate fingerprint: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ok (y/n)? y # y を入力する

trust_password の入力を求められるので入力する。

lxc remote list で一覧を確認する。

$ lxc remote list
+-------------+-----------------------------------------+--------+
|    NAME     |                   URL                   | PUBLIC |
+-------------+-----------------------------------------+--------+
| images      | https://images.linuxcontainers.org:8443 | YES    |
| local       | unix://                                 | NO     |
| oreno-local | https://127.0.0.1:8443                  | NO     |
+-------------+-----------------------------------------+--------+

API のエンドポイントにアクセスする

/1.0/ を参考にした。

以下のように実行する。

$ curl -s -k --cert $HOME/.config/lxc/client.crt --key $HOME/.config/lxc/client.key https://127.0.0.1:8443/1.0 | jq .
{
  "operation": "",
  "metadata": {
    "environment": {
      "storage_version": "",
      "storage": "dir",
      "server_version": "0.25",
      "server_pid": 8168,
      "addresses": [
        "192.168.xxx.xxx:8443",
        "[2001:a452:48b:ed00:309f:497e:b743:655c]:8443",
        "[2001:a452:48b:ed00:8e70:5aff:fe7c:11a4]:8443",
        "10.0.x.x:8443",
        "172.17.x.x:8443"
      ],
      "architectures": [
        2,
        1
      ],

(snip)

    "config": {
      "core.trust_password": true,
      "core.https_address": "[::]:8443"
    },
    "auth": "trusted",
    "api_compat": 1
  },
  "status_code": 200,
  "status": "Success",
  "type": "sync"
}

コンテナを作成する

/1.0/containers を参考にした。

以下のように実行する。

$ curl --s X POST -k --cert $HOME/.config/lxc/client.crt --key $HOME/.config/lxc/client.key https://127.0.0.1:8443/1.0/containers -d '
{
  "name": "oreno-container",
  "architecture": 2,
  "profiles": ["default"],
  "ephemeral": true,
  "config": {"limits.cpu": "1"},
  "source": {"type": "image", "alias": "oreno-ubuntu-image"}
}'

以下のように出力される。

{
  "operation": "/1.0/operations/66a6d8e8-bc20-43d2-8266-4c801ee856df",
  "metadata": {
    "err": "",
    "may_cancel": false,
    "id": "66a6d8e8-bc20-43d2-8266-4c801ee856df",
    "class": "task",
    "created_at": "2015-12-27T21:04:04.449438237+09:00",
    "updated_at": "2015-12-27T21:04:04.449438237+09:00",
    "status": "Running",
    "status_code": 103,
    "resources": {
      "containers": [
        "/1.0/containers/oreno-container"
      ]
    },
    "metadata": null
  },
  "status_code": 100,
  "status": "OK",
  "type": "async"
}

コンテナ一覧を確認する

/1.0/containers を参考にした。

以下のように実行する。

$ curl -s -k --cert $HOME/.config/lxc/client.crt --key $HOME/.config/lxc/client.key https://127.0.0.1:8443/1.0/containers | jq .
{
  "operation": "",
  "metadata": [
    "/1.0/containers/oreno-container",
    "/1.0/containers/oreno-ubuntu",
    "/1.0/containers/oreno-ubuntu01"
  ],
  "status_code": 200,
  "status": "Success",
  "type": "sync"
}

lxc コマンドで確認する。

$ lxc list
+-----------------+---------+------+------+-----------+-----------+
|      NAME       |  STATE  | IPV4 | IPV6 | EPHEMERAL | SNAPSHOTS |
+-----------------+---------+------+------+-----------+-----------+
| oreno-container | STOPPED |      |      | YES       |         0 |
+-----------------+---------+------+------+-----------+-----------+
| oreno-ubuntu    | STOPPED |      |      | NO        |         0 |
+-----------------+---------+------+------+-----------+-----------+
| oreno-ubuntu01  | STOPPED |      |      | NO        |         0 |
+-----------------+---------+------+------+-----------+-----------+

EPHEMERALYES となっているコンテナはコンテナを停止すると自動的に削除される。

コンテナを起動する

/1.0/containers//state を参考にした。

以下のように実行する。

$ CONTAINER_NAME="oreno-container"
$ curl -X PUT -k --cert $HOME/.config/lxc/client.crt --key $HOME/.config/lxc/client.key https://127.0.0.1:8443/1.0/containers/${CONTAINER_NAME}/state -d '
{
  "action": "start",
  "timeout": 30,
  "force": true
}'

以下のように出力される。

{
  "operation": "/1.0/operations/31517205-e64f-4b23-92fa-b2634f408885",
  "metadata": {
    "err": "",
    "may_cancel": false,
    "id": "31517205-e64f-4b23-92fa-b2634f408885",
    "class": "task",
    "created_at": "2015-12-27T21:07:34.618819353+09:00",
    "updated_at": "2015-12-27T21:07:34.618819353+09:00",
    "status": "Running",
    "status_code": 103,
    "resources": {
      "containers": [
        "/1.0/containers/oreno-container"
      ]
    },
    "metadata": null
  },
  "status_code": 100,
  "status": "OK",
  "type": "async"
}

コンテナのステータスを確認する

/1.0/containers/ を参考にした。

以下のように実行する。

$ CONTAINER_NAME="oreno-container"
$ curl -s -k --cert $HOME/.config/lxc/client.crt --key $HOME/.config/lxc/client.key https://127.0.0.1:8443/1.0/containers/${CONTAINER_NAME} | jq .
{
  "operation": "",
  "metadata": {
    "status": {
      "ips": [
        {
          "host_veth": "veth7GH2NJ",
          "address": "10.0.x.xxx",
          "protocol": "IPV4",
          "interface": "eth0"
        },
        {
          "host_veth": "",
          "address": "127.0.0.1",
          "protocol": "IPV4",
          "interface": "lo"
        },
        {
          "host_veth": "",
          "address": "::1",
          "protocol": "IPV6",
          "interface": "lo"
        }
      ],
      "processcount": 9,
      "init": 11358,
      "status_code": 103,
      "status": "Running"
    },

(snip)

    },
    "expanded_devices": {
      "eth0": {
        "type": "nic",
        "parent": "lxcbr0",
        "nictype": "bridged"
      }
    },
    "name": "oreno-container",
    "profiles": [
      "default"
    ]
  },
  "status_code": 200,
  "status": "Success",
  "type": "sync"
}

"status" : "Running" となっているのコンテナは起動しているはず…

念の為、lxc コマンドでも確認してみる。

$ lxc list
+-----------------+---------+-------------------+------+-----------+-----------+
|      NAME       |  STATE  |       IPV4        | IPV6 | EPHEMERAL | SNAPSHOTS |
+-----------------+---------+-------------------+------+-----------+-----------+
| oreno-container | RUNNING | 10.0.x.xxx (eth0) |      | YES       |         0 |
+-----------------+---------+-------------------+------+-----------+-----------+
| oreno-ubuntu    | STOPPED |                   |      | NO        |         0 |
+-----------------+---------+-------------------+------+-----------+-----------+
| oreno-ubuntu01  | STOPPED |                   |      | NO        |         0 |
+-----------------+---------+-------------------+------+-----------+-----------+

起動している。

念の為、exec サブコマンドも実行してみる。

$ lxc exec oreno-container -- hostname
oreno-container

よし。

コンテナでコマンドを実行する

/1.0/containers//exec を参考にした。

以下のように実行する。

$ CONTAINER_NAME="oreno-container"
$ curl -s -X POST -k --cert $HOME/.config/lxc/client.crt --key $HOME/.config/lxc/client.key https://127.0.0.1:8443/1.0/containers/${CONTAINER_NAME}/exec -d '
{
  "command": ["/bin/sh", "-c", "while true; do echo "foo"; sleep 5; done"],
  "wait-for-websocket": true,
  "interactive": true
}'

以下のように出力される。

{
  "operation": "/1.0/operations/83940f18-7646-458e-b1dd-cb65ea9ddb07",
  "metadata": {
    "err": "",
    "may_cancel": false,
    "id": "83940f18-7646-458e-b1dd-cb65ea9ddb07",
    "class": "websocket",
    "created_at": "2015-12-27T21:21:47.852563283+09:00",
    "updated_at": "2015-12-27T21:21:47.852563283+09:00",
    "status": "Running",
    "status_code": 103,
    "resources": {
      "containers": [
        "/1.0/containers/oreno-container"
      ]
    },
    "metadata": {
      "fds": {
        "control": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "0": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
      }
    }
  },
  "status_code": 100,
  "status": "OK",
  "type": "async"
}

実行したコマンドの出力を確認する

/1.0/operations//websocket を参考にした。

以下のように実行する。

$ ID="83940f18-7646-458e-b1dd-cb65ea9ddb07"
$ SECRET="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
$ curl 
  -H "Sec-WebSocket-Key: `ruby -r "base64" -e "puts Base64.encode64('oreno_container')"`" 
  -H "Upgrade: websocket" 
  -H "Connection: upgrade" 
  -H "Sec-WebSocket-Version: 13" 
  -k --cert $HOME/.config/lxc/client.crt --key $HOME/.config/lxc/client.key 
"https://127.0.0.1:8443/1.0/operations/${ID}/websocket?secret=${SECRET}"
�foo
�foo
�foo
�foo
�foo

Ctrl+c で出力を止めるとコンテナ上のコマンドも停止する。

尚、Websocket へのアクセスについては以下の記事を参考にさせて頂いた。

intro なんだかんだ WebSocket を使ってるのに、 WebSocket サーバを自分で書いたことが無かったので、RFC も落ち着いてきたここらで、仕様を読みながら実装してみようと思いました。 "WebSocket サーバ 実装" とかでググると、 Socket.IO とか pywebsocke...

jxck.hatenablog.com

http://hwmemo01.tumblr.com/post/24658856934/一発芸curlでwebsocket受信専用

hwmemo01.tumblr.com

有難うございます。

コンテナを停止する

/1.0/containers//state を参考にした。

以下のように実行する。

$ curl -X PUT -k --cert $HOME/.config/lxc/client.crt --key $HOME/.config/lxc/client.key https://127.0.0.1:8443/1.0/containers/${CONTAINER_NAME}/state -d '
{
  "action": "stop",
  "timeout": 30,
  "force": true
}'

以下のように出力される。

{
  "operation": "/1.0/operations/9b506e26-1962-4b7e-ac9d-b59968e41192",
  "metadata": {
    "err": "",
    "may_cancel": false,
    "id": "9b506e26-1962-4b7e-ac9d-b59968e41192",
    "class": "task",
    "created_at": "2015-12-27T21:29:33.198590419+09:00",
    "updated_at": "2015-12-27T21:29:33.198590419+09:00",
    "status": "Running",
    "status_code": 103,
    "resources": {
      "containers": [
        "/1.0/containers/oreno-container"
      ]
    },
    "metadata": null
  },
  "status_code": 100,
  "status": "OK",
  "type": "async"
}

エフェメラルなコンテナなのでコンテナを停止した時点でコンテナは削除されている。

$ curl -s -k --cert $HOME/.config/lxc/client.crt --key $HOME/.config/lxc/client.key https://127.0.0.1:8443/1.0/containers | jq .
{
  "operation": "",
  "metadata": [
    "/1.0/containers/oreno-ubuntu",
    "/1.0/containers/oreno-ubuntu01"
  ],
  "status_code": 200,
  "status": "Success",
  "type": "sync"
}

コンテナを削除する

/1.0/containers/ を参考にした。

コンテナを削除する際には以下のように実行する。

$ CONTAINER_NAME="oreno-container"
$ curl -X DELETE -s -k --cert $HOME/.config/lxc/client.crt --key $HOME/.config/lxc/client.key https://127.0.0.1:8443/1.0/containers/${CONTAINER_NAME}

以下のように出力される。

{
  "operation": "/1.0/operations/ac1e30e5-ae88-44ec-b053-b6d5a489f668",
  "metadata": {
    "err": "",
    "may_cancel": false,
    "id": "ac1e30e5-ae88-44ec-b053-b6d5a489f668",
    "class": "task",
    "created_at": "2015-12-27T21:34:07.358316581+09:00",
    "updated_at": "2015-12-27T21:34:07.358316581+09:00",
    "status": "Running",
    "status_code": 103,
    "resources": {
      "containers": [
        "/1.0/containers/oreno-container"
      ]
    },
    "metadata": null
  },
  "status_code": 100,
  "status": "OK",
  "type": "async"
}

以上

メモでした。

元記事はこちら

超メモで走り切る 2015 年(3) LXD の REST API 目的別チートシート(アルファ版)