第7回 Dockerに触れ、マルチOSを体験してみよう(後編):古賀政純の「攻めのITのためのDocker塾」(2/3 ページ)
“攻めのIT”を考える情シスリーダーが今後知っておくべき注目の技術「Docker」を基本から応用まで解説します。今回のテーマは「Webサーバ入りDockerイメージの再利用」です
コンテナにログインしなくても、ホストOSからDockerコンテナ上のコマンドを実行できる
Dockerコンテナ環境では、ホストOSから直接Dockerコンテナ上のコマンドを確認できます。例えば、先ほどのWebサーバ入りのDockerコンテナ「c0001」のIPアドレスを知るには、Dockerコンテナのコマンドプロンプトでipコマンドを入力する以外にホストOSからも実行できます。
これを実現するには「docker exec」に稼働中のコンテナ名を指定し、コンテナで実行したいコマンドを付与します。以下に稼働中のDockerコンテナ「c0001」で、ip aコマンドを実行した例を示します。
# docker exec -i -t c0001 ip a |grep inet inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host inet 172.17.0.1/16 scope global eth0 inet6 fe80::42:acff:fe11:1/64 scope link
Webサーバ入りDockerイメージは、みんなで再利用
WebサーバとWebコンテンツ“test.html”入りのDockerコンテナ「c0001」は、Dockerイメージとして保存できます。Dockerイメージとして保管しておけば、他の開発者や運用担当者がDockerイメージを再利用し、カスタマイズすることができます。
Dockerコンテナ「c0001」を使って、新しいDockerイメージ(今回は「c66apache0001」という名前のDockerイメージにします)を作ってみます。既存のDockerコンテナからDockerイメージを作成するには、ホストOS上で「docker commit」コマンドにイメージ化したいコンテナ名(c0001)とDockerイメージ名を指定します。
# docker commit c0001 c66apache0001
これで、Dockerイメージ「c66apache0001」が作成されました。Dockerイメージを確認してみます。
# docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE c66apache0001 latest 594aac610bd8 2 minutes ago 443.3 MB
では、このDockerイメージ「c66apache0001」から、Dockerコンテナ「c0003」を起動してみましょう。c66apache0001は、Apache WebサーバもWebコンテンツ“test.html”も入っているイメージです。Dockerコンテナ「c0003」でも、すぐにWebサーバとして稼働し、クライアントにWebコンテンツを提供できるはずです。
# docker run -i -t --name c0003 --hostname c0003 c66apache0001 /bin/bash [root@c0003 /]# ip a |grep inet inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host inet 172.17.0.7/16 scope global eth0 inet6 fe80::42:acff:fe11:5/64 scope link [root@c0003 /]# service httpd restart
起動したDockerコンテナ「c0003」のIPアドレスは、172.17.0.7です。では、クライアントとなるホストOSから、Dockerコンテナc0003が提供するWebコンテンツ“test.html”が見えるかを確認してみます。
# curl http://172.17.0.7/test.html Hello Docker.
ここで、少し疑問に感じた方はいるかもしれません。
コンテナ「c0003」を起動後、コンテナ上でserviceコマンドを実行することでWebサービス(httpdデーモン)を再起動しています。では、Dockerコンテナ「c0003」を起動後、Webサービスのhttpdデーモンも自動的に起動できないのでしょうか。
コンテナでない環境の普通のOS環境では、通常、CentOS 6.xならば「chkconfig」コマンドを使って、OS起動時にデーモンなどのサービスを自動的に起動させる設定が行えます。CentOS 7.xならば、「systemctl」コマンドでサービスの自動起動が可能です。しかし、Dockerコンテナ環境でchkconfigやsystemctlコマンドを使用してサービス(デーモン)を自動的に起動するには、少し工夫が必要になります。
CentOS 6.xにおけるchkconfigは、OS起動時のinitスクリプトと呼ばれるスクリプト群の実行が深く関係しています。しかしDocker環境では、「docker run」実行時に/bin/bashを指定して実行した場合、DockerコンテナのOS起動時のinitスクリプトの実行をスキップします。このため、Dockerコンテナ内であらかじめchkconfigコマンドによるサービスの自動起動を設定し、Dockerイメージを作成しても、次回のコンテナ起動時に/sbin/initを指定しなければサービスの自動起動が行われません。
CentOS 6.xにおけるchkconfigや、CentOS 7.xにおけるsystemctlを使ってOS起動時のサービスの自動起動をDockerコンテナ上で実現するためには、Dockerコンテナの起動の際に、以下のように/sbin/initを指定する必要があります。
# docker run -i -t -d --name c0003 --hostname host0003 c66apache0001 /sbin/init
このほかに、Docker起動時に/sbin/initを指定せず、サービスを自動的に起動するスクリプトを組み込む場合もあります。Dockerの初心者にとって、このサービスの起動方法は少し複雑に思えるかもしれませんが、Dockerコンテナにおけるサービスの自動起動は通常のOSにおける起動プロセスとは異なる場合があることを正しく理解しておく必要があります。ここでは、厳密な仕組みは省きますが、まずは最低限、以下のポイントを理解してください。
Dockerコンテナ起動時に自動的にサービスを起動させるため際のポイント
- Dockerコンテナ起動時に、/sbin/initを指定しない場合、OSが持つinitスクリプトなどによるサービスの自動起動の処理は行われない
- Dockerコンテナ上でchkconfigやsystemctlを使ったサービスの自動起動を行うには、コンテナ起動時に/sbin/initを指定する
- /sbin/initを使用せずに、コンテナ起動時にサービスを自動起動させるには、サービスを起動させるスクリプトなどを組み込む工夫が必要である
ちなみに、起動させたいDockerコンテナがCentOS 7.xのようなsystemdが採用されているLinux OSで、systemdによるサービスの起動をDockerコンテナで実現するには、docker runによるコンテナ起動時に、/sbin/initの指定のほかに管理者権限モードのオプション(--privileged、または、--cap-add=SYS_ADMIN)が必要になります。しかし、管理者権限モードで実行されたDockerコンテナは、ホストOSのハードウェア資源(デバイスなど)へのアクセスが無制限に許可されるため、セキュリティ面において注意すべきです。Dockerの本番環境では、Dockerコンテナに対して、必要最低限の権限のみを付与するような運用をできるだけ心掛けて下さい。
関連記事
- 【古賀政純の「攻めのITのためのDocker塾」】バックナンバー
- 第2回 chroot/Dockerを手元のWindowsで手軽に試す方法
なぜ企業がDockerに着目するのか、今後の“攻めのIT”に必要と言われているのか。今回はこれをふまえ、簡単にざっくりと体験学習してみませんか。今回は準備編として、CentOS 7.xをお手元のWindows PCで手軽に試す方法を簡単に紹介します。 - ゲームもレースもビッグデータ分析で上手くなる!?
企業の“ビッグデータ活用”への期待度は高い。しかし、現実には「ビッグデータは持っているが活用はできていない」という企業がほとんどだろう。ここでは、思いがけない方法でビッグデータ分析を活用している事例などを紹介する。 - クラウドエバンジェリスト4者対談:「エンタープライズクラウド」は、どこへ向かうのか?
エンタープライズ領域におけるクラウド利用がいよいよ本格的に普及段階に入った。その理由と背景は何か。自社は、導入をどう考えればよいか。主要ベンダーのクラウド関連エバンジェリストに、現状とその未来を分析してもらった。
Copyright © ITmedia, Inc. All Rights Reserved.