Dockerの普及に伴い、昨今ではDockerを使ったさまざまなクラスタ構築ツールが登場している。今回紹介するKontenaもそのようなクラスタ構築ツールの1つで、多機能かつ構成が容易で、またさまざまな環境で利用できるのが特徴だ。

多機能でかつ構成が容易なDockerクラスタ構築ツール

Linuxによるインフラ関連において、ここ数年で最も注目されていると言っても過言ではないDockerだが、開発当初は単一のサーバーでの利用にのみフォーカスして開発が進められており、複数のマシンを連ねたクラスタ環境でDockerを利用するためには、サードパーティ製のツールが必要となっていた。その代表的なものに以前にも紹介した「Kubernete」や「CoreOS」があるが(過去記事:「CoreOSを使ってDockerコンテナを動かす——15分でできるCoreOSクラスタの作り方」、「kubernetesによるDockerコンテナ管理入門」)、今回紹介するのはそれらとは別のアプローチを採用したコンテナクラスタ環境構築ツール「Kontena」だ。

KontenaもKuberneteやCoreOSと同様に既存のさまざまな技術を組み合わせてコンテナを実行させるためのクラスタを構築するツールであるが、それら各コンポーネントが組み込まれたコンテナとして提供されている点が特徴となる。そのため、Dockerが利用できる環境であればディストリビューションを問わずに利用が可能だ。

Dockerクラスタとは

さて、Kontenaについて説明する前に、Kontenaが実現するDockerクラスタについて簡単に説明しておこう。まず、ネットワークで複数のサーバーを接続し、その各サーバーでそれぞれアプリケーションを実行できる環境を「クラスタ環境」と呼ぶ(図1)。

図1 クラスタ環境のイメージ
図1 クラスタ環境のイメージ

クラスタ環境ではアプリケーションを分散実行させることで負荷を分散でき、また複数のサーバー上で同一のアプリケーションを重複実行することで、もしサーバーに障害が発生してもサービスを提供し続けられる、といったメリットがある。なお、クラスタ環境を構成する各サーバーは「ノード」と呼ばれる。

いっぽう、Dockerを使ったクラスタ環境(Dockerクラスタ)では、クラスタの各ノード上にDockerをインストールし、Dockerのコンテナを使ってアプリケーションを実行させる点が特徴となる(図2)。

図2 Dockerクラスタのイメージ
図2 Dockerクラスタのイメージ

Dockerを利用することで、アプリケーションとOS環境の依存関係を減らすことができるのがDockerクラスタのメリットだ。さらに、DockerのSwarmモードや、Kubernete、Kontenaなどのクラスタ構築支援ツールを利用することで、各ノードを遠隔操作して自動的にコンテナを実行させたり、サーバーの障害を検知して停止したコンテナを自動的に別のノードで実行させる、といったことも可能になる。

Kontenaのアーキテクチャ

Kontenaは、このようなDockerクラスタを構築するためのツールだ。クラスタ管理にクライアント−サーバー構成を採用しているのが特徴で、「Kontena Server」がクラスタ全体の管理を行うアーキテクチャになっている。管理者は「Kontena CLI」と呼ばれるクライアント経由でKontena Serverにアクセスしてさまざまな操作を実行する。また、コンテナを実行するノードの管理は、各ノードで「Kontena Agent」と呼ばれるエージェントを実行させることで行われる。Kontena AgentはKontena Serverとやり取りを行い、コンテナやネットワークなどの各種管理作業やコンテナの実行を行う仕組みになっている(図3)。

図3 Kontenaのアーキテクチャ
図3 Kontenaのアーキテクチャ

なお、Kontena CLIはRubyで実装されており、Rubyのパッケージ管理ツールであるgem経由でインストールが可能だ。また、Kontena ServerおよびKontena AgentはともにDocker用のイメージとして配布されており、「docker pull」コマンドや「docker run」コマンドだけでダウンロードおよびインストール、実行が可能になっている。

Kontenaが備える機能

Kontenaでは、前述したようにクラスタのノードを遠隔操作し、指定したコンテナを適切なノード上で自動的に実行させることが可能だ。もちろんコンテナの監視機能や、停止したコンテナを自動的に再起動させる機能もある。

また、ユーザー認証機能を備えているのも特徴だ。KontenaではKontena ServerやKontena Agentがインストールされたサーバー上のユーザーとは独立したユーザー管理機構を備えており、これらサーバー上に個別にユーザーを作成することなしに、ユーザー毎に異なる権限を与えることができる。権限がないコンテナに対する操作は行えないため、たとえば異なる複数のプロジェクトのコンテナを同じクラスタ環境上に同居させる、といったことが可能になる。

