Swarm初探

1 简介

Swarm 是使用 SwarmKit 构建的 Docker 引擎内置(原生)的集群管理和编排工具。其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源。Swarm和Kubernetes比较类似,但是更加轻量,具有的功能也较kubernetes更少一些。

Docker v1.12 是一个非常重要的版本,Docker 重新实现了集群的编排方式。在此之前,提供集群功能的 Docker Swarm 是一个单独的软件,而且依赖外部数据库(比如 Consul、etcd 或 Zookeeper)。从 v1.12 开始,Docker Swarm 的功能已经完全与 Docker Engine 集成,要管理集群,只需要启动 Swarm Mode。安装好 Docker,Swarm 就已经在那里了,服务发现也在那里了(不需要安装 Consul 等外部数据库)。

2 架构分析

2.1 基本架构

基本架构
如上图所示,Swarm Node表示加入Swarm集群中的一个Docker Engine实例,基于该Docker Engine可以创建并管理多个Docker容器。其中,最开始创建Swarm集群的时候,Swarm Manager便是集群中的第一个Swarm Node。在所有的Node中,又根据其职能划分为Manager Node和Worker Node。

manager node

Manger 节点,顾名思义,是进行 Swarm 集群的管理工作的,它的管理工作集中在如下部分,

  • 维护一个集群的状态
  • 对Services进行调度
  • 为Swarm提供外部可调用的API接口

Manager 节点需要时刻维护和保存当前 Swarm 集群中各个节点的一致性状态,这里主要是指各个 Tasks 的执行的状态和其它节点的状态;因为 Swarm 集群是一个典型的分布式集群,在保证一致性上,Manager 节点采用 Raft 协议来保证分布式场景下的数据一致性;
通常为了保证 Manager 节点的高可用,Docker 建议采用奇数个 Manager 节点,这样的话,你可以在 Manager 失败的时候不用关机维护,我们给出如下的建议:

  • 3 个 Manager 节点最多可以同时容忍 1 个 Manager 节点失效的情况下保证高可用;
  • 5 个 Manager 节点最多可以同时容忍 2 个 Manager 节点失效的情况下保证高可用;
  • N 个 Manager 节点最多可以同时容忍 (N−1)/2个 Manager 节点失效的情况下保证高可用;
  • Docker 建议最多最多的情况下,使用 7 个 Manager 节点就够了,否则反而会降低集群的性能了。
Worker Node

Worker Node接收由Manager Node调度并指派的Task,启动一个Docker容器来运行指定的服务,并且Worker Node需要向Manager Node汇报被指派的Task的执行状态。

更换角色

可以通过docker node promote/demote 来提升或者降级节点

2.2 设计架构

设计架构

跨主机容器通信

Docker Swarm 内置的跨主机容器通信方案是overlay网络,这是一个基于vxlan协议的网络实现。VxLAN 可将二层数据封装到 UDP 进行传输,VxLAN 提供与 VLAN 相同的以太网二层服务,但是拥有更强的扩展性和灵活性。 overlay 通过虚拟出一个子网,让处于不同主机的容器能透明地使用这个子网。所以跨主机的容器通信就变成了在同一个子网下的容器通信,看上去就像是同一主机下的bridge网络通信。
为支持容器跨主机通信,Docker 提供了 overlay driver,使用户可以创建基于 VxLAN 的 overlay 网络。其实,docker 会创建一个 bridge 网络 “docker_gwbridge”,为所有连接到 overlay 网络的容器提供访问外网的能力。docker network inspect docker_gwbridge 查看网络信息。
docker network ls
overlay网络的具体实现:
docker 会为每个 overlay 网络创建一个独立的 network namespace,其中会有一个 linux bridge br0,endpoint 还是由 veth pair 实现,一端连接到容器中(即 eth0),另一端连接到 namespace 的 br0 上。

br0 除了连接所有的 endpoint,还会连接一个 vxlan 设备,用于与其他 host 建立 vxlan tunnel。容器之间的数据就是通过这个 tunnel 通信的。逻辑网络拓扑结构如图所示:
在这里插入图片描述

服务发现

docker Swarm mode下会为每个节点的docker engine内置一个DNS server,各个节点间的DNS server gossip协议互相交互信息。此处DNS server用于容器间的服务发现。swarm mode会为每个 –net=自定义网络的service分配一个DNS entry。目前必须是自定义网络,比如overaly,自建bridge。(在engine DNS之上)

