【Docker入門#05】Dockerの世界を覗いてみる【ネットワークとボリューム】

Docker入門05 tech

こんにちは、Mashです。

本業でDockerを触る機会がありまして、自分の知識整理のためと、せっかくならということで初学者さんに向けて記事を作成しています。

今回はDocker入門第5回です。

前回記事で、Docker Composeを利用して複数コンテナで構成されるシステム(WordPress)を立ち上げることができました。

今回は docker-compose.yml ファイルの中身についてじっくり見ていきたいと思います。

座学中心になりますが、Dockerをより深く理解するための情報を盛り込みましたので、じっくり読み込んでいただけるとうれしいです。

今回のゴール
  • docker-compose.ymlで最低限必要なパラメータを知る
  • Dockerの内部構造を理解して、頭の中でイメージできるようになる

※本シリーズはDocker初心者向けではありますが、前提として多少のLinux知識が必要となります。ご了承ください。

それではいきましょう!

前回のおさらい

まずは前回使用したdocker-compose.ymlファイルを再掲します。

いまからこのYAMLファイルの内容を読み解いていきます。

version: '3'

networks:
  default:
    external:
      name: bridge
  mash-network:
    driver: bridge

volumes:
    db_data:

services:
   db:
     image: mysql
     container_name: db
     hostname: db
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: root_password
       MYSQL_DATABASE: wordpress
       MYSQL_USER: mash
       MYSQL_PASSWORD: mash_password
     networks:
       - mash-network

   wordpress:
     depends_on:
       - db
     image: wordpress
     container_name: wordpress
     hostname: wordpress
     ports:
       - 80:80
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: mash
       WORDPRESS_DB_PASSWORD: mash_password
     networks:
       - mash-network

   phpmyadmin:
     depends_on:
       - db
     image: phpmyadmin
     container_name: phpmyadmin
     hostname: phpmyadmin
     ports:
       - 8080:80
     restart: always
     networks:
       - mash-network

そしてこの定義をもとに $ docker-compose up して立ち上がる環境がこちらになります。

以下、文章での説明がつづきます。わからなくなったらこのイメージ図に戻ってきてください。

docker-compose

今回docker-compseファイルの中身について確認していきますが、お伝えしたい内容はおおきく2つです。

  • Dockerのネットワーク
  • Dockerのデータボリューム

docker-composeファイルを解析

ひとつずつ追いかけていきましょう。

version

docker-composeのこの部分です。

version: '3'

文字どおり、docker-composeファイルのバージョンを指定しています。公式リファレンスはこちら

もちろん新しいバージョンになるほど機能が拡充しているわけですが、ホストに導入するDockerエンジンのバージョンによってサポートされない場合があるのでご注意ください。

ひとまず本日時点(2020年11月23日)ではバージョン3系を選択しておけば問題ありません

networks

docker-composeのこの部分です。

networks:
  default:
    external:
      name: bridge
  mash-network:
    driver: bridge

重要ポイント1つ目です。

networksセクションでは、Docker内で使用するネットワークを定義します。公式リファレンスはこちら

これまであまり触れませんでしたが、Dockerを導入したホストの内部にはホストに割り当てられたIPアドレスとは別にDockerが利用する独自のネットワークが出来あがっています

そして起動したコンテナたちはこの内部ネットワーク内でIPアドレスが割り当てられています

docker-compose.ymlのnetworksセクションでは、Docker Composeで構築するコンテナ環境用のネットワークを定義することができます。

ホストOS上でIPアドレス一覧を取得するコマンドを実行してみましょう。(私の環境はUbuntu 20.04です)

みなさんの環境でも試してみてください。

$ ip a
(中略)
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:5a:b1:0b brd ff:ff:ff:ff:ff:ff
    inet 10.10.1.1/24 brd 10.10.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::215:5dff:fe5a:b10b/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:b1:11:0c:83 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
4: br-b818ceb630f4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ef:59:b2:49 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.1/16 brd 172.19.255.255 scope global br-b818ceb630f4
       valid_lft forever preferred_lft forever
    inet6 fe80::42:efff:fe59:b249/64 scope link
       valid_lft forever preferred_lft forever
(以下略)

「eth0」がDockerホストに割り当てられている実IPアドレスです。

そして分かりづらいのですが、「br-b818ceb630f4」がdocker-compose.ymlファイルで定義した mash-network」 というDockerネットワークの入り口になります。

