Docker0网络详解

linux可以ping通docker容器内部
docker容器也可以互相ping

容器A与容器B有一个公用的路由器 docker0
只要安装了docker就会有一个网卡docker0
不指定网络的情况下,都是docker0路由的,docker会给容器分配一个可用的ip

容器与docker0之间是桥接模式,使用的是veth-pair技术
veth-pair是一对虚拟设备接口,成对出现,一端接着协议,一端彼此相连,用来充当桥梁连接各种虚拟网络设备


容器互联 –link(已经不建议使用)

创建一个tomcat02 前面还用同样的方式创建了tomcat01

1
docker run -d -P --name tomcat02 tomcat

用tomcat02直接ping tomcat01的ip 可以ping通

1
2
3
[root@Assass1n ~]# 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.xx.0.2: icmp_seq=1 ttl=64 time=0.095 ms

ping名字则无法ping通

1
2
[root@Assass1n ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known

--link创建一个tomcat03容器 ping tomcat02

1
docker run -d -P --name tomcat03 --link tomcat02 tomcat

成功ping通
反向则无法ping通

原理

1
2
3
4
5
6
7
8
9
[root@Assass1n ~]# 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 d850e0a19297
172.17.0.4 a5b166ef9e50

在hosts文件中写死了tomcat02的ip,所以可以直接用名字ping


自定义网络

查看所有docker网络

1
2
3
4
5
6
[root@Assass1n ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
a09fbbf08c5a bridge bridge local
dd2554509609 docker_default bridge local
69c73198c123 host host local
e75c66799c64 none null local

网络模式

1
2
3
4
bridge:桥接 docker(默认,自己创建也使用bridge模式)
none:不配置网络
host:和宿主机共享网络
container:容器网络连通(局限大,用的少)

创建

1
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
1
2
3
--driver bridge:使用bridge模式
--subnet 192.168.0.0/16:子网段 192.168.0.2 ~ 192.168.255.255
--gateway 192.168.0.1:网关地址

检查网络信息

1
docker network inspect mynet

在自定义网络下创建容器

1
docker run -d -P --name tomcat-net-01 --net mynet tomcat

在同一个网络下的容器即使没有--link也可以用名字ping通

网络连通

网络和网络之间无法直接打通
但是可以使容器和网络相连

1
docker network connect mynet tomcat01

检查时发现将tomcat01容器加进了mynet中

一个容器两个ip地址


实战redis集群部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 创建网卡
docker network create redis --subnet 172.38.0.0/16

# 通过脚本创建六个redis容器
for port in $(seq 1 6);\
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

# 启动
for port in $(seq 1 6);\
do \
docker run -p 637${port} -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
done


# 进入容器
docker exec -it redis-1 /bin/sh

redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

# redis相关命令
redis-cli -c #有-c才是集群
cluster nodes

# 如果主机挂了,从机会替补上