docker网络


文章目录

  • docker网络
  • 前言
  • docker的四种网络模式
  • bridge网桥模式
  • 查看宿主机与容器的连接方式
  • 使用--link进行容器之间的连接
  • 探究--link参数的原理
  • none模式
  • 容器与宿主机的网络配置
  • 容器与容器之间的网络配置
  • 自定义网桥(高级用法)
  • 使两个不同网段的容器进行通信
  • 结语


前言

它来了,他来了,它带着n多个坑来了。作为初学者,这是一个伤心的故事!!!

docker的四种网络模式

学习docker network 命令

docker network --help
[root@zhanghuixiong ~]# docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network      #连接一个容器到网络
  create      Create a network                      #创建一个网络
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks  #显示一个或多个网络的详细信息
  ls          List networks                                         #网络列表
  prune       Remove all unused networks
  rm          Remove one or more networks

查看docker容器创建时的网络模式

[root@zhanghuixiong ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
07e6fd355979   bridge    bridge    local
f1f5a12e9e4e   host      host      local
73464510fe31   none      null      local

docker网络在容器创建时有三种网络模式,bridge则是默认的模式不需要指定,而其他模式则需要使用–net去指定

  • –net=bridge ;网桥模式,创建容器默认的模式
    此模式会为每一个创建的容器分配、设置ip,并用veth pair技术将容器连接到docker0网桥。
  • –net=host ;主机模式
    容器不会虚拟自己的网卡和配置ip,而是使用宿主机的ip和端口
  • –net=container ;容器模式
    容器不会创建自己的网卡和配置ip,而是使用另外一台创建的容器的ip和端口
  • –net=none ;none模式
    该模式就直接不配置网络功能,需要自己手动去打通网络,想要什么网络就去打通什么网络(高级用法)

bridge网桥模式

查看宿主机与容器的连接方式

1、宿主机与容器互联

[root@zhanghuixiong ~]# 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
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:e9:c5:d0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.132/24 brd 192.168.200.255 scope global noprefixroute dynamic ens33
       valid_lft 1647sec preferred_lft 1647sec
    inet6 fe80::fc02:c32:6099:9557/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:b1:8c:a8:fa 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
#docker0  ;安装docker时所默认的虚拟网桥

进入容器查看对应的IP地址

[root@zhanghuixiong ~]# docker run -d -P --name tomcat01 tomcat
Unable to find image 'tomcat:latest' locally
latest: Pulling from library/tomcat
d960726af2be: Pull complete 
e8d62473a22d: Pull complete 
8962bc0fad55: Pull complete 
65d943ee54c1: Pull complete 
774078a3f8bb: Pull complete 
Digest: sha256:71703331e3e7f8581f2a8206a612dbeedfbc7bb8caeee972eadca1cc4a72e6b1
Status: Downloaded newer image for tomcat:latest
e9bca43aa976aceea8360f3fcd13095ac183ea33a6e018f00a05a093632c4a58

[root@zhanghuixiong ~]# docker exec -it tomcat01 /bin/bash
root@e9bca43aa976:/usr/local/tomcat# 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
14: eth0@if15: <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
       
#etho@if15    ;容器内的veth pair接口

[root@zhanghuixiong ~]# 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
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:e9:c5:d0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.132/24 brd 192.168.200.255 scope global noprefixroute dynamic ens33
       valid_lft 1549sec preferred_lft 1549sec
    inet6 fe80::fc02:c32:6099:9557/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:b1:8c:a8:fa 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:b1ff:fe8c:a8fa/64 scope link 
       valid_lft forever preferred_lft forever
15: vethcc0a577@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 96:9e:06:58:b3:49 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::949e:6ff:fe58:b349/64 scope link 
       valid_lft forever preferred_lft forever
      
      #vethccoa577@14        ;宿主机上的veth pair接口

测试在主机上ping容器网络和容器上ping宿主机

[root@zhanghuixiong ~]# docker exec -it tomcat01 ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.252 ms
64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=0.032 ms
64 bytes from 172.17.0.1: icmp_seq=3 ttl=64 time=0.031 ms
^C
--- 172.17.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 3ms
rtt min/avg/max/mdev = 0.031/0.105/0.252/0.103 ms

[root@zhanghuixiong ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.114 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.050 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.052 ms
^C
--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 0.050/0.072/0.114/0.029 ms
[root@zhanghuixiong ~]# 

原理:我们每安装一个docker就会给容器分配一个ip,只要我们安装了docker,就会有一个网卡docker0桥接模式,使用的技术是veth-pair技术

使用–link进行容器之间的连接

再启动一个容器进行测试

[root@zhanghuixiong ~]# docker run -d -P --name tomcat02 tomcat
b0b98201c677539c405ea376fd343396efadae94e2db46644c4db1d0a04898bd
[root@zhanghuixiong ~]# docker exec -it tomcat02 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
16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
       
[root@zhanghuixiong ~]# 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
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:e9:c5:d0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.132/24 brd 192.168.200.255 scope global noprefixroute dynamic ens33
       valid_lft 1266sec preferred_lft 1266sec
    inet6 fe80::fc02:c32:6099:9557/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:b1:8c:a8:fa 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:b1ff:fe8c:a8fa/64 scope link 
       valid_lft forever preferred_lft forever
15: vethcc0a577@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 96:9e:06:58:b3:49 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::949e:6ff:fe58:b349/64 scope link 
       valid_lft forever preferred_lft forever
17: vetha182581@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 12:99:43:91:ed:6b brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::1099:43ff:fe91:ed6b/64 scope link 
       valid_lft forever preferred_lft forever
#每创建容器都增加了一个veth pair接口

测试进入Tomcat02容器pingTomcat01容器

[root@zhanghuixiong ~]# docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.162 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.054 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.061 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.056 ms
^C
--- 172.17.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 8ms
rtt min/avg/max/mdev = 0.054/0.083/0.162/0.046 ms

#发现容器之间ping ip是可以访问的

#思考:直接ping域名可以ping通吗?

[root@zhanghuixiong ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED        STATUS        PORTS                                         NAMES
b0b98201c677   tomcat    "catalina.sh run"   16 hours ago   Up 16 hours   0.0.0.0:49155->8080/tcp, :::49155->8080/tcp   tomcat02
e9bca43aa976   tomcat    "catalina.sh run"   17 hours ago   Up 17 hours   0.0.0.0:49154->8080/tcp, :::49154->8080/tcp   tomcat01
[root@zhanghuixiong ~]# docker exec -it tomcat01 /bin/bash
root@e9bca43aa976:/usr/local/tomcat# ping tomcato2
ping: tomcato2: Temporary failure in name resolution

#发现并不能ping通

使用–link则可以实现ping域名

[root@zhanghuixiong sbin]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
5efa47eefa8935d22a170c7a9c9e73e5741f33c3d413e46e825223424aa8016f
docker: Error response from daemon: driver failed programming external connectivity on endpoint tomcat03 (637ac54e5a209118fd752d753aecd824a2ca6392ae259af6d5391f7ba0550b36):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 49185 -j DNAT --to-destination 172.17.0.4:8080 ! -i docker0: iptables: No chain/target/match by that name.

##发现问题;启动容器失败,报错显示iptables的规则不允许连接
##试着把防火墙清空规则                 --查阅资料发现--link是涉及到iptables的规则,不使用-P随机指定端口,可能导致外网不能访问容器
[root@zhanghuixiong sbin]# iptables -F
[root@zhanghuixiong sbin]# iptables -X
[root@zhanghuixiong sbin]# iptables -Z
[root@zhanghuixiong sbin]# iptables-save

##切记当要再次启动Tomcat03时必须要把之前启动失败的Tomcat03删除,不然会报错容器已经存在

[root@zhanghuixiong ~]# docker run -d --name tomcat03 --link tomcat02 tomcat  
67e6f87e4f13a8755e5de140e9f8855267e78fa129176fe1bb32fb90d26d8363
[root@zhanghuixiong ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                                         NAMES
67e6f87e4f13   tomcat    "catalina.sh run"   18 seconds ago   Up 17 seconds   8080/tcp                                      tomcat03
b0b98201c677   tomcat    "catalina.sh run"   17 hours ago     Up 17 hours     0.0.0.0:49155->8080/tcp, :::49155->8080/tcp   tomcat02
e9bca43aa976   tomcat    "catalina.sh run"   17 hours ago     Up 17 hours     0.0.0.0:49154->8080/tcp, :::49154->8080/tcp   tomcat01
[root@zhanghuixiong ~]# docker exec -it tomcat03 /bin/bash
root@67e6f87e4f13:/usr/local/tomcat# ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.311 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.118 ms
^C
--- tomcat02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 4ms
rtt min/avg/max/mdev = 0.046/0.158/0.311/0.112 ms
## 发现可以直接ping域名

再次思考,tomcat02可以直接ping通tomcat03的域名吗?

[root@zhanghuixiong ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Temporary failure in name resolution
[root@zhanghuixiong ~]# 

##发现反向是ping不同的,那说明容器使用了--link才能使用域名ping通

探究–link参数的原理

实质上就是做了一个映射,可以通过容器内的/etc/hosts/文件进行查看

[root@zhanghuixiong ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED        STATUS        PORTS                                         NAMES
67e6f87e4f13   tomcat    "catalina.sh run"   3 hours ago    Up 3 hours    8080/tcp                                      tomcat03
b0b98201c677   tomcat    "catalina.sh run"   20 hours ago   Up 20 hours   0.0.0.0:49155->8080/tcp, :::49155->8080/tcp   tomcat02
e9bca43aa976   tomcat    "catalina.sh run"   20 hours ago   Up 20 hours   0.0.0.0:49154->8080/tcp, :::49154->8080/tcp   tomcat01
[root@zhanghuixiong ~]# docker exec -it tomcat02 cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3      b0b98201c677
[root@zhanghuixiong ~]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3      tomcat02 b0b98201c677   ##所以实质上就是对Tomcat02做了一个映射,这就是--link做的事
172.17.0.4      67e6f87e4f13

none模式

容器与宿主机的网络配置

[root@zhanghuixiong ~]# docker run -it -d --network=none nginx /bin/bash
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
69692152171a: Pull complete 
30afc0b18f67: Pull complete 
596b1d696923: Pull complete 
febe5bd23e98: Pull complete 
8283eee92e2f: Pull complete 
351ad75a6cfa: Pull complete 
Digest: sha256:6d75c99af15565a301e48297fa2d121e15d80ad526f8369c526324f0f7ccb750
Status: Downloaded newer image for nginx:latest
1030b79b4b903fd12622723d69052b2672875bfebc63f0c23b284fe4ca7c668f
[root@zhanghuixiong ~]# 

[root@zhanghuixiong ~]# docker inspect -f '{{.State.Pid}}' 1030b79b4b90
2246
 ## pid --守护进程
 
[root@zhanghuixiong ~]# mkdir -p /var/run/netns
[root@zhanghuixiong ~]# ln -s /proc/$pid/ns/net /var/run/netns/2246
[root@zhanghuixiong ~]# 
##ip netns命令只能操作/var/run/netns/ 目录下的network namespace,docker创建的namespace不在这上面,需要建立软连接

[root@zhanghuixiong ~]# ip addr show docker0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:b1:8c:a8:fa 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:b1ff:fe8c:a8fa/64 scope link 
       valid_lft forever preferred_lft forever
[root@zhanghuixiong ~]# 
##检查桥接网卡ip和子网掩码信息

创建一对veth pair接口A和B,绑定A到网桥docker0,并启用

[root@zhanghuixiong ~]# brctl addif docker0 A
-bash: brctl: command not found   ##需要安装tunctl工具,小插曲  使用yum install -y bridge-utils
[root@zhanghuixiong ~]# brctl addif docker0 A
[root@zhanghuixiong ~]# ip link set A up
[root@zhanghuixiong ~]# 
[root@zhanghuixiong ~]# ip link set B netns $pid
Command line is not complete. Try option "help"    ##报错。开始习惯了。查看帮助文档

[root@zhanghuixiong ~]# ip link set help
Usage: ip link add [link DEV] [ name ] NAME
                   [ txqueuelen PACKETS ]
                   [ address LLADDR ]
                   [ broadcast LLADDR ]
                   [ mtu MTU ] [index IDX ]
                   [ numtxqueues QUEUE_COUNT ]
                   [ numrxqueues QUEUE_COUNT ]
                   type TYPE [ ARGS ]

       ip link delete { DEVICE | dev DEVICE | group DEVGROUP } type TYPE [ ARGS ]

       ip link set { DEVICE | dev DEVICE | group DEVGROUP }
                          [ { up | down } ]
                          [ type TYPE ARGS ]
                          [ arp { on | off } ]
                          [ dynamic { on | off } ]
                          [ multicast { on | off } ]
                          [ allmulticast { on | off } ]
                          [ promisc { on | off } ]
                          [ trailers { on | off } ]
                          [ carrier { on | off } ]
                          [ txqueuelen PACKETS ]
                          [ name NEWNAME ]
                          [ address LLADDR ]
                          [ broadcast LLADDR ]
                          [ mtu MTU ]
                          [ netns { PID | NAME } ]   ##使用name不行时,可以尝试使用PID
                          [ link-netnsid ID ]


[root@zhanghuixiong ~]# ip link set B netns 2246   

[root@zhanghuixiong ~]# ip netns exec $pid ip link set dev B name etho
Cannot open network namespace "ip": No such file or directory

[root@zhanghuixiong ~]# ip netns exec 2246 ip link set dev B name eth0
[root@zhanghuixiong ~]# ip netns exec 2246 ip link set eth0 up
[root@zhanghuixiong ~]# ip netns exec 2246 ip addr add 172.17.42.99/16 dev eth0
[root@zhanghuixiong ~]# ip netns exec 2246 ip route add default via 172.17.42.1
[root@zhanghuixiong ~]# 
## 主要就是干了这个,把一个接口放在网络命令空间,一个放在docker0上。在网络空间中设置自己ip,以及一个路由转发

##测试是可以通过宿主机ping通
Last login: Wed Jun  2 23:09:46 2021 from 192.168.200.1
[root@zhanghuixiong ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED       STATUS       PORTS     NAMES
4c8bb375b236   nginx     "/docker-entrypoint.鈥   5 hours ago   Up 5 hours             jovial_heyrovsky
[root@zhanghuixiong ~]# ping 172.17.42.99
PING 172.17.42.99 (172.17.42.99) 56(84) bytes of data.
64 bytes from 172.17.42.99: icmp_seq=1 ttl=64 time=0.078 ms
64 bytes from 172.17.42.99: icmp_seq=2 ttl=64 time=0.087 ms
^C
--- 172.17.42.99 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.078/0.082/0.087/0.010 ms
[root@zhanghuixiong ~]#

容器与容器之间的网络配置

[root@zhanghuixiong ~]# docker run -it -d --name nginx01 --network=none nginx /bin/bash
b1bc4e7bcf4935ed4be407f97e356f2565afd627e8e05ec8195ffd66f3df2362
[root@zhanghuixiong ~]# docker run -it -d --name nginx02 --network=none nginx /bin/bash
01658a0ed8e6aea5fe6594e1747d0177dc4082c9c6d29eeca46197be9474ca8e
[root@zhanghuixiong ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
01658a0ed8e6   nginx     "/docker-entrypoint.鈥   3 seconds ago    Up 2 seconds              nginx02
b1bc4e7bcf49   nginx     "/docker-entrypoint.鈥   11 seconds ago   Up 10 seconds             nginx01

[root@zhanghuixiong ~]# docker inspect -f '{{.State.Pid}}' b1bc4e7bcf49
2783
[root@zhanghuixiong ~]# docker inspect -f '{{.State.Pid}}' 01658a0ed8e6
2850
注意查看pid所对应的数值

[root@zhanghuixiong ~]# mkdir -p /var/run/netns
[root@zhanghuixiong ~]# ln -s /proc/2783/ns/net /var/run/netns/2783
[root@zhanghuixiong ~]# ln -s /proc/2850/ns/net /var/run/netns/2850
##创建命名空间,做软连接


[root@zhanghuixiong ~]# ip link add A type veth peer name B
[root@zhanghuixiong ~]# ip link set A netns 2783        #启动A接口
[root@zhanghuixiong ~]# ip netns exec 2783 ip addr add 10.1.1.1/32 dev A  #在命名空间中配置ip
[root@zhanghuixiong ~]# ip netns exec 2783 ip link set A up
[root@zhanghuixiong ~]# ip netns exec 2783 ip route add 10.1.1.2/32 dev A  #配置路由做转换
[root@zhanghuixiong ~]# 
[root@zhanghuixiong ~]# ip link set B netns 2850
[root@zhanghuixiong ~]# ip netns exec 2850 ip addr add 10.1.1.2/32 dev B
[root@zhanghuixiong ~]# ip netns exec 2850 ip link set B up
[root@zhanghuixiong ~]# ip netns exec 2783 ip route add 10.1.1.1/32 dev B
[root@zhanghuixiong ~]# 
[root@zhanghuixiong ~]# docker exec -it 8a8377674cfd /bin/bash
root@8a8377674cfd:/# ping --help
bash: ping: command not found
root@8a8377674cfd:/# ping 10.1.1.1
bash: ping: command not found
root@8a8377674cfd:/# 
。。。。。##莫名发现,nginx这玩意也没有ping命令把。。。

##再次启动centos镜像做实验
Last login: Thu Jun  3 09:30:17 2021 from 192.168.200.1
[root@zhanghuixiong ~]# docker run -it -d --name centos01 --network=none centos /bin/bash
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
7a0437f04f83: Pull complete 
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
051d7dfed62642c5362af6023e2b7d216fd1d5211fba2db7ebeb85cea3902912
[root@zhanghuixiong ~]# docker run -it -d --name centos02 --network=none centos /bin/bash
4709520153b7b967bc1fb956107f388353422f806b7bd661adfdac2ba4e46c96
[root@zhanghuixiong ~]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
4709520153b7   centos    "/bin/bash"   6 seconds ago    Up 5 seconds              centos02
051d7dfed626   centos    "/bin/bash"   15 seconds ago   Up 13 seconds             centos01
[root@zhanghuixiong ~]# docker inspect -f '{{.State.Pid}}' 051d7dfed626
2959
[root@zhanghuixiong ~]# docker inspect -f '{{.State.Pid}}' 4709520153b7
3031
[root@zhanghuixiong ~]# mkdir -p /var/run/netns
[root@zhanghuixiong ~]# ln -s /proc/2959/ns/net /var/run/netns/2959
[root@zhanghuixiong ~]# ln -s /proc/3031/ns/net /var/run/netns/3031
[root@zhanghuixiong ~]# ip link add A type veth peer name B
[root@zhanghuixiong ~]# ip link set A netns 2959
[root@zhanghuixiong ~]# ip netns exec 2959 ip addr add 10.1.1.1/32 dev A
[root@zhanghuixiong ~]# ip netns exec 2959 ip link set A up
[root@zhanghuixiong ~]# ip netns exec 2959 ip route add 10.1.1.2/32 dev A
[root@zhanghuixiong ~]# ip link set B netns 3031
[root@zhanghuixiong ~]# ip netns exec 3031 ip addr add 10.1.1.2/32 dev B
[root@zhanghuixiong ~]# ip netns exec 3031 ip link set B up
[root@zhanghuixiong ~]# ip netns exec 3031 ip route add 10.1.1.1/32 dev B
[root@zhanghuixiong ~]# docker exec -it 051d7dfed626 /bin/bash
[root@051d7dfed626 /]# ping 10.1.1.1
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=0.016 ms
64 bytes from 10.1.1.1: icmp_seq=2 ttl=64 time=0.027 ms
^C
--- 10.1.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1ms
rtt min/avg/max/mdev = 0.016/0.021/0.027/0.007 ms
[root@051d7dfed626 /]# 
##莫名的顺畅感有么有

自定义网桥(高级用法)

使用docker network create 来自定义网络

[root@zhanghuixiong ~]# docker network create --help

Usage:  docker network create [OPTIONS] NETWORK

Create a network

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
      --config-from string   The network from which to copy the configuration
      --config-only          Create a configuration only network
  -d, --driver string        Driver to manage the Network (default "bridge")  #默认桥接
      --gateway strings      IPv4 or IPv6 Gateway for the master subnet
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       Subnet in CIDR format that represents a network segment  ##自己设置
[root@zhanghuixiong ~]#

使用centos镜像开启测试之路

##创建自定义网络

[root@zhanghuixiong ~]# docker network create --subnet 192.168.100.0/16 --gateway 192.168.100.1 mynetwork
Error response from daemon: Failed to Setup IP tables: Unable to enable SKIP DNAT rule:  (iptables failed: iptables --wait -t nat -I DOCKER -i br-73999ae39769 -j RETURN: iptables: No chain/target/match by that name.
 (exit status 1))
 
 ##怎么说呢,攻克这个玩意儿快两天了。就一直报iptables的错,然后我就一直改iptables的配置文件,最后发现是里面的链表的规则被改动过了,应该是以前改的。心酸
 
 [root@zhanghuixiong ~]# docker network create --driver bridge --subnet 192.168.1.0/16 --gateway 192.168.1.0 mynet
6c22ca408653a0d0e389c835ff822d1d85b38345943540bc3d94ab791a85906d
[root@zhanghuixiong ~]# docker networ ls
docker: 'networ' is not a docker command.
See 'docker --help'
[root@zhanghuixiong ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
63f0deb998e5   bridge    bridge    local
f379a7790b0e   host      host      local
6c22ca408653   mynet     bridge    local
6da748779d0d   none      null      local

查看我们自定义网桥的信息

[root@zhanghuixiong ~]# docker inspect mynet
[
    {
        "Name": "mynet",
        "Id": "6c22ca408653a0d0e389c835ff822d1d85b38345943540bc3d94ab791a85906d",
        "Created": "2021-06-03T11:00:33.482070245-04:00",      ##创建时间
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.0/16",    ##自己配置的网段
                    "Gateway": "192.168.1.0"       ##网关
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
[root@zhanghuixiong ~]#

启动两个容器进行测试

[root@zhanghuixiong ~]# docker run -it -d --name centos01 --network=mynet centos /bin/bash
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
7a0437f04f83: Pull complete 
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
1cdd308f2b30d28906432c5aa2521461aaafd20bb32c8f643f55e37863ddc168
[root@zhanghuixiong ~]# docker run -it -d --name centos02 --network=mynet centos /bin/bash
bc7267643605a935e479007023291690d616ecea32434d254d6f32fb55f1c281
[root@zhanghuixiong ~]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
bc7267643605   centos    "/bin/bash"   9 seconds ago    Up 8 seconds              centos02
1cdd308f2b30   centos    "/bin/bash"   27 seconds ago   Up 25 seconds             centos01
[root@zhanghuixiong ~]# 

##再次进行查看
[root@zhanghuixiong ~]# docker inspect mynet
[
    {
        "Name": "mynet",
        "Id": "6c22ca408653a0d0e389c835ff822d1d85b38345943540bc3d94ab791a85906d",
        "Created": "2021-06-03T11:00:33.482070245-04:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.0/16",
                    "Gateway": "192.168.1.0"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "1cdd308f2b30d28906432c5aa2521461aaafd20bb32c8f643f55e37863ddc168": {
                "Name": "centos01",
                "EndpointID": "74c1b4db2cf45bb2c8d96ad59469069bc79049c7e0ad8d3791f7c27ec4e1137c",
                "MacAddress": "02:42:c0:a8:00:01",
                "IPv4Address": "192.168.0.1/16",    ##自己网络分配的ip
                "IPv6Address": ""
            },
            "bc7267643605a935e479007023291690d616ecea32434d254d6f32fb55f1c281": {
                "Name": "centos02",
                "EndpointID": "7fe45d34dd308546ed4104168d1db791838d9d045dc10dfbbb5843e38a562d9a",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

测试其联通性

[root@zhanghuixiong ~]# docker exec -it 1cdd308f2b30 /bin/bash
[root@1cdd308f2b30 /]# ping centos02   
PING centos02 (192.168.0.2) 56(84) bytes of data.
64 bytes from centos02.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.083 ms
64 bytes from centos02.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from centos02.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.044 ms
^C
--- centos02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 4ms
rtt min/avg/max/mdev = 0.044/0.057/0.083/0.019 ms

##相对比与默认网桥,是不是功能更加强大。完全不用做映射直接就可以ping域名
##而且像后期的集群放在这样单独网段里面更加的安全,便于管理,高可塑

使两个不同网段的容器进行通信

我们再来试试打通不同的网段进行通信,启动两个容器

^C
[root@zhanghuixiong ~]# docker run -it --name centos04 centos /bin/bash   
[root@1e49befe01e5 /]# [root@zhanghuixiong ~]# docker run -it --name centos05 centos /bin/bash
[root@a30cf4c57f77 /]# [root@zhanghuixiong ~]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
a30cf4c57f77   centos    "/bin/bash"   23 seconds ago   Up 22 seconds             centos05
1e49befe01e5   centos    "/bin/bash"   38 seconds ago   Up 37 seconds             centos04
bc7267643605   centos    "/bin/bash"   11 minutes ago   Up 11 minutes             centos02
1cdd308f2b30   centos    "/bin/bash"   11 minutes ago   Up 11 minutes             centos01
[root@zhanghuixiong ~]# 

#Ctrl+p+q;不停止容器退出

查看容器网段

[root@zhanghuixiong ~]# ^C
[root@zhanghuixiong ~]# docker inspect bridge
[
    {
        "Name": "bridge",
        "Id": "b890697984debe0cb136440f072aec9adf2f485da82eec766fca79e0d2cdaa1c",
        "Created": "2021-06-03T11:32:15.786433219-04: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": {
            "1e49befe01e5f762446983be8eeae8b28666ca619ef7bd95f9dcf4c37ccee68c": {
                "Name": "centos04",
                "EndpointID": "8bbabf9139e8797020c201c0fde1dfec57930c8604d02115abef3ad2506a5b4d",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",     #与mynet不同的网段
                "IPv6Address": ""
            },
            "a30cf4c57f77d450832889b0ab7d023cab19c726a81603100aa194d42a1a7dcb": {
                "Name": "centos05",
                "EndpointID": "b3dcc03466c4770df96877b7a209cdca3b0f320473a96b7a8742b08d0d05e47d",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",      #与mynet不同的网络
                "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": {}
    }
]

使用 -connect参数来打通

[root@zhanghuixiong ~]# docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network     #每错就是它了
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.
[root@zhanghuixiong ~]# 

##首先我们测试正常情况下是ping不通的
[root@zhanghuixiong ~]# docker exec -it centos01 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
^C

[root@zhanghuixiong ~]# docker exec -it centos01 ping centos04
ping: centos04: Name or service not known
[root@zhanghuixiong ~]#

我们测试把centos01连接到centos04

[root@zhanghuixiong ~]# docker network connect mynet centos04
[root@zhanghuixiong ~]# docker exec -it centos04 ping centos01
PING centos01 (192.168.0.1) 56(84) bytes of data.
64 bytes from centos01.mynet (192.168.0.1): icmp_seq=1 ttl=64 time=0.078 ms
64 bytes from centos01.mynet (192.168.0.1): icmp_seq=2 ttl=64 time=0.112 ms
64 bytes from centos01.mynet (192.168.0.1): icmp_seq=3 ttl=64 time=0.047 ms
64 bytes from centos01.mynet (192.168.0.1): icmp_seq=4 ttl=64 time=0.045 ms
^C
--- centos01 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 34ms
rtt min/avg/max/mdev = 0.045/0.070/0.112/0.028 ms
[root@zhanghuixiong ~]# 

##就是这么简单呀,我们来探究它的实质

[root@zhanghuixiong ~]# docker inspect mynet
[
    {
        "Name": "mynet",
        "Id": "6c22ca408653a0d0e389c835ff822d1d85b38345943540bc3d94ab791a85906d",
        "Created": "2021-06-03T11:00:33.482070245-04:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.0/16",
                    "Gateway": "192.168.1.0"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "1cdd308f2b30d28906432c5aa2521461aaafd20bb32c8f643f55e37863ddc168": {
                "Name": "centos01",
                "EndpointID": "74c1b4db2cf45bb2c8d96ad59469069bc79049c7e0ad8d3791f7c27ec4e1137c",
                "MacAddress": "02:42:c0:a8:00:01",
                "IPv4Address": "192.168.0.1/16",
                "IPv6Address": ""
            },
            "1e49befe01e5f762446983be8eeae8b28666ca619ef7bd95f9dcf4c37ccee68c": {
                "Name": "centos04",
                "EndpointID": "4a4eab40ccbda11f996e87c62796c5c66261bd6b85614604f491afe0594fb08a",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",  #重点看这里,居然是直接把它给安进来了。够暴力
                "IPv6Address": ""                  #也就是说一个容器对应着两个ip,自然两边就可以ping了
            },                                      #实质上就是连接到网络中,再去连接容器 
            "bc7267643605a935e479007023291690d616ecea32434d254d6f32fb55f1c281": {
                "Name": "centos02",
                "EndpointID": "7fe45d34dd308546ed4104168d1db791838d9d045dc10dfbbb5843e38a562d9a",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
[root@zhanghuixiong ~]# docker inspect bridge
[
    {
        "Name": "bridge",
        "Id": "b890697984debe0cb136440f072aec9adf2f485da82eec766fca79e0d2cdaa1c",
        "Created": "2021-06-03T11:32:15.786433219-04: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": {
            "1e49befe01e5f762446983be8eeae8b28666ca619ef7bd95f9dcf4c37ccee68c": {
                "Name": "centos04",
                "EndpointID": "8bbabf9139e8797020c201c0fde1dfec57930c8604d02115abef3ad2506a5b4d",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",    ##在bridge下是木有什么变化的
                "IPv6Address": ""
            },
            "a30cf4c57f77d450832889b0ab7d023cab19c726a81603100aa194d42a1a7dcb": {
                "Name": "centos05",
                "EndpointID": "b3dcc03466c4770df96877b7a209cdca3b0f320473a96b7a8742b08d0d05e47d",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/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": {}
    }
]
[root@zhanghuixiong ~]#

结语

到这里呢差不多就是我对docker网络的探索之路,更希望能对我未能发觉的错误做出指正,我会很认真的接受,当然了,路还很长,怎能止步不前呢,就像hoyeong所说,真正的大佬,通常都是怀着一颗学徒的心!!!