UDN-企业互联网技术人气社区

板块导航

浏览  : 1625
回复  : 0

[资源分享] 学习Docker容器网络模型 - 搭建分布式Zookeeper集群

[复制链接]
独领风骚的头像 楼主
发表于 2016-10-12 09:45:30 | 显示全部楼层 |阅读模式
1.png

  ZooKeeper是一个流行的分布式协调服务。它提供了两种不同的部署方式:单机模式和分布式模式。其中单机模式的部署非常简单,网上也有很多资料,我们今天会利用Docker搭建分布式Zookeeper集群,并来帮助大家熟悉Docker中容器网络模型的使用。

  ZooKeeper集群中所有的节点作为一个整体对分布式应用提供服务。节点中有两个的角色:Leader和Follower。在整个集群运行过程中,只有一个Leader,其他节点的都是Follower,如果ZK集群在运行过程中Leader出了问题,系统会采用选举算法重新在集群节点选出一个Leader。

  Zookeeper节点之间是利用点对点的方式互相联结在一起的,这样的点对点部署方式对利用Docker容器搭建ZK集群提出了挑战。这是因为Zookeeper集群中每个节点需要在启动之前获得集群中所有节点的IP信息, 而当使用Docker缺省bridge网络模式启动容器时,Docker Daemon会为容器分配一个新的的IP地址。这样就形成了信息循环依赖。我们需要一些技巧来确保Zookeeper集群配置正确。

  利用Host网络模式

  自从1.9.1之后,Docker容器支持5种不同的网络模式,分别为bridge、host、container、overlay,none。我们可以在Docker run命令中利用“--net”参数来指定容器网络。详解信息请参见 https://docs.Docker.com/reference/run/#network-settings

  如果启动容器的时候使用--net host模式,那么这个容器将和宿主机共用一个Network Namespace。这时Docker Engine将不会为容器创建veth pair并配置IP等,而是直接使用宿主机的网络配置,就如直接跑在宿主机中的进程一样。注意,这时容器的其他资源,如文件系统、进程列表等还是和宿主机隔离的。

  利用host网络,容器的IP地址和机器节点一致,这样我们在部署容器之前就能确定每个ZK节点的IP地址。我们可以分别在三台的机器上用host模式启动一个ZK容器并配置一个分布式集群。

  首先我们需要获得一个ZK的Docker镜像。

  你也可以参照GitHub上代码自己构造

  https://github.com/denverdino/Docker-zookeeper

  我们假设三个节点的主机名:zookeeper1, zookeeper2, zookeeper3

  我们分别在三台不同的主机上依次启动zookeeper容器:利用环境变量SERVER_ID指明节点ID,并在/opt/zookeeper/conf/zoo.cfg中添加ZK集群节点配置信息,具体请详见Docker镜像的启动脚本https://github.com/denverdino/Docker-zookeeper/blob/master/run.sh

  登录到zookeeper1上,并执行下列命令启动集群的第一个节点
13.png

  登录到zookeeper2上,并执行下列命令启动集群的第二个节点
12.png

  登录到在zookeeper3上,再执行下列命令启动集群的第三个节点
11.png

  你可以通过Docker logs ...来查看容器日志,ZK集群是否搭建成功

  采用host网络方式的优点是,配置简单、网络性能与原生进程一样,对于关注性能和稳定性的生产环境,host方式是一个较好的选择。但是需要登录到每台虚机、物理机上操作太过繁琐。

  我们可以利用下面的Docker-compose模板,一键在一组ESC实例上创建基于host网络方式的ZK集群。注意:下面模板部署要求集群上至少包括3个ECS实例。
10.png

  这里利用Docker Compose支持的变量名替换能力,比如 ${...} 可以在运行时让用户输入下列参数

  ZOOKEEPER_1:第一个ECS实例的IP地址或域名

  ZOOKEEPER_2:第二个ECS实例的IP地址或域名

  ZOOKEEPER_3:第三个ECS实例的IP地址或域名

  当部署应用时,会提示用户根据集群实际信息输入下面参数