なお、コンテナ間の通信は独自のVPN(仮想プライベートネットワーク)を利用する仕組みになっている。そのため、クラスタを構成する各ホスト間がプライベートなネットワークで接続されていない場合でも、安全にホスト間の通信が行える。

「オーケストレーション」と呼ばれる、複数のコンテナを組み合わせて提供されるようなサービスを適切に自動設定する機能も備えている。オーケストレーション機能は前回紹介した「Docker Compose」と互換性があり、Docker Compose用の設定ファイルをほぼそのまま利用することが可能だ。

そのほか、監査機能やログ、統計処理機能、独自のプライベートイメージレジストリといった機能も備えている。

なお、Kontenaはオープンソースで提供されており、完全に無料で利用できる。Kontenaのpricingページによると、Kontenaを開発するKontena社ではサポートやカスタマイズ等のビジネスで収益を得るとのことだ。

KontenaによるDockerクラスタ構築

それでは、実際にKontenaを使ってDockerクラスタを構築していく例を紹介していこう。流れとしては、まずクライアントであるKontena CLIをインストールし、続けてKontena ServerとKontena Agentをインストールする、という形になる。

CLIのインストール

前述の通り、KontenaではKontena CLI(kontenaコマンド)というコマンドラインクライアントを使ってクラスタの管理を行う。Kontena CLIはKontena Serverとネットワーク経由で通信できるマシンであれば、どのマシンでもインストールが可能だ。通常は管理作業に使用するマシンにインストールするのが一般的だろう。

なお、Kontena CLIはRubyで実装されており、実行にはRuby 2.0以降が必要となる。あらかじめyumやapt-getなどのパッケージマネージャでRubyおよびRuby向けパッケージマネージャであるgemをインストールしておこう。

Kontena CLIのインストールは、以下のようにgemコマンドで行える。

# gem install --no-document kontena-cli

インストールが完了したら、kontenaコマンドを実行できるか確認しておこう。なお、引数を指定せずにkontenaコマンドを実行すると簡単なヘルプが表示される。

$ kontena
Usage:
    kontena [OPTIONS] SUBCOMMAND [ARG] ...

Parameters:
    SUBCOMMAND                    subcommand
    [ARG] ...                     subcommand arguments

Subcommands:
    grid                          Grid specific commands
    app                           App specific commands
    service                       Service specific commands
    vault                         Vault specific commands
    node                          Node specific commands
    master                        Master specific commands
    vpn                           VPN specific commands
    registry                      Registry specific commands
    container                     Container specific commands
    etcd                          Etcd specific commands
    external-registry             External registry specific commands
    register                      Register Kontena Account
    login                         Login to Kontena Master
    logout                        Logout from Kontena Master
    whoami                        Shows current logged in user
    user                          User related commands
    version                       Show version

Options:
    -h, --help                    print help

なお、今回検証に使用したKontena CLIのバージョンは0.14.7だ。これは「kontena version」コマンドで確認できる。

# kontena version
cli: 0.14.7

続いて、「kontena register」コマンドを実行してKontena環境上で使用されるユーザーを作成しておく。ユーザーの作成にはメールアドレスとパスワードが必要だ。

# kontena register
Email: hylom@example.com
Password: **********
Password again: **********

Kontena Serverのインストール

KontenaにはKontena Serverのインストールを行うためのいくつかのプラグインが用意されており、いくつかのクラウド環境においてはこれらを利用して容易にKontena Serverを作成できるのだが、今回はこれらを利用せずにKontena Serverをインストールする手順を紹介する。これらプラグインの利用についてはKontenaのドキュメントを参照して欲しい。また、Docker Composeを使って簡易的にKontena Serverをインストールする方法もドキュメントには掲載されているので、手軽に試したい場合はこちらを利用しても良いだろう。

なお、今回Kontena Serverをインストールした環境はCentOS 7.2だが、サービスの起動にはsystemdを使用しているため、systemdが利用できる環境であればほかのLinuxディストリビューションでも同様の手順で利用できるはずだ。

また、Kontena ServerおよびKontena Agentをインストールするホスト上にはDockerがインストールされている必要がある。そのほか、Kontena Serverで使用するサーバー証明書の用意も必要だ。

サーバー証明書の作成

Kontenaでは、Kontena ServerとKontena CLI、Kontena Agent間の通信にデフォルトではHTTPSを利用する。そのため、HTTPSを利用するためのサーバー証明書が必要となる。今回は検証目的ということで、いわゆる自己署名証明書を作成して使用する。

まず、opensslコマンドで適当な秘密鍵を作成する。今回はRSA方式で2048ビットの鍵を作成した。

$ openssl genrsa 2048 > kontena-server.key

続いて、この鍵を使ってCSRファイルを作成する。この際、証明書を利用する組織の所在地や組織名の入力が必要となるので、適切なものを入力しておこう。

