Docker NetWord (容器之间是如何通信的)

环境 两台, 安装了Docker 的 centos7 虚拟主机   Docker1  和 Docker2:

保证两台主机,  是可以在 外面ping 通的.  /etc/sysconfig/network-script/ifcfg-ens33  这个文件可以编辑, 

[miller@docker4 network-scripts]$ cat ifcfg-ens33 
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="b673928c-4590-4dd6-acc3-577f8312ef46"
DEVICE="ens33"
ONBOOT="yes"
IPV6_PRIVACY="no"
IPADDR=192.168.42.22
NETMASK=255.255.255.0
GATEWAY=192.168.42.2
DNS1=8.8.8.8
DNS2=114.114.114.114

ping  检测ip的可达性

telnet 检测服务的可用性。

[miller@docker4 network-scripts]$ telnet 192.168.42.23:5000
telnet: 192.168.42.23:5000: Name or service not known
192.168.42.23:5000: Unknown host
[miller@docker4 network-scripts]$ telnet 192.168.42.23 5000
Trying 192.168.42.23...
Connected to 192.168.42.23.
Escape character is '^]'. 
# 上面这种情况 说明 192.168.42.23 这个ip 的 5000端口是 可达的。 因为我将docker容器中的flask app 的web应用的端口 映射到了 192.168.42.23这台机器的5000
# 端口上。
[miller@docker4 network
-scripts]$ telnet 192.168.42.23 500 Trying 192.168.42.23...
telnet: connect to address 192.168.42.23: Connection refused
# 这种的就是不行了. 500 端口开都没开

############################## Linux 网络名称空间  network name space  ##############################

ip netns list    # 查看当前主机的 网络名名称空间

ip netns delete test1     # 删除test1 这个网络名称空间

ip netns add  test1    # 添加 名为test1 的 网络名称空间。

[miller@docker4 python-flask]$ sudo ip netns add test1  # 添加一个 test 网络名称空间
 
[miller@docker4 python-flask]$ sudo ip netns exec test1 ip addr     # 通过exec 命令, 在 test 这个名称空间中 执行  ip  addr 这个命令
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000   # 这个回环口是 DOWN 的状态
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00


[miller@docker4 python-flask]$ sudo ip netns exec test1 ip link set dev lo up  # 把这个回环口启动起来
[miller@docker4 python-flask]$ sudo ip netns exec test1 ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00    # 显示结果是 UNKNOWN, 要UP起来是需要两端 连起来的. 
#  后面把 linux 上的两个 网络名称空间  test1 和 test2 连起来

##############################################################################################################################

[miller@docker4 python-flask]$ sudo ip netns list
test2
test1

[miller@docker4 python-flask]$ sudo ip netns exec test1 ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00


[miller@docker4 python-flask]$ sudo ip link add veth-test1 type veth peer name veth-test2  # 在主机添加一对 link
[miller@docker4 python-flask]$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 00:0c:29:00:d0:42 brd ff:ff:ff:ff:ff:ff
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
link/ether 02:42:2d:ec:8c:ee brd ff:ff:ff:ff:ff:ff
9: veth0d99baa@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether ee:00:f8:b4:a5:d5 brd ff:ff:ff:ff:ff:ff link-netnsid 0

# 刚刚添加的两个link
10: veth-test2@veth-test1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 2e:d5:94:91:fd:97 brd ff:ff:ff:ff:ff:ff
11: veth-test1@veth-test2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 7e:fb:1b:d6:d9:6f brd ff:ff:ff:ff:ff:ff

# 将本机的刚刚添加的一对link  分别添加到 test1 和 test2 这两个网络名称空间中

[miller@docker4 python-flask]$ sudo ip link set veth-test1 netns test1
[miller@docker4 python-flask]$ sudo ip link set veth-test2 netns test2

[miller@docker4 python-flask]$ sudo ip netns exec test1 ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
11: veth-test1@if10: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 7e:fb:1b:d6:d9:6f brd ff:ff:ff:ff:ff:ff link-netnsid 1
[miller@docker4 python-flask]$ sudo ip netns exec test2 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
10: veth-test2@if11: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 2e:d5:94:91:fd:97 brd ff:ff:ff:ff:ff:ff link-netnsid 0

# 给 test1 中的  veth-test1 接口分配一个 ip地址为 192.168.1.1 掩码是24
# 给 test2 中的  veth-test1 接口分配一个 ip地址为 192.168.1.2 掩码是24

[miller@docker4 python-flask]$ sudo ip netns exec test1 ip addr add 192.168.1.1/24 dev veth-test1
[miller@docker4 python-flask]$ sudo ip netns exec test2 ip addr add 192.168.1.2/24 dev veth-test2

# 将两个名称空间的 两个接口全都 启动起来

