Docker网络详解

2020-12-18 10:34:56 浏览数 (1)

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宿主机

启动一个容器,在镜像内 ping 192.168.0.198(宿主机地址,由 ip a 中 eth0所知)

代码语言:javascript复制
# 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

容器的ip可能改变,如何强制进行之间通信?

代码语言:javascript复制
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

0 人点赞