使用docker network的好处是:在同一个网络上的容器之间可以相互通信,而无需使用expose端口特性

本文使用docker-swarm进行overlay网络的分析。使用2个vmware模拟2个node节点,不关注swarm的使用,无关信息会有所删减,如不相关的接口或端口

  • 将node1作为master,在node1上执行init swarm,初始化swarm环境
# docker swarm init

启动docker swarm之后可以在host上看到启动了2个端口:2377和7946,2377作为cluster管理端口,7946用于节点发现。swarm的overlay network会用到3个端口,由于此时没有创建overlay network,故没有4789端口(注:4789端口号为IANA分配的vxlan的UDP端口号)。官方描述参见use overlay network

# netstat -ntpl
tcp6 0 0 :::2377 :::* LISTEN 3333/dockerd-curren
tcp6 0 0 :::7946 :::* LISTEN 3333/dockerd-curren
  • 设置node2加入swarm,同时该节点上也会打开一个7946端口,与swarm服务端通信。
docker swarm join --token SWMTKN-1-62iqlof4q9xj2vmlwlm2s03xfncq6v9urgysg96f4npe2qeuac-4iymsra0xv4f7ujtg1end3qva 192.168.80.130:2377
  • 在node1上查看节点信息,可以看到2个节点信息,即node1和node2
# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
50u2a7anjo59k5yw4p4namzv4 localhost.localdomain Ready Active
qetcamqa2xgk5rvpmhf03nxu1 * localhost.localdomain Ready Active Leader

查看网络信息,可以发现新增了如下网络,docker_gwbridge和ingress,前者提供通过bridge方式提供容器与host的通信,后者在默认情况下提供通过overlay方式与其他容器跨host通信

# docker network ls
NETWORK ID NAME DRIVER SCOPE
6405d33c608c docker_gwbridge bridge local
lgcns0epsksl ingress overlay swarm
  • 在node1创建一个自定义的overlay网络
docker network create -d overlay --attachable my-overlay 
  • 在node1上创建一个连接到my-overlay的容器
# docker run -itd --network=my-overlay --name=CT1 centos /bin/sh

在node2上创建连接到my-overlay的容器

# docker run -itd --network=my-overlay --name=CT2 centos /bin/sh

  在CT2上ping CT1的地址,可以ping通

sh-4.2# ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=1.20 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.908 ms

  查看node2上CT2容器的网络信息,可以看到overlay网络的接口为eth0,它对应的对端网卡编号为26;eth1对应的对端网卡编号为28,该网卡连接的网桥就是docker_gwbridge

sh-4.2# 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
25: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
link/ether 02:42:0a:00:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.0.0.3/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:aff:fe00:3/64 scope link
valid_lft forever preferred_lft forever
27: eth1@if28: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet 172.18.0.3/16 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe12:3/64 scope link
valid_lft forever preferred_lft forever
sh-4.2# ip route
default via 172.18.0.1 dev eth1
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.3
172.18.0.0/16 dev eth1 proto kernel scope link src 172.18.0.3

  CT2的eth1对应的网卡即为host上的vethd4eadd9,非overlay的报文使用该bridge转发,转发流程参见docker网络之bridge

# ip link show master docker_gwbridge
23: veth5d40a11@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP mode DEFAULT group default
link/ether 6a:4a:2a:95:dc:73 brd ff:ff:ff:ff:ff:ff link-netnsid 1
28: vethd4eadd9@if27: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP mode DEFAULT group default
link/ether d6:90:57:a6:44:e0 brd ff:ff:ff:ff:ff:ff link-netnsid 3

overlay的网络通过CT2容器的eth0流出,那eth0对应的对端网卡在哪里?由于CT2连接到名为my-overlay的网络,在/var/run/docker/netns下查看该网络对应的namespace(1-9gtpq8ds3g),可以看到eth0对应该my-overlay的veth2,且它们连接到bridge br0