割り当てられているIPアドレスが「172.19.0.1」であることがわかりますね。

ちなみに docker0 は、Dockerエンジンをインストールすると必ず作成されるデフォルトのDockerネットワークです。

今回はあえて mash-network を作成しましたが、特になにも指定しない場合はこのdocker0ネットワークにコンテナが所属していくことになります。

docker network コマンド

Dockerネットワークを確認してみましょう。下記コマンドを実行してください。

$ docker network ls
NETWORK ID          NAME                                DRIVER              SCOPE
c42fba611ebf        bridge                              bridge              local
b818ceb630f4        dockercompose-test01_mash-network   bridge              local

ひとつめの bridge がデフォルトネットワーク。OS側で docker0 として見えてたやつね。

で、ふたつめがNAMEをみていただくとわかるとおり今回利用するmash-networkとなります。

実はさきほど $ ip a コマンドで表示されたネットワークデバイスとNETWORK IDが一致しています。少し戻って確認してみてください。

つづいて、mash-networkの詳細を確認するコマンドです。

最後の引数はネットワーク名かIDを指定します。(今回はネットワーク名を指定して実行)

$ docker network inspect dockercompose-test01_mash-network

実行結果が長いため省略しますが、このDockerネットワークの名称やIPアドレス帯、所属しているコンテナなどの情報がバッチリ取得できます。みなさんの環境でも確認してみてください。

コンテナ同士が通信できていないような事象が発生した際には、もしかすると各コンテナが別々のネットワークに所属している とかあるかもしれません。

volumes

docker-compsoseのこの部分です。

volumes:
    db_data:

重要ポイント2つ目です。

volumesセクションでは、Dockerコンテナで使用するデータ領域を定義します。公式リファレンスはこちら

Dockerボリュームもはじめて登場したので少し前段のお話から。

コンテナは基本的に使い捨てです。起動して使い終わったらコンテナは停止、そして破棄します。

コンテナに障害が発生した場合も、コンテナ復旧するために頑張るのではなく、使い捨てて新しいコンテナを起動するという運用をします。

このような考え方のことを「エフェメラル(一時的)」といい、Docker公式マニュアルにもベストプラクティスとして明記されています。

さて、ここで問題になることが一つあります。

それはデータベースのように情報を永続化しておく必要があるデータ保存はどうするの? です。

今回、Docker Compseの題材としてWordPressを取り上げています。

WordPressではブログ記事などを更新するとすべての情報がMySQLデータベースに蓄積していくわけですが、前述の通りコンテナに障害が発生したときには対象のコンテナを再起動して対処します。

何も手当をしていないとWordPressのデータはMySQLコンテナの中に保存されるため、コンテナを破棄するとデータ自体も消えてしまいます

だれでもわかりますが、それはいかんですよね。

そこで登場するのが Dockerボリューム という考え方です。

ボリュームとは結論からお伝えすると、消えたら困るデータをDockerホスト側に保存しておく仕組みです。

コンテナが破棄され、新しいコンテナが起動してきても、MySQLのデータはDockerホスト側に残っています。

そのため、データが消失することなくMySQLコンテナが復活できるようになります。

今回使ったdocker-composeファイルでは、「db_data」というボリューム領域を作成しています。

docker volume コマンド

さて、ネットワークと同様にボリュームも確認してみましょう。

$ docker volume ls
DRIVER              VOLUME NAME
local               4ed21e47499fbb17c5cf1e623875c13bebd916b3d992145749dd8a5a89117479
local               5f8d0656e11f7bd82e2e1ff36f0027daa0a628759743046474f2e3763299cc14
local               d8b4815e82a52ac747a5a45a058d186b672dc282d4c7d79e76dc781a47fe4923
local               dockercompose-test01_db_data

いろいろ作成されているようですが、4つめが今回作成した「db_data」ボリュームですね。

db_dataボリュームの詳細を確認してみましょう。

$ docker volume inspect dockercompose-test01_db_data

実際のコマンド結果は省略しますが、ここで確認しておきたいのは「db_data」というボリュームはDockerホストの「/var/lib/docker/volumes/dockercompose-test01_db_data/_data」に紐付いているという点です。

このPATHが、コンテナから見えるようになっていてデータを保存できるようになっている というわけですねー。

