①. Docker默认网络原理
- ①. 在linux下使用 ip addr
- lo: 本地所有的
- ethO:虚拟机的私有ip地址 172.28.0.3(所处的路由器分配的),公网不能访问
- docker0:是一个桥接网络 172.17.0.1/16,这里的/16是什么意思呢?
(点分10进制 11111111.11111111.11111111.11111111,172.17.0.2/16 是前16位不变(也就是172.17不变) ,现在能分配到的ip是 256*256-2(子网域))
- ②. 环境搭建:拉取一个alpine的镜像,基于这个镜像启动两个容器,进入容器查看各自的ip addr,最后我们重开一个窗口,使用ip addr 查看linux下的网络情况
# 第一个窗口
# 内部有一个330,外部有一个331对应
[root@i-id8g0yu9 ~]# docker run -it --name myalpine1 alpine
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
330: eth0@if331: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 第二个窗口
[root@i-id8g0yu9 ~]# docker run -it --name myalpine2 alpine
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
332: eth0@if333: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
/ #
# 第三个窗口
[root@i-id8g0yu9 ~]# ip addr
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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:99:b7:86:34 brd ff:ff:ff:ff:ff:ff
inet 172.28.0.3/24 brd 172.28.0.255 scope global noprefixroute dynamic eth0
valid_lft 79710sec preferred_lft 79710sec
inet6 fe80::5054:99ff:feb7:8634/64 scope link
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:aa:2c:80:a6 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:aaff:fe2c:80a6/64 scope link
valid_lft forever preferred_lft forever
331: veth0808c3f@if330: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether c2:44:6c:bc:76:b8 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::c044:6cff:febc:76b8/64 scope link
valid_lft forever preferred_lft forever
333: vetha2656be@if332: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether ae:55:f3:40:d2:f3 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::ac55:f3ff:fe40:d2f3/64 scope link
valid_lft forever preferred_lft forever
[root@i-id8g0yu9 ~]#
- ③. 默认网络原理:Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
- Docker容器网络就很好的利用了Linux虚拟网络技术,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair)
- 每一个安装了Docker的linux主机都有一个docker0的虚拟网卡。桥接网卡
- 每启动一个容器linux主机多了一个虚拟网卡
②. 网络模式
③. 外部是如何访问tomcat或者redis的?
-
①. 使用(宿主机的ip:端口号)进行访问tomcat或者redis的时候,会根据启动容器的-p映射端口原则,找到对应的映射端口,通过 iptables -nL去查看容器内的端口对应的ip,通过这个ip就可以访问到docker中的容器(tomcat/ redis)
-
②. 默认、域名访问不通
[root@i-id8g0yu9 ~]# docker run -d --name mytomcat tomcat:jre8-alpine
2e4107a77847a3b1805b5010fe46bfd14c02b0389a6bc5c84f897547ad5c0f2d
[root@i-id8g0yu9 ~]# docker exec -it mytomcat /bin/bash
bash-4.4# ping myredis
ping: bad address 'myredis'
bash-4.4#
- ③. 容器之间互相ping通(–link), docker run -d -P --name=mytomcat1 --link=myredis tomcat:jre8-alpine;这种方式启动的时候,会查询–link的容器的ip并写死到当前容器的/etc/hosts下面;而是单向的,对方并不知道我的存在,问题: myredis ip地址变了不会更新(解决方案:使用自定义网络)
[root@i-id8g0yu9 ~]# docker run -d --name=mytomcat1 --link=myredis tomcat:jre8-alpine
0c5e60a75d031ef3b627eb0b794694e85c15c55cffee612597d356a3c1bf1f07
[root@i-id8g0yu9 ~]# docker exec -it mytomcat1 /bin/bash
bash-4.4# ping myredis
PING myredis (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.180 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.123 ms
64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.120 ms
^C
--- myredis ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.120/0.141/0.180 ms
bash-4.4# 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 myredis 4982a68fda73(容器id)
172.17.0.3 0c5e60a75d03(容器id)
[root@i-id8g0yu9 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0c5e60a75d03 tomcat:jre8-alpine "catalina.sh run" 2 minutes ago Up About a minute 8080/tcp mytomcat1
4982a68fda73 redis "docker-entrypoint.s…" 25 minutes ago Up 25 minutes 6379/tcp myredis
④. 自定义网络 解决域名互通问题
- ①. 创建网络以及查看网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway
docker network ls
# 创建网络
# --driver bridge桥接方式
# --subnet 子网范围
# --gateway 网关
[root@i-id8g0yu9 ~]docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
[root@i-id8g0yu9 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e5cd143c03d2 bridge bridge local
f32331eb0b47 host host local
78640edcbc51 mynet bridge local
a034131e72f2 none null local
- ②. 给容器指定网络
docker run -d -P --name mytomcat2 --network=mynet tomcat:jre8-alpine
"Networks": {
"mynet": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"b52789c95d6b"
],
"NetworkID": "78640edcbc51ba5eae3989e44ff88b9481bab7c171323c2ba4c90425b18cd31b",
"EndpointID": "2ce04296a84e5f79da2a2494ca24efdc387a4ec7976f6529984f76501e1c70bc",
"Gateway": "192.168.0.1",
"IPAddress": "192.168.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:c0:a8:00:02",
"DriverOpts": null
}
}
- ③. docker run -it --name myalpine6 --network container:mytomcat alpine
[root@i-id8g0yu9 ~]# docker run -it --name myalpine6 --network container:mytomcat alpine
/ # ping mytomcat
PING mytomcat (192.168.0.2): 56 data bytes
64 bytes from 192.168.0.2: seq=0 ttl=64 time=0.042 ms
64 bytes from 192.168.0.2: seq=1 ttl=64 time=0.088 ms
64 bytes from 192.168.0.2: seq=2 ttl=64 time=0.110 ms
^C
--- mytomcat ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.042/0.080/0.110 ms
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
351: eth0@if352: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:c0:a8:00:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.2/16 brd 192.168.255.255 scope global eth0
valid_lft forever preferred_lft forever
/ #
- ④. 跨网络连接别人就用。把mytomcat3加入到mynet网络
docker run -d -P --name mytomcat3 tomcat:jre8-alpine
# docker network connect [OPTIONS] NETWORK CONTAINER
docker network connect mynet mytomcat3