1. 程式人生 > 其它 >Docker 與 K8S學習筆記(九)—— 容器間通訊

Docker 與 K8S學習筆記(九)—— 容器間通訊

容器之間可通過IP、Docker DNS Server或joined三種方式進行通訊,今天我們來詳細學習一下。

一、IP通訊

IP通訊很簡單,前一篇中已經有所涉及了,只要容器使用相同網路,那麼就可以使用IP進行訪問,本節不做贅述。

二、Docker DNS Server

使用IP通訊存在一個最大的問題就是容器的IP地址一般是隨機的不固定的,所以導致這種方式不夠靈活,對於這個問題,可以通過Docker自帶的DNS伺服器解決。這種方式使用也很簡單,即啟動容器時通過--name引數即可指定其域名。我們使用前面建立的test_net1,啟動兩個nginx容器:

sudo docker run -d --network=test_net1 --name=ng1nginx

sudo docker run -d --network=test_net1 --name=ng2 nginx

接著我們進入ng1,然後嘗試ping一下ng2:

# ping ng2
PING ng2 (172.18.0.3) 56(84) bytes of data.
64 bytes from ng2.test_net1 (172.18.0.3): icmp_seq=1 ttl=64 time=0.094 ms
64 bytes from ng2.test_net1 (172.18.0.3): icmp_seq=2 ttl=64 time=0.101 ms
64 bytes from ng2.test_net1 (172.18
.0.3): icmp_seq=3 ttl=64 time=0.097 ms 64 bytes from ng2.test_net1 (172.18.0.3): icmp_seq=4 ttl=64 time=0.086 ms ^C --- ng2 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 59ms rtt min/avg/max/mdev = 0.086/0.094/0.101/0.011 ms

PS:預設Nginx容器裡面沒有ping命令,需要手動安裝一下:

apt-get update
apt-get install iputils-ping

這裡要注意,使用Docker DNS有個限制:只能在使用者自定義網路中使用。也就是說預設的Bridge網路是無法使用的。

$ sudo docker run -d  --name ng3 nginx
53fd36e0e778bc0b29ae70ac3b5c5d76c74b4a8d987b23290a868f7f0f02d435
$ sudo docker run -d  --name ng4 nginx
c91d26a3b948089a1b19db08b6a719c101e5bef4007c9d727662c2363a3c6d9f
$ sudo docker exec -it 53fd36e0e778bc0b29ae70ac3b5c5d76c74b4a8d987b23290a868f7f0f02d435 /bin/sh
# apt-get update
此處省略更新apt的輸出
# apt-get install iputils-ping
此處省略安裝ping命令的輸出
# ping ng4
ping: ng4: Name or service not known

三、joined容器

joined容器是另一種實現容器間通訊的方式,這種方式非常特別,它可以使多個容器共享同一個網路棧,共享網絡卡和配置資訊,下面舉例說明:

我們首先啟動一個nginx容器:

$ sudo docker run -d -it --name ng nginx
128be82cc38adb2bc56ee4e8aa2a7e7026601c6cd056af6848539f5e27b6210d

接著啟動redis容器,並通過--network引數join到nginx容器網路中,我們進入容器看下其網路配置:

 sudo docker run -it -d --network=container:ng redis
344d10125f1693d96bea471c94a13c36f8c868b203dbe234cbb8863fec24f775
$ sudo docker exec -it 344d10125f1693d96bea471c94a13c36f8c868b203dbe234cbb8863fec24f775 /bin/sh
注意此處請大家先自行安裝iproute2工具
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
43: eth0@if44: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

接著,我們在進入nginx容器中看下它的網路配置:

$ sudo docker exec -it 128be82cc38a /bin/sh
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
43: eth0@if44: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

看到沒?這兩個容器網路配置一樣的,它們共享相同的網路棧,這樣redis容器可以直接通過127.0.0.1訪問nginx:

# curl 127.0.0.1:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

joined容器方式非常適合以下場景:

  • 不同容器中的程式希望通過loopback高效快速通訊,比如Web Server和App Server;

  • 安裝在獨立容器中的監控服務對其它容器中應用進行監控。