dockerのlink機能は何かをリンクしているわけではない

docker runの–link機能は、コンテナ間の「通信を可能にする」機能ではないです。

–linkオプションなしでも実は通信できる。

同一ホスト内のコンテナ同士は、そもそもデフォルトで相互に通信ができます。これを実験で確かめてみましょう。

ターミナルを2つ開いて、それぞれコンテナをひとつづつ起動して中に入ります。

コンテナ1

docker run --rm -it --name tmp1 -p 1001:80 centos:7 bash

コンテナ2

docker run --rm -it --name tmp2 -p 1002:80 centos:7 bash

次に、それぞれのコンテナのIP Addressを調べます。

コンテナ1

[root@f6647a5af8e2 /]# hostname -i
172.17.0.5

コンテナ2

[root@d2016160a460 /]# hostname -i
172.17.0.6

ではお互いに ping を打ってみましょう。

コンテナ1からコンテナ2へping

[root@f6647a5af8e2 /]# ping 172.17.0.6
PING 172.17.0.6 (172.17.0.6) 56(84) bytes of data.
64 bytes from 172.17.0.6: icmp_seq=1 ttl=64 time=0.129 ms
64 bytes from 172.17.0.6: icmp_seq=2 ttl=64 time=0.163 ms

ご覧のようにpingが返ってきています。 逆向きに、コンテナ2からコンテナ1へのpingしても同様です。

つまり IP層では通信ができていることがわかります。

–linkなしでhttp通信できるか実験

つぎに、TCPレイヤで通信できるか見てみましょう。

コンテナ1で httpdサーバを起動します。 (awkワンライナー)

[root@f6647a5af8e2 /]# awk 'BEGIN {port="80";s="/inet/tcp/" port "/0/0";RS=ORS="\r\n";for(;;){if((s |& getline) > 0){printf "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\nHello, World\n" |& s;}close(s);}}'

コンテナ2からcurlでアクセスしてみます。

[root@d2016160a460 /]# curl http://172.17.0.5/
Hello, World

見事にレスポンスが返ってきました。

これで、docker run の–linkオプションなしでもコンテナ間通信ができることがわかりました。

じゃあ–linkの役割はなんなの?

ひとことで言うと「環境変数と/etc/hostsに値を注入する」ことです。

上記の手順をよく見返すと、まず各コンテナのIPアドレスを調べてから通信をしました。 いちいちIPアドレスを調べてからアプリケーショ内に記述していたら面倒なので、–linkによって通信相手のIPアドレスを変数として注入することで、コンテナ間通信が「楽」になります。

ちなみにここまで書いといてなんですが、この –link機能は今では Legacy container links と呼ばれていて、将来廃止予定のようです。

https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/

The –link flag is a deprecated legacy feature of Docker.

まあなので –linkのことはもう忘れましょう。

参考

下記記事の図がわかりやすかったです。

Docker の基本学習 ~ コンテナ間のリンク

カテゴリ: