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サーバと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コンテナがCentOS 7.xのようなsystemdが採用されているLinux OSで、systemdによるサービスの起動をDockerコンテナで実現するには、docker runによるコンテナ起動時に、/sbin/initの指定のほかに管理者権限モードのオプション(--privileged、または、--cap-add=SYS_ADMIN)が必要になります。しかし、管理者権限モードで実行されたDockerコンテナは、ホストOSのハードウェア資源(デバイスなど)へのアクセスが無制限に許可されるため、セキュリティ面において注意すべきです。Dockerの本番環境では、Dockerコンテナに対して、必要最低限の権限のみを付与するような運用をできるだけ心掛けて下さい。
Copyright © ITmedia, Inc. All Rights Reserved.