# docker network ls
NETWORK ID NAME DRIVER SCOPE
2cd167c9fb17 bridge bridge local
d84c003d86f9 docker_gwbridge bridge local
e8476b504e33 host host local
lgcns0epsksl ingress overlay swarm
9gtpq8ds3gsu my-overlay overlay swarm
96a70c1a9516 none null local # ll
total 0
-r--r--r--. 1 root root 0 Nov 25 08:05 1-9gtpq8ds3g
-r--r--r--. 1 root root 0 Nov 25 08:05 1-lgcns0epsk
-r--r--r--. 1 root root 0 Nov 25 08:05 dd845ad1c97a
-r--r--r--. 1 root root 0 Nov 25 08:05 ingress_sbox # nsenter --net=1-9gtpq8ds3g ip a
2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
link/ether 8a:11:66:30:16:aa brd ff:ff:ff:ff:ff:ff
inet 10.0.0.1/24 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::6823:3dff:fe77:c01c/64 scope link
valid_lft forever preferred_lft forever
24: vxlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master br0 state UNKNOWN group default
link/ether 8a:11:66:30:16:aa brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::8811:66ff:fe30:16aa/64 scope link
valid_lft forever preferred_lft forever
26: veth2@if25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master br0 state UP group default
link/ether fe:41:38:d6:00:c6 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::fc41:38ff:fed6:c6/64 scope link
valid_lft forever preferred_lft forever
# nsenter --net=1-9gtpq8ds3g ip link show master br0
24: vxlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master br0 state UNKNOWN mode DEFAULT group default
link/ether 8a:11:66:30:16:aa brd ff:ff:ff:ff:ff:ff link-netnsid 0
26: veth2@if25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master br0 state UP mode DEFAULT group default
link/ether fe:41:38:d6:00:c6 brd ff:ff:ff:ff:ff:ff link-netnsid 1
# nsenter --net=1-9gtpq8ds3g ip route
10.0.0.0/24 dev br0 proto kernel scope link src 10.0.0.1

  这样overlay在CT2上的报文走向如下,所有的容器使用bridge方式直接连接在默认的docker_gwbridge上,而overlay方式通过在my-overlay上的br0进行转发。这样做的好处是,当在一个host上同时运行多个容器的时候,仅需要一个vxlan的udp端口即可,所有的vxlan流量由br0转发。

  br0的vxlan(该vxlan是由swarm创建的)会在host上开启一个4789的端口,报文过该端口进行跨主机传输

# netstat -anup
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 0.0.0.0:4789 0.0.0.0:*

  在CT2上ping CT1,并在node2上开启tcpdump抓包,可以看到有vxlan的报文

# tcpdump -i ens33 udp and port 4789
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
16:31:41.604930 IP localhost.localdomain.57170 > 192.168.80.130.4789: VXLAN, flags [I] (0x08), vni 4097
IP 10.0.0.3 > 10.0.0.2: ICMP echo request, id 138, seq 1, length 64
16:31:41.606434 IP 192.168.80.130.45035 > localhost.localdomain.4789: VXLAN, flags [I] (0x08), vni 4097
IP 10.0.0.2 > 10.0.0.3: ICMP echo reply, id 138, seq 1, length 64

CT2 ping CT1的ping报文如下,可以看到外层为node2节点的地址,通过udp目的端口上送到node1的vxlan端口处理

实现一个基于自定义的overlay网络

组网如下,2个node节点上分别创建一个bridge和一个netns,使用单播方式指定对端node(vxlan的多播方式参见linux 上实现 vxlan 网络)。

  • node1配置如下(端口最好使用IANA指定的端口4789,其他端口wireshark无法解析):
ip netns add netns1
ip link add my-br type bridge
ip link add veth_C type veth peer name veth_H
ip link add vxlan100 type vxlan id dstport remote 192.168.80.137 local 192.168.80.134 dev ens33 ip link set veth_C netns netns1
ip netns exec netns1 ip addr add 1.1.1.1/ dev veth_C
ip netns exec netns1 ip link set dev veth_C up ip link set dev my-br up
ip link set dev vxlan100 up
ip link set dev veth_H up
ip link set dev veth_H master my-br
ip link set dev vxlan100 master my-br
  • node2配置如下:
ip netns add netns2
ip link add my-br type bridge
ip link add veth_C type veth peer name veth_H
ip link add vxlan100 type vxlan id dstport remote 192.168.80.134 local 192.168.80.137 dev ens33 ip link set veth_C netns netns2
ip netns exec netns2 ip addr add 1.1.1.2/ dev veth_C
ip netns exec netns2 ip link set dev veth_C up ip link set dev my-br up
ip link set dev vxlan100 up
ip link set dev veth_H up
ip link set dev veth_H master my-br
ip link set dev vxlan100 master my-br

