20、容器网络与服务发现解决方案深度解析

容器网络与服务发现解决方案深度解析

1. Weave 作为插件运行

Weave 可以通过 Docker 插件框架运行,这能有效替代代理容器。不过,在撰写本文时,这种方法存在一些限制,主要原因是网络插件 API 仍在不断完善,以向 Weave 和其他网络插件提供所需的所有信息和钩子。例如,如果集群重启,Weave 可能会丢失配置信息。但当你阅读本文时,这些问题或许已得到解决。

2. Flannel 网络解决方案

Flannel 是 CoreOS 推出的跨主机网络解决方案,主要用于基于 CoreOS 的集群,当然也可用于其他堆栈。它会为每个主机分配一个子网,进而为容器分配 IP 地址。在 Kubernetes 中,Flannel 能为每个 Pod 分配唯一且可路由的 IP 地址。

Flannel 在每个主机上运行一个守护进程,该进程从 etcd 中获取配置信息,因此集群必须先配置好使用 etcd。Flannel 提供了多种后端:
| 后端类型 | 说明 |
| ---- | ---- |
| udp | 默认后端,形成覆盖网络,将二层网络信息封装在 UDP 数据包中,通过现有网络传输 |
| vxlan | 使用 VXLAN 封装网络数据包,在内核中完成,可能比需经过用户空间的 UDP 更快 |
| aws - vpc | 用于在 Amazon EC2 上设置网络 |
| host - gw | 使用远程 IP 地址设置子网的 IP 路由,要求主机之间有直接的二层连接 |
| gce | 用于在 Google Compute Engine 上设置网络 |

下面介绍使用 Docker Machine 搭建 Flannel 网络的详细步骤:
1. 创建虚拟机

$ docker-machine create -d virtualbox flannel-1
$ docker-machine create -d virtualbox flannel-2
$ docker-machine ip flannel-1 flannel-2

记录下每个机器的 IP 地址,后续设置 etcd 会用到。
2. 在 flannel - 1 上安装 etcd

$ docker-machine ssh flannel-1
docker@flannel-1:~$ sudo /usr/local/etc/init.d/docker stop
docker@flannel-1:~$ sudo ip link delete docker0
docker@flannel-1:~$ curl -sL https://github.com/coreos/etcd/releases/download/v2.0.13/etcd-v2.0.13-linux-amd64.tar.gz -o etcd.tar.gz
docker@flannel-1:~$ tar xzvf etcd.tar.gz
docker@flannel-1:~$ HOSTA=192.168.99.102
docker@flannel-1:~$ HOSTB=192.168.99.103
docker@flannel-1:~$ nohup etcd-v2.0.13-linux-amd64/etcd \
  -name etcd-1 -initial-advertise-peer-urls http://$HOSTA:2380 \
  -listen-peer-urls http://$HOSTA:2380 \
  -listen-client-urls http://$HOSTA:2379,http://127.0.0.1:2379 \
  -advertise-client-urls http://$HOSTA:2379 \
  -initial-cluster-token etcd-cluster-1 \
  -initial-cluster etcd-1=http://$HOSTA:2380,etcd-2=http://$HOSTB:2380 \
  -initial-cluster-state new &

使用 nohup 确保 etcd 在退出主机后仍能运行,输出日志会记录在 nohup.out 文件中。
3. 在 flannel - 2 上安装 etcd 和 Flannel

docker@flannel-1:~$ exit
$ docker-machine ssh flannel-2
docker@flannel-2:~$ sudo /usr/local/etc/init.d/docker stop
docker@flannel-2:~$ sudo ip link delete docker0
docker@flannel-2:~$ curl -sL https://github.com/coreos/etcd/releases/download/v2.0.13/etcd-v2.0.13-linux-amd64.tar.gz -o etcd.tar.gz
docker@flannel-2:~$ tar xzvf etcd.tar.gz
docker@flannel-2:~$ HOSTA=192.168.99.102
docker@flannel-2:~$ HOSTB=192.168.99.103
docker@flannel-2:~$ nohup etcd-v2.0.13-linux-amd64/etcd \
  -name etcd-2 -initial-advertise-peer-urls http://$HOSTB:2380 \
  -listen-peer-urls http://$HOSTB:2380 \
  -listen-client-urls http://$HOSTB:2379,http://127.0.0.1:2379 \
  -advertise-client-urls http://$HOSTB:2379 \
  -initial-cluster-token etcd-cluster-1 \
  -initial-cluster etcd-1=http://$HOSTA:2380,etcd-2=http://$HOSTB:2380 \
  -initial-cluster-state new &
