在通常情况下,Docker使用网桥(Bridge)与NAT的通信模式
网络通信解决的几个问题:
(1)容器与容器之间
容器与容器之间通过namesapce进行隔离,隔离为两端,一端放在宿主机,一端放在容器内部,容器与容器之间通过Docker0网桥的方式解决通信
(2)容器访问外部网络(SNAT转换)
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -o docker0 -j MASQUERADE
(3)外部网络访问容器(DNAT转换)
docker run -d -p 80:80 apache
添加:
iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
iptables -t nat -A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用IP。
Docker通信的基本原理
(1)Docker的网络接口是虚拟的接口
(2)虚拟的网络接口的转发的效率高
(3)宿主机的信息:
#网桥
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:49ff:fead:3df7 prefixlen 64 scopeid 0x20<link>
ether 02:42:49:ad:3d:f7 txqueuelen 0 (Ethernet)
RX packets 5541 bytes 310509 (303.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6428 bytes 9743745 (9.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
vethb419634: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::9c28:26ff:fe70:a646 prefixlen 64 scopeid 0x20<link>
ether 9e:28:26:70:a6:46 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7 bytes 586 (586.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
(4)到容器内查看网卡的信息:
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 6420 bytes 9742407 (9.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5541 bytes 388083 (378.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
(5)Docker创建容器的时候,会执行下面的操作
Docker进程网络修改,进程修改完所有的容器生效
Docker容器网络修改,只在修改的容器生效
暴露端口
-p/P选项的使用格式
docker port ContainerName/ContainerID:暴露所需要的所有端口
修改/etc/docker/daemon.json文件
{
"bip":"192.168.1.5/24",
"fixed-cidr":"10.20.0.0/16",
"fixed-cidr-v6":"2001:db8::/64",
"mtu":"1500",
"default-gateway":"10.20.1.1",
"default-gateway-v6":"2001:db8:abcd::89",
"dns":["10.20.1.2","10.20.1.3"]
}
[root@nod ~]# docker network create -d bridge lamp
[root@nod ~]# docker network create -d bridge lnmp
[root@nod ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
b56262be3330 bridge bridge local
f7c235f691cf host host local
b27ec591e92c lamp bridge local
069709451b61 lnmp bridge local
a845c75daa9c none null local
[root@nod ~]# docker run --name centsxx --network lamp -d hub.c.163.com/public/centos:6.7-tools
思考一个场景,我们编写了一个微服务,database url=ip,项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以名字来进行访问容器?
[root@nod tomcat]# docker exec tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
#如何可以解决呢?
[root@nod tomcat]# docker run -d --name tomcat03 --link tomcat02 diytomcat
#通过--link就可以解决了网络连通问题
[root@nod tomcat]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.4) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.4): icmp_seq=1 ttl=64 time=0.210 ms
64 bytes from tomcat02 (172.17.0.4): icmp_seq=2 ttl=64 time=0.116 ms
#反向可以ping通么?
[root@nod tomcat]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
探究:其实这个tomcat03就是在本地配置了tomcat02的配置
#查看hosts
[root@b58469eed04e local]# 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.4 tomcat02 9a6a8a0d5433
本质就是:–link就是我们在hosts配置中增加一个172.17.0.4 tomcat02 9a6a8a0d5433,Docker不建议使用–link了。
Docker0的问题:他不支持容器名连接访问!
#创建一个自定义网络
[root@nod tomcat]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
[root@nod tomcat]# docker run -d --name tomcat-net-01 --net mynet diytomcat
[root@nod tomcat]# docker run -d --name tomcat-net-02 --net mynet diytomcat
#自定义网络docker都已帮我们维护好了对应的关系,通过容器名称可以通。推荐使用自定义网络
[root@nod tomcat]# docker exec tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.125 ms
[root@nod tomcat]# docker exec tomcat-net-02 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.046 ms
#跨网段通信
[root@nod tomcat]# docker exec -it tomcat01 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known
通过把容器加入到网关中解决,相当于一个容器(tomcat-01)中有两个ip
[root@nod tomcat]# docker network connect mynet tomcat01
#连通之后就是将tomcat01放到了mynet网络下
[root@nod tomcat]# docker inspect mynet
[
{
"Name": "mynet",
"Id": "779f2474c31d2675003e8981612d11b34c0b09707bb3e67641830bb79221a78c",
"Created": "2021-12-05T20:23:44.975492399+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {
"03460b28c342fe40b5b9d8d1935c1f64700fae0f523ae912e1491c3fd96ae510": {
"Name": "tomcat-net-01",
"EndpointID": "3fe5a19690fc30380147a8a243d91cf11af2c7abc412dad7779f1c6d38d8ab2b",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"0ca7a7f12f0a125ef7c0bc78487d945d68ffa8f772a1554caf6757ca29384426": {
"Name": "tomcat-net-02",
"EndpointID": "296285916a674b1bb763cc7edae32f6ce0fcaf82afa0d350a8d9f5a79cc5e89b",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"7137c8ff401b333896bed79d63fbb9446c20d7f918c2d65665b02c8f2dad2c4c": {
"Name": "tomcat01",
"EndpointID": "d7c6b85e9c792527d42e8d5a3e130f36c7ce30349c814ff8c4b081940bf485e4",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
#测试
[root@nod tomcat]# docker exec tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.149 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.083 ms
[root@nod tomcat]# docker exec tomcat01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.312 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.417 ms