$ openssl req -new -key kontena-server.key > kontena-server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]: ←国名を入力。日本ならJP
State or Province Name (full name) []: ←州・県名を入力
Locality Name (eg, city) [Default City]: ←都市名を入力
Organization Name (eg, company) [Default Company Ltd]: ←組織名を入力
Organizational Unit Name (eg, section) []: ←部門名を入力
Common Name (eg, your name or your server's hostname) []: ←サーバーのホスト名を入力
Email Address []: ←担当者のメールアドレスを入力

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: ←何も入力せずにスキップ
An optional company name []: ←何も入力せずにスキップ

続いて、鍵ファイルとCSRファイルを元にCRTファイルを作成する。

$ openssl x509 -days 365 -req -signkey kontena-server.key < kontena-server.csr > kontena-server.crt

最後に、鍵ファイルとCRTファイルを1つのファイルにまとめたPEMファイルを作成する。このファイルが、Kontena Serverで使われる証明書ファイルとなる。

$ cat kontena-server.key kontena-server.crt > kontena-server.pem

設定ファイルの作成

続いて、Konena Serverを稼動させるホスト上で設定ファイルを作成する。必要な設定ファイルは下記のとおりだ。

  • /etc/kontena/kontena-server.pem
  • /etc/kontena/kontena-server.env
  • /etc/kontena/kontena-haproxy.sh
  • /etc/systemd/system/kontena-server-haproxy.service
  • /etc/systemd/system/kontena-server-api.service
  • /etc/systemd/system/kontena-server-mongo.service

/etc/kontenaディレクトリは通常は存在しないので、こちらは手動で作成しておく必要がある。

# mkdir /etc/kontena

/etc/kontena/kontena-server.pemファイルは、先に述べた手順で作成したSSLサーバー証明書ファイルだ。また、kontena-server.envファイルはKontena Serverの各種設定を記述したファイルで、内容は下記のようになる。

KONTENA_VERSION=latest
KONTENA_VAULT_KEY=<ランダムな文字列>
KONTENA_VAULT_IV=<ランダムな文字列>
SSL_CERT="/etc/kontena/kontena-server.pem"

ここで「KONTENA_VAULT_KEY」および「KONTENA_VAULT_IV」パラメータではランダムな文字列を設定しておく必要がある。ここで利用できるランダムな文字列は、たとえば次のようにして生成できる。

# cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 64 | head -n 1
3f9KZl8J6i0ozlOrrjaT1pm0qYUG2i12G7Bs5CDrC8mQTR8vvHw1kRaOMfDJskxS ←表示された文字列をコピー&ペーストする

また、/etc/kontena/kontena-haproxy.shファイルの中身は以下のようになる。

#!/bin/sh

if [ -n "$SSL_CERT" ]; then
    SSL_CERT=$(awk 1 ORS='\\n' $SSL_CERT)
else
    SSL_CERT="**None**"
fi

/usr/bin/docker run --name=kontena-server-haproxy \
  --link kontena-server-api:kontena-server-api \
  -e SSL_CERT="$SSL_CERT" -e BACKEND_PORT=9292 \
  -p 80:80 -p 443:443 kontena/haproxy:latest

このファイルには実行可能属性を付けておこう。

# chmod +x kontena-haproxy.sh

/etc/systemd/system以下に配置する3つのファイルは、それぞれ下記のようになる。

リスト1 kontena-server-api.service

[Unit]
Description=kontena-server-api
After=network-online.target
After=docker.service
Description=Kontena Agent
Documentation=http://www.kontena.io/
Requires=network-online.target
Requires=docker.service

[Service]
Restart=always
RestartSec=5
EnvironmentFile=/etc/kontena/kontena-server.env
ExecStartPre=-/usr/bin/docker stop kontena-server-api
ExecStartPre=-/usr/bin/docker rm kontena-server-api
ExecStartPre=/usr/bin/docker pull kontena/server:${KONTENA_VERSION}
ExecStart=/usr/bin/docker run --name kontena-server-api \
          --link kontena-server-mongo:mongodb \
          -e MONGODB_URI=mongodb://mongodb:27017/kontena_server \
          -e VAULT_KEY=${KONTENA_VAULT_KEY} -e VAULT_IV=${KONTENA_VAULT_IV} \
          kontena/server:${KONTENA_VERSION}

リスト2 kontena-server-haproxy.service

[Unit]
Description=kontena-server-haproxy
After=network-online.target
After=docker.service
Description=Kontena Server HAProxy
Documentation=http://www.kontena.io/
Requires=network-online.target
Requires=docker.service

[Service]
Restart=always
RestartSec=5
EnvironmentFile=/etc/kontena/kontena-server.env
ExecStartPre=-/usr/bin/docker stop kontena-server-haproxy
ExecStartPre=-/usr/bin/docker rm kontena-server-haproxy
ExecStartPre=/usr/bin/docker pull kontena/haproxy:latest
ExecStart=/etc/kontena/kontena-haproxy.sh

リスト3 kontena-server-mongo.service

[Unit]
Description=kontena-server-mongo
After=network-online.target
After=docker.service
Description=Kontena Server MongoDB
Documentation=http://www.mongodb.org/
Requires=network-online.target
Requires=docker.service

[Service]
Restart=always
RestartSec=5
ExecStartPre=/usr/bin/docker pull mongo:3.0
ExecStartPre=-/usr/bin/docker create --name=kontena-server-mongo-data mongo:3.0
ExecStartPre=-/usr/bin/docker stop kontena-server-mongo
ExecStartPre=-/usr/bin/docker rm kontena-server-mongo
ExecStart=/usr/bin/docker run --name=kontena-server-mongo \
          --volumes-from=kontena-server-mongo-data \
          mongo:3.0 mongod --smallfiles

これら設定ファイルを配置したら、systemdの設定をリロードしておく。

# systemctl daemon-reload

なお、それぞれのサービスの起動順だが、まず最初にkontena-server-mongoサービスを起動し、続いてkontena-server-api、最後にkontena-server-haproxyという順番で起動する。

# systemctl start kontena-server-mongo
# systemctl start kontena-server-api
# systemctl start kontena-server-haproxy

これらコマンドの実行後、systemctlコマンドでそれぞれのサービスが正しく起動しているかを確認しておこう。

# systemctl | grep kontena
  kontena-server-api.service                                                                             loaded    active running   Kontena Agent
  kontena-server-haproxy.service                                                                         loaded    active running   Kontena Server HAProxy
  kontena-server-mongo.service                                                                           loaded    active running   Kontena Server MongoDB

前述のとおり各サービスはそれぞれDockerコンテナとして稼動しており、その状況は「docker ps」コマンドで確認できる。

# docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                                      NAMES
223a233c1fa2        kontena/haproxy:latest   "./run.sh"               2 minutes ago       Up 2 minutes        0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   kontena-server-haproxy
87da7385c808        kontena/server:latest    "./run.sh"               2 minutes ago       Up 2 minutes        9292/tcp                                   kontena-server-api
1e436c80bdab        mongo:3.0                "/entrypoint.sh mongo"   2 minutes ago       Up 2 minutes        27017/tcp                                  kontena-server-mongo

なお、kontena-server-mongoコンテナは各種データを格納するために「kontena-server-mongo-data」というコンテナを利用する。このコンテナは単純にデータを格納するためだけに確保されたコンテナで、実行はされない。kontena-server-haproxyやkontena-server-api、kontena-server-mongoコンテナを削除しても関連データは失われないが、このkontena-server-mongo-dataコンテナを削除してしまうとDockerクラスタに関するすべての設定が失われてしまうので注意してほしい。

Kontena Serverが稼動したら、Kontena CLIをインストールしたホストからのログインを行ってみよう。ログインは「kontena login <Kontena Serverのホスト名もしくはIPアドレス>」コマンドで行える。たとえばKontena ServerのIPアドレスが「192.168.1.10」だった場合、以下のようになる。また、今回は自己署名証明書を利用しているため、SSL証明書の検証をスキップするよう「SSL_IGNORE_ERRORS」環境変数に「ture」を設定している。

$ export SSL_IGNORE_ERRORS=true
$ kontena login https://192.168.1.10
Email: hylom@example.com
Password: **********
 _               _
| | _____  _ __ | |_ ___ _ __   __ _
| |/ / _ \| '_ \| __/ _ \ '_ \ / _` |
|   < (_) | | | | ||  __/ | | | (_| |
|_|\_\___/|_| |_|\__\___|_| |_|\__,_|
-------------------------------------
Copyright (c)2016 Kontena, Inc.

Logged in as hylom@example.com
Welcome! See 'kontena --help' to get started.

グリッドの作成

エージェントをインストールする前に、各ノードが所属する「グリッド(grid)」の設定を行っておく必要がある。まず、「kontena grid create <グリッド名>」コマンドを実行してグリッドを作成する。たとえば「grid01」という名前のグリッドを作成する場合、次のようになる。

$ kontena grid create grid01
Using grid: grid01

グリッドの情報は、「kontena grid current」コマンドで確認できる。なおここで表示される「token」はKontena Agentの設定時に必要となる文字列だ(後述)。

$ kontena grid current
grid01:
  uri: wss://192.168.1.10
  token: JJ8LDpFfB8uPo6iwq87O4XCr2Tgez2E+8MuUyZKh1lRqUatpTkfhKkud9jDcZxZWdwAzZfoFMA7/I2Rfil761w==
  stats:
    nodes: 0 of 0
    cpus: 0
    load: 0.0 0.0 0.0
    memory: 0.0 of 0.0 GB
    filesystem: 0.0 of 0.0 GB
    users: 1
    services: 0
    containers: 0

エージェントのインストール

続いて、コンテナを稼動させるノード上にKontena Agentをインストールしていこう。Kontena Agentに必要な設定ファイルは以下の2つだ。

  • /etc/kontena/kontena-agent.env
  • /etc/systemd/system/kontena-agent.service

まず/etc/kontena/kontena-agent.envファイルだが、以下のようになる。

KONTENA_URI="https://<Kontena Serverのホスト名もしくはIPアドレス>"
KONTENA_TOKEN="<グリッドのトークン>"
KONTENA_PEER_INTERFACE=<Kontena Serverとの通信に使用するNIC>
KONTENA_VERSION=latest

たとえばKontena ServerのIPアドレスが192.168.1.10、グリッドのトークンが「JJ8LDpFfB8uPo6iwq87O4XCr2Tgez2E+8MuUyZKh1lRqUatpTkfhKkud9jDcZxZWdwAzZfoFMA7/I2Rfil761w==」、使用するNICがeth1だった場合、以下のようになる。

KONTENA_URI="https://192.168.1.10"
KONTENA_TOKEN="JJ8LDpFfB8uPo6iwq87O4XCr2Tgez2E+8MuUyZKh1lRqUatpTkfhKkud9jDcZxZWdwAzZfoFMA7/I2Rfil761w=="
KONTENA_PEER_INTERFACE=eth1
KONTENA_VERSION=latest

また、/etc/systemd/system/kontena-agent.serviceファイルは以下のようになる。

[Unit]
Description=kontena-agent
After=network-online.target
After=docker.service
Description=Kontena Agent
Documentation=http://www.kontena.io/
Requires=network-online.target
Requires=docker.service

[Service]
Restart=always
RestartSec=5
EnvironmentFile=/etc/kontena/kontena-agent.env
ExecStartPre=-/usr/bin/docker stop kontena-agent
ExecStartPre=-/usr/bin/docker rm kontena-agent
ExecStartPre=/usr/bin/docker pull kontena/agent:${KONTENA_VERSION}
ExecStart=/usr/bin/docker run --name kontena-agent \
          -e KONTENA_URI=${KONTENA_URI} \
          -e KONTENA_TOKEN=${KONTENA_TOKEN} \
          -e KONTENA_PEER_INTERFACE=${KONTENA_PEER_INTERFACE} \
          -v=/var/run/docker.sock:/var/run/docker.sock \
          -v=/etc/kontena-agent.env:/etc/kontena.env \
          --net=host \
          kontena/agent:${KONTENA_VERSION}

これらファイルを作成したら、Kontena Serverの場合と同様にsystemdをリロードし、「kontena-agent」サービスを開始させよう。

# systemctl daemon-reload
# systemctl start kontena-agent

kontena-agentサービスも、Kontena Serverのサービスと同様にコンテナ内で稼動する。「docker ps」コマンドでそれらの稼動を確認できる。

# docker ps
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS               NAMES
9610a645423c        kontena/etcd:2.3.3        "/usr/bin/etcd --name"   2 minutes ago       Up 2 minutes                            kontena-etcd
b1f62187436d        weaveworks/weave:1.4.5    "/home/weave/weaver -"   2 minutes ago       Up 2 minutes                            weave
9589d74e93d2        kontena/cadvisor:0.23.0   "/entrypoint.sh --doc"   3 minutes ago       Up 3 minutes        8080/tcp            kontena-cadvisor
3206025005ef        kontena/agent:latest      "/app/bin/kontena-age"   3 minutes ago       Up 3 minutes                            kontena-agent

ノードの状況把握

Kontena Agentを起動させたら、Kontena CLIをインストールしたマシンで「kontena node ls」コマンドを実行して正しくノードが認識されているか確認してみよう。たとえば「centos11」というホスト上でKontena Agentが稼動している場合、次のように表示される。

# kontena node ls
Name                                                                   Status     Initial    Labels                          
centos11                                                               online     yes        -                               

複数のノードを稼働させる

2つめ以降のノードを稼働させる場合、以上の作業を各ノードで繰り返せば良い。各ノードに配置する設定ファイルはまったく同じなので、たとえばさくらのクラウドのような環境で利用する場合、ディスクイメージをそのままコピーすることで容易に複数のノードを追加できる。

Kontenaクラスタ上でアプリケーションを実行する

以上でKontenaクラスタが完成したので、続いてはKontenaクラスタ上でのコンテナ実行について説明していこう。Kontenaでは実行されるコンテナを「サービス」と呼び、「kontena service」コマンドで管理できる。

コンテナを実行する場合、まずサービスを作成し、続いてそれをデプロイする、という手順となる。サービスの作成は「kontena service create <サービス名> <コンテナイメージ名>」コマンドで行える。

たとえば「httpd」というコンテナを実行したい場合、まず次のようにしてサービスを作成する。サービス名には任意のものが使用できるが、ここでは「httpd_test」とした。

$ kontena service create httpd_test httpd

なお、公開するポートやリンク、環境変数、ボリュームなどの設定もサービスの作成時に行う。ここでは「docker run」コマンドで指定できるオプションとほぼ同一のものが利用できるが、詳しくは「kontena service create –help」コマンドなどで確認できるオンラインヘルプなどを参照してほしい。

作成したサービスは、「kontena service ls」コマンドで確認できる。

$ kontena service ls
NAME                                                         INSTANCES  STATEFUL STATE      EXPOSED PORTS                                     
httpd_test                                                   0 / 1      no       initialized  

続いて、「kontena serice deploy <サービス名>」コマンドで作成したコンテナのデプロイを行う。

$ kontena service deploy httpd_test

デプロイ後に再度「kontena service ls」コマンドで確認すると、「INSTANCES」が「1/1」となり、「STATE」が「running」となっていることが分かる。

$ kontena service ls
NAME                                                         INSTANCES  STATEFUL STATE      EXPOSED PORTS                                     
httpd_test                                                   1 / 1      no       running 

また、「kontena service show <サービス名>」でサービスの詳細情報を確認できる。たとえば下記の例では、「centos11」ノードでこのインスタンスが稼働していることが分かる。

$ kontena service show httpd_test
grid01/httpd_test:
  status: running
  image: httpd:latest
  stateful: no
  scaling: 1
  strategy: ha
  deploy_opts:
    min_health: 0.8
  dns: httpd_test.grid01.kontena.local
  net: bridge
  instances:
    httpd_test-1:
      rev: 2016-08-16 12:48:36 UTC
      node: centos11
      dns: httpd_test-1.grid01.kontena.local
      ip: 10.81.1.161
      public ip: ***.***.**.***
      status: running

稼働中のコンテナを停止させるには、「kontena service stop <サービス名>」コマンドを使用する。

$ kontena service stop httpd_test

また、サービスを削除するには「kontena service rm <サービス名>」コマンドを使用する。この際、本当に削除を行うかの確認が行われるので、確認して再度サービス名を入力する。また、「–force」オプション付きでコマンドを実行すると確認無しで削除が行われる。

$ kontena service rm httpd_test
Destructive command. To proceed, type "httpd_test" or re-run this command with --force option.
> httpd_test

複数のコンテナをまとめて管理する

Kontenaでは、複数のコンテナをまとめた「アプリケーション」という単位でコンテナを管理する機能が用意されている。前回紹介した「Docker Compose」と同様、コンテナの起動オプションや設定などを記述したファイルを事前に用意しておくことで、それらコンテナをまとめて管理できるというものだ。

この設定ファイルはDocker Composeの設定ファイルと互換性があり、すでにDocker Compose向けの設定ファイルがある場合、それらをほぼそのまま利用することができる。Kontenaクラスタ内でコンテナが分散実行されることを除いて、実現できる機能や使い勝手はDocker Composeとほぼ同じだ。Docker Composeの使い方や設定ファイルについては前回記事で解説しているので、そちらも参照してほしい。

アプリケーション単位でのコンテナ管理では、「kontena app」コマンドを使用する。設定ファイルを自動生成する「kontena app init」コマンドが用意されているので、まずは適当なディレクトリでこのコマンドを使って設定ファイルを作成すると良いだろう。

以下では、Docker Compose記事で説明したMySQLとWordPressをデプロイする以下のような設定ファイル(docker-compose.ymlファイル)を元に、Kontenaクラスタでこれらのコンテナを稼働させる例を紹介する。

version: '2'
services:
  my_mysql:
    image: mysql:5.7
    volumes:
      - /var/test/mysql:/var/lib/mysql
      - /var/test/mysql_conf.d:/etc/mysql/conf.d
    environment:
      MYSQL_ROOT_PASSWORD: some_password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress_password

  my_wordpress:
    image: wordpress:4.5-apache
    links:
      - my_mysql:mysql
    volumes:
      - /var/test/wp_plugins:/var/www/html/wp-content/plugins
    environment:
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress_password
      WORDPRESS_DB_NAME: wordpress

まず、Docker Composeの設定ファイル(docker-compose.ymlファイル)が格納されているディレクトリ(ここでは「wordpress」ディレクトリで「kontena app init」コマンドを実行する。

$ kontena app init
Dockerfile not found. Do you want to create it? [Yn]: n ←Dockerfileを作成しないので「n」と入力
Found docker-compose.yml.
Creating kontena.yml
Your app is ready! Deploy with 'kontena app deploy'.

「kontena app init」コマンドではコンテナイメージを作成するための「Dockerfile」ファイルと、「docker-compose.yml」ファイル、「kontena.yml」ファイルを作成できる。今回の場合Dockerfileファイルは不要なので、「Dockerfile not found. Do you want to create it?」という質問に対し「n」と入力して作成をキャンセルしている。また、docker-compose.ymlファイルは先に用意してあるので作成されず、これをベースにkontena.ymlファイルが作成される。

作成されたkontena.ymlファイルは以下のようになる。

---
version: '2' ←kontena.ymlファイルフォーマットのバージョン
name: wordpress  ←プロジェクト名
services:  ←サービスの設定
  my_mysql: ←サービス名「my_mysql」について
    extends: ←「docker-compose.yml」ファイルの「my_mysql」設定を読み込む
      file: docker-compose.yml
      service: my_mysql
  my_wordpress: ←サービス名「my_wordpress」について
    extends: ←「docker-compose.yml」ファイルの「my_wordpress」設定を読み込む]
      file: docker-compose.yml
      service: my_wordpress

kontena.ymlファイルの詳細についてはオンラインドキュメントのリファレンスページを参照して欲しいが、基本的にはDocker Composeのdocker-compose.ymlとほぼ同じだ。

Kontenaにおけるコンテナ間通信

Kontenaでは前述したとおり、独自にVPNを構築することで異なるホスト上にあるコンテナ間の通信を可能にしている。さらにVPN内に独自のDNSサーバーが用意され、コンテナ間では「<サービス名>.kontena.local」もしくは「<サービス名>-<インスタンス番号>.kontena.local」というホスト名で各コンテナにアクセスできるように設定される。

また、「kontena app」コマンドで作成されたサービスはサービス名として「<プロジェクト名>-<サービス名>」という名前が付けられる。今回の例では、プロジェクト名が「wordpress」、サービス名が「my_mysql」および「my_wordpress」なので、各コンテナは「wordpress-my_mysql.kontena.local」や「wordoress-my_wordpress.kontena.local」というホスト名でアクセスが可能だ。

これを踏まえて、生成されたkontena.ymlファイルに下記の太字の部分を追記している。追加したのはWordPressサービスの設定で使用するデータベースのホスト名を指定する「WORDPRESS_DB_HOST」環境変数の設定だ。これにより、WordPressは「wordpress-my_mysql.kontena.local」というホストをデータベースとして使用するようになる(「${project}」の部分はプロジェクト名に置換される)。

---
version: '2'
name: wordpress
services:
  my_mysql:
    extends:
      file: docker-compose.yml
      service: my_mysql
  my_wordpress:
    extends:
      file: docker-compose.yml
      service: my_wordpress
    environment:
      WORDPRESS_DB_HOST: ${project}-my_mysql.kontena.local

アプリケーションのデプロイ

設定ファイルを元にしたデプロイは、設定ファイルが格納されたディレクトリで「kontena app deploy」コマンドを実行することで行える。コマンドを引数無しで実行すると、次のようにkontena.ymlファイル内に記述されたサービスの作成とデプロイが実行される。

$ kontena app deploy
Not found any service with build option
creating my_mysql
creating my_wordpress
deploying my_mysql ... done
deploying my_wordpress ... done

実行されているサービスは「kontena app ls」コマンドで確認できる。

$ kontena app ls
NAME                           IMAGE                                              INSTANCES       STATEFUL   STATE           PORTS
my_mysql                       mysql:5.7                                          1 / 1           no         running      
my_wordpress                   wordpress:4.5-apache                               1 / 1           no         running         0.0.0.0:80->80/tcp

サービスの停止は「kontena app stop」コマンド、削除は「kontena app rm」コマンドで行える。

$ kontena app stop
stopping wordpress-my_mysql
stopping wordpress-my_wordpress
$ kontena app rm
Destructive command. Are you sure? (y/n) or re-run this command with --force option.
> y
deleting my_wordpress ... done
deleting my_mysql ... done

「kontena app start」コマンドでは個別のサービスを指定することで、そのサービスだけを起動することも可能だ。

$ kontena app start my_mysql
starting wordpress-my_mysql

ロードバランサとスケーリング

Kontenaでは、Kontenaクラスタで利用できるロードバランサイメージを公開しており、簡単な設定だけでロードバランサを使った負荷分散/冗長化を行えるようになっている。最後に、このロードバランサの使い方を紹介しておこう。

ロードバランサを使用するには、kontena.ymlファイルにロードバランサコンテナの設定を追加し、ロードバランス対象となるコンテナで環境変数にロードバランスのための各種パラメータおよびリンク設定を追加すれば良い。

たとえば先のWordPressおよびMySQLを使った構成の場合、kontena.ymlファイルは以下のようになる。

---
version: '2'
name: wordpress
services:
  internet_lb:
    image: kontena/lb:latest
    affinity:
      - node==centos12
    ports:
      - 80:80
  my_mysql:
    extends:
      file: docker-compose.yml
      service: my_mysql
  my_wordpress:
    extends:
      file: docker-compose.yml
      service: my_wordpress
    environment:
      WORDPRESS_DB_HOST: ${project}-my_mysql.kontena.local
    links:
      - internet_lb

ここで太字の部分が新たに追加したものだ。追加した「internet_lb」がロードバランサとして実行されるサービスとなり、このサービスに対してリンクを行ったサービス(ここではmy_wordpressサービス)がロードバランシングされる対象のサービスとなる。また、「affinity:」設定で「- node==centos12」と指定することで、このロードバランサは「centos12」というノード上で実行されるようになる。

なお、ロードバランサのデフォルト設定ではHTTPについてロードバランスを行うようになっているため、ここでは特に追加の設定はおこなっていない。HTTP以外のロードバランスを行う場合の設定についてはオンラインドキュメントを参照してほしい。

この設定でコンテナをデプロイすると、ロードバランサ経由で指定したコンテナ(ここでは「my_wordpress」コンテナ)にアクセスが可能になる。

$ kontena app deploy
Not found any service with build option
creating internet_lb
creating my_mysql
creating my_wordpress
deploying internet_lb ... done
deploying my_mysql ... done

正しくロードバランシングが行われているかを確認するため、my_wordpressコンテナの稼働数を増やし、実際にアクセスが振り分けられているかを確認してみよう。まず、「kontena app scale」コマンドで「my_wordpress」サービスのインスタンスを2に設定する。

$ kontena app scale my_wordpress 2

この状態で「kontena app ls」コマンドを実行すると、「INSTANCES」の値が「2/2」になっていることが確認できる。

$ kontena app ls
NAME                           IMAGE                                              INSTANCES       STATEFUL   STATE           PORTS                                             
internet_lb                    kontena/lb:latest                                  1 / 1           no         running         0.0.0.0:80->80/tcp                                
my_mysql                       mysql:5.7                                          1 / 1           no         running                                                           
my_wordpress                   wordpress:4.5-apache                               2 / 2           no         running                                                           

この状態で、centos12ノードにWebブラウザで数回アクセスした後、「kontena app logs my_wordpress」コマンドでmy_wordpressサービスのログを表示させると、「wordpress-my_wordpress-1」と「wordpress-my_wordpress-2:」の2つのコンテナに対しアクセスが振り分けられていることが分かる。

$ kontena app logs my_wordpress
  
  
2016-08-16T14:31:12.000Z wordpress-my_wordpress-1: 10.81.1.162 - - [16/Aug/2016:14:31:12 +0000] "GET / HTTP/1.1" 200 3839 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7"
2016-08-16T14:31:15.000Z wordpress-my_wordpress-2: 10.81.1.162 - - [16/Aug/2016:14:31:14 +0000] "GET / HTTP/1.1" 200 3839 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7"
2016-08-16T14:34:45.000Z wordpress-my_wordpress-1: 10.81.1.162 - - [16/Aug/2016:14:34:45 +0000] "GET / HTTP/1.1" 200 3839 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7"
2016-08-16T14:34:47.000Z wordpress-my_wordpress-2: 10.81.1.162 - - [16/Aug/2016:14:34:47 +0000] "GET / HTTP/1.1" 200 3839 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7"

多機能で使いやすいのが特徴、今後の発展にも期待

Kontenaは2014年にスタートしたプロジェクトでまだ若いプロジェクトだが、現時点で十分に実用的な機能を提供している。また、すでに全世界で2万ノード以上のノードが使われており、開発も活発だ。

近年ではDockerもクラスタ機能に注力しており、8月1日にリリースされたDocker 1.12では容易にDockerクラスタを構築できる「Swarmモード」が搭載された。これにより、Dockerだけでも複数のホスト上でコンテナを動作させ、それらを組み合わせてサービスを提供するような構成が可能である。とはいえ、提供されるクラスタ関連機能としてはまだ最低限であり、セットアップの容易さという点以外では、機能的にはまだKontenaやKuberneteには劣っている状況だ。

また、KontenaはDockerの技術を使用しているものの、Docker以外のコンテナ実行環境などもサポートできる構造となっている。そのため、将来性についても今のところ不安はない。Dockerベースのコンテナクラスタ環境構築ツールは今後も厳しい競争が予想されるが、Kontenaは現時点でも十分に利用を検討できる環境になっていると言えるだろう。