docker@flannel-2:~$ curl -sL https://github.com/coreos/flannel/releases/download/v0.5.1/flannel-0.5.1-linux-amd64.tar.gz -o flannel.tar.gz
docker@flannel-2:~$ tar xzvf flannel.tar.gz
docker@flannel-2:~$ ./etcd-v2.0.13-linux-amd64/etcdctl set /coreos.com/network/config '{ "Network": "10.1.0.0/16" }'
docker@flannel-2:~$ nohup sudo ./flannel-0.5.1/flanneld -iface=eth1 &

运行 ifconfig flannel0 可以看到 Flannel 网桥信息。
4. 配置 Docker 使用 Flannel

docker@flannel-2:~$ cat /run/flannel/subnet.env
docker@flannel-2:~$ sudo vi /var/lib/boot2docker/profile

--bip 设置为 FLANNEL_SUBNET 的值, --mtu 设置为 FLANNEL_MTU 的值。

docker@flannel-2:~$ sudo /etc/init.d/docker start
  1. 在 flannel - 1 重复上述 Flannel 安装和 Docker 配置步骤
  2. 测试容器通信
$ eval $(docker-machine env flannel-1)
$ docker run --name nc-test -d amouat/network-utils nc -l 5001
$ IP=$(docker inspect -f {{.NetworkSettings.IPAddress}} nc-test)
$ eval $(docker-machine env flannel-2)
$ docker run -e IP=$IP amouat/network-utils sh -c 'echo -n "hello" | nc -v $IP 5001'
$ eval $(docker-machine env flannel-1)
$ docker logs nc-test

通过以上步骤,两个容器就能通过各自的 IP 地址跨主机通信。但目前还无法让 identidock 运行,因为缺少服务发现功能,这需要使用如 SkyDNS 等解决方案或重写 identidock 以使用 etcd。

3. Project Calico 网络解决方案

Project Calico(以下简称 Calico)采用了不同的网络方法。从 OSI 模型来看,大多数网络解决方案(如 Weave 和使用 UDP 后端的 Flannel)通过将二层流量封装到更高层来构建覆盖网络,而 Calico 则使用标准的 IP 路由和网络工具提供三层解决方案。

Calico 的主要优势在于简单和高效,其主要运行模式无需封装,适用于组织能控制物理网络结构的数据中心。Calico 网络内的路由通过边界网关协议(BGP)建立,这使得它能在多种二层和三层物理拓扑上运行。在安全策略和 IP 可用的情况下,容器可直接连接到公共 IP,无需使用 NAT。

不过,Calico 的主要模式在公共云环境中无法使用,因为用户无法控制网络结构。在公共云中使用 Calico 通常需要使用 IP - in - IP 隧道来提供连接。此外,Calico 的安全模型允许对容器间的通信进行细粒度控制。

以下是使用 Calico 搭建网络的步骤:
1. 创建虚拟机

$ docker-machine create -d digitalocean \
         --digitalocean-access-token=<token> \
         --digitalocean-private-networking \
         --engine-install-url "https://experimental.docker.com" calico-1
$ docker-machine create -d digitalocean \
          --digitalocean-access-token=<token> \
          --digitalocean-private-networking \
          --engine-install-url "https://experimental.docker.com" calico-2
  1. 在每个主机上设置 etcd
$ HOSTA=<calico-1 ipv4>
$ HOSTB=<calico-2 ipv4>
$ eval $(docker-machine env calico-1)
$ docker run -d -p 2379:2379 -p 2380:2380 -p 4001:4001 \
  --name etcd quay.io/coreos/etcd \
  -name etcd-1 -initial-advertise-peer-urls http://${HOSTA}:2380 \
  -listen-peer-urls http://0.0.0.0:2380 \
  -listen-client-urls http://0.0.0.0:2379,http://0.0.0.0:4001 \
  -advertise-client-urls http://${HOSTA}:2379 \
  -initial-cluster-token etcd-cluster-1 \
  -initial-cluster etcd-1=http://${HOSTA}:2380,etcd-2=http://${HOSTB}:2380 \
  -initial-cluster-state new
