技術メモなど

ほぼ自分用の技術メモです。

CentOS6.5でDockerを動かしてみる(その1)

ゆるい勉強会のお盆明け勉強会に参加し、Dockerについて発表する機会をいただきました。勉強会は色々な方向、ジャンルの話が聞けてとても楽しかったのですが、自分の発表は緊張でダメダメでした……。

しかしダメダメなままで終わるのは勿体ないので、発表したかった内容をもう一度文字で整理してみようと思います。

Dockerとは

仮想化技術の主流となっているハイパーバイザ型に対し、Dockerはコンテナ型に属する仮想化技術です。

ハイパーバイザ型仮想化

ハイパーバイザと呼ばれるソフトウェア(またはカーネルモジュール)の仕組みで、ホストOSのハイパーバイザ上に物理ハードウェアをエミュレートした仮想の物理マシンを作り、この仮想マシンでゲストOSを実行できるようにするものです。代表的なものに、VMWare ESXi、XenHyper-V、そしてオープンソースKVMがあります。

コンテナ型仮想化(Linux

ハイパーバイザを持たず、ホストOSとカーネル領域を共有し、ユーザー領域のみをコンテナとして独立させるものです。各コンテナには仮想のハードウェア、ネットワークが割り当てられるので、独立したゲストOSとして扱うことができます。コンテナのハードウェア資源、ネットワークはホストOSのカーネルに依存するものです。

コンテナ型仮想化のメリット・デメリット

ハードウェアをエミュレートするハイパーバイザ型の仮想化に比べ、ホストOSのカーネルをそのまま利用するコンテナ型の方がオーバーヘッドが小さく軽快に動作すると言われています。

ただし、ユーザー領域(ユーザープロセス)を仮想的に分離するという仕組み上、コンテナ間は独立していても、ホストOSからコンテナのプロセスは見えてしまうため、セキュリティには注意が必要です。

Dockerのいいところ

上記コンテナ型仮想化のメリットに加え、コンテナを用意するためのイメージという仕組みが用意されており、ベースとなるコンテナイメージからコンテナを起動することができます。

コンテナイメージはDockerhubに様々なもの(CentOSの公式イメージなど)があり、これを簡単に手元へ引っ張ってくることができます。引っ張ってきたイメージに独自のカスタマイズを加えて、オリジナルのイメージを構築することも簡単です。

更にDockerfileという仕組みを使えば、イメージの構築手順を全てスクリプトに記載しておき、イメージのビルドを自動化することができます。そのため、Dockerfile自体が構築手順書になり得ます。

さっそくCentOS6.5にDocker環境を構築する

今旬なDocker環境の構築は、RHEL7(やそれの互換を目指しているCentOS7)、CoreOS、本家本元のUbuntuを使うようですが、ヘタレな私は使い慣れたCentOS6.5を使いました……。

CentOS6.5でも、Docker環境構築はとても簡単でした。具体的な手順は次のとおりです。

yumでEPELリポジトリを使用できるようにする

RPMをダウンロードし、yumでEPELリポジトリを使用できるようにします。最後のコマンドで、リポジトリを指定しない限り標準リポジトリを使用するようコンフィグを書き換えています。

$ rpm --import http://ftp.iij.ad.jp/pub/linux/fedora/epel/RPM-GPG-KEY-EPEL-6
$ rpm -ivh http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm
$ sed -i -e 's/^enabled=1$/enabled=0/g' /etc/yum.repos.d/epel.repo

EPELリポジトリからyumでDockerをインストール

DockerはLXC(Linuxコンテナ)やcgroupの技術を使いますが、yumでインストールしてしまえば依存関係はyumが解決してくれるので楽です。

$ yum -–enablerepo=epel install docker-io

とりあえずのDockerの使い方

なにはともあれ、まずはDockerを触ってみます。概要は次の通りです。

  1. 元となるコンテナイメージを手元にプルする
  2. プルしたイメージからコンテナを起動し、何かプロセスを実行させる
  3. 終了したコンテナの状態を確認する
  4. 今度はコンテナを起動し、シェルを対話的に実行する
  5. 終了したコンテナを再利用するためイメージとしてコミットする
  6. コミットしたイメージからコンテナを起動する

それでは始めてみましょう。

元となるコンテナイメージを手元にプルする

コンテナイメージをDockerhubからプルするには、docker pullコマンドを使います。ここではCentOSの公式イメージをプルすることにします。

$ docker pull centos

これだけでcentosの公式イメージをローカルに引っ張ってくることができました。docker imagesコマンドでローカルのイメージの状態を確認します。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              centos7             1a7dc42f78ba        6 minutes ago         236.4 MB
centos              latest              1a7dc42f78ba        6 minutes ago         236.4 MB
centos              centos6             cd934e0010d5        6 minutes ago

centosというリポジトリから、centos6、centos7、latestというタグの付いたイメージがローカルに保存されていることを示しています。

現時点でCentOSの最新イメージはCentOS7なので、latestとはCentOS7と同一です。

プルしたイメージからコンテナを起動し、何かプロセスを実行させる

docker runコマンドで、ローカルのイメージからCentOS6のコンテナを起動してプロセスを実行させます。

$ docker run centos:centos6 /bin/echo "Hello, World!!"

ここでポイントは、docker runの後に指定するcentos:centos6の部分で、コロンの前がリポジトリ名を、後がタグを指定しています。ローカルのcentosリポジトリにはCentOS6と7がありましたが、タグを指定することでCentOS6でコンテナを実行するようにしています。

上記の例ではechoで標準出力に「Hello, World!!」と出しています。

終了したコンテナの状態を確認する

Dockerコンテナは基本的に実行したプロセスが終了すると、コンテナも終了状態となります。終了したコンテナの状態を表示するためには、次のコマンドを使います。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                      PORTS               NAMES
e6331182be91        centos:centos6      /bin/echo 'Hello, Wo   26 seconds ago      Exited (0) 23 seconds ago

docker psコマンドに引数aを付けて実行すると、終了したコンテナを含めて全てのコンテナの状態が表示されます。先程実行したコンテナは、echoのプロセスを終了し、コンテナも終了した状態(Exited)になっていることが分かります。

今度はコンテナを起動し、シェルを対話的に実行する

今度はコンテナでシェルを起動し、コンテナを対話的に操作したいと思います。

$ docker run -i -t centos:centos6 /bin/bash
bash-4.1#

これでコンテナのシェルを開くことができました。シェルを抜けるまでコンテナを実行され続けています。

この状態で例えばyumを使ってapacheをインストールしたり、ユーザーを追加したりといった設定を行うことができます。

ここではシェルからyumを使って何か適当なソフトウェアをインストールした後シェルを抜けたと想定します。シェルを抜けたことでコンテナは終了状態となりました。

終了したコンテナを再利用するためイメージとしてコミットする

先程シェルを実行したコンテナの状態を確認します。

CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                      PORTS               NAMES
2db39ef055e0        centos:centos6      /bin/bash              5 minutes ago       Exited (0) 5 seconds ago                        happy_carson

このままではせっかく先程yumでソフトウェアをインストールしたコンテナを再利用できません。そこで、終了したコンテナをコミットし、再利用できるDockerイメージにする操作をします。

$ docker commit 2db takedah:test1

docker commitコマンドの後にdocker ps -aで表示したコンテナIDを、その後にリポジトリ名:タグを指定します。コンテナIDは特定できればいいので、最初の数文字だけで認識してくれます。

コミット後のローカルのイメージの状態を確認します。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
takedah             test1               18799f69459e        5 minutes ago       212.5 MB
centos              centos6             b1bd49907d55        3 weeks ago         212.5 MB
centos              centos7             b157b77b1a65        3 weeks ago         243.7 MB
centos              latest              b157b77b1a65        3 weeks ago         243.7 MB

コミットしたイメージからコンテナを起動する

先程コミットしたイメージをベースにコンテナを起動してみます。

$ docker run takedah:test1 /bin/echo "Hello, World!!"

標準出力に文字が表示されましたか?

ここまでの一旦まとめ

まず手っ取り早くDockderイメージを作るには、

  1. 元となるイメージのプル
  2. コンテナ起動時にシェルを対話的に実行
  3. シェルからソフトウェアのインストールや設定などを行ってからコンテナを終了
  4. 終了したコンテナをコミットして確定する

という手順になるかと思います。

しかし、Dockerイメージを作るには、Dockerfileという方法を使わない手はありません。次の記事で、Dockerfileを使ったDockerイメージのビルドについて説明してみたいと思います。