环境 两台, 安装了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 要访问外网 就是通过 路由地址转换完成的。 但是我不会。
原文:https://www.cnblogs.com/chengege/p/12679261.html