$ eval $(docker-machine env calico-2)
$ docker run -d -p 2379:2379 -p 2380:2380 -p 4001:4001 \
  --name etcd quay.io/coreos/etcd \
  -name etcd-2 -initial-advertise-peer-urls http://${HOSTB}:2380 \
  -listen-peer-urls http://0.0.0.0:2380 \
  -listen-client-urls http://0.0.0.0:2379,http://0.0.0.0:4001 \
  -advertise-client-urls http://${HOSTB}:2379 \
  -initial-cluster-token etcd-cluster-1 \
  -initial-cluster etcd-1=http://${HOSTA}:2380,etcd-2=http://${HOSTB}:2380 \
  -initial-cluster-state new
  1. 安装 Calico
$ docker-machine ssh calico-1
root@calico-1:~# curl -sSL -o calicoctl \
  https://github.com/Metaswitch/calico-docker/releases/download/v0.5.2/calicoctl
root@calico-1:~# chmod +x calicoctl
root@calico-1:~# modprobe xt_set
root@calico-1:~# sudo ./calicoctl pool add 192.168.0.0/16 --ipip --nat-outgoing
root@calico-1:~# sudo ./calicoctl node --ip=<calico-1 ipv4>
  1. 在另一台主机上重复安装步骤
$ docker-machine ssh calico-2
root@calico-2:~# curl -sSL -o calicoctl \
  https://github.com/Metaswitch/calico-docker/releases/download/v0.5.2/calicoctl
root@calico-2:~# chmod +x calicoctl
root@calico-2:~# modprobe xt_set
root@calico-2:~# sudo ./calicoctl node --ip=<calico-1 ipv4>
  1. 运行 identidock
root@calico-2:~# docker run --name redis -d \
       --publish-service redis.anet.calico redis:3
root@calico-2:~# exit
$ docker-machine ssh calico-1
root@calico-1:~# docker run --name redis-client \
        --publish-service redis-client.anet.calico \
        redis:3 redis-cli -h redis ping
root@calico-1:~# docker run --name dnmonster \
        --publish-service dnmonster.anet.calico -d amouat/dnmonster:1.0
root@calico-1:~# docker run --name identidock \
        --publish-service identidock.anet.calico -d amouat/identidock:1.0
root@calico-1:~# docker exec identidock curl -s localhost:9090

Calico 背后有几个关键组件:
- etcd:存储和分发主机与容器的信息。
- BIRD:使用 BGP 路由 IP 流量。
- Felix:在每个计算主机上运行,根据 etcd 中的数据配置本地网络策略。
- Calico 插件:负责在创建 Docker 容器时设置网络连接,并将其记录到 etcd 中。

Calico 目前专注于为组织能控制网络结构的场景(如大型公司的私有云)提供高效、相对简单的网络解决方案。同时,Calico 插件也有望为在同一公共云上运行的容器提供高效且简单的网络解决方案。

4. 服务发现与网络解决方案选择

在现代分布式和动态系统中,服务发现通常是必不可少的功能。容器和服务不断变化,手动重新路由连接的解决方案已无法满足需求。

大多数服务发现解决方案支持基于 DNS 的查找,这在客户端使用上很简单,也能支持现有应用和工具。但在高度动态的系统中,DNS 可能会成为障碍,因为其响应通常会被缓存,导致服务迁移时出现延迟和错误,且负载均衡通常只是简单的轮询。此外,客户端可能希望使用更丰富的 API 来实现自己的服务选择逻辑。

选择服务发现工具需根据具体用例。大多数项目因软件需求或现有平台工具(如 Mesos 使用 ZooKeeper,GKE 使用 etcd)已在使用相关工具,此时使用现有工具更为合理。在 etcd(或 etcd 加 SkyDNS)和 Consul 之间做出选择较为困难。两者都是相对较新的项目,基于可靠的底层算法。Consul 默认包含 DNS 支持和一些高级功能,而 etcd 相对不那么“固执己见”,拥有更高级的键值存储,在需要大量定制的场景中可能是更好的选择。如果使用 API 进行服务发现或已有提供名称解析的网络解决方案,Consul 和 SkyDNS 的 DNS 支持可能就不那么重要了。

