一:如何解决容器之间的网络互相通信。
(1)第一种:同一物理机的上的两个容器之间如何通信:

解决方法:基于OVS(虚拟的开源软交换机程序),我们在物理机之上安装一个虚拟的软交换机,我们都知道容器也有单独的网络,当创建容器时会自动创建一对虚拟网卡。一个在虚拟软交换机上,一个在容器中,那们容器之间通信就基于软交换机通信即可。

(2)第二种:不同物理机上的虚拟交换机如何通信。

解决方法:当不同物理机上的虚拟交换机通信时,我们只需将虚拟机设置成桥接模式,把物理网卡当交换机使用。

(3)第三种:不同物理机上的容器之间如何访问?

解决方法:当不同物理机上的容器相互访问时,我们会把物理网卡上的OVS(虚拟交换机)当网卡使用,将报文发送给虚拟交换机,然后打开物理机的核心转发功能,将源地址改为物理机的网卡地址,然后访问另一台物理机网卡,当报文送到另一台物理机上,物理机通过DNAT方式与容器通信。

(4)第四种:叠加网路的实现

所谓叠加网路(Overlay
network)基于物理间隧道转发,叠加网路必须遵守:不同物理机在同一网络内,不同物理机上的容器必须在同一网络内。
通信格式:当物理机(w1)中的容器访问物理机(w2)中的容器时:容器1会将报文先交给虚拟桥物理网卡,然后再交给物理机(w2)最后转交给容器2,物理机都是被承载转发的。物理机,容器之间实现二层转发。

二:docker网络的分类:

(1)closed container(封闭式容器):只有lo接口不能实现网络通信。
(2)bridged container(桥接式网络):有虚拟网卡对,有lo接口,基于容器虚拟接口通信。
(3)联盟试容器:容器之间共享UTC,IPC,NET.
(4)open container(开放式容器网络):共享物理机的网卡设备,网络。

三:docker网络的相关配置

[root@node2 ~]# docker network ls       查看docker所支持的网络。
NETWORK ID          NAME                DRIVER              SCOPE
4573a5cdd3ac        bridge              bridge              local
76552af3e340        host                host                local
492877c7df79        none                null                local

[root@node2 ~]# docker run --name t1 -it --network none --rm httpd:latest    将docker网络设置成none,只有lo接口,不能进行通信。
--network:指明我们要设置的网络。 ---rm:表示我们退出容器时删除容器。
AH00557: httpd: apr_sockaddr_info_get() failed for 037e0669ac82
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
AH00557: httpd: apr_sockaddr_info_get() failed for 037e0669ac82
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
[Thu May 07 07:04:08.557264 2020] [mpm_event:notice] [pid 1:tid 139663259935872] AH00489: Apache/2.4.43 (Unix) configured -- resuming normal operations
[Thu May 07 07:04:08.557430 2020] [core:notice] [pid 1:tid 139663259935872] AH00094: Command line: 'httpd -D FOREGROUND'

[root@node2 ~]# docker run --name t1 -it --network bridge -h t1.shuoshuo.com --rm httpd:latest
将docker网络设置成bridge桥接网络,  -h:向容器注入的主机名称
--dns:指明DNS服务器。             --dns-searsh:指明搜索域
--add-host:域名:IP地址 :使用这个选项可以指明容器内/etc/hosts文件中IP地址与域名的解析绑定。
[Thu May 07 09:20:45.096324 2020] [mpm_event:notice] [pid 1:tid 140314062308480] AH00489: Apache/2.4.43 (Unix) configured -- resuming normal operations
[Thu May 07 09:20:45.096469 2020] [core:notice] [pid 1:tid 140314062308480] AH00094: Command line: 'httpd -D FOREGROUND'

[root@node2 ~]# docker exec -it t1 /bin/bash   进入到t1容器中查看相关修改。
root@t1:/usr/local/apache2# la
bash: la: command not found
root@t1:/usr/local/apache2# ls
bin  build  cgi-bin  conf  error  htdocs  icons  include  logs	modules
root@t1:/usr/local/apache2# 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.2	t1.shuoshuo.com t1
root@t1:/usr/local/apache2# hostname  
t1.shuoshuo.com
root@t1:/usr/local/apache2#

四:如何设置物理访问另一台物理机中容器中的web服务。

node2(docker)

node3

10.5.100.183

10.5.100.208

在docker中,我们物理机访问容器中服务时需要进行DNAT目标地址转换。使用-p选项
-p选项使用的格式:
(1):-p:将指定的容器端口映射至主机所有地址的一个动态端口
       -p <hostport>:<container port>:将容器端口映射至指定的主机端口<hostport>
         
