Docker はコンテナ型ハードウェア仮想化と呼ばれる技術を用いたアプリケーション配布用のプラットフォーム。
今回はその Docker を CentOS7 で一通り使ってみる。
$ cat /etc/redhat-release CentOS Linux release 7.1.1503 (Core) $ uname -r 3.10.0-229.14.1.el7.x86_64
コンテナ型仮想化とは
ハードウェア仮想化には、大きく分けてハイパーバイザ型とコンテナ型というふたつがある。 どちらにおいても、ホスト OS の上で仮想化された複数のゲスト OS を実行することができる。
まず、ハイパーバイザ型ではハードウェアをソフトウェアまたはハードウェアの支援機能を使ってエミュレーションする。 ゲスト OS はエミュレーションされた仮想的なハードウェアの上で動作することになる。
それに対してコンテナ型では、ホスト OS の内部に隔離されたリソースを用意する。 ゲスト OS はその隔離されたリソースを使って動作することになる。 隔離されたリソースとは、具体的にはプロセスやネットワーク機能 (ネームスペース) を指す。
コンテナ型は、ハイパーバイザ型に比べると実行に必要なオーバーヘッドが小さいというメリットもある。 ただし、あくまでホスト OS の中の隔離されたリソースを使って動作するという特性上、ちょっとクセがある。 例えば Docker ではひとつのプロセスをホスト OS から隔離してゲスト OS に使わせるため、複数のプロセスを動かすにはまずプロセスマネージャなどを使って最初のひとつを fork する必要がある。
Docker をインストールする
CentOS7 であれば追加のリポジトリなどを入れることなく Docker をインストールできる
$ sudo yum -y install docker ...(省略)... 完了しました!
インストールできたら Docker のサービスを開始する。
$ sudo systemctl start docker
$ sudo systemctl enable docker
Docker イメージをダウンロードする
まずは、公式リポジトリに登録されている CentOS6 の Docker イメージをダウンロードしてみる。 これにはゲスト OS の rootfs が入っている。
$ sudo docker pull centos:6 6: Pulling from docker.io/centos 6a7b54515901: Pull complete e788880c8cfa: Pull complete 1debf8fb53e6: Pull complete 72703a0520b7: Pull complete 47d44cb6f252: Already exists docker.io/centos:6: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security. Digest: sha256:045c14a29c8b318678455a788546705a238249595cdad59f8b880fd3fb21f37a Status: Downloaded newer image for docker.io/centos:6
動かしてみる
まずは Docker コンテナを起動してみる。 起動する際には、実行するコマンドを指定する。 以下では echo コマンドでメッセージを出力させている。
$ sudo docker run centos:6 /bin/echo "Hello, World" Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning. Hello, World
上記では、何やら警告が出ていた。 本番環境でループデバイスを使うのは非推奨ということらしい。 とりあえず今は検証用に過ぎないので警告を消す方向で。
$ sudo sed -i -e ' s:\(DOCKER_STORAGE_OPTIONS=\):\1"--storage-opt dm.no_warn_on_loop_devices=true": ' /etc/sysconfig/docker-storage
警告を表示しないように起動オプションを変更したら Docker サービスを再起動する。
$ cat /etc/sysconfig/docker-storage | tail -n 1 DOCKER_STORAGE_OPTIONS="--storage-opt dm.no_warn_on_loop_devices=true" $ sudo systemctl restart docker
再度実行すると警告は表示されない。
$ sudo docker run centos:6 /bin/echo "Hello, World" Hello, World
端末を取得する
コンテナの起動時に端末を取得する場合は -i オプションを付ける。
$ sudo docker run -i -t centos:6 /bin/bash # cat /etc/redhat-release CentOS release 6.7 (Final) # uname -r 3.10.0-229.14.1.el7.x86_64 # exit
ハイパーバイザ型の仮想化であれば端末を手放してもシャットダウンしていない限り再度ログインできるが、 コンテナ型仮想化の Docker の場合 exit で抜けるとプロセスが終了してしまう。 起動中のコンテナを docker ps コマンドで確認してみよう。
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
過去に実行されていたコンテナは docker ps コマンドに -a オプションを付けると確認できる。
$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 00c381768f16 centos:6 "/bin/bash" About a minute ago Exited (0) 22 seconds ago kickass_sinoussi 27833b767635 centos:6 "/bin/echo 'Hello, W 6 minutes ago Exited (0) 6 minutes ago hopeful_hopper eea7b32a8c08 centos:6 "/bin/echo 'Hello, W 17 minutes ago Exited (0) 17 minutes ago furious_jang
プロセスを終了せずにコンテナから抜ける (端末を手放す) には Ctrl+p, Ctrl+q を入力する
$ sudo docker run -i -t centos:6 /bin/bash #
今度はコンテナから抜けても起動したままであることが確認できる。
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 72d863377ecf centos:6 "/bin/bash" 41 seconds ago Up 40 seconds happy_goodall
起動中のコンテナの端末を再度取得するには docker attach コマンドを使う。
$ sudo docker attach 72d863377ecf # cat /etc/redhat-release CentOS release 6.7 (Final)
自分用の Docker イメージを作ってみる
次に、自分でカスタマイズを施した Docker イメージを作ってみる。 一旦作ってしまえば同じコンテナが何度も作れるようになる。
docker images コマンドを使うと今ローカルにあるイメージを確認できる。
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE docker.io/centos 6 72703a0520b7 13 days ago 190.6 MB
まずは先ほどリポジトリから pull してきた CentOS6 のイメージからコンテナを起動して /var/tmp 以下にテキストファイルを設置しておく。
$ sudo docker run -i -t centos:6 /bin/bash # cat << EOF > /var/tmp/greet.txt Hello, World EOF # exit
今実行したコンテナの ID を docker ps コマンドで確認しておく。
$ sudo docker ps -a | head -n 2 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 149ce7af73d5 centos:6 "/bin/bash" 5 minutes ago Exited (0) 23 seconds ago hungry_payne
docker commit コマンドで確認したコンテナからイメージを作ることができる。
$ sudo docker commit 149ce7af73d5 amedama/centos:6
12c4ba192dc361f2870ed485d2141a34cc4b14020e5652c1d929f26a47a21010
新しくイメージが登録された。
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE amedama/centos 6 12c4ba192dc3 11 seconds ago 386.2 MB docker.io/centos 6 72703a0520b7 13 days ago 190.6 MB
作成したイメージからコンテナを起動すると、確かに /var/tmp 以下にテキストファイルがあることが確認できる。
$ sudo docker run amedama/centos:6 /bin/cat /var/tmp/greet.txt
Hello, World
ちなみにコンテナの履歴は消さないといつまでも残り続けてディスクを圧迫するようなので定期的にクリーンアップしよう。
$ sudo docker rm $(sudo docker ps -a -q)
Dockerfile を使ってイメージを作る
先ほどの例では起動したコンテナからイメージを作ったけど、イメージを作る場合は Dockerfile という設定ファイルを使った方が便利。
試しに MySQL をインストールして起動するイメージを作ってみる。
$ cat << EOF > Dockerfile FROM centos:6 MAINTAINER example <example@example.jp> RUN yum -y install mysql-server EXPOSE 3306 CMD ["/usr/bin/mysqld_safe", "--skip-grant-tables"] EOF
Dockerfile の書き方は公式サイトのリファレンスを参照のこと。
https://docs.docker.com/reference/builder/
Dockerfile を元にイメージをビルドする。
$ sudo docker build -t amedama/centos:mysql . ...(省略)... Successfully built 4f2ccbbabf0c
ビルドしたイメージを元にコンテナを起動する。 -d オプションはデーモンモードで標準入出力を表示しないというもの。 -p オプションはコンテナのポートをホスト OS 経由でアクセスできるようにするためのもの。 MySQL 用にコンテナの TCP:3306 ポートを、ホスト OS の TCP:3306 ポートと接続している。
$ sudo docker run -d -p 3306:3306 -t amedama/centos:mysql 64a36059d1055d6f1ab630e45de37f93f494e4b68fd3c6458e56a5e8b6c23a17
コンテナに接続するために MySQL クライアントをインストールする。
$ sudo yum -y install mysql
インストールできたら mysql コマンドで localhost に接続する。 実際にアクセスしている先は Docker コンテナということになる。
$ mysql -u root -h 127.0.0.1 Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.1.73 Source distribution Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | +--------------------+ 1 row in set (0.00 sec) MySQL [(none)]> Bye
ばっちり。
まとめ
今回は CentOS7 を使って Docker を一通り使ってみた。 CentOS6 の頃は追加のリポジトリを必要としていた Docker も 7 では標準でサポートされている。 ちなみに、Docker の RHEL/CentOS6 サポートは既に打ち切られているので、Docker ホストに RHEL/CentOS を使う場合は必ず 7 を使うようにしよう。
スマートPythonプログラミング: Pythonのより良い書き方を学ぶ
- 作者: もみじあめ
- 発売日: 2016/03/12
- メディア: Kindle版
- この商品を含むブログを見る