前面说到了Flannel的部署,今天这里说下Docker跨主机容器间网络通信的另一个工具Weave的使用。当容器分布在多个不同的主机上时,这些容器之间的相互通信变得复杂起来。容器在不同主机之间都使用的是自己的私有IP地址,不同主机的容器之间进行通讯需要将主机的端口映射到容器的端口上,而且IP地址需要使用主机的IP地址。Weave正是为了解决这个问题而出现的,它把不同主机上容器互相连接的网络虚拟成一个类似于本地网络的网络。
如果了解SDN技术或者部署过OpenStack的网络模块(Neutron)的话,这里通过Weave构建的网络与它们比较类似。它是在一个网络的基础上,构建了一层由软件定义的网络层,这个网络看起来就像是一个本地的局域网,但是实际上它的底层通过另一个网络进行通信。这个网络可能会比实际物理局域网的可靠性要差一些,但是从可用性角度来看,它带来了很大的便利性:可以在位于不同位置的节点之间通信,而好像它们在一个地方一样。也可以把这种网络想象成一个类似于VPN似的东西。
一. weave介绍
Weave是由weaveworks公司开发的解决Docker跨主机网络的解决方案,它能够创建一个虚拟网络,用于连接部署在多台主机上的Docker容器,这样容器就像被接入了同一个网络交换机,那些使用网络的应用程序不必去配置端口映射和链接等信息。外部设备能够访问Weave网络上的应用程序容器所提供的服务,同时已有的内部系统也能够暴露到应用程序容器上。Weave能够穿透防火墙并运行在部分连接的网络上,另外,Weave的通信支持加密,所以用户可以从一个不受信任的网络连接到主机。
Weave通过创建虚拟网络使Docker容器能够跨主机通信并能够自动相互发现。通过weave网络,由多个容器构成的基于微服务架构的应用可以运行在任何地方:主机,多主机,云上或者数据中心。应用程序使用网络就好像容器是插在同一个网络交换机上一样,不需要配置端口映射,连接等。在weave网络中,使用应用容器提供的服务可以暴露给外部,而不用管它们运行在何处。类似地,现存的内部系统也可以接受来自于应用容器的请求,而不管容器运行于何处。
一个Weave网络由一系列的’peers’构成----这些weave路由器存在于不同的主机上。每个peer都由一个名字,这个名字在重启之后保持不变.这个名字便于用户理解和区分日志信息。每个peer在每次运行时都会有一个不同的唯一标识符(UID).对于路由器而言,这些标识符不是透明的,尽管名字默认是路由器的MAC地址。
Weave路由器之间建立起TCP连接,通过这个连接进行心跳握手和拓扑信息交换,这些连接可以通过配置进行加密。peers之间还会建立UDP连接,也可以进行加密,这些UDP连接用于网络包的封装,这些连接是双工的而且可以穿越防火墙。Weave网络在主机上创建一个网桥,每个容器通过veth pari连接到网桥上,容器由用户或者weave网络的IPADM分配IP地址。
二. 选择weave的原因?
1)无忧的配置
Weave网络能够简化容器网络的配置。因为weave网络中的容器使用标准的端口提供服务(如,MySQL默认使用3306),管理微服务是十分直接简单的。
每个容器都可以通过域名来与另外的容器通信,也可以直接通信而无需使用NAT,也不需要使用端口映射或者复杂的linking.
部署weave容器网络的最大的好处是无需修改你的应用代码。
2)服务发现
Weave网络通过在每个节点上启动一个"微型的DNS"服务来实现服务发现。你只需要给你的容器起个名字就可以使用服务发现了,还可以在多个同名的容器上提供负载均衡的功能。
3)不需要额外的集群存储
所有其它的Docker网络插件,包括Docker自带的"overlay"驱动,在你真正能使用它们之间,都需要安装额外的集群存储----一个像Consul或者Zookeepr那样的中心数据库. 除了安装,维护和管理困难外,甚至Docker主机需要始终与集群存储保持连接,如果你断开了与其的连接,尽管很短暂,你也不能够启动和停止任何容器了。Weave网络是与Docker网络插件捆绑在一起的,这意味着你可以马上就使用它,而且可以在网络连接出现问题时依旧启动和停止容器。
4)在部分连接情况下进行操作
Weave网络能够在节点间转发流量,它甚至能够在网状网络部分连接的情况下工作。这意味着你可以在混合了传统系统和容器化的应用的环境中使用Weave网络来保持通信。
5)Weave网络很快
Weave网络自动在两个节点之间选择最快的路径,提供接近本地网络的吞吐量和延迟,而且这不需要你的干预。关于Fast Datapath如何工作请参考 How Fast Datapath Works .
6)组播支持
Weave网络完全支持组播地址和路径。数据可以被发送给一个组播地址,数据的副本可以被自动地广播。
7)NAT 转换
使用Weave网络,部署你的应用—无论是点对点的文件共享,基于ip的voice或者其它应用,你都可以充分利用内置的NAT转换。通过Weave网络,你的app将会是可移值的,容器化的,加上它对网络标准化的处理,将又会使你少关心一件事。
8)与任何框架集成: Kubernetes, Mesos, Amazon ECS, …
如果想为所有框架使用一个工具,Weave网络是一个好的选择。比如: 除了作为Docker插件使用,你还可以将其作为一个Kubernetes插件plugin.你还可以在 Amazon ECS ,Mesos和Marathon中使用它.
三. weave实现原理
容器的网络通讯都通过route服务和网桥转发。Weave会在主机上创建一个网桥,每一个容器通过 veth pair 连接到该网桥上,同时网桥上有个 Weave router 的容器与之连接,该router会通过连接在网桥上的接口来抓取网络包(该接口工作在Promiscuous模式)。
在每一个部署Docker的主机(可能是物理机也可能是虚拟机)上都部署有一个W(即Weave router),它本身也可以以一个容器的形式部署。Weave run的时候就可以给每个veth的容器端分配一个ip和相应的掩码。veth的网桥这端就是Weave router容器,并在Weave launch的时候分配好ip和掩码。
Weave网络是由这些weave routers组成的对等端点(peer)构成,每个对等的一端都有自己的名字,其中包括一个可读性好的名字用于表示状态和日志的输出,一个唯一标识符用于运行中相互区别,即使重启Docker主机名字也保持不变,这些名字默认是mac地址。
每个部署了Weave router的主机都需要将TCP和UDP的6783端口的防火墙设置打开,保证Weave router之间控制面流量和数据面流量的通过。控制面由weave routers之间建立的TCP连接构成,通过它进行握手和拓扑关系信息的交换通信。 这个通信可以被配置为加密通信。而数据面由Weave routers之间建立的UDP连接构成,这些连接大部分都会加密。这些连接都是全双工的,并且可以穿越防火墙。
四. weave优劣势
Weave优势
-> 支持主机间通信加密。
-> 支持container动态加入或者剥离网络。
-> 支持跨主机多子网通信。
Weave劣势
-> 只能通过weave launch或者weave connect加入weave网络。
五. 安装weave
所有节点都需要安装。Weave不需要集中式的 key-value 存储,所以安装和运行都很简单。直接把Weave二进制文件下载到系统中就可以了.
[root@client ~]# curl -L git.io/weave -o /usr/local/bin/weave
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- 0:00:05 --:--:-- 0
100 616 100 616 0 0 84 0 0:00:07 0:00:07 --:--:-- 495
100 52227 100 52227 0 0 5210 0 0:00:10 0:00:10 --:--:-- 24705
[root@client ~]# chmod a+x /usr/local/bin/weave
测试是否安装成功 (前提是要安装并启动了docker服务)
[root@client ~]# weave version
weave script 2.6.2
Unable to find image 'weaveworks/weaveexec:2.6.2' locally
2.6.2: Pulling from weaveworks/weaveexec
4167d3e14976: Pull complete
715da9ac9fc3: Pull complete
b3290913a00a: Pull complete
d4af2ab8bd46: Pull complete
f15440c6ce9d: Pull complete
8223efbab92a: Pull complete
cb54261643f4: Pull complete
e8930a17aa30: Pull complete
5ab554aa194c: Pull complete
Digest: sha256:a28b3c098a049d923fb08231a1bba22e6d57c83710257e41220c28ffccb2d66c
Status: Downloaded newer image for weaveworks/weaveexec:2.6.2
weave 2.6.2
[root@client ~]# weave version
weave script 2.6.2
weave 2.6.2
weave version 默认不会下载对应容器, 需要运行"weave launch" 来启动相关服务
[root@client ~]# weave launch
2.6.2: Pulling from weaveworks/weave
4167d3e14976: Already exists
715da9ac9fc3: Already exists
b3290913a00a: Already exists
d4af2ab8bd46: Already exists
f15440c6ce9d: Already exists
Digest: sha256:6f6839774ca225076116790145a415fa99706133310bcf7a56ce29fd89c245d3
Status: Downloaded newer image for weaveworks/weave:2.6.2
latest: Pulling from weaveworks/weavedb
72bf8a6af285: Pull complete
Digest: sha256:7badb003b9c0bf5c51bf801be2a4d5d371f0738818f9cbe60a508f54fd07de9a
Status: Downloaded newer image for weaveworks/weavedb:latest
8be82e7aecbd8ddc7911f43803627fb2aa4e07202c0328c05d6eb8c6a93f3338
[root@client ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 9beeba249f3e 14 hours ago 127MB
<none> <none> eb9ad9062b3b 12 days ago 106MB
ubuntu 16.04 005d2078bdfa 3 weeks ago 125MB
ubuntu latest 1d622ef86b13 3 weeks ago 73.9MB
weaveworks/weaveexec 2.6.2 4f1fc48398d9 8 weeks ago 149MB
weaveworks/weave 2.6.2 a37f4211904c 8 weeks ago 98.7MB
centos latest 470671670cac 3 months ago 237MB
weaveworks/weavedb latest 6898eac75586 6 months ago 698B
registry 2.2 ad379b517aa6 4 years ago 225MB
[root@client ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8be82e7aecbd weaveworks/weave:2.6.2 "/home/weave/weaver …" 26 seconds ago Up 23 seconds weave
5225a37ef481 ubuntu:16.04 "/bin/bash" 4 hours ago Up 4 hours client.test
六. 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将流量转发到对端主机上。
其基本过程如下:
1)容器流量通过veth pair到达宿主机上weave router网桥上。
2)weave router在混杂模式下使用pcap在网桥上截获网络数据包,并排除由内核直接通过网桥转发的数据流量,例如本子网内部、本地容器之间的数据以及宿主机和本地容器之间的流量。捕获的包通过UDP转发到所其他主机的weave router端。
3)在接收端,weave router通过pcap将包注入到网桥上的接口,通过网桥的上的veth pair,将流量分发到容器的网卡上。weave默认基于UDP承载容器之间的数据包,并且可以完全自定义整个集群的网络拓扑,但从性能和使用角度来看,还是有比较大的缺陷的:
-> weave自定义容器数据包的封包解包方式,不够通用,传输效率比较低,性能上的损失也比较大。
-> 集群配置比较负载,需要通过weave命令行来手工构建网络拓扑,在大规模集群的情况下,加重了管理员的负担。
七. weave的安装与启动
1)这里选择直接从github下载二进制文件进行安装。weave下载地址:https://pan.baidu.com/s/1FBLyOQc8MfJfNmIeSe6cHg 提取码: 432p
[root@client ~]# cp weave /usr/local/bin/
[root@client ~]# chmod a+x /usr/local/bin/weave
2)启动weave路由器,这个路由器其实也是以容器的形式运行的。(前提是已经启动了docker服务进程)
[root@client ~]# weave launch
latest: Pulling from weaveworks/weave
21c83c524219: Pull complete
5298dd92219a: Pull complete
256874dfe3be: Pull complete
3eb4f352f2e8: Pull complete
20a1f715e0db: Pull complete
Digest: sha256:c56dcf94b7842fb3e04e980d3c7c265ce5d0bb7e3c182bf0c7c18f91e3cba3d2
Status: Downloaded newer image for weaveworks/weave:latest
Unable to find image 'weaveworks/weaveexec:latest' locally
latest: Pulling from weaveworks/weaveexec
21c83c524219: Already exists
5298dd92219a: Already exists
256874dfe3be: Already exists
3eb4f352f2e8: Already exists
20a1f715e0db: Already exists
00bfad9f7e88: Pull complete
38f3cb4a931c: Pull complete
6c212a5c67be: Pull complete
8f85336b098e: Pull complete
Digest: sha256:bad5ad7c6f9fc83c4cbeeb677e82d22654ae96322678e9b269d4f112f7e8fb83
Status: Downloaded newer image for weaveworks/weaveexec:latest
weave is already running; you can stop it with 'weave stop'.
3)查看镜像,可以发现上面下载的weave路由容器镜像
[root@client ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 9beeba249f3e 14 hours ago 127MB
weaveworks/weaveexec latest 64302601507f 4 days ago 149MB
weaveworks/weave latest bd6ddd77d9f6 4 days ago 98.7MB
<none> <none> eb9ad9062b3b 12 days ago 106MB
ubuntu 16.04 005d2078bdfa 3 weeks ago 125MB
ubuntu latest 1d622ef86b13 3 weeks ago 73.9MB
weaveworks/weaveexec 2.6.2 4f1fc48398d9 8 weeks ago 149MB
weaveworks/weave 2.6.2 a37f4211904c 8 weeks ago 98.7MB
centos latest 470671670cac 3 months ago 237MB
weaveworks/weavedb latest 6898eac75586 6 months ago 698B
registry 2.2 ad379b517aa6 4 years ago 225MB
4)此时会发现有两个网桥,一个是Docker默认生成的,另一个是Weave生成的。
[root@client ~]# yum install -y bridge-utils
[root@client ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242d8952cf0 no vethd9faf5c
weave 8000.6e3375087c54 no vethwe-bridge
查看运行的容器,发现weave路由容器已经自动运行
[root@client ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8be82e7aecbd weaveworks/weave:2.6.2 "/home/weave/weaver …" 45 minutes ago Up 45 minutes weave
5225a37ef481 ubuntu:16.04 "/bin/bash" 5 hours ago Up 5 hours client.test
weave关闭
[root@client ~]# weave stop
[root@client ~]# docker stop weave
weave
[root@client ~]# docker rm weave
weave
weave命令帮助
[root@client ~]# weave --help
Usage:
weave --help | help
setup
version
weave launch [--password <pass>] [--trusted-subnets <cidr>,...]
[--host <ip_address>]
[--name <mac>] [--nickname <nickname>]
[--no-restart] [--resume] [--no-discovery] [--no-dns]
[--ipalloc-init <mode>]
[--ipalloc-range <cidr> [--ipalloc-default-subnet <cidr>]]
[--plugin=false] [--proxy=false]
[-H <endpoint>] [--without-dns] [--no-multicast-route]
[--no-rewrite-hosts] [--no-default-ipalloc]
[--hostname-from-label <labelkey>]
[--hostname-match <regexp>]
[--hostname-replacement <replacement>]
[--rewrite-inspect]
[--log-level=debug|info|warning|error]
[--token <weave-cloud-service-token>]
<peer> ...
weave prime
weave env [--restore]
config
dns-args
weave connect [--replace] [<peer> ...]
forget <peer> ...
weave attach [--without-dns] [--rewrite-hosts] [--no-multicast-route]
[<addr> ...] <container_id>
detach [<addr> ...] <container_id>
weave expose [<addr> ...] [-h <fqdn>] [--without-masquerade]
hide [<addr> ...]
weave dns-add [<ip_address> ...] <container_id> [-h <fqdn>] |
<ip_address> ... -h <fqdn>
dns-remove [<ip_address> ...] <container_id> [-h <fqdn>] |
<ip_address> ... -h <fqdn>
dns-lookup <unqualified_name>
weave status [targets | connections | peers | dns | ipam]
report [-f <format>]
ps [<container_id> ...]
weave stop
weave reset [--force]
rmpeer <peer_id> ...
where <peer> = <ip_address_or_fqdn>[:<port>]
<cidr> = <ip_address>/<routing_prefix_length>
<addr> = [ip:]<cidr> | net:<cidr> | net:default
<endpoint> = [tcp://][<ip_address>]:<port> | [unix://]/path/to/socket
<peer_id> = <nickname> | <weave internal peer ID>
<mode> = consensus[=<count>] | seed=<mac>,... | observer
To troubleshoot and visualize Weave networks, try Weave Cloud: http://www.weave.works/product/cloud/
接下来就可以运行应用容器,使用weave提供的网络功能了。
Weave的应用示例
1)机器环境准备:
k8s-h1 192.168.31.80
k8s-h2 192.168.31.90
k8s-h1宿主机上的应用容器my-test1: 192.168.0.2/24
k8s-h2宿主机上的应用容器my-test2: 192.168.0.3/24
两台机上均安装Docker及Weave,并均启动好Weave路由容器(安装及启动操作如上)。最好关闭两台机器的防火墙!(如果打开防火墙,需要开放6783端口)
2)在两台机上均启动一个应用容器,有以下两种方式:
第一种方式:可以直接使用weave run命令;
[root@k8s-h1 ~]# weave run 192.168.0.2/24 -itd centos:latest /bin/bash
The 'weave run' command has been removed as of Weave Net version 2.0
Please see release notes for further information
由上可知,weave在2.0版本之后就没有“weave run”这个命令了,所以还是使用下面的第二种方式
第二种方式:先使用docker run启动好容器,然后使用weave attach命令给容器绑定IP地址
在node-1机器上启动第一个容器my-test1,容器ip绑定为192.168.0.2
[root@k8s-h1 ~]# docker run -itd --name my-test1 centos:latest /bin/bash
2d54da3ad4b1537a26f1571ec69bccb6336088659387ab4d3a51694857d25098
[root@k8s-h1 ~]# weave attach 192.168.0.2/24 my-test1
#使用容器名称或容器id都可以;即给my-test1容器绑定ip为192.168.0.2
192.168.0.2
[root@k8s-h1 ~]# docker exec -it my-test1 /bin/bash
[root@2d54da3ad4b1 /]# ifconfig #执行安装yum install -y net-tools,就会出现ifconfig命令
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 1801 bytes 10081971 (9.6 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1623 bytes 92194 (90.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ethwe: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1376
inet 192.168.0.2 netmask 255.255.255.0 broadcast 192.168.0.255
ether be:5e:c2:f6:d3:be txqueuelen 0 (Ethernet)
RX packets 9 bytes 698 (698.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1 bytes 42 (42.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
在node-2机器上启动容器my-test2,容器ip绑定为192.168.0.3
[root@k8s-h2 ~]# docker run -it --name my-test2 centos:latest /bin/bash
[root@k8s-h2 ~]# weave attach 192.168.0.3/24 my-test2 //weave detach 192.168.0.3/24 my-test2表示删除这个绑定
192.168.0.3
[root@k8s-h2 ~]# docker exec -it my-test2 /bin/bash
[root@5dc040b814e9 /]# ifconfig #执行安装yum install -y net-tools,就会出现ifconfig命令 //或者ip addr命令查看
......
ethwe: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1376
inet 192.168.0.3 netmask 255.255.255.0 broadcast 192.168.0.255
ether c2:70:47:73:d5:21 txqueuelen 0 (Ethernet)
RX packets 9 bytes 698 (698.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1 bytes 42 (42.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
温馨提示:
上面在docker run启动容器时,可以添加--net=none参数,这个表示容器启动后不使用默认的虚拟网卡docker0自动分配的ip,而是使用weave绑定的ip;
当然也可以选择不添加这个参数去启动容器,这样,容器启动后就会有两个网卡,即两个ip:
一个是docker0自动分配的ip,这个适用于同主机内的容器间通信,即同主机的容器使用docker0分配的ip可以相互通信;另一个就是weave网桥绑定的ip。
3)容器互联
默认情况下,上面在k8s-h1和k8s-h2两台宿主机上创建的2个容器间都是相互ping不通的。需要使用weave connect命令在两台weave的路由器之间建立连接。
[root@k8s-h1 ~]# weave connect 192.168.31.90 //连接的是对方宿主机的ip,注意"weave forget ip" 则表示断开这个连接
然后就会发现,此时位于两台不同主机上的相同子网段内的容器之间可以相互ping通了
[root@k8s-h1 ~]# docker exec -it my-test1 /bin/bash
[root@2d54da3ad4b1 /]# ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=3.83 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.921 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.645 ms
.....
[root@k8s-h2 ~]# docker exec -it my-test2 /bin/bash
[root@5dc040b814e9 /]# ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=1.75 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.610 ms
.....
再在k8s-h1上启动容器my-test3,绑定ip为192.168.0.8,在k8s-h2上启动容器my-test4,绑定ip为192.168.0.10,会发现这四个在同一个子网内的容器都是可以相互ping通的!
因此:只有两个能通信的宿主机做了weave connect操作,则在他们俩上创建并weave attach绑定同网段的容器都是可以相互之间通信的!
--------------------------------------------------------------------------------------------------------
再接着启动与上面不在同一个子网内的容器
k8s-h1上启动容器my-test4,绑定ip为192.168.10.10,k8s-h2上启动容器my-test5,绑定ip为192.168.10.20
[root@k8s-h1 ~]# docker run -itd --name my-test5 centos:latest /bin/bash
808848a2993ceb31e8996ba2832da4ebbfc51a6c126d09b433e88d30b53cb29b
[root@k8s-h1 ~]# weave attach 192.168.10.10/24 my-test5
192.168.10.10
[root@k8s-h1 ~]# docker exec -it my-test5 /bin/bash
[root@808848a2993c /]# ifconfig
bash: ifconfig: command not found
[root@808848a2993c /]# yum install -y net-tools
[root@808848a2993c /]# ifconfig
ethwe: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1376
inet 192.168.10.10 netmask 255.255.255.0 broadcast 192.168.10.255
ether fe:28:d2:69:83:ca txqueuelen 0 (Ethernet)
RX packets 9 bytes 698 (698.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1 bytes 42 (42.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@k8s-h2 ~]# docker run -itd --name my-test6 centos:latest /bin/bash
3f18006419ff72e23cee98da3f6d5ecfda16c4a514b882425b25895f24e5edd3
[root@k8s-h2 ~]# weave attach 192.168.10.20/24 my-test6
192.168.10.20
[root@k8s-h2 ~]# docker exec -it my-test6 /bin/bash
[root@3f18006419ff /]# yum install -y net-tools
[root@3f18006419ff /]# ifconfig
ethwe: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1376
inet 192.168.10.20 netmask 255.255.255.0 broadcast 192.168.10.255
ether 02:80:70:9b:8d:85 txqueuelen 0 (Ethernet)
RX packets 9 bytes 698 (698.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1 bytes 42 (42.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@3f18006419ff /]# ping 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=3.30 ms
64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.825 ms
......
会发现在跨主机情况下,相同子网内的容器是可以相互通信的;但是处于不同子网的两个容器是不能互联的,尽管这两个容器在同一个主机下也是不能通信的!
这样的好处就是:使用不同子网进行容器间的网络隔离了。
--------------------------------------------------------------------------------------------------------
注意一个细节,在使用weave的时候:
1)如果使用Docker的原生网络,在容器内部是可以访问宿主机以及外部网络的。也就是说在启动容器的时候,使用了虚拟网卡docker0分配ip,
这种情况下,登陆容器后是可以ping通宿主机ip,并且可以对外联网的!
这个时候,在宿主机上是可以ping通docker0网桥的ip,但是ping不通weave网桥的ip。这个时候可以使用
"weave expose 192.168.0.1/24"命令来给weave网桥添加IP,以实现容器与宿主机网络连通。如下:
默认在k8s-h1和k8s-h2宿主机上是ping不通my-test1容器的weave网桥ip的
[root@k8s-h1 ~]# ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
From 192.168.0.102 icmp_seq=3 Destination Host Unreachable
.......
[root@k8s-h2 ~]# ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
From 192.168.0.102 icmp_seq=3 Destination Host Unreachable
.......
在k8s-h1和k8s-h2两台机器上都添加weave网桥的ip
[root@k8s-h1 ~]# weave expose 192.168.0.1/24
192.168.0.1
//注意这里的192.168.0.1/24是上面my-test1、my-test2、my-test3、my-test4容器的weave网桥的网关地址
[root@k8s-h2 ~]# weave expose 192.168.0.1/24
192.168.0.1
//weave hide 192.168.0.1/24表示覆盖/删除这个设置
然后再在两台宿主机上ping上面同网段内的容器,发现都可以ping通了
[root@k8s-h1 ~]# ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.280 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.072 ms
[root@k8s-h2 ~]# ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.202 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.046 ms
然后再给另一网段的容器的weave网桥添加ip(可以在宿主机上对不同网段的容器的weave网桥添加ip)
[root@k8s-h1 ~]# weave expose 192.168.10.1/24
192.168.10.1
[root@k8s-h2 ~]# weave expose 192.168.10.1/24
192.168.10.1
[root@k8s-h1 ~]# ping 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.198 ms
64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.079 ms
[root@k8s-h1 ~]# ping 192.168.10.20
PING 192.168.10.20 (192.168.10.20) 56(84) bytes of data.
64 bytes from 192.168.10.20: icmp_seq=1 ttl=64 time=26.8 ms
64 bytes from 192.168.10.20: icmp_seq=2 ttl=64 time=0.984 ms
[root@k8s-h2 ~]# ping 192.168.10.20
PING 192.168.10.20 (192.168.10.20) 56(84) bytes of data.
64 bytes from 192.168.10.20: icmp_seq=1 ttl=64 time=0.215 ms
64 bytes from 192.168.10.20: icmp_seq=2 ttl=64 time=0.101 ms
[root@k8s-h2 ~]# ping 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=3.04 ms
64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.617 ms
2)如果不适用Docker的原生网络,即在容器启动的时候,添加--net=none,这样容器启动后,就不会使用docker0网卡分配ip。
这种情况下,登陆容器后发现不能访问宿主机以及外部网络的,而在宿主机上也不能ping通容器ip。
这个时候添加对应容器网段的weave网桥ip,这样可以实现容器与宿主机网络连通。但是,此时在容器内部依然不能访问外部网络。
所以说,可以同时使用Docker的原生网络和weave网络来实现容器互联及容器访问外网和端口映射。
使用外部网络及端口映射的时候就使用docker0网桥,需要容器互联的时候就使用weave网桥。每个容器分配两个网卡。
weave的其他特性
1)应用隔离:
不同子网容器之间是默认隔离的,即便它们位于同一台物理机上也相互不通(使用-icc=false关闭容器互通);不同物理机之间的容器默认也是隔离的
2)安全性:
可以通过weave launch -password wEaVe设置一个密码用于weave peers之间加密通信
3)查看weave路由状态:weave ps
[root@k8s-h1 ~]# weave ps
weave:expose 26:eb:e8:0a:e6:66 192.168.0.1/24 192.168.10.1/24
808848a2993c fe:28:d2:69:83:ca 192.168.10.10/24
2d54da3ad4b1 be:5e:c2:f6:d3:be 192.168.0.2/24
[root@k8s-h2 ~]# weave ps
weave:expose 86:41:4b:69:9b:3c 192.168.0.1/24 192.168.10.1/24
3f18006419ff 02:80:70:9b:8d:85 192.168.10.20/24
5dc040b814e9 c2:70:47:73:d5:21 192.168.0.3/24
4)效率
weave 路由通过pcap捕获包这种方式来完成封装和解封装这个过程,效率应该是有问题的。
这个过程中需要将数据包从内核态拷贝到用户态,然后按照自定义的格式完成封装和解封装。
--------------------------------------------------------------------------------------------------
在已经关闭了weave(weave stop)后,发现weave网桥信息还在:
[root@k8s-h2 ~]# weave stop
[root@k8s-h2 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242d038a4fe no veth55b9948
vethab3131f
weave 8000.86414b699b3c no vethwe-bridge
vethwepl13242
vethwepl13650
[root@k8s-h2 ~]# ifconfig
........
weave: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1376
inet 192.168.0.1 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::8441:4bff:fe69:9b3c prefixlen 64 scopeid 0x20<link>
ether 86:41:4b:69:9b:3c txqueuelen 1000 (Ethernet)
RX packets 36 bytes 1888 (1.8 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 22 bytes 1580 (1.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
删除weave网桥信息(其他ifconfig命令查出的网络设备删除的方法类似):
[root@k8s-h2 ~]# ip link set dev weave down
[root@k8s-h2 ~]# brctl delbr weave
[root@k8s-h2 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242d038a4fe no veth55b9948
vethab3131f
[root@k8s-h2 ~]# ifconfig #发现已经没有weave网卡信息