9.png

  然而容器服务是如何保证特定的zookeeper容器能够确保调度到指定ECS实例上呢?

  因为完全支持Docker Swarm的调度约束,比如对于zookeeper1容器,它会调度到满足下面约束的constraint:aliyun.node_index==1ECS实例上。对于容器服务集群中的每一个ECS实例,在加入集群时都会被自动添加一系列的标签(label),比如节点序号、地域(Region)、可用区(Avaliablity Zone)等信息。通过这些约束我们可以控制容器和ECS实例的亲和性,来控制调度过程。 关于Docker Swarm 调度和容器服务Compose扩展的信息可以通过连接获得。
8.png

  体验Docker容器网络模型(Container Network Model)的自定义网络

  在开发环测试境,为了节省资源,我们经常需要将ZK集群部署在一台主机。这时候我们必须采用手工的方法调整每个Docker容器暴露的服务端口来避免端口冲突,然而这样会导致端口管理的复杂性。那么是否可以有其他方式来解决呢?我们是否可以让每个ZK容器有自己独立的IP,它们之间可以互相发现对方呢?

  在Docker 1.9以前,Docker的网络模型有很多限制,比如:不支持跨节点的容器网络,服务发现能力较弱等等。而且不同应用对网络的需求不同,不同的底层网络技术也各有特点。所以Docker在2015年中发布了一个可扩展的容器网络管理项目libnetwork,并引入了新的容器网络模型(Container Network Model CNM)。

  CNM在Docker 1.9版本中第一次正式发布,并持续增强。从此network成为了Docker的第一类资源。用户可以创建容器网络,并将容器关联到网络之上。在相同network上的任何容器都可以利用容器名称来解析服务的访问地址。这样不但解决了容器之间网络互联的问题,还简化了容器之间的服务端点发现。

  我们下面利用CNM的自定义特性来部署ZK集群

  下面我们首先创建一个名为“foo”的网络
7.png

  然后,我们会创建三个ZK节点容器并分别在“foo”的网络将它们命名为"zk1","zk2",和"zk3"。利用CNM的特性,我们可以使用容器名称来访问网络中其他容器。执行命令如下
6.png

  在这里我们利用容器名作为DNS中容器的域名来配置ZK节点。由于3个ZK容器都被挂载到相同的"foo"网络,他们之间可以通过容器名相互访问。这就优雅地解决了ZK配置和动态容器IP地址之间的循环依赖问题。

  当然,我们还可以在本地使用下面的Docker-compose.yml文件,执行Docker-compose up -d来一键部署一个ZK集群。这将大大简化搭建测试环境的工作。
5.png

  在云端,阿里容器服务为集群缺省创建了一个全局跨节点的“multi-host-network”网络,这样在集群内部容器之间的网络是相互连通的。无需指明网络模式,容器之间就可以直接通过容器名进行访问,相应的Docker-compose模板被简化如下:
4.png

  利用容器网络模型提供的容器连接

  除了上面的方法,我们还可以在自定义网络中利用容器连接。

  自从Docker 1.10版本之后,Docker内嵌了DNS服务,还支持在用户定义的网络上使用容器链接别名来访问引用的容器。 比如我们在容器zk1中,定义了连接 --link zk2:zknode2 那么意味着,在容器中可以利用zknode2作为容器zk2的别名来访问,而Docker容器内部的DNS将其动态解析正确的IP地址。注意与经典的容器链接不同,在自定义网络中容器链接并不需要被连接的容器已经启动,所以我们可以方便地描述双向连接或者P2P方式部署的应用。
3.png

  注:在Docker 1.11版本中对容器链接方式进一步增强,支持一对多这种方式的容器链接。并支持DNS轮询来实现简单的负载均衡。

  静态分配容器IP

  自从Docker 1.10开始,已经允许用户直接指明容器的IP地址。我们也可以利用这种方法来配置ZK集群。

  我们首先创建一个网络“bar”,并设置它的子网为“172.19.0.0/16”动态IP分配区域为“172.19.0.0/17”
2.png

  这样,我们就保留了172.19.128.0/17这个子网可以用于静态IP地址分配了,下面我们可以自己选择几个不冲突的IP地址来配置ZK集群。比如:节点1至3的IP地址为,172.19.200.1,172.19.200.2和172.19.200.3。
1.png

  总结

  Docker的容器网络模型的出现大大推动了容器网络技术的发展。善用容器网络模型可以解决不同应用的互联互通问题。

原文作者:denverdino 来源:阿里百川

相关帖子

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部