後ほど触れますが、今回のdocker-composeではMySQLコンテナでdb_data領域を使用しています。

services

docker-composeのこの部分です。

services:
   db:
     image: mysql
     container_name: db
     hostname: db
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: root_password
       MYSQL_DATABASE: wordpress
       MYSQL_USER: mash
       MYSQL_PASSWORD: mash_password
     networks:
       - mash-network

   wordpress:
     depends_on:
       - db
     image: wordpress
     container_name: wordpress
     hostname: wordpress
     ports:
       - 80:80
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: mash
       WORDPRESS_DB_PASSWORD: mash_password
     networks:
       - mash-network

   phpmyadmin:
     depends_on:
       - db
     image: phpmyadmin
     container_name: phpmyadmin
     hostname: phpmyadmin
     ports:
       - 8080:80
     restart: always
     networks:
       - mash-network

servicesセクションでは、起動するコンテナに関するパラメータを定義します。公式リファレンスはこちら

今回は「MySQL」、「WordPress(Apache)」、「phpMyAdmin」の3コンテナについて定義しています。

ひとまずMySQLを例にみていきましょう。すべてコメントをいれていきます。

# まずはじめにサービス名を定義
db:

 # コンテナのもととなるイメージ名を定義
 # image の代わりに build として、Dockerfileからコンテナ立ち上げることも可能
  image: mysql

 # コンテナ名を定義
  container_name: db

 # コンテナのホスト名を定義
  hostname: db

 # 先程登場したボリュームを使用する宣言
 # ホスト側のdb_data領域が、コンテナの/var/lib/mysql(MySQLのデータ領域)とイコールになっている
  volumes:
    - db_data:/var/lib/mysql

 # コンテナが終了したら再度起動するよう定義
  restart: always

 # 環境変数を定義
 # MySQLコンテナの場合は、データベースのユーザ名やパスワードを指定する必要あり
 # 定義が必要な環境変数は使用するイメージ毎に異なるため、公式ドキュメント要参照
  environment:
    MYSQL_ROOT_PASSWORD: root_password
    MYSQL_DATABASE: wordpress
    MYSQL_USER: mash
    MYSQL_PASSWORD: mash_password

 # 所属するネットワークを定義。新規作成したmash-networkに所属するよう指定
  networks:
    - mash-network

servicesで指定できるパラメータはほかにもたくさんありますので、ぜひさきほど貼り付けた公式リファレンスを一度ごらんいただければと思います。

このようにservices定義をどんどん追記していって、起動するコンテナを管理していくわけです。

docker container コマンド

コンテナの起動状況を確認してみましょう。

$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
99fbe830e4ad        phpmyadmin          "/docker-entrypoint.…"   3 days ago          Up 28 hours         0.0.0.0:8080->80/tcp   phpmyadmin
e61d634bb206        wordpress           "docker-entrypoint.s…"   3 days ago          Up 28 hours         0.0.0.0:80->80/tcp     wordpress
466f72f6ba6d        mysql               "docker-entrypoint.s…"   3 days ago          Up 28 hours         3306/tcp, 33060/tcp    db

※これまで私の記事では $ docker ps コマンドを使用していましたが少し古いコマンドでした。失礼しました。

このように起動中のコンテナ一覧を取得できます。

そして、例えばdbコンテナの詳細を確認したいときはこちらのコマンド。

$ docker container inspect db

コンテナの状況や設定一覧がガバっと取得できます。

まとめ

少々端折った部分もありますが、docker-compose.ymlの「version」、「networks」、「volumes」、「services」それぞれのセクションで定義されている内容を確認しました。

今回使用したdocker-compose.ymlで立ち上がるDocker環境のイメージ図を再掲します。本記事を読み前と比べて、伝えたい内容が少しでも理解いただけるようになっていればうれしいです。

docker-compose

Docker Composeまで学習すれば、あとはみなさんご自身でコンテナ化したい環境をイメージしてもらって実践あるのみです。

ぜひDockerコンテナの世界に一歩足を踏み入れてチャレンジしていただければと思います。

それではいったんDocker入門シリーズは終了です。

追加で○○のことが知りたい!

とか

✕✕のような動きを実現したいんだけど教えて!

などなどあれば対応しますので、お気軽にコメント/メッセージください。

それじゃあまたね。

(Kubernetes入門シリーズを検討中です。。。おたのしみに。。。)

タイトルとURLをコピーしました