話題の記事

Dockerコンテナ管理ツールGearDを試してみた

2014.04.20

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ども、大瀧です。
Dockerコンテナをデプロイするツールが欲しいという理由でAWS OpsWorksとの組み合わせを以前のエントリーで紹介しましたが、今回は別のアプローチでデプロイを行うGearDを試してみました。

GearDとは

GearDは、Red Hat社が開発するDockerコンテナを管理するCLIツール兼エージェントです。
最近、ITニュースサイトのPublickeyで紹介されたProject Atomicのコンポーネントの1つです。Project Atomic自体はRHELベースの軽量Linuxディストリビューション(Atomic Host)を前提とするものですが、GearDは独立した造りになっており、Fedora 20およびRHEL 7-Beta(EPEL経由なのでサポートなし)で動作します。

Red_Hat-Project-Atomic-Introduction
ブログ記事 : GearD: The Intersection of PaaS, Docker and Project Atomic | Openshift Blog から

また、Red Hat社が開発するPaaSプロダクト、OpenShiftとも深い関係が見受けられます。OpenShiftでは次期アプリケーションコンテナへのDockerの導入を進めており、Project Atomicコミュニティと協調するとの記述があります。(OpenShiftの開発チームはRed Hat社が買収して得たプロダクトのため、Project Atomicのチームとは別と考えられます)

OpenShift engineers are working closely with the Project Atomic community to design the next generation DevOps stack.

How Docker Changed the Way We Develop and Release OpenShift Online | Openshift Blog

まぁ、GearDのGitHubリポジトリ自体OpenShift Organization配下ですし、ブログもOpenShiftのサイトにありますので、ざっくりとOpenShiftの一部と考えてしまっても支障ないでしょう。

ちなみに、GearDはGo言語で実装されています。最近インフラ界隈のプロダクトはDockerをはじめ、Serf/ConsulCloud Foundry V2の一部などGoが流行ってますねー。

GearDの機能

GearDは、主に以下の機能を持ちます。

  1. Dockerコンテナのsystemd連携
  2. 複数Dockerコンテナの一括デプロイ
  3. Dockerコンテナのプライベートネットワーク構築のサポート
  4. 複数Dockerホスト連携向けAPI

Docker自体の機能拡張ではなく、Dockerのコンテナ管理に特化していますね。個人的に最も気になるのがsystemd連携です。

systemd連携といっても、仕組みはとてもシンプルです。GearDは、Dockerコンテナ毎にsystemdのUnit(サービス/デーモンに相当)定義ファイルを生成しsystemdによるコンテナの実行を設定し、各コンテナの状態を管理します。実装自体はDockerの公式ドキュメントで紹介されているものと同じですが、GearDに含まれるgearコマンドでいい感じに扱うことができます。

systemdの設定をあまりよく知らないという方は、@enakai00さんの以下のスライドをご覧ください。

ここからは、そのgearコマンドを試してみた手順をご紹介していきます。

セットアップ手順

公式ページにyumでインストールする方法がありますが、今回はVagrantを使いたかったのでGitHubリポジトリにある手順でやってみました。リポジトリにあるVagrantfileでVMを立ち上げ、/vagrantで共有されるリポジトリのファイルをそのままビルドに使用する、なかなかダイナミックな仕組みです。

Fedora VMの起動とプロビジョニング

