Docker 网络
Docker网络原理
每启动一个Docker 容器,docker 将给docker 容器分配一个ip
只要启动了docker 就会有一个docker0
网络使用的是桥接模式,evth-pair技术
桥接模式 直接连接到实际的网络上,可以理解为与宿主机没有任何联系 理解:手机、电脑连接路由器,wifi就是之间的桥梁 host-only(主机模式) 所有的虚拟系统是可以相互通信的,但虚拟系统和真实的网络是被隔离开的。 理解:VM中所有虚拟机可相互通信,但真实机器与虚拟机之间不能相互访问 NAT(网络地址转换模式) NAT模式下的虚拟系统的TCP/IP配置信息是由VMnet8(NAT)虚拟网络的DHCP服务器提供的,无法进行手工修改,因此虚拟系统也就无法和本局域网中的其他真实主机进行通讯。采用NAT模式最大的优势是虚拟系统接入互联网非常简单,你不需要进行任何其他的配置,只需要宿主机能访问互联网即可。 veth-pair 就是一对的虚拟设备接口,和 tap/tun 设备不同的是,它都是成对出现的。一端连着协议栈,一端彼此相连着。 veth pair 不是一个设备,而是一对设备,以连接两个虚拟以太端口。操作veth pair,需要跟namespace一起配合,不然就没有意义。
网络互通性测试
若两网络可ping通,可证两(多)服务器。通信正常
查看网络地址
代码语言:javascript复制# ip a
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 mq state UP group default qlen 1000
link/ether fa:16:3e:0e:c1:2c brd ff:ff:ff:ff:ff:ff
inet 192.168.0.198/24 brd 192.168.0.255 scope global dynamic noprefixroute eth0
valid_lft 64952sec preferred_lft 64952sec
inet6 fe80::f816:3eff:fe0e:c12c/64 scope link
valid_lft forever preferred_lft forever
# 。。。。8: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:7f:4c:51:60 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:7fff:fe4c:5160/64 scope link
valid_lft forever preferred_lft forever
1: lo: 本机回环地址 2: eth0: 服务器内网地址 8:docker0: docker 回环地址
docker内 ping宿主机
代码语言:javascript复制启动一个容器,在镜像内 ping 192.168.0.198(宿主机地址,由 ip a 中 eth0所知)
# Docker 启动tomcat docker run -it --name tomcat01 tomcat ping 192.168.0.198
测试结果如下
宿主机与Docker容器
查看Tomcat服务地址
代码语言:javascript复制root@ecs-dc8a-0003:~# docker exec -it tomcat01 /bin/bash
root@c29a5f95de97:/usr/local/tomcat# ip a
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
133: eth0@if134: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# Docker 中Tomcat 服务IP:172.17.0.2
Docker 容器服务 ping Docker 容器服务
结构如下
感兴趣可自行演示
docker网络通信结构图
结论:tomcat01 与tomcat02 共有一个路由器(Docker0)
容器互联 —link
代码语言:javascript复制容器的ip可能改变,如何强制进行之间通信?
docker exec -it tomcat02 ping tomcat01
ping:tomcat01:Name or service not know
# --link 更具自定义name单向连接
docker run -d -P --name tomcat02 --link tomcat01 tomcat
c71cbe1e421329034f06a798c3f41cab6d218e7b79d146c55ab37062313e1800
docker exec -it ping tomcat01
Error: No such container: ping
root@ecs-dc8a-0003:~# docker exec -it tomcat02 ping tomcat01
PING tomcat01 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.089 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.031 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=3 ttl=64 time=0.028 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=4 ttl=64 time=0.032 ms
—link 根据自定义name单向连接
代码语言:javascript复制docker run -d -P --name tomcat02 --link tomcat01 tomcat
c71cbe1e421329034f06a798c3f41cab6d218e7b79d146c55ab37062313e1800
docker exec -it ping tomcat01
Error: No such container: ping
root@ecs-dc8a-0003:~# docker exec -it tomcat02 ping tomcat01
PING tomcat01 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.089 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.031 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=3 ttl=64 time=0.028 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=4 ttl=64 time=0.032 ms
代码语言:javascript复制root@ecs-dc8a-0003:~# docker exec -it tomcat02 cat /etc/hosts127.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-allrouters172.17.0.2 tomcat01 c29a5f95de97172.17.0.3 c71cbe1e4213
—link :在hosts配置中增加一个172.17.0.2 tomcat01 c29a5f95de97 的映射
自定义网络
容器互联
查看所有的docker网络
代码语言:javascript复制root@ecs-dc8a-0003:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
2c76e02c3c6d bridge bridge local
3e6c8ff6eb88 host host local
a573bbc92227 none null local
代码语言:javascript复制
# 启动
docker run -d -P --name tomcat01 [--net bridge] tomcat
# docker0特点:默认, 域名不能访问,--link 后单向访问
代码语言:javascript复制Create a network
Options:
--attachable Enable manual container attachment
--aux-address map Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
--config-from string The network from which copying the configuration
--config-only Create a configuration only network
-d, --driver string Driver to manage the Network (default "bridge")
--gateway strings IPv4 or IPv6 Gateway for the master subnet
--ingress Create swarm routing-mesh network
--internal Restrict external access to the network
--ip-range strings Allocate container ip from a sub-range
--ipam-driver string IP Address Management Driver (default "default")
--ipam-opt map Set IPAM driver specific options (default map[])
--ipv6 Enable IPv6 networking
--label list Set metadata on a network
-o, --opt map Set driver specific options (default map[])
--scope string Control the network's scope
--subnet strings Subnet in CIDR format that represents a network segment
创建网络
代码语言:javascript复制docker network create [--driver brideg] --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
代码语言:javascript复制
# docker network create --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet# docker network lsNETWORK ID NAME DRIVER SCOPE2c76e02c3c6d bridge bridge local3e6c8ff6eb88 host host local1a961534f907 mynet bridge local
a573bbc92227 none null local# docker network inspect mynet [
{ "Name": "mynet", "Id": "1a961534f907193562b4391235a6e898d53be96c99b561d178db25013217f5dc", "Created": "2020-10-02T23:37:31.941000752 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@ecs-dc8a-0003:~#
使用自定义网络
代码语言:javascript复制# 开启服务
docker run -d -P --name mynet_tomcat01 --net mynet tomcat
docker run -d -P --name mynet_tomcat01 --net mynet tomcat
# 验证
# mynet_tomcat01 ping mynet_tomcat02
docker exec -it mynet_tomcat01 ping mynet_tomcat02
mynet_tomcat02 ping mynet_tomcat01
docker exec -it mynet_tomcat02 ping mynet_tomcat01
可直接更具自定义镜像名相互ping,正常访问。有兴趣可自行测试
网络连通
代码语言:javascript复制
# Connect a container to a networkdocker network connect [OPTIONS] NETWORK CONTAINER
Options:
--alias strings Add network-scoped alias for the container
--driver-opt strings driver options for the network
--ip string IPv4 address (e.g., 172.30.100.104)
--ip6 string IPv6 address (e.g., 2001:db8::33)
--link list Add link to another container
--link-local-ip strings Add a link-local address for the container
代码语言:javascript复制# 链接网络
docker network connect mynet tomcat01
# 检查
docker network inspect mynet
一个容器俩个IP
实战-部署Redis集群
代码语言:javascript复制# 创建网络docker network create redis --subnet 192.38.0.0/16 # 脚本创建多个redis.conffor 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 6379bind 0.0.0.0cluster-enabled yes
cluster-config-file nodes.conf
cluster-config-timeout 5000cluster-announce-ip 172.38.0.1${port}cluster-announce-port 6379cluster-announce-bus-port 16379appendonly yes
EOFdonefor port in $(seq 1 6); do
docker run -itd -p 637${port}:6379 -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
--net redis --ip 192.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
donedocker run -p 6371:6379 -p 16371:16379 --name redis-1
-v /mydata/redis/node-1/data:/data
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 192.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf