Docker学习笔记(六)Docker容器的通信

容器之间可以通过IP,DockerDNSServer或者joined容器三种方式通信。

一、IP的方式

可以参考前面讲到的容器的网络。

二、Docker DNS Server的方式

docker daemon内嵌了一个默认的DNS Server,使容器可以通过“容器名”通信,只需要在启动容器时使用 --name命名就行了,但是这种方式只能适用于自定义网络的容器,使用docker0默认网桥的不行。例如我们刚才启动的nginx1、2和3,都是使用了自定义的网络,我们可以在容器内部使用ping命令直接ping容器名:

root@37773b729b9b:/# ping -c 4 nginx3
PING nginx3 (172.19.0.3) 56(84) bytes of data.
64 bytes from nginx3.mynet2 (172.19.0.3): icmp_seq=1 ttl=64 time=0.081 ms
64 bytes from nginx3.mynet2 (172.19.0.3): icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from nginx3.mynet2 (172.19.0.3): icmp_seq=3 ttl=64 time=0.062 ms
64 bytes from nginx3.mynet2 (172.19.0.3): icmp_seq=4 ttl=64 time=0.057 ms

--- nginx3 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.057/0.065/0.081/0.009 ms

如上,使用了自定义网络的容器,可以互相之间直接ping容器名,但使用默认网桥docker0的就不行,比如我们启动两个容器分别为web1和web2,互相ping一下:

[root@docker ~]# docker run --name web1 -P -d docker.io/nginx
927c8a9ebe634e635ebd707a7b9ba2721b96f3057b058d2ae29c2e2b24f11278
[root@docker ~]# docker run --name web2 -P -d docker.io/nginx
e815be1402fb242333fd32a07b3e6604395d80e3c011ed73906642f43d09a704
[root@docker ~]# docker exec -it web1 bash
root@927c8a9ebe63:/# ping -c 4 web2
ping: web2: No address associated with hostname
root@927c8a9ebe63:/#

以上,标黄的地方可以看出,使用docker0默认网桥的容器,使用DNS Server是ping不通的。

三、 joined容器的方式

joined容器可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined容器之间可以使用127.0.0.1通信。
先创建一个nginx容器,名为web1:

[root@docker ~]# docker run --name web1 -P -d docker.io/nginx
68b821dca1e364065bcfefcf068f5e288ce9ef6e08f4650f5be77ecd616fae46

再创建一个busybox容器,并使用–network=container:web1指定joined容器为web1,并查看busybox容器的IP和MAC地址:

[root@docker ~]# docker run -it --network=container:web1 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
34: eth0@if35: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link 
       valid_lft forever preferred_lft forever

再查看web1容器的IP和MAC:

[root@docker ~]# docker exec -it web1 bash
root@98b1b5be5fd7:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:acff:fe11:2  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 2944  bytes 8607213 (8.2 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2830  bytes 198380 (193.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

由上面标黄处可看出,两个容器的IP和MAC完全一致。
joined容器非常适合以下场景:
不同容器中的程序,希望通过lookback高效快速地通信,比如web server和app server。
希望监控其他容器中的网络流量,比如运行在独立容器中的网络监控程

四、外部网络访问容器

在启动容器时,如果不指定启动参数,外部网络是无法访问容器内部的。当容器中运行一些网络应用,要让外部网络访问这些应用时,可以通过-P或者-p参数来指定端口映射。
(1)-P是随机指定映射端口,后面不需要写上端口号;
(2)-p是手动指定映射端口,后面必须要写上宿主机端口和容器端口。
具体使用方法如:

[root@docker ~]# docker run --name nginx1 -P -d docker.io/nginx
cad6b93f1b9cd6214e5fa16d1f1e812b4ab11b00e137ee48cf38ac195977d666
[root@docker ~]# docker run --name nginx2 -p 8080:80 -d docker.io/nginx
3970f4a12026fb0c29595a531837b46d209fbb42cc99f04af9b8de0f174eca6e
[root@docker ~]#

以上启动了两个容器,我们来看一下两个容器的映射端口:
在这里插入图片描述
可以看出nginx1我们使用的-P参数,系统随机指定的宿主机端口是32728,映射到容器的80/tcp端口,我们在外部访问nginx1容器的时候,可以直接访问宿主机IP:32782,;而nginx2容器我们使用的是-p 8080:80参数,手动指定宿主机的80端口映射到容器的80端口,我们在访问nginx2容器的时候,可以直接访问素质及IP:80。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章