3
2

More than 3 years have passed since last update.

docker-composeのコンテナ稼働状態をホストとコンテナ間で共有する

Last updated at Posted at 2020-05-01

はじめに

 dockerコンテナ内からコンテナを制御する方法の1つにDooD(Docker outside of Docker)がありますが、コンテナを制御するときにホストとコンテナ両方ともにdocker-composeを使用できるか検証してみました。
 検証では、CentOS 7.6にdocker-ce(19.03)とdocker-compose(1.25.2)をインストールして検証しました。構成としては、下のような構成で、Ubuntuからアクセスして設定しています。

test-environment.png

準備

 CentOS 7.6 のminimalインストールの状態からdockerとdocker-composeをインストールし、ついでにdoodコンテナイメージを自作します。

dockerのインストール

参考:http://docs.docker.jp/engine/installation/linux/docker-ce/centos.html

  • CentOS 7のバージョンを7.6の固定してupdateする。
  • yum-utils、device-mapper-persistent-data、lvm2をインストールする。
  • docker-ceをインストールする。
# echo 7.6.1810 > /etc/yum/vars/releasever
# sed -i".org" -e "s/^mirror/#mirror/" -e "s/^#baseurl/baseurl/g" -e "s/mirror.centos/vault.centos/g" /etc/yum.repos.d/CentOS-Base.repo
# yum update
# yum install -y yum-utils device-mapper-persistent-data lvm2
# yum install docker-ce-19.03.8-3.el7
# yum clean all

dockerdの設定変更

*この設定は半分くらい趣味です。dockerのimageやvolume情報等は、デフォルトでは/var/lib/docker以下に格納されますが、そのディレクトリを/home/docker/system以下に変更します。

  • docker.serviceが起動している場合は、停止させる。
  • /usr/lib/systemd/system/docker.service をviで以下のように修正する。
  • /var/lib/docker/以下のファイルをすべて削除する。
  • daemon reload後、docker.serviceを再起動する。
# systemctl stop docker
# mkdir /home/docker; mkdir /home/docker/system; mkdir /home/docker/container
# vi /usr/lib/systemd/system/docker.service
--------------------------------------------------------------------------------
(修正前)
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

(修正後)
ExecStart=/usr/bin/dockerd -g /home/docker/system --storage-driver overlay2 -H fd:// --containerd=/run/containerd/containerd.sock
--------------------------------------------------------------------------------
# rm -rf /var/lib/docker/
# systemctl daemon-reload
# systemctl restart docker

docker起動確認

 公式のhttpdイメージを使って動作確認します。

  • docker hubからhttpdコンテナイメージをpullする。
  • port 58080をfirewallの許可ポートに設定する。(port 58080からアクセスさせるため)
  • httpdコンテナをport 58080 -> 80に転送するようにオプションを設定して起動する。
  • Ubuntuのブラウザからhttp://192.168.1.10:58080にアクセスし、「It works!」が表示されることを確認する。
# docker image pull httpd
# firewall-cmd --add-port=58080/tcp --zone=public --permanent
# docker container run -d --rm --name web -p 58080:80 httpd:latest
(動作確認後)
# docker container stop web

docker-composeのインストール

 githubのdocker-composeプロジェクトのreleaseからdocker-composeを取得する。(下のコマンドはreleaseの手順より)

# curl -L https://github.com/docker/compose/releases/download/v1.25.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose

DooDコンテナイメージ作成

 DooDを実施するだけならば、dockerhub公式のdockerイメージを活用すると良いです。今回はDooDコンテナ内に入ってデバッグ等することを考慮して、準備作業で作ったCentOS7.6をまるごとコンテナ化してDooDコンテナイメージを作成します。

  • /root/workspace/container_base を作成し、この中に/ 以下の必要なディレクトリをコピーしたり、空ディレクトリを作成したりする。
  • docker image importを使用して、centos7-dood:0.0としてローカルリポジトリに登録する。
# mkdir /root/workspace/container_base
# cd /root/workspace/container_base
# cp -r /etc /run /srv /usr /var .
# mkdir boot dev home media opt proc root sys tmp 
# chmod 777 tmp
# ln -s usr/bin; ln -s usr/sbin; ln -s usr/lib; ln -s usr/lib64
# cd /root/workspace/container_base/root;cp /root/.* .
# cd /root/workspace/container_base/home;cp -r /home/guest .; chown -R guest:guest guest; chmod 755 guest
# cd /root/workspace/container_base; tar cvf centos7-dood.tar *
# cat centos7-dood.tar | docker import - centos7-dood:0.0