这样在node2的netns2上ping node1的netns1就可以ping通了

# ip netns exec netns2 ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1) () bytes of data.
bytes from 1.1.1.1: icmp_seq= ttl= time=0.342 ms
bytes from 1.1.1.1: icmp_seq= ttl= time=0.460 ms

 TIPS:

可以使用ip -d link show的方式查看接口的详细信息,如在node2上查看vxlan100的结果如下:

# ip -d link show vxlan100
: vxlan100: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue master my-br state UNKNOWN mode DEFAULT group default qlen
link/ether a6::2a:b4:8f:d7 brd ff:ff:ff:ff:ff:ff promiscuity
vxlan id remote 192.168.80.134 local 192.168.80.137 dev ens33 srcport dstport ageing noudpcsum noudp6zerocsumtx noudp6zerocsumrx
bridge_slave state forwarding priority cost hairpin off guard off root_block off fastleave off learning on flood on port_id 0x8002 port_no 0x2 designated_port designated_cost designated_bridge .a6::2a:b4:8f:d7 designated_root .a6::2a:b4:8f:d7 hold_timer 0.00 message_age_timer 0.00 forward_delay_timer 0.00 topology_change_ack config_pending proxy_arp off proxy_arp_wifi off mcast_router mcast_fast_leave off mcast_flood on addrgenmode eui64 numtxqueues numrxqueues gso_max_size gso_max_segs
  • 使用bridge -s fdb show br 可以显示bridge的mac转发表,在node2上查看my-br的mac转发表如下:

第一列表示目的mac地址,全0的mac地址表示默认mac地址,类似默认路由;第三列表示达到目的mac的出接口,后面self表示自身的意思,即该条表项类似到达loopback接口的路由,permanent表示该表项是永久的。最后一条默认mac转发表中可以看到,到达node1(192.168.80.138)的出接口为vxlan100,对应设备接口为ens33(该设置是在创建vxlan接口时创建的)。used表示该表项使用/更新的时间。

# bridge -s fdb show br my-br
::::: dev my-br self permanent
::5e::: dev my-br self permanent
::ff::9c: dev my-br self permanent
e6:2f::c4::e0 dev veth_H used / master my-br permanent
e6:2f::c4::e0 dev veth_H vlan used / master my-br permanent
::::: dev veth_H self permanent
::5e::: dev veth_H self permanent
::ff:c4::e0 dev veth_H self permanent
a6::2a:b4:8f:d7 dev vxlan100 used / master my-br permanent
a6::2a:b4:8f:d7 dev vxlan100 vlan used / master my-br permanent
00:00:00:00:00:00 dev vxlan100 dst 192.168.80.134 via ens33 used 3156/6092 self permanent
  • 特别注意:在自建overlay的场景下,最好关闭防火墙,否则报文可能无法上送到vxlan端口,也可以使用firewall-cmd命令单独开放vxlan端口,如下开放vxlan的4789端口
firewall-cmd --zone=public --add-port=/udp --permanent
firewall-cmd --reload

参考:

https://docs.docker.com/v17.12/network/overlay/#create-an-overlay-network

https://www.securitynik.com/2016/12/docker-networking-internals-container.html

http://blog.nigelpoulton.com/demystifying-docker-overlay-networking/

https://github.com/docker/labs/blob/master/networking/concepts/06-overlay-networks.md

https://cumulusnetworks.com/blog/5-ways-design-container-network/

https://neuvector.com/network-security/docker-swarm-container-networking/

http://man7.org/linux/man-pages/man8/bridge.8.html