选择网络解决方案则更加困难,主要是因为该领域尚不成熟。未来几个月,会有更多解决方案出现,它们之间的差异也会更加明显。目前,从现有的解决方案来看:
| 解决方案 | 特点及适用场景 |
| ---- | ---- |
| Docker 的覆盖网络 | 开发阶段可能是最常用的解决方案,因为它是“开箱即用”的选项。如果稳定性和效率足够高,也适用于在云上的小型部署 |
| Weave | 注重易用性和开发者体验,适合开发阶段。其加密和防火墙穿越等功能在跨云部署等场景中很有吸引力 |
| Flannel | 用于 CoreOS 堆栈,提供多种后端。目前在开发中使用可能较麻烦,但在一些生产场景中提供了高效简单的解决方案 |
| Project Calico | 主要针对能控制自身网络结构的大型组织或数据中心,其三层方法提供了简单高效的解决方案。Calico 网络插件在开发和单云部署中也很有吸引力 |
| 自定义方案 | 在某些情况下,运维人员可能确切知道如何高效地连接网络。此时可以创建自己的网络插件或使用 pipework 等工具。也可以使用容器或主机网络模式,消除 Docker 网桥和 NAT 规则的开销,但容器需共享 IP 地址 |

正确的选择很大程度上取决于你的具体需求和运行平台。你可能会发现某些解决方案的运行速度明显快于或慢于其他方案,或者某些方案能实现其他方案无法实现的用例。因此,在模拟应用运行条件的测试中实际尝试不同的解决方案是最好的方法。

容器网络与服务发现解决方案深度解析

5. 不同解决方案的对比分析

为了更清晰地了解各个网络与服务发现解决方案的特点,我们可以通过以下表格进行对比:
| 解决方案 | 优点 | 缺点 | 适用场景 |
| ---- | ---- | ---- | ---- |
| Docker 的覆盖网络 | 开发阶段“开箱即用”,可能适用于小型云部署 | 目前稳定性和效率有待观察 | 开发环境、小型云部署 |
| Weave | 易用性强,有加密和防火墙穿越功能 | 集群重启可能丢失配置信息 | 开发、跨云部署 |
| Flannel | 适用于 CoreOS 堆栈,有多种后端 | 开发使用较麻烦 | CoreOS 集群、特定生产场景 |
| Project Calico | 简单高效,有细粒度安全控制 | 公共云需 IP - in - IP 隧道 | 大型组织私有云、单云部署 |

下面是一个 mermaid 流程图,展示了选择网络解决方案的大致流程:

graph LR
    A[开始] --> B{是否是开发环境}
    B -- 是 --> C{对易用性要求高?}
    C -- 是 --> D[选择 Weave]
    C -- 否 --> E[选择 Docker 覆盖网络]
    B -- 否 --> F{是否是 CoreOS 堆栈}
    F -- 是 --> G[选择 Flannel]
    F -- 否 --> H{是否能控制网络结构}
    H -- 是 --> I[选择 Project Calico]
    H -- 否 --> J[考虑自定义方案]
6. 服务发现与网络解决方案的未来趋势

随着容器技术的不断发展,服务发现和网络解决方案也将不断演进。未来,我们可能会看到以下趋势:
- 标准化 :网络插件的标准化将使得不同解决方案之间的兼容性更好,用户可以更方便地切换和组合不同的工具。
- 性能优化 :各解决方案将不断优化性能,以满足大规模集群和高并发场景的需求。
- 安全增强 :安全将成为越来越重要的考虑因素,解决方案将提供更强大的安全功能,如更细粒度的访问控制和加密机制。
- 集成度提高 :服务发现和网络解决方案将与其他容器编排工具(如 Kubernetes)更紧密地集成,提供一站式的解决方案。

7. 总结与建议

在选择服务发现和网络解决方案时,需要综合考虑多个因素,包括使用场景、性能需求、安全要求等。以下是一些具体的建议:
- 开发阶段 :可以优先考虑 Docker 的覆盖网络和 Weave,因为它们的易用性和开发体验较好。
- 生产环境 :如果是 CoreOS 堆栈,可以选择 Flannel;如果组织能控制网络结构,Project Calico 是一个不错的选择;如果需要更灵活的解决方案,可以考虑自定义方案。
- 服务发现 :根据项目现有的工具和需求来选择,如 Mesos 项目可以使用 ZooKeeper,GKE 项目可以使用 etcd。如果需要高级功能和 DNS 支持,可以考虑 Consul;如果需要更多定制,可以选择 etcd。

总之,选择合适的解决方案需要根据实际情况进行评估和测试,以确保满足业务需求。希望本文能为你在容器网络和服务发现方面的决策提供有价值的参考。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值