RubyからDockerコンテナを作ってsshで操作できるようにする

Dockerは操作をするためのAPIも用意されていて、便利そうなのでRubyからコンテナを自動起動するための方法をメモしておきます。

sshが使えるコンテナを作る

ubuntuのイメージを使用します。
標準のイメージだとsshは使えないのでいったんシェルログインし、インストールします。
あとでログインするためにrootのパスワードも設定しておきます。

$ docker run -i -t ubuntu:latest /bin/bash
root@853f85828aa9:/# apt-get update
root@853f85828aa9:/# apt-get install openssh-server
root@853f85828aa9:/# mkdir /var/run/sshd
root@853f85828aa9:/# passwd
root@853f85828aa9:/# exit

今作成したコンテナをイメージとして保存します。
docker commitする際にCONTAINER IDが必要なので、docker ps -aをしてIDを調べ、それを指定しcommitします。

$ docker ps -a | head -n 2
CONTAINER ID        IMAGE                            COMMAND
853f85828aa9        ubuntu:latest                    /bin/bash
$ docker commit 853f85828aa9 kurochan/ubuntu-sshd

試しに起動する

とりあえず、今作成したイメージできちんと動作するか試します。

$ docker run -d -p 22 kurochan/ubuntu-sshd /usr/sbin/sshd -D
$ docker ps
CONTAINER ID        IMAGE                         COMMAND             CREATED             STATUS              PORTS
d1cb149af9f5        kurochan/ubuntu-sshd:latest   /usr/sbin/sshd -D   4 seconds ago       Up 2 seconds        0.0.0.0:49155->22/tcp

sshdを起動する際に-Dオプションをつけていますが、これを付加することでフォアグラウンドで動作させています。Dockerはフォアグラウンドで動いているものがないとコンテナが終了してしまうので。
docker psすると、PORTSの部分(右側です)に、"0.0.0.0:49155->22/tcp"のような記述があると思います。
コンテナの22番ポートがホストの49155番にバインドされているという意味です。
ログインする時はさきほど指定したパスワードを入力します。

$ ssh root@[dockerのipアドレス] -p 49155
root@d1cb149af9f5:~# exit

ログインできていれば成功です。コンテナを停止させます。

$ docker stop d1cb149af9f5

コンテナ起動の操作をRubyから行う

docker-apiというGemを使いますので、インストールしておきます。

$ gem install docker-api

前置きが長くなってしまいましたが、以下がコンテナを起動するスクリプトです。
コンテナを起動し、returnキーが押されたらそのコンテナを停止させるようにしました。

# sample.rb
require 'docker'

container = Docker::Container.create('Cmd' => ['/usr/sbin/sshd', '-D'], 'Image' => 'kurochan/ubuntu-sshd', 'PortSpecs' => '22', 'ExposedPorts' => ['22/tcp'])
container.start('PortBindings' => {'22/tcp' => [{'HostIp' => '0.0.0.0', 'HostPort' => '49156'}]})

puts 'Press return to stop...'
gets

container.stop
puts 'Container stopped.'

コンテナを生成した後に、startするのですが、その時にホストにバインドするポート(ここでは49156)を指定すると、外部からアクセスができるようになります。

コンテナが立ち上がっている状態で、

$ ssh root@[dockerのipアドレス] -p 49156

とすればさきほどと同じようにsshログインができます。