docker网络之overlay的更多相关文章

  1. Docker Swarm 创建overlay网络

    Docker Swarm 创建overlay网络 环境: 系统:Centos 7.4 x64 应用版本:Docker 18.09.0 管理节点:192.168.1.79 工作节点:192.168.1. ...

  2. docker 使用swarm overlay网络时,报“network xx not manually attachable”错误解决

    当使用swarm的overlay网络,在该网络中运行容器时报“network xx not manually attachable”的错误 docker network create -d overl ...

  3. docker 跨主机网络:overlay 简介

    简介 docker 在早前的时候没有考虑跨主机的容器通信,这个特性直到 docker 1.9 才出现.在此之前,如果希望位于不同主机的容器能够通信,一般有几种方法: 使用端口映射:直接把容器的服务端口 ...

  4. 理解Docker(5):Docker 网络

    本系列文章将介绍 Docker的相关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...

  5. docker网络配置方法总结

    docker启动时,会在宿主主机上创建一个名为docker0的虚拟网络接口,默认选择172.17.42.1/16,一个16位的子网掩码给容器提供了65534个IP地址.docker0只是一个在绑定到这 ...

  6. docker网络解析

    Docker概念和默认网络 什么是Docker网络呢?总的来说,网络中的容器们可以相互通信,网络外的又访问不了这些容器.具体来说,在一个网络中,它是一个容器的集合,在这个概念里面的一个容器,它会通过容 ...

  7. 一文搞懂各种 Docker 网络 - 每天5分钟玩转 Docker 容器技术(72)

    前面各小节我们先后学习了 Docker Overaly,Macvaln,Flannel,Weave 和 Calico 跨主机网络方案.目前这个领域是百家争鸣,而且还有新的方案不断涌现. 本节将从不同维 ...

  8. Docker 网络之进阶篇

    笔者在<Docker 基础 : 网络配置>一文中简单介绍了容器网络的基本用法,当时网络的基本使用方式还处于 --link 阶段.时过境迁,随着 docker 的快速发展,其网络架构也在不断 ...

  9. Docker网络(五)--技术流ken

    本章内容 1.dokcer默认自带的几种网络介绍 2. 自定义网络 3. 容器间通信 4. 容器与外界交互 docker网络分为单个主机上的容器网络和多个主机上的哇网络,本文主要讲解单个主机上的容器网 ...

随机推荐

  1. leaflet入门(五)API翻译(下)

    L.PointConstructor(函数构造器)Properties(属性)Methods(方法) L.BoundsConstructor(函数构造器)Properties(属性)Methods(方 ...

  2. python计算机硬件基础以及变量常量常量池,解释器编译器比较,python的两种运行方式

    1.什么是编程语言 语言是一个事物与另外一个事物沟通的介质 编程语言是程序员与计算机沟通的介质 2.什么是编程 编程就是程序按照某种编程语言的语法规范将自己想要让计算机做的事情表达出来 表达的结果就是 ...

  3. 踏破铁鞋无觅处,从AsyncTask学Android线程池

    android对于主线程的响应时间限制的非常严格,稍有不慎就会遇到Application Not Responding(ANR)的弹框.用户可以轻点手指关掉你的APP.官方文档写的非常明确!同时,保持 ...

  4. Forward团队-爬虫豆瓣top250项目-代码设计规范

    组长地址:http://www.cnblogs.com/mazhuangmz/p/7603641.html 成员:马壮,李志宇,刘子轩,年光宇,邢云淇,张良 1.缩进采用一个Tab键 2.大括号:如: ...

  5. 项目管理系统Redmine(v1.1.2)安装手记

    一.环境   1.硬件 普通PC.   2.软件 Windows 2003操作系统.   二.下载必要的软件   1.Ruby 1.8.x Redmine是基于Ruby On Rails的软件,所以首 ...

  6. java基础-day19

    第08天 异常 今日内容介绍 u  异常体系&异常处理 u  Throwable常用方法&自定义异常 u  递归 第1章   异常产生&异常处理 1.1      异常概述 什 ...

  7. Webpack 学习2

    webpack + react 优化:缩小js包体积 webpack 介绍 & 安装 & 常用命令 30分钟手把手教你学webpack实战 Webpack 中文指南

  8. Apache Flink 漫谈系列

    阿里云讲Flink的,还是蛮不错 https://yq.aliyun.com/articles/666043?spm=a2c4e.11153940.blogcont679659.23.9fae56e7 ...

  9. 一.认识python.变量.数据类型.条件if

    01.万恶之源-python基础 ⼀.python介绍  python的创始⼈为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决⼼ ...

  10. SRM481

    250pt 题意:上帝知道一个“先有鸡还是先有蛋”的答案,上帝和N<=10^6个人说了答案,不过有x个人故意告诉了他们错误的答案,然后有一个人问了这N个人问题的答案,有M个人说先有鸡,N-M个人 ...