確認

 現時点で、centos7.6にはhttpdイメージとcentos7-doodイメージがローカルリポジトリ登録されたことになります。
(centos7-doodコンテナは自作なのでサイズがデカイです。多言語の言語ファイルやfirmware等のゴミを削除すればもう少し小さくなります。)

# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos7-dood        0.0                 e5fb14d9d88a        XX hours ago        1.48GB
httpd               latest              b2c2ab6dcf2e        YY hours ago         166MB

検証

docker-compose.ymlの構成

 /home/docker/container以下にdocker-compose.ymlを作成し、以下のようにdirectorサービスとwebサービスを定義します。directorがDooDを実施するコンテナであり、コンテナ内でwebサービスの起動を実施します。DooDをするため、ホストのdocker.sockをコンテナ内にマウントします。

# docker-compose.yml

version: '3'
services:
  director:
    image: centos7-dood:0.0
    privileged: true
    tty: true
    stdin_open: true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /home/docker/container/docker-compose.yml:/home/docker/container/docker-compose.yml:ro
    command: /bin/bash

  web:
    image: httpd:latest
    ports:
      - "58080:80"

ホスト側での動作確認

docker-compose up -dで実行し、コンテナが起動することを確認します。また、httpdが立ち上がったことを確認するため、Ubuntuのブラウザからhttp://192.168.1.10:58080にアクセスし、「It works!」が表示されることを確認します。

# cd /home/docker/container/
# docker-compose up -d
Creating network "container_default" with the default driver
Creating container_web_1      ... done
Creating container_director_1 ... done
(動作確認後)
# docker-compose down

 止める前に、docker inspectにてcontainer_director_1の中身を確認してみます。

# docker container inspect container_director_1
                    (中略)
        "Labels": {
                "com.docker.compose.config-hash": "a93046・・・・・・"
                    (後略)

 docker-composeのソースコードを確認していないのでこれは推測となりますが、このconfig-hash生成の一部にdocker-compose.ymlのパス情報が含まれます。(そのため、-fオプションでymlファイルを指定して、yumファイルごとにcompose制御できます。)
 そのため、ホストとコンテナでdocker-composeの情報を共有するならば、ホストと同じディレクトリにホストと同じdocker-compose.ymlを配置すればいい、とわかります。上記のdocker-compose.ymlで/home/docker/container/docker-compose.yml:/home/docker/container/docker-compose.yml:roとしているのは、そのためです。

*2020/5/3(日) 一部訂正:ホストとコンテナで同じディレクトリにdocker-compose.ymlを配置する必要はなかったです。
 追調査したところ、docker-compose.ymlが格納されるディレクトリ名称が同じならば大丈夫でした。例えば、
「/home/docker/container/docker-compose.yml:/home/container/docker-compose.yml:ro」
とcontainerが揃っていればOKです。

DooDの実施

 ホストにてdirectorサービスを立ち上げた後、directorコンテナ内に入り、docker-composeでwebサービスを立ち上げます。確認は上記と同様にUbuntuのブラウザからhttp://192.168.1.10:58080にアクセスし、「It works!」が表示されることを確認します。
(区別がつくように、@centos1 と表示されているときはホスト、@a8784c960fe6 と表示されているときはコンテナの操作となります。)

[root@centos1 ~]# cd /home/docker/container/

[root@centos1 container]# docker-compose up -d director
Creating network "container_default" with the default driver
Creating container_director_1 ... done

[root@centos1 container]# docker-compose ps
        Name            Command    State   Ports
------------------------------------------------
container_director_1   /bin/bash   Up           

[root@centos1 container]# docker-compose exec director /bin/bash

[root@a8784c960fe6 /]# docker-compose -f /home/docker/container/docker-compose.yml ps
        Name            Command    State   Ports
------------------------------------------------
container_director_1   /bin/bash   Up           

[root@a8784c960fe6 /]# docker-compose -f /home/docker/container/docker-compose.yml up -d web
Creating container_web_1 ... done

[root@a8784c960fe6 /]# docker-compose -f /home/docker/container/docker-compose.yml ps
        Name               Command        State           Ports        
-----------------------------------------------------------------------
container_director_1   /bin/bash          Up                           
container_web_1        httpd-foreground   Up      0.0.0.0:58080->80/tcp

まとめ

 DooDするときに、docker-composeの情報をホストとコンテナで共有できます。これ単独では旨味が少ないですが、Docker Remote APIと組み合わせて、外部サーバからDooDコンテナにコンテナ起動指示を出すことで、複数コンテナの同時制御ができるようになります。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2