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通,可证两(多)服务器。通信正常
查看网络地址
# 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宿主机
启动一个容器,在镜像内
ping 192.168.0.198(宿主机地址,由 ip a 中 eth0所知)
# Docker 启动tomcat
docker run -it --name tomcat01 tomcat ping 192.168.0.198
测试结果如下
宿主机与Docker容器
查看Tomcat服务地址
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
容器的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单向连接
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
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网络
root@ecs-dc8a-0003:~# docker network ls NETWORK ID NAME DRIVER SCOPE 2c76e02c3c6d bridge bridge local 3e6c8ff6eb88 host host local a573bbc92227 none null local
# 启动 docker run -d -P --name tomcat01 [--net bridge] tomcat # docker0特点:默认, 域名不能访问,--link 后单向访问
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
创建网络
docker network create [--driver brideg] --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# 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:~#
使用自定义网络
# 开启服务 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,正常访问。有兴趣可自行测试
网络连通
# 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
# 链接网络 docker network connect mynet tomcat01 # 检查 docker network inspect mynet
一个容器俩个IP
实战-部署Redis集群
# 创建网络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