(2):-p <ip>::<containerport>:将指定的容器端口映射至主机指定的ip的动态端口

(3):-p <ip>:<hostport>:<container>:将指定的容器端口映射至主机指定ip的端口<hostport>

"动态端口“指随机端口,具体的映射结果可使用docker port 命令查看

第一种-p方法的演示:

[root@node2 ~]# docker run --name t1 -it --rm -p 80 httpd:latest
端口映射情况都会记录在iptables规则当中。

AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Thu May 07 09:42:21.768687 2020] [mpm_event:notice] [pid 1:tid 139703923799168] AH00489: Apache/2.4.43 (Unix) configured -- resuming normal operations
[Thu May 07 09:42:21.768804 2020] [core:notice] [pid 1:tid 139703923799168] AH00094: Command line: 'httpd -D FOREGROUND'
10.5.100.48 - - [07/May/2020:09:43:15 +0000] "GET / HTTP/1.1" 200 45
10.5.100.48 - - [07/May/2020:09:43:15 +0000] "GET /favicon.ico HTTP/1.1" 404 196
10.5.100.48 - - [07/May/2020:09:44:06 +0000] "-" 408 -
10.5.100.208 - - [07/May/2020:09:44:11 +0000] "GET / HTTP/1.1" 200 45

[root@node2 ~]# iptables -t Nat -L
iptables v1.4.21: can't initialize iptables table `Nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
[root@node2 ~]# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
PREROUTING_direct  all  --  anywhere             anywhere            
PREROUTING_ZONES_SOURCE  all  --  anywhere             anywhere            
PREROUTING_ZONES  all  --  anywhere             anywhere            
DOCKER     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
OUTPUT_direct  all  --  anywhere             anywhere            
DOCKER     all  --  anywhere            !loopback/8           ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        anywhere            
POSTROUTING_direct  all  --  anywhere             anywhere            
POSTROUTING_ZONES_SOURCE  all  --  anywhere             anywhere            
POSTROUTING_ZONES  all  --  anywhere             anywhere            
MASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:http

Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            
DNAT       tcp  --  anywhere             anywhere             tcp dpt:32789 to:172.17.0.2:80   
上述映射结果将容器80端口映射至物理(虚拟)机的32789

[root@node2 ~]# curl 10.5.100.208:32789
<html><body><h1>It works!</h1></body></html>
[root@node2 ~]# 

如果是另一台物理机访问的话,我们需要打开地址转换功能。
[root@node2 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward   这种只是暂时打开了地址转换功能。重启网络就不行了
[root@node2 ~]# vim /etc/sysctl.conf      要想重启网络生效,必须写入配置文件中。
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv4.ip_forward = 1
~ 
[root@node2 ~]# systemctl restart network

打开物理机的网络地址功能。跟上述操作相同。
[root@node3 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@node3 ~]# vim /etc/sysctl.conf      
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv4.ip_forward = 1
~ 
[root@node3 ~]# systemctl restart network       

[root@node2 ~]# docker container ls
CONTAINER ID        IMAGE                COMMAND              CREATED             STATUS              PORTS                   NAMES
a381a877a3db        httpd:latest         "httpd-foreground"   4 days ago          Up 17 hours         0.0.0.0:32790->80/tcp   t1
244437368c16        yanss/httpd:v0.1-2   "sh"                 5 days ago          Up 5 days                                   web4
57392c202bd2        yanss/httpd:v0.1-1   "sh"                 12 days ago         Up 5 days                                   web3
[root@node2 ~]# docker restart t1   重启docker中容器。
t1
[root@node2 ~]# docker container ls
CONTAINER ID        IMAGE                COMMAND              CREATED             STATUS              PORTS                   NAMES
a381a877a3db        httpd:latest         "httpd-foreground"   4 days ago          Up 4 seconds        0.0.0.0:32791->80/tcp   t1
244437368c16        yanss/httpd:v0.1-2   "sh"                 5 days ago          Up 5 days                                   web4
57392c202bd2        yanss/httpd:v0.1-1   "sh"                 12 days ago         Up 5 days                                   web3
[root@node2 ~]# 
[root@node3 ~]# curl 10.5.100.208:32791     根据目标地址映射访问web服务。
<html><body><h1>It works!</h1></body></html>
[root@node3 ~]#

-p选项的第二种映射方法:将web服务映射为宿主机指定ip的随机端口

[root@node2 ~]# docker run --name t1 --rm -p 10.5.100.208::80 httpd:latest
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Tue May 12 03:33:26.099259 2020] [mpm_event:notice] [pid 1:tid 139866347693184] AH00489: Apache/2.4.43 (Unix) configured -- resuming normal operations
[Tue May 12 03:33:26.099408 2020] [core:notice] [pid 1:tid 139866347693184] AH00094: Command line: 'httpd -D FOREGROUND'

