Dockerコンテナ間通信

Docker を使ったサービスでは、サービスを構成する各サーバプログラムをそれぞれ別のコンテナで立ち上げるのが一般的なようだ。例えばデータベース(MySQLなど)を利用する web アプリケーションであれば、つぎの3つのコンテナを立ち上げることになる:

  • データベースサーバ
  • web アプリケーションサーバ
  • HTTP サーバ

当然、これらを連携するにはコンテナ間をまたいだ通信をする必要がある。Docker にはコンテナ間通信を実現するネットワーク機能が備わっていて、各コンテナは同じ(Docker の)ネットワークに接続していれば、コンテナ名とポート番号を使って通信することができる。

今日はそのコンテナ間通信を試してみる。

題材と構成

先日作った書籍管理 web アプリと、HTTP サーバとして Nginx を前に立てる構成とする。上にはデータベースサーバが書いてあるけど、この書籍管理アプリはデータベースに Sqlite を使っているので、今回データベースサーバはなし。アプリケーションサーバと HTTP サーバ(Nginx)の2つだ。

コンテナ名は、アプリケーションサーバを bruschetta-back、HTTP サーバを nginx-c とする。この2つが Docker ネットワークで通信するわけだ。nginx-c は80番ポートをホスト側の8080ポートに接続する。ホスト側からは bruschetta-d というホスト名で nginx-c にアクセスできるようにしておく。

アプリケーションサーバ

先日作ったものなので詳細は省略。ただ、あいだに PC のリプレイスをはさんだので、イメージ名が bruschetta:1 に変わっている。内容は変更なし。

HTTPサーバ

全面に立てる HTTP サーバには、Docker Hub で公開されている Nginx こイメージをメースにして、アプリケーションサーバにつなぐための設定ファイルをコピーしたものを用意する。

Dockerfile はこう:

ROM nginx:1.17.10

COPY ./files/bruschetta-d /etc/nginx/conf.d/bruschetta-d.conf
RUN mkdir /var/log/nginx/bruschetta

CMD [ "nginx", "-g", "daemon off;" ]

この中でコピーしている Nginx の仮想ホストの設定ファイルはこうだ:

upstream uwsgi-bruschetta {
    server bruschetta-back:5000;
}

server {
    # port
    listen      80;

    # server name
    server_name bruschetta-d;

    # log files
    access_log /var/log/nginx/bruschetta/access.log combined;
    error_log  /var/log/nginx/bruschetta/error.log  warn;

    keepalive_timeout     60;
    proxy_connect_timeout 60;
    proxy_read_timeout    60;
    proxy_send_timeout    60;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_pass http://uwsgi-bruschetta;
    }

}

これで docker build した。

できたイメージの状況。

akatoh@apostrophe:docker$ docker image ls
REPOSITORY          TAG                IMAGE ID            CREATED              SIZE
nginx-c             1                  6f5be529ea6d        About a minute ago   127MB
bruschetta          1                  11afb91367ae        2 hours ago          451MB
nginx               1.17.10            9beeba249f3e        8 hours ago          127MB
ubuntu              20.04              1d622ef86b13        3 weeks ago          73.9MB

Docker ネットワークの作成

Docker ネットワークの作成は docker network create コマンドを利用する。

takatoh@apostrophe:docker$ docker network create nginx-network

これで nginx-network という名前の Docker ネットワークができた。つぎのようにすると様子が見える。

takatoh@apostrophe:docker$ docker network ls
NETWORK ID           NAME               DRIVER              SCOPE
d0c23099f6be         bridge             bridge              local
492e64e5d79d         host               host                local
7f38bac647a0         nginx-network      bridge              local
b42cbd843632         none               null                local

nginx-network 当名前が見える。ほかにもあるけど、これらはデフォルトで用意されているものらしい。詳細は調べてない。

コンテナの起動

2つのコンテナを起動する。その際、--netowork オプションで接続する Docker ネットワークの名前(今回は nginx-network)を指定する。また、HTTP サーバのコンテナの方でアプリケーションサーバの名前を bruschetta-back と指定しているので、これを間違えないようにする。

まずはアプリケーションサーバのコンテナから。

takatoh@apostrophe:docker$ docker run --name bruschetta-back --network nginx-network -d bruschetta:1

HTTP サーバ。ポートの指定も忘れずに。

akatoh@apostrophe:docker$ docker run --name nginx-front --network nginx-network -p 8080:80 -d nginx-c:1

ホスト側から確認

起動したコンテナは bruschetta-d というホスト名で待ち受けているので、/etc/hosts ファイルに 127.0.0.1 を指すように記述を追加する。それができたら準備は完了だ。http://bruschetta-d:8080/ にブラウザでアクセスしてみる。

結果、期待通りにアプリケーションにアクセス、使用できることが確認できた。

参考ページ