原理:
每个Docker容器都有一个resolv.conf,它将DNS查询转发到docker engine,该引擎充当DNS服务器。docker 引擎收到请求后就会在发出请求的容器所在的所有网络中,检查域名对应的是不是一个容器或者是服务,如果是,docker引擎就会从存储的key-value建值对中查找这个容器名、任务名、或者服务名对应的IP地址,并把这个IP地址或者是服务的虚拟IP地址返回给发起请求的域名解析器。
由上可知,docker的服务发现的作用范围是网络级别,也就意味着只有在同一个网络上的容器或任务才能利用内嵌的DNS服务来相互发现,不在同一个网络里面的服务是不能解析名称的,另外,为了安全和性能只有当一个节点上有容器或任务在某个网络里面时,这个节点才会存储那个网络里面的DNS记录。
如果目的容器或服务和源容器不在同一个网络里面,Docker引擎会把这个DNS查询转发到配置的默认DNS服务 。
service-dns
在上面的例子中,总共有两个服务myservice和client,其中myservice有两个容器,这两个服务在同一个网里面。在client里针对docker.com和myservice各执行了一个curl操作,下面时执行的流程:

  • 为了client解析docker.com和myservice,DNS查询进行初始化
  • 容器内建的解析器在127.0.0.11:53拦截到这个DNS查询请求,并把请求转发到docker引擎的DNS服务
  • myservice被解析成服务对应的虚拟IP(10.0.0.3),在接下来的内部负载均衡阶段再被解析成一个具体任务的IP地址。如果是容器名称这一步直接解析成容器对应的IP地址(10.0.0.4或者10.0.0.5)。
  • docker.com在mynet网络上不能被解析成服务,所以这个请求被转发到配置好的默认DNS服务器(8.8.8.8)上。
负载均衡

负载均衡分为两种:Swarm集群内的service之间的相互访问需要做负载均衡,称为内部负载均衡(Internal LB);从Swarm集群外部访问服务的公开端口,也需要做负载均衡,称外部部负载均衡(Exteral LB or Ingress LB)。

  • internal LB
    内部负载均衡就是我们在上一段提到的服务发现,集群内部通过DNS访问service时,Swarm默认通过VIP(virtual IP)、iptables、IPVS转发到某个容器。
    my-net
    当在docker swarm集群模式下创建一个服务时,会自动在服务所属的网络上给服务额外的分配一个虚拟IP,当解析服务名字时就会返回这个虚拟IP。对虚拟IP的请求会通过overlay网络自动的负载到这个服务所有的健康任务上。这个方式也避免了客户端的负载均衡,因为只有单独的一个IP会返回到客户端,docker会处理虚拟IP到具体任务的路由,并把请求平均的分配给所有的健康任务。
    mynet
  • Exteral LB(Ingress LB 或者 Swarm Mode Routing Mesh)
    看名字就知道,这个负载均衡方式和前面提到的Ingress网络有关。Swarm网络要提供对外访问的服务就需要打开公开端口,并映射到宿主机。Ingress LB就是外部通过公开端口访问集群时做的负载均衡。

当创建或更新一个服务时,你可以利用–publish选项把一个服务暴露到外部,在docker swarm模式下发布一个端口意味着在集群中的所有节点都会监听这个端口,这时当访问一个监听了端口但是并没有对应服务运行在其上的节点会发生什么呢? 接下来就该我们的路由网(routing mesh)出场了,路由网时docker1.12引入的一个新特性,它结合了IPVS和iptables创建了一个强大的集群范围的L4层负载均衡,它使所有节点接收服务暴露端口的请求成为可能。当任意节点接收到针对某个服务暴露的TCP/UDP端口的请求时,这个节点会利用预先定义过的Ingress overlay网络,把请求转发给服务对应的虚拟IP。ingress网络和其他的overlay网络一样,只是它的目的是为了转换来自客户端到集群的请求,它也是利用我们前一小节介绍过的基于VIP的负载均衡技术。

启动服务后,你可以为应用程序创建外部DNS记录,并将其映射到任何或所有Docker swarm节点。你无需担心你的容器具体运行在那个节点上,因为有了路由网这个特性后,你的集群看起来就像是单独的一个节点一样。
ingress
上面这个图表明了路由网是怎么工作的:

  • 服务(app)拥有两份复制,并把端口映射到外部端口的8000
  • 路由网在集群中的所有节点上都暴露出8000
  • 外部对服务app的请求可以是任意节点,在本例子中外部的负载均衡器将请求转发到了没有app服务的主机上
  • docker swarm的IPVS利用ingress overlay网路将请求重新转发到运行着app服务的节点的容器中
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值