Vagrantを動作させるために、あらかじめVagrantVirtualBoxをPCにインストールしておきましょう。まずはGitHubリポジトリ(https://github.com/openshift/geard)をgit cloneし、Vagrantfileを利用してVMの起動およびプロビジョニングがVagrantによって自動で実行されます。

ikkomon:~ ryuta$ git clone git@github.com:openshift/geard && cd geard
Cloning into 'geard'...
remote: Reusing existing pack: 9154, done.
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 9159 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (9159/9159), 4.15 MiB | 837.00 KiB/s, done.
Resolving deltas: 100% (5736/5736), done.
Checking connectivity... done
ikkomon:geard ryuta$ ls
Dockerfile   cmd/         contrib/     docker/      git/         jobs/        router/      systemd/     vendor/
README.md    config/      deployment/  docs/        http/        pkg/         selinux/     tests/
Vagrantfile  containers/  dispatcher/  encrypted/   idler/       port/        ssh/         utils/
ikkomon:geard ryuta$ vagrant up
Sharing GOPATH with VM
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'fedora20'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: geard_default_1397977291193_8455
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 43273 => 43273 (adapter 1)
    default: 6060 => 2225 (adapter 1)
    default: 22 => 2222 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Error: Connection timout. Retrying...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Mounting shared folders...
    default: /vagrant => /Users/ryuta/.go
==> default: Running provisioner: shell...
    default: Running: inline script
Installing dependencies and setting up vm for geard development
  :
(yum update諸々で10〜20分程度かかります)
  :
Initializing gear daemon
To use the geard service, run
systemctl enable /usr/lib/systemd/system/geard-image.service
systemctl start geard-image.service

Otherwise, run
vagrant ssh
contrib/build
[vagrant@localhost geard]$

GearDのビルド

続いて、GearDをビルドします。ビルドスクリプトがリポジトリのcontrib/buildに用意されているのでそれを実行するだけですが、vagrantユーザーのホームディレクトリが/vagrant/src/github.com/openshift/geardに設定されているのでvagrant sshでログインする先が/vagrant以下の共有フォルダになっていることに注意します。

ikkomon:~ ryuta$ vagrant ssh
Sharing GOPATH with VM
Last login: Fri Dec 20 18:02:34 2013 from 10.0.2.2
[vagrant@localhost geard]$ pwd
/vagrant/src/github.com/openshift/geard
[vagrant@localhost geard]$ contrib/build
Downloading build dependencies

Note: Packages downloaded by go get at this point may need to be vendored.
..done
Building..
..done
Copying binaries..
..done
[vagrant@localhost geard]$

gearコマンドを実行し、ヘルプが表示されればOKです。

[vagrant@localhost geard]$ gear
A commandline client and server that allows Docker containers to be installed to systemd in an opinionated and distributed fashion.

Complete documentation is available at http://github.com/openshift/geard

Usage:
  gear [flags]
  gear [command]

Available Commands:
  deploy <file> <host>...              :: Deploy a set of containers to the named hosts
  : 
Use "gear help [command]" for more information about that command.
[vagrant@localhost geard]$

動作確認

では、DockerコンテナをGearDで動かしてみましょう。gear installで、今回はサンプルのコンテナ pmorie/sti-html-app をコンテナ名"my-sample-service"で作成します。

[vagrant@localhost geard]$ sudo gear install pmorie/sti-html-app my-sample-service
2014/04/20 07:23:42 ports: Releasing
local Container my-sample-service is installed
[vagrant@localhost geard]$

まだこの時点ではDockerコンテナは作成されておらず、コンテナのためのsystemdのUnit設定ファイルが生成された状況です。従来のSysVinitで言うchkconfig --addに相当します。設定ファイルは、/etc/systemd/system/ctr-<コンテナ名>.serviceで作成されます。

/etc/systemd/system/ctr-my-sample-service.service

[Unit]
Description=Container my-sample-service


[Service]
Type=simple
TimeoutStartSec=5m
Slice=container-small.slice
  :

続いて、コンテナをgear start <コンテナ名>で実行します。

[vagrant@localhost geard]$ sudo gear start my-sample-service
You can also control this container via 'systemctl start ctr-my-sample-service.service'
local Container my-sample-service starting

コンテナの状態は、gear list-unitsで確認できます。systemctl list-unitsからGearD配下のコンテナUnitのみを抜粋するもので、dockerコマンドであればdocker psに相当します。

[vagrant@localhost geard]$ gear list-units
You can also display the set of containers via 'systemctl list-units'
2014/04/20 07:25:04 local execute *jobs.ListContainersResponse
ID                SERVER  ACTIVE     SUB       LOAD    TYPE
my-sample-service         activating start-pre loaded  start
[vagrant@localhost geard]$ docker ps
CONTAINER ID        IMAGE                        COMMAND                CREATED             STATUS              PORTS               NAMES
064ce442553a        pmorie/sti-html-app:latest   /bin/sh -c /usr/bin/   6 seconds ago       Up 6 seconds        8080/tcp            my-sample-service
[vagrant@localhost geard]$

動いてますね!
systemdによってOS起動時にDockerコンテナも自動実行するようになっているので、VMの再起動を試してみます。

[vagrant@localhost geard]$ exit
ikkomon:geard ryuta$ vagrant reload
  : 
ikkomon:geard ryuta$ vagrant ssh
[vagrant@localhost geard]$ gear list-units
You can also display the set of containers via 'systemctl list-units'
2014/04/20 07:51:08 local execute *jobs.ListContainersResponse
ID                SERVER  ACTIVE  SUB     LOAD    TYPE
my-sample-service         failed  failed  loaded
[vagrant@localhost geard]$

あれ、failedなので、コンテナの起動に失敗しているようです。こんなときはgear status <コンテナ名>で状態を確認します。systemdのUnitとして動作しているので、個別にログを抽出でき便利です。

[vagrant@localhost geard]$ gear status my-sample-service
You can also display the status of this container via 'systemctl status ctr-my-sample-service.service'
2014/04/20 07:51:10 container_status: Unable to fetch container status logs: exit status 3
ctr-my-sample-service.service - Container my-sample-service
   Loaded: loaded (/var/lib/containers/units/my/ctr-my-sample-service.service; enabled)
   Active: failed (Result: exit-code) since 日 2014-04-20 07:50:17 UTC; 53s ago
  Process: 434 ExecStartPre=/bin/sh -c /usr/bin/docker inspect --format="Reusing {{.ID}}" "my-sample-service-data" || exec docker run --name "my-sample-service-data" --volumes-from "my-sample-service-data" --entrypoint true "pmorie/sti-html-app" (code=exited, status=1/FAILURE)

 4月 20 07:50:17 localhost.localdomain systemd[1]: Starting Container my-sample-service...
 4月 20 07:50:17 localhost.localdomain sh[434]: dial unix /var/run/docker.sock: no such file or directory2014/04/20 07:50:17 dial unix /var/run/docker.sock: no such file or directory
 4月 20 07:50:17 localhost.localdomain systemd[1]: ctr-my-sample-service.service: control process exited, code=exited status=1
 4月 20 07:50:17 localhost.localdomain systemd[1]: Failed to start Container my-sample-service.
 4月 20 07:50:17 localhost.localdomain systemd[1]: Unit ctr-my-sample-service.service entered failed state.

/var/run/docker.sockファイルが無い、というエラーなので、dockerサービスよりも先にコンテナが起動されてしまっているようです。systemdの様式に沿って試しにサービスの依存関係の記述を以下のように追加してみましたが、改善せず。

/etc/systemd/system/ctr-my-sample-service.service

[Unit]
Description=Container my-sample-service
After=docker.service

[Service]
Type=simple
TimeoutStartSec=5m
Slice=container-small.slice
  :

ひとまず、再度手動(gear start)でコンテナは起動しましたが、解決策を知っている方がいればぜひ教えてください!

まとめ

GearDは、Dockerコンテナを管理するツールとして様々な機能があります。今回はセットアップとsystemd連携についてご紹介しました。他の機能もそれぞれ触ってみたいですね。ついでに、sti(source into images)という関連プロダクトもあるので、そちらも試してみたいス。

次々にツールが出ていることで、Red HatのDocker対応が本気ということが感じられるのではないでしょうか。OpenShiftが次期システムに移行されれば、大規模なDockerの本番事例としても脚光を浴びそうです。