一:如何解决容器之间的网络互相通信。
(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网络的基配置已经讲解完成了。