[miller@docker4 python-flask]$ sudo ip netns exec test1 ip link set dev veth-test1 up
[miller@docker4 python-flask]$ sudo ip netns exec test2 ip link set dev veth-test1 up

# 两个 网络名称空间 都有了  ip 地址

[miller@docker4 python-flask]$ sudo ip netns exec test2 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
10: veth-test2@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 2e:d5:94:91:fd:97 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.1.2/24 scope global veth-test2
valid_lft forever preferred_lft forever
inet6 fe80::2cd5:94ff:fe91:fd97/64 scope link
valid_lft forever preferred_lft forever
[miller@docker4 python-flask]$ sudo ip netns exec test1 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
11: veth-test1@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 7e:fb:1b:d6:d9:6f brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet 192.168.1.1/24 scope global veth-test1
valid_lft forever preferred_lft forever
inet6 fe80::7cfb:1bff:fed6:d96f/64 scope link
valid_lft forever preferred_lft forever

# 两边ping 一下。 都可以 通
[miller@docker4 python-flask]$ sudo ip netns exec test1 ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.079 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.072 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.078 ms
^C
--- 192.168.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.072/0.076/0.079/0.007 ms
[miller@docker4 python-flask]$ sudo ip netns exec test2 ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.076 ms
^C
--- 192.168.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.068/0.072/0.076/0.004 ms
[miller@docker4 python-flask]$

# 上面这个原理, 其实就是 docker 创建的 容器之间可以相互, 通信的一个原理。

每个容器都有自己的 网络名称空间。

每个名称空间  都会开一个接口, 并且分配  ip地址。  最后 两个容器之间的接口, 连接起来  就可以进行通信。

Docker NetWork 网络部分:
            - Bridge NetWork
单机 -   - Host NetWork
            - None NetWork

多级   - Overlay NetWork

docker network ls # 列举出docker在本机上都有哪些网络

[miller@docker4 python-flask]$ docker ps   # 当前有一个叫 test1 的 docker container
CONTAINER ID   IMAGE                             COMMAND            CREATED          STATUS          PORTS        NAMES
3c1f23e3530e   caijiwandocker/flask-hello-world  "python3 app.py"   10 minutes ago   Up 10 minutes   5000/tcp     test1

[miller@docker4 python-flask]$ docker network ls
NETWORK        ID      NAME     DRIVER      SCOPE
d6e9516055df   bridge  bridge   local
2d4c88aac3be   host    host     local
8f43716b9791   none    null     local


[miller@docker4 python-flask]$ docker network inspect d6e9516055df [ { "Name": "bridge", "Id": "d6e9516055dfad8303ab9e5d10f42ea01f358cc6c691db04fee61d93e33bbecb", "Created": "2020-04-11T11:21:18.757306845+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "3c1f23e3530eadb54eb2fc61e7e33b36627428ba25c3b037c70c8d9a5fd9954a": { "Name": "test1", # 这个就是在本机上 连接到这个网络的 那个容器的名字 "EndpointID": "555d09be7c38f0107bfbd74ce1161836dc5a6bc043fbe0e61d5bd31f3b70e90a", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]

通过这个可以看到  test1 这个容器。 链接到了docker 的bridge 网络上。

bridge 是个什么东西?  桥接网络

# 下面是本机的 ip  信息, 前两个不关注主要是 后两个。

[miller@docker4 python-flask]$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    .....2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    ....3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:2d:ec:8c:ee brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:2dff:feec:8cee/64 scope link 
       valid_lft forever preferred_lft forever
13: vethddd5c78@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether ca:7b:a3:98:58:2a brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::c87b:a3ff:fe98:582a/64 scope link 
       valid_lft forever preferred_lft forever

可以想一下 连个电脑想要通信, 就需要网线链接。
 vethddd5c78@if12 这个东西就相当于是一条网线。 一端连接着 docker0 这台电脑上的接口。 另一端连接着 test1 这个容器中的一个接口。
[miller@docker4 python-flask]$ docker exec test1 ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
[miller@docker4 python-flask]$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:00:d0:42 brd ff:ff:ff:ff:ff:ff
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 02:42:2d:ec:8c:ee brd ff:ff:ff:ff:ff:ff
13: vethddd5c78@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
    link/ether ca:7b:a3:98:58:2a brd ff:ff:ff:ff:ff:ff link-netnsid 0

 就跟这张图一样, veth......  起到的作用就相当于网线。 链接这个 docker0 和 docker启动起来的容器。

所以两个container之间  是可以进行通信的。  即使两个容器之间没有 直接通过 veth 链接。  而是简介的通过docker0 连接起来的。

而docker0 要访问外网 就是通过 路由地址转换完成的。  但是我不会。

猜你喜欢

转载自www.cnblogs.com/chengege/p/12679261.html
今日推荐