[root@node2 ~]# docker container ls -a
CONTAINER ID        IMAGE                COMMAND              CREATED             STATUS                    PORTS                        NAMES
b46a42816dc9        httpd:latest         "httpd-foreground"   27 seconds ago      Up 25 seconds             10.5.100.208:32768->80/tcp   t1
244437368c16        yanss/httpd:v0.1-2   "sh"                 5 days ago          Up 5 days                                              web4
57392c202bd2        yanss/httpd:v0.1-1   "sh"                 12 days ago         Up 5 days                                              web3
950bd2de0e28        busybox              "sh"                 12 days ago         Exited (137) 5 days ago                                web2
[root@node2 ~]# docker port t1
80/tcp -> 10.5.100.208:32768
[root@node2 ~]#

-p的第三种选项:将宿主机的80端口映射至docker中web服务的80端口

[root@node2 ~]# docker run --name t1 --rm -p 80:80 httpd:latest
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Tue May 12 07:48:00.957194 2020] [mpm_event:notice] [pid 1:tid 140045216781440] AH00489: Apache/2.4.43 (Unix) configured -- resuming normal operations
[Tue May 12 07:48:00.957376 2020] [core:notice] [pid 1:tid 140045216781440] AH00094: Command line: 'httpd -D FOREGROUND'
[root@node2 ~]# docker container ls
CONTAINER ID        IMAGE                COMMAND              CREATED             STATUS              PORTS                NAMES
592a26c979de        httpd:latest         "httpd-foreground"   10 seconds ago      Up 9 seconds        0.0.0.0:80->80/tcp   t1
244437368c16        yanss/httpd:v0.1-2   "sh"                 5 days ago          Up 5 days                                web4
57392c202bd2        yanss/httpd:v0.1-1   "sh"                 12 days ago         Up 5 days                                web3
[root@node2 ~]# docker port t1
80/tcp -> 0.0.0.0:80
[root@node2 ~]#

五:联盟式容器:共享IPC,network,utc

[root@node2 ~]# docker run --name web2 -it --rm busybox 
[root@node2 ~]# docker run --name web1 --network container:web2 -it --rm busybox 创建一个web1容器指明与web2的网络名称空间相同。
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:656 (656.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # 

[root@node2 ~]# docker exec -it web2 /bin/sh
/ # ls
bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:656 (656.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # exit

六:如何自定义修改docker 0桥的默认的ip地址

[root@node2 ~]# vi /etc/docker/daemon.json 
{
 "bip": "172.17.0.2/16",
 "registry-mirrors": [
     "https://a73cc22x.mirror.aliyuncs.com",
     "https://registry.docker-cn.com"
 ]
}
[root@node2 ~]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:d0ff:fef8:66b6  prefixlen 64  scopeid 0x20<link>
        ether 02:42:d0:f8:66:b6  txqueuelen 0  (Ethernet)
        RX packets 71  bytes 6418 (6.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 99  bytes 7722 (7.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

七:如何设置docker进程允许其他docker主机链接。

[root@node2 ~]# vi /etc/docker/daemon.json 
{
 "bip": "172.17.0.2/16",
 "registry-mirrors": [
     "https://a73cc22x.mirror.aliyuncs.com",
     "https://registry.docker-cn.com",
     "https": [  "tcp://0.0.0.0:2375" ,  "unix://var/run/docker.sock"
 ]
}

八,在docker中我们也可以创建一个自己的桥,默认是使用的docker0桥

[root@node2 ~]# docker network create -d bridge --subnet "172.16.0.8/16" --gateway "172.16.0.1" mybr0
4c4e6eb28b89764c38ceb0df2d4c57e54fffad79528f4083b7bfe82d41502614
-d:指明网络设备类型,   mybr0:这表示的是网络设备名称,  --subnet指明了子网段。
[root@node2 ~]# ifconfig
br-4c4e6eb28b89: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.16.0.1  netmask 255.255.0.0  broadcast 172.16.255.255
        ether 02:42:99:42:97:9c  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:d0ff:fef8:66b6  prefixlen 64  scopeid 0x20<link>
        ether 02:42:d0:f8:66:b6  txqueuelen 0  (Ethernet)
        RX packets 71  bytes 6418 (6.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 99  bytes 7722 (7.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

docker网络的基配置已经讲解完成了。