压缩包
docker网络(容器互联)
理解docker0
- 理解docker0
- ip addr 查看网络的配置

查看启动的容器的网络配置
docker exec -it tomcat01 ip addr
- 查看启动的容器的网络配置
- 查看容器的内部网络地址,ip addr,发现容器启动的时候会得到一个96: eth0@if97的ip地址,docker自动分配的

- 思考:linux 能不能ping 通我们的容器内部?
- 可以

原理
- 我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0,桥接模式,使用的技术就是evth-pair技术。

- 在启动一个容器,我们发现又多了一对网卡
- 我们发现这个容器带来的网卡,都是一对对的
- evth-pair 就是一对虚拟设备接口,他们都是成对出现的,一端连着协议,一端连着彼此

- 正是因为有这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备的
- 我们来测试下两个容器之间是不是能ping通

- 终极原理:docker0的路由转发
- 我们感觉好像是容器之间的通信是直接联通的,其实并不是,而是我们的docker0充当了路由器的功能,首先tomcat01发送一条信息通过evth-pair技术传到docker0,然后docker0通过路由配置/广播机制,将我们的信息在通过evth-pair技术传送到tomcat02中

- 所有的容器在不指定网络的情况下,都是docker0进行路由的,docker都会给我们的容器分配一个默认的可用的ip
- docker中所有的网络接口都是虚拟的,虚拟的转发效率高!
- 当我们删除了这个容器的时候,evth-pair也是直接就消失了,docker自动管理

通过名字来进行网络通信
- 通过名字来进行网络通信
- 问题
- 我们每次重新启动容器,docker都是重新自动的分配evth-pair的地址,这样就会产生一个问题,假设我们写了一个服务,我们在服务中访问mysql,我们的MySQL是通过容器开启的,项目代码中写的是mysql的容器地址,mysql突然崩了,在重启ip就发生了变化,我们服务访问不到mysql,这样服务就会出现问题
- 解决办法
- 查看网络详情
docker network inspect bridge
root@iZbp12kyfwxfku3288sr59Z:~# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "d80554cf321bff3d2821acfe37abdff08809fa1ee0f4a8d37693bb949e529476",
"Created": "2020-10-02T13:30:57.993132975+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1" # docker0
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": { # 容器的网络
"6fcc850bb9dda8098daae0129af2995a823330a79d6fc74a536e4f53b5bc093a": {
"Name": "tomcat02",
"EndpointID": "e54399c3dd68ca240379dfff6251652a888e61fa880b90334ac8cff872794521",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16", # tomcat02的网络
"IPv6Address": ""
},
"8d2b39b543083ba0028212ccf2fc986eeb9b7591662c28b0171321c7dcaf93d5": {
"Name": "tomcat01",
"EndpointID": "453f09d79583b22ce429d2054eb720b0666d2cfb0c5978379b6a7dd89aa2907f",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16", # tomcat01的网络
"IPv6Address": ""
},
"acf6df2a5d4e36e23b32aad793f1d28b9f91dfc1a53ecac569ec1c64f812ed3e": {
"Name": "tomcat03",
"EndpointID": "60eeb95e2e97d91070378771d2a4bd384e55e2285603232e067dd6cb25ebd622",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/16", # tomcat03的网络
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
- 查看所有网络
- 网络模式
- Bridge:桥接 docker(默认,自己创建也是使用的是桥接的模式)
- none:不配置网络
- Host: 和宿主机共享网络
- Container:容器网络联通(不推荐)
docker network ls
root@iZbp12kyfwxfku3288sr59Z:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
d80554cf321b bridge bridge local
0985e4179804 host host local
d95b28d99da4 none null local
自定义网络
- 默认命令的完整版
- 我们直接使用的run命令 --net bridge 而这个是我们的docker0
docker run -d -P --name tomcat01 --net bridge tomcat
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
- 参数
- --driver bridge 网络模式
- --subnet 192.168.0.0/16 定义网段和主机数目 255*255
- --gateway 192.168.0.0 网关路由

- 自定义网络mynet的详细信息
root@iZbp12kyfwxfku3288sr59Z:~# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "11690a7560b3c847045e9216a2fb3e91d90b0c8c8c5c3711ac57ce834ed0991b",
"Created": "2020-10-04T20:50:40.991733452+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,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
- 创建三个自定义网络下的容器
root@iZbp12kyfwxfku3288sr59Z:~# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "11690a7560b3c847045e9216a2fb3e91d90b0c8c8c5c3711ac57ce834ed0991b",
"Created": "2020-10-04T20:50:40.991733452+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,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": { # 在这个部分的容器选项中,包含了三个容器
"5ef9b87d364aafd27a509422bb24cdfbd249c2bcf74b2297b47bbfae1601b1e8": {
"Name": "tomcat-net-01",
"EndpointID": "e83f9febc5939b18d3e6c459c8564c12389c10cc2346678060327235437c23c3",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"99c0df5990a5ec9d78fc392eb0ee698d00f320e387b5a66d05782ea2013ac3a1": {
"Name": "tomcat-net-03",
"EndpointID": "41c4e5a4f2f5712a3a070e5337aa80021e8c13844cac1243aa1d8b371cb1679e",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
},
"cb12e21c37b83c38d894cca0a3b55816aebca90ba8b3b083289f28608d70a566": {
"Name": "tomcat-net-02",
"EndpointID": "ba491227f9a347145718fd051ff461aa1bd7200c66cacf3397a5a915a86e52a3",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
- 通过ip和容器名称进行ping的测试

- 我们自定义网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络
- 好处:
- 可以将不同的集群间建立不同的子网进行隔离,互不干扰
网络联通
实战
- 搭建redis的集群
- 第一步:创建子网
docker network create redis --subnet 172.38.0.0/16
- 第二步:使用shell脚本构建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
- 第三步:设置容器(自定义网络、卷映射、端口等)
# 将下面的红色数字替换成相应的1~6的序号就行
docker run -p 6376:6379 -p 16676:16379 --name redis-6 -v /mydata/redis/node-6/data:/data -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
- 第四步:进入redis的某一台机器
docker exec -it redis-1 /bin/sh #redis默认没有bash
- 第五步:创建集群,构建节点
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
- 测试搭建结果