简介
- weave是由weaveworks公司开发的解决Docker跨主机网络的解决方案,它能够创建一个虚拟网络,用于连接部署在多台主机上的Docker容器,这样容器就像被接入了同一个网络交换机,那些使用网络的应用程序不必去配置端口映射和链接等信息
- 外部设备能够访问weave网络上的应用程序容器所提供的服务,同时已有的内部系统也能够暴露到应用程序容器上。weave能够穿透防火墙并运行在部分连接的网络上,另外,weave的通信支持加密,所以用户可以从一个不受信任的网络连接到主机。
- 对容器来说,weave 就像一个巨大的以太网交换机,所有容器都被接入这个交换机,容器可以直接通信,无需 NAT 和端口映射。除此之外,weave 的 DNS 模块使容器可以通过 hostname 访问
- weave 不依赖分布式数据库(例如 etcd 和 consul)交换网络信息,每个主机上只需运行 weave 组件就能建立起跨主机容器网络。但是同样也是其缺点:主机不能动态加入节点网络,只能手动通过weave launch或connect加入weave网络。不支持动态分配IP,所有IP需要手动管理及分配,难以保证分配的IP不冲突。
- 项目地址:https://github.com/weaveworks/weave
weave网络通信模型
-
weave通过在docker集群的每个主机上启动虚拟路由器,将主机作为路由器,形成互联互通的网络拓扑,在此基础上,实现容器的跨主机通信。其主机网络拓扑参见下图
-
在每一个部署Docker的主机上都部署有一个W(即weave router,它本身也可以以一个容器的形式部署)。weave网络是由这些weave routers组成的对等端点(peer)构成,并且可以通过weave命令行定制网络拓扑。
-
每个部署了weave router的主机之间都会建立TCP和UDP两个连接,保证weave router之间控制面流量和数据面流量的通过。控制面由weave routers之间建立的TCP连接构成,通过它进行握手和拓扑关系信息的交换通信。控制面的通信可以被配置为加密通信。而数据面由weave routers之间建立的UDP连接构成,这些连接大部分都会加密。这些连接都是全双工的,并且可以穿越防火墙
-
当容器通过weave进行跨主机通信时,其网络通信模型可以参考下图。对每一个weave网络中的容器,weave都会创建一个网桥,并且在网桥和每个容器之间创建一个veth pair,一端作为容器网卡加入到容器的网络命名空间中,并为容器网卡配置ip和相应的掩码,一端连接在网桥上,最终通过宿主机上weave router将流量转发到对端主机上。
-
基本过程
-
网卡设备
- Container eth0:eth0是容器主机的默认网络,主要提供容器访问外网所提供的服务,走的默认docker网络架构,只不过他创建了docker_gwbridge这个网桥。
- docker_gwbridge:docker_gwbridge是容器所创建的网桥它替代了docker0的服务。
- Contailner ethwe:它是veth pair虚拟设备对,与其他容器通信的网络虚拟网卡。
- vethwe-bridge:是ethwe设备对创建的weave网桥。网桥内分配的具体的IP与网关。
- weave:weave网桥,通过route路由表找到目标,通过端口将数据包转发到对端端口节点。
- eth0:真机网卡与外界网卡连接得真机网卡,它用来转发,容器VXLAN与NAT两种网卡类型的数据包到指定的对端节点。
安装
-
weave不需要集中式的
key-value
存储,直接安装即可 -
安装环境:
- Linux内核3.8及以上
- docker 1.10.0及以上
- 节点之间如果有防火墙时,必须彼此放行
TCP 6783
和UDP 6783/6784
端口,这是weave控制和数据端口。 - 主机名不能相同
-
安装
$ sudo curl -L https://git.io/weave -o /usr/local/bin/weave $ sudo chmod a+x /usr/local/bin/weave 测试是否安装成功 $ weave version weave script 2.8.1 weave 2.8.1
-
初始化weave网络
1. 安装必备依赖 $ yum install -y bridge-utils net-tools 2. 这条命令是在容器中运行一个weave router,需要在每台主机上都启用这个服务。 该服务需要三个docker容器来辅助运行,首次运行时会自动下载相关镜像 $ weave launch 或者使用weave setup 预加载镜像 设置环境变量,这样通过docker命令行启动的容器就会自动地连接到weave网络中了。 $ eval $(weave env) 3. 查看下载并运行的容器 $ docker ps weaveworks/weaveexec 2.8.1 e02bec83a27c 7 months ago 71.2MB weaveworks/weave 2.8.1 8de39aae7c4e 7 months ago 61.2MB weaveworks/weavedb latest 19661b1dbf28 8 months ago 698B 4. 还会生成一个名字叫weave的网桥,docker0是默认的。查看桥接 $ brctl show bridge name bridge id STP enabled interfaces docker0 8000.02429362485b no weave 8000.4231bec3cf76 no vethwe-bridge $ ifconfig weave weave: flags=4163<UP,broADCAST,RUNNING,MULTICAST> mtu 1376 inet6 fe80::4031:beff:fec3:cf76 prefixlen 64 scopeid 0x20<link> ether 42:31:be:c3:cf:76 txqueuelen 1000 (Ethernet) RX packets 14 bytes 936 (936.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 7 bytes 634 (634.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 docker中也会生成一个使用weave的网桥的自定义网络。 $ docker network ls docker network ls NETWORK ID NAME DRIVER ScopE 3dbd79b0c831 bridge bridge local b31f13c07393 host host local bc7e4b7556c4 none null local 468375b4740b weave weavemesh local 5. weave的数据保存在每台机器上分配的名为weavedb的容器上的, 它是一个data volume容器,只负责数据的持久化。
连接不同主机
-
机器:关闭两台机器的防火墙,如果打开防火墙,需要开放6783端口
主机名 IP地址 软件环境 docker1 192.168.100.140 weave、Docker Docker2 192.168.100.141 weave、Docker -
从docker1连接到docker2。只需要在
weave launch
后面跟上docker2主机的ip或者hostname就行了。两台机器就会自动建立集群,并同步所有需要的信息。1. 在docker1(192.168.100.140)上执行 这个命令相当于在本地启动了weave route,再通过weave connect 192.168.100.141来 和 $ weave launch 192.168.100.141 29d7b8b5740b71e065beb4fef1e86b904aa4e776a6c855b28aee6c270a5de3b9 2. 在docker2(192.168.100.141)上执行 $ weave launch 192.168.100.140 3. 查看状态信息 $ weave status Version: 2.8.1 (up to date; next check at 2021/09/21 17:04:19) Service: router Protocol: weave 1..2 Name: fe:f7:46:79:0c:d7(docker1) Encryption: disabled Peerdiscovery: enabled Targets: 1 Connections: 1 (1 established) # 建立连接 Peers: 2 (with 2 established connections) # 2 表示有两个节点 Trustedsubnets: none Service: ipam Status: ready Range: 10.32.0.0/12 Defaultsubnet: 10.32.0.0/12 Service: dns Domain: weave.local. Upstream: 192.168.100.2 TTL: 1 Entries: 6 Service: proxy Address: unix:///var/run/weave/weave.sock Service: plugin (legacy) DriverName: weave 4. 查看状态详情 $ weave status connections
-
如果要连接新的主机
$ weave connect $NEW_HOST
-
断开连接
$ weave forget $HOST
-
停止
$ weave stop
集成Docker
-
方式一:使用
weave env
方式1. 配置weave Net环境,以便通过Docker命令行启动的容器自动附加到weave网络 $ eval $(weave env) $ docker run -it --rm --name docker1-busyBox busyBox $ docker run -it --rm --name docker1-busyBox busyBox
-
方式二:使用
weave plugin
直接运行容器1. 在docker1上启动容器 $ docker run -it --rm --net=weave --name docker1-busyBox busyBox 2. 在docker2上启动容器 $ docker run -it --rm --net=weave --name docker2-busyBox busyBox 3. 可以在容器中看到,会多出一个网卡ethwe0 docker1下 $ ifconfig ...省略... ethwe0 Link encap:Ethernet HWaddr 7E:CA:30:FC:3E:8B inet addr:10.40.0.0 Bcast:10.47.255.255 Mask:255.240.0.0 UP broADCAST RUNNING MULTICAST MTU:1376 Metric:1 RX packets:16 errors:0 dropped:0 overruns:0 frame:0 TX packets:11 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1244 (1.2 KiB) TX bytes:798 (798.0 B) ...省略... docker2下 $ ifconfig ...省略... ethwe0 Link encap:Ethernet HWaddr C2:97:2B:BF:7E:A2 inet addr:10.32.0.1 Bcast:10.47.255.255 Mask:255.240.0.0 UP broADCAST RUNNING MULTICAST MTU:1376 Metric:1 RX packets:17 errors:0 dropped:0 overruns:0 frame:0 TX packets:11 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1342 (1.3 KiB) TX bytes:798 (798.0 B) ...省略...
-
默认情况下不会使用weave的DNS,故不能用容器名进行访问。如果要使用容器主机名,可按以下方法:
如果创建容器时指定了--name参数,在注册DNS时还是以hostname优先。 $ docker run -it --rm --net=weave --name docker1-busyBox -h c1.weave.local $(weave dns-args) busyBox $ docker run -it --rm --net=weave --name docker2-busyBox -h c2.weave.local $(weave dns-args) busyBox 在docker中以下方式都可以通 ping c1 ping c2 ping docker1-busyBox ping docker2-busyBox 在宿主机查看 $ weave dns-lookup c1.weave.local 10.40.0.0 $ weave dns-lookup c2.weave.local 10.32.0.1
-
查看local domain
$ weave status ...省略... Service: dns Domain: weave.local. Upstream: 192.168.100.2 TTL: 1 Entries: 4 ...省略...
-
修改local domain
$ weave launch --dns-domain="cluster.local."
-
可以通过DNS提供负载均衡
1. 启动多个容器(c2.weave.local) $ docker run --net=weave --rm --name docker21-busyBox -h c2.weave.local $(weave dns-args) -ti busyBox $ weave dns-lookup c2.weave.local 10.32.0.1 10.32.0.2
技巧
-
IP手动分配:weave会保证容器ip都是唯一的,并且自动负责容器ip的分配和回收,你不需要配置任何东西就能得到这个好处。如果对分配有特定需求也是可以自定义分配ip网段的。weave默认使用的网段是
10.32.0.0/12
,也就是从10.32.0.0
到10.47.255.255
。如果这个网段已经被占用,weave就会报错,这个时候可以使用--ipalloc-range
参数手动指定weave
要使用的网段$ weave launch --ipalloc-range 10.60.0.0/12
-
网络隔离:默认情况下,所有的容器都在同一个子网,不过可以通过
--ipalloc-default-subnet
指定分配的子网(子网必须在可分配网段里)。如果要实现容器网络的隔离,而不是集群中所有容器都能互相访问。weave可以使用子网实现这个功能,同一个子网的容器互相连通,而不同的子网中容器是隔离的。一个容器可以在多个子网中,通过和多个网络里的容器互连。docker允许同一个机器上的容器互通,为了完全隔离,需要在docker daemon
启动参数添加上--icc=false
。$ weave launch --ipalloc-default-subnet 10.40.0.0/24 192.168.2.210
-
指定特定的IP地址:
-
通过设置环境变量
$ eval $(weave env) $ docker run -e weave_CIDR=10.35.1.1/24 --name c3 -it busyBox sh /# ifconfig
-
通过
weave run
命令实现$ weave run 10.36.1.1/24 --name c4 -it busyBox sh $ docker exec -it c4 sh
-
动态分配网络:如果在运行容器的时候还不能确定网络,可以使用
-e weave_CIDR=none
参数先不分配网络信息。$ eval $(weave env) $ docker run -e weave_CIDR=none --name c5 -it busyBox sh / # ifconfig 使用weave attach ${container_id}给运行中的容器分配网络 $ weave attach b1f7a647aee3 10.32.0.1 如果要把容器从某个网络中移除,可以使用weave detach命令 $ weave detach net:10.32.0.0/24 b1f7a647aee3 10.32.0.1
-
外网连weave
-
宿主机如何访问虚拟机中的Docker镜像
1. macos $ sudo route add -net 10.32.0.0/12 -netmask 255.240.0.0 192.168.100.141 2. linux $ ip route add 10.32.0.0/12 via 192.168.100.141
命令整理
-
命令
1. 查看weave状态 $ weave status 2. 查看状态详情 $ weave status connections 3. 查看weave相互之间节点建立的关系 $ weave status peers 4. 查看当前分配的容器 $ weave ps 5. 查看weave当前版本 $ weave version 6. 启动并与其他主机建立连接,启动weave并下载镜像 $ weave launch 7. 进行连接 IP连接对端服务器 $ weave launch <ip address> 8. 使用weave代理 $ weave env 9. 执行输出|来自weave env的输出 $ export DOCKER_HOST=unix:///var/run/weave/weave.sock 10. 关闭weave $ weave stop 11. 关闭weave env代理 $ export DOCKER=OPTS=
常见问题
-
如果用虚拟机测试并且多个虚拟机是用同一虚拟机克隆的,所有机器的machine-id会是一样的。就会引起不同主机间连接失败,因为每台主机weave网桥上的虚拟网卡分配的IP段是一样的。解决方法就是为每台机器重新生成不同的machine-id:
$ rm /etc/machine-id /var/lib/dbus/machine-id $ dbus-uuidgen --ensure $ systemd-machine-id-setup $ reboot
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。