Docker容器技术之容器间通信

说明,在本文中,所有的images采用的是busybox:latest。系统采用的是Ubuntu22.04.

容器之间可通过IP或joined容器2种方式通信。

1. IP通信

容器间利用IP通信非常的好理解,在前面的文章中已经介绍了四种Docker网络,其中bridge网络和user-defined网络非常的常用。IP通信就好比是不同的容器连接到相同的虚拟交换机(网桥)上面,当然在创建容器的时候,容器的IP地址在同一个网络段纸3,利用IP地址可以实现通信。下面请看实例。
在这里插入图片描述在上图中可以看到两个容器连接到helmer_net网络,两个容器之间利用IP地址可以实现通信,那么如果两个容器没有连接到一个网络上面又要怎么通信,其实可以通过为容器增加虚拟网卡来实现通信,下面请看实例。

在这里插入图片描述
可以看出两个容器处于不同的网络无法进行通信,但是在增加网卡之就可以了。
请看下面:

helmer@Hanssen:~$ docker run -it --network=helmer_net2 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
24: eth0@if25: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # helmer@Hanssen:~$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED         STATUS         PORTS     NAMES
5df5cbc92589   busybox   "sh"      9 seconds ago   Up 8 seconds             practical_hofstadter
helmer@Hanssen:~$ docker run -it --network=helmer_net 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
26: eth0@if27: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:0f:16:02 brd ff:ff:ff:ff:ff:ff
    inet 172.15.22.2/24 brd 172.15.22.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # helmer@Hanssen:~$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS          PORTS     NAMES
01644bb8533a   busybox   "sh"      14 seconds ago   Up 14 seconds             xenodochial_blackwell
5df5cbc92589   busybox   "sh"      34 seconds ago   Up 33 seconds             practical_hofstadter
helmer@Hanssen:~$ docker network connect helmer_net5df5
"docker network connect" requires exactly 2 arguments.
See 'docker network connect --help'.

Usage:  docker network connect [OPTIONS] NETWORK CONTAINER

Connect a container to a network
helmer@Hanssen:~$ docker network connect helmer_net 5df5
helmer@Hanssen:~$ docker attach 5df5
/ # 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
24: eth0@if25: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
28: eth1@if29: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:0f:16:03 brd ff:ff:ff:ff:ff:ff
    inet 172.15.22.3/24 brd 172.15.22.255 scope global eth1
       valid_lft forever preferred_lft forever
/ # ping 172.15.22.2
PING 172.15.22.2 (172.15.22.2): 56 data bytes
64 bytes from 172.15.22.2: seq=0 ttl=64 time=0.236 ms
64 bytes from 172.15.22.2: seq=1 ttl=64 time=0.193 ms
64 bytes from 172.15.22.2: seq=2 ttl=64 time=0.128 ms
^C
--- 172.15.22.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.128/0.185/0.236 ms
/ # 

可以看到在添加了另外网络的网卡之后,两个容器间能够相互的通信。

2. joined容器

joined容器是另一种实现容器间通信的方式。
joined容器非常特别,它可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined容器之间可以通过127.0.0.1直接通信。
下面请看实例:

helmer@Hanssen:~$ docker run -d -it --name=web1 httpd
72afa82663a976316da66976811eb74c7b615de9efa89b6bf2bf5e533fffd546
helmer@Hanssen:~$ 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
38: eth0@if39: <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 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # helmer@Hanssen:~$ docker exec -it web1 bash
root@72afa82663a9:/usr/local/apache2# read escape sequence
helmer@Hanssen:~$ docker inspect web1
[
    {
        "Id": "72afa82663a976316da66976811eb74c7b615de9efa89b6bf2bf5e533fffd546",
        "Created": "2022-07-20T07:14:06.97461468Z",
        "Path": "httpd-foreground",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 29167,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-07-20T07:14:07.96231121Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
      #省略
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "0c7fa9ecd7b5dfa93625c668327f6641e20ca612337addb607a49933e10cc508",
                    "EndpointID": "3709d2541851cffcab5c399d48d604a39e9d0b299050699eeea6c4e04ceb301a",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",#可以看出两个容器的IP地址一样,使用了相同的网络栈。
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

helmer@Hanssen:~$ docker attach 4181
/ # wget 127.0.0.1
Connecting to 127.0.0.1 (127.0.0.1:80)
saving to 'index.html'
index.html           100% |******************************************************|    45  0:00:00 ETA
'index.html' saved
/ # cat index.html 
<html><body><h1>It works!</h1></body></html>
/ # 

joined容器非常适合以下场景:
(1)不同容器中的程序希望通过loopback高效快速地通信,比如Web Server与App Server。
(2)希望监控其他容器的网络流量,比如运行在独立容器中的网络监控程序。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