八、Docker Swarm

Docker Swarm有两件事:一个企业级的Docker主机安全集群,另一个是用于协调微服务应用程序的引擎。

在集群方面,它将一个或多个Docker节点组合在一起,并允许你将他们作为一个集群来管理。开箱即用就可以得到加密的分布式集群存储,加密的网络、互助的TLS、安全的集群加入令牌以及使轻松管理和旋转证书比较容易的PKI。也可以无中断地添加和删除节点。

在协调方面,Swarm公开了一个丰富的API,允许您轻松的部署和管理复杂的微服务应用程序。你可以在声明性的manifest文件中定义你的应用程序,并使用本机Docker命令部署它们。你甚至可以执行滚动更新、回滚和缩放操作。

一、Swarm 入门

在集群方面,swarm由一个或多个Docker节点组成。这些节点可以是物理服务器、VMs、Raspberry Pi’s或云实例。唯一的要求就是所有的节点可以再可靠的网络上通信。节点可被配置为管理者(manager)或者工作者(worker)。管理者照看集群的控制平面,意味着可以查看集群的状态,分配任务给工作者。工作者从管理者接收任务并执行他们。

swarm的配置和状态保存在分布式的etcd数据库,它位于所有的管理者节点上。它保存在内存中并且是最新的。但最好的事情是它需要0配置。起 作为swarm安装的一部分。Swarm使用TLS加密通信,认证 节点,授权角色,还有自动的秘钥轮换。
在应用协调方面,在swarm上调度的原子单元是服务。在API中,这是一个新对象,伴随着swarm引入的。它是一个高层次的结构,将一些高级功能环绕在容器周围。当一个容器被包括在一个服务中时,我们称之为task或replica。并且服务构造添加了诸如缩放、滚动更新和简单回滚等内容。


45e9b3c42cb04617c6afd33dcdd1685ee23.jpg
 


二、构建一个安全的swarm集群

在本小节,将使用3个管理节点和3个工作节点来构建一个安全的swarm集群。当然你也可使用具有不同数量的管理节点和工作节点,这些节点可以有不同的名称和IPs。

2a483c09f4165fc21db3142b9c256fedadb.jpg

每一个节点上都需要安装Docker,并且需要和swarm中的其他节点通信。如果配置了名称解析会更好,因为有助于解决问题。

在 网络方面,需要在路由器和路由器上开启以下端口:

  • 2377/tcp: 为安全的client-to-swarm通信
  • 7946/tcp and 7946/udp: control plane gossip
  • 4789/udp: 基于VXLAN的overlay 网络

一旦满足了先决条件,就可以构建一个swarm。构建swarm的过程有时也叫做初始化swarm。这个高级过程是初始化第一个管理者节点->加入其它的管理者节点->加入工作者节点->完成。

(1)初始化一个全新的swarm

在单引擎模式中,Docker节点并不是swarm的一部分,一旦他们加入swarm,就切换到swarm模式。

736e162338c0bb7b89476b5f848c3fda345.jpg

在单引擎模式的Docker主机上运行“docker swarm init”,将会切换到swarm模式,创建全新的swarm,并使得此节点作为swarm的第一个管理者。其他节点可以作为管理者或工作者加入。下面的步骤将mgr1放入swarm模式并初始化全新的swarm。然后加入wrk1, wrk2和wrk3作为工作者-自动将他们放入swarm模式。最后,加入mgr2 和mgr3,作为其他的管理者并将他们切换到swarm模式。最后,所有的6个节点将在swarm模式,并作为同一个swarm的一部分来运行。

本例子将会使用上图中显示的IP地址和DNS名称,也可以使用不同的。

第一步,登录mgr1,输入docker swarm init --advertise-addr 192.168.0.13:2377 --listen-addr 192.168.0.13:2377(由于是网络模拟环境,IP必须使用分配的,不能更改),如下图所示:

4a45106ea3143760149fde13db153297b53.jpg

根据提示,在此输入docker swarm join-token manager,然后在Docker主机上执行 “docker swarm join --token SWMTKN-1-2estpkdxh6io84lcsc7e0z5m6iwsgljn2xi85mi6dys0vybifi-4j64us5rpdxh6tv3uww638exk 192.168.0.13:2377”,可以将相关主机添加为worker,执行docker swarm join --token SWMTKN-1-2estpkdxh6io84lcsc7e0z5m6iwsgljn2xi85mi6dys0vybifi-bukw34c8glin7q034dgo3vb6v 192.168.0.13:2377,可以将相关主机添加为manager(注:--token后面的字符串会有所不同),如下所示:

2ad398df67224bbf0a65ead3072e993d993.jpg

c48f1859b37d9f26c439fb5f40ee2a91d16.jpg

db4a047bf836feb79aaf6a12ea25f35f9c7.jpg

660b72beb50607e91be9832a677fb4e8370.jpg

执行完毕后,有3个manager节点和2个worker节点 。

  • docker swarm init :告诉Docker初始化一个全新swarm,并使得此节点成为第一个管理者,并使得此节点变为swarm模式;
  • --advertise-addr:其他节点连接到此管理者的IP和端口,是一个可选标志;
  • --listen-addr:指定哪个IP和端口用来监听swarm流量,通常与 --advertise-addr匹配。

swarm运行的缺省端口是2377,也是可以定制化的,使用2377/tcp为安全的 (HTTPS) client-to-swarm连接是一个惯例。

在任何一个管理者节点上输入:docker node ls,显示出刚才创建的5个节点,3个管理者,2个工作者。如下所示:

b387429b25aa886734472c4f60d96ca14de.jpg

如上所示,在manager status栏里显示Leader或者Reachable的为管理者,其他的为工作者。ID后面带*号,表明docker node ls是从node1节点的主机执行的。

(2)swarm管理者的高可用性(HA)

swarm天生支持高可用性,如果一个或多个失败,存活的管理者节点仍可以保持swarm运行。

从技术上讲,Swarm实现了一种主动-被动的多管理器的形式。这意味着尽管你可能也应该有多个管理者,但只有一个被认为是活跃的。我们称这个活跃的管理者为“Leader”,而“Leader”是唯一一个能对集群发出实时命令的。所以只有“Leader”才能改变配置,或者向工作者发布任务。如果被动(非主动)管理者接收集群命令,并代理它们转发到“Leader”节点上。如下图所示:

b50df01119f0888c346ceda6689fbefc659.jpg

如上图所示,managers或者是leaders或者是followers。这是Raft术语,因为swarm使用了Raft一致性算法的一个实现来驱动manager的HA。在HA的话题上,应用两个最佳实践:

  1. 部署奇数个managers
  2. 不要部署太多的managers(推荐3-5个)

swarm内置安全

swarm集群有大量的内置安全性,在合理缺省的情况下是开箱即用的。包括CA 设置、join tokens, mutual TLS, encrypted cluster store、encrypted networks, 加密的节点 ID’s等。具体详细的请看后续。

锁定集群

尽管有这些内置的安全性,但是重新启动旧的管理者或恢复旧备份可能会危害集群。旧的管理者重新加入Swarm,将自动解密并访问raft日志时间序列数据库-这可能会引起安全问题。恢复旧备份可以清除当前的集群配置。

为了阻止上述情况的发生,Docker允许用Autolock特性来锁定swarm。这强制需要重启的管理者在允许返回到集群之前需要提供集群解锁key。

对于新建的swarm,可以在docker swarm init 命令后传递--autolock标志,也可以对已存在的swarm进行lock,使用命令docker swarm update --autolock=true。

在任一个管理者节点上执行docker swarm update --autolock=true,确保unlock key存储在一个安全的地方。如下图所示:

03bffe6fa5ac51f1740e39e6932bcfbc320.jpg

重新启动一个管理者节点,看是否可以自动的加入集群。用sudo执行命令service docker restart,然后用docker node ls显示集群节点信息。

三、Deploy一些swarm服务

集群服务(swarm services)

本小节中的每件事都可以通过Docker Stacks来改进(后续会介绍)。服务仅存在于swarm模式。

服务可以让我们指定大多数熟悉的容器选项,诸如name, port,mappings, attaching to networks, and images。但是他们也增加了一些东西,比如让我们
声明应用程序服务的所需状态,将其提供给Docker,并让Docker负责部署和管理它。

例如,假设你有一个Web前端的应用程序。其对应的有一个镜像,测试表明你需要5个实例来处理正常的日常流量。你可以把这个要求传送给一个单一服务,这个服务声明了容器应该使用的映像,以及该服务有5个正在运行的副本。可以使用命令:docker service create --name web-fe -p 8080:8080 --replicas 5 nigelpoulton/pluralsight-docker-ci,如下所示:

cdad669766d4880a8fffca75b866057c8cf.jpg

注意:所有的服务副本使用相同的镜像和配置。

在返回后,管理者作为leader,在集群中实例化了5个副本-记住swarm管理者也作为一个工作者。每一个工作者或者管理者拉取镜像并在8080端口启动容器。swarm leader确保服务副本所需的状态存储在集群中,并且复制到集群中的每一个管理者节点。所有的服务被swarm持续监控,运行一个后台检查循环,持续比较服务的实际状态和所需状态。如果两个状态匹配,不需要才去进一步行动,否则将采取行动。换句话说,swarm持续确保实际状态匹配所需状态。

例如,5个副本之一的工作者节点失败,web-fe服务的实际状态从5个变为4个,不再匹配所需的状态。因此Docker将会启动一个新的web-fe副本来恢复实际状态。这种行为非常强大,允许服务在节点故障等情况下自我修复。

查看和检查服务(Viewing and inspecting services)

可以使用docker service ls来显示swarm中运行的服务。此命令需要在manager节点上执行。

c575b592195e11904585a971a1dcbf6cda6.jpg

可以使用 docker service ps <service-name or serviceid>来显示服务副本的列表,如下:

9475fc18d22d1194004f76c3efb23a1a226.jpg

为获得每个服务的详细信息,可使用docker service inspect --pretty <service-name or serviceid>(--pretty 限制输出最感兴趣的信息),如下图所示:

bd08b269f9f71eda3577e15f99625b2161a.jpg

Replicated vs global 服务

一个服务的缺省复制模式是replicated,这将部署一个期望的副本数量,尽可能均匀的再集群中分发他们。另一个模式是global,在集群中的每一个节点上运行一个单一副本,可使用--mode global标志。

扩展服务

服务的另一个强大特性是可以容易的向上或向下进行扩展。例如将上述的web-fe服务扩展到10个,docker service scale web-fe=10,如下:

bd34a9ae895c7c04492a5286b4eac61e22d.jpg

其中new的是新建的,running是已经存在的。

将服务从10个缩小到5个,可以使用命令docker service scale web-fe=5,如下:

2c48d5023f05a5acad19cfb50a8a0fd7b93.jpg

删除服务

删除服务使用 docker service rm <service-name or serviceid>

滚动跟新(Rolling updates)

向已部署的应用程序推送更新是一件重要的事,幸亏有Docker服务,向设计良好的应用程序推送更新是一件容易的事。

首先我们将创建一个新的服务,但是在创建新服务之前,我们需要为服务创建一个新的overlay网络。这不是必须的,但可以学习如何创建网络,以及如何将网络附着到服务上。

创建网络的命令如下:docker network create -d overlay uber-net,其创建了一个overlay网络,叫uber-net,可使用docker network ls显示:

a7a04ea0f5445d180f12555445df6c8d23f.jpg

从上图可以看出,uber-net在swarm范围,并且暂时仅被swarm中的管理者节点可见。

overlay网络创建了一个第二层网络,我们可以在其上运行容器,所有的容器都能够进行通信。即便运行容器的Docker主机在不同的基础网络上,这是因为overlay在潜在的多个不同的基础网络之上创建了一个第二层容器网络,如下图:

a16cab39160f192c41d9630c92f18ed91c6.jpg

上图显示了由3层路由器连接的两个基础网络,有一个横跨他们的单一的overlay网络。Docker主机连接到基础网络,容器连接到overlay。所有在overlay上的容器都可以通信即使他们的Docker主机在不同的基础网络。

创建一个新的服务,并使用overlay网络,docker service create --name uber-svc --network uber-net -p 80:80 --replicas 12 nigelpoulton/tu-demo:v1,如下所示:

5bf04817315aec5b4bb5e4139391564e331.jpg

向服务传递-p 80:80标志,将确保集群范围内的映射被创建,映射所有进入集群中任何节点的80端口的流量 ,并通过80段扩进入到任何一个服务副本。

在集群中每一个节点上发布一个端口的模式-即使不运行服务副本-称之为ingress模式,且是缺省的。可供选择的另一种模式是host模式,仅在运行副本的集群节点上发布服务,命令下:docker service create --name uber-svc --network uber-net --publish published=80,target=80,mode=host --replicas 12 nigelpoulton/tu-demo:v1

docker service update 可以对运行中的程序进行更新。
四、故障排除(Troubleshooting)

可以使用命令docker service logs来查看swarm服务日志。然而,并不是所有的日志驱动都支持此命令。

缺省情况下,Docker使用json-file格式的日志驱动,但是其他的驱动也存在,包括:journald (only works on Linux hosts running systemd)、syslog、splunk、gelf。

json-file 和journald 是最容易配置的,二者都可以使用docker service logs 命令,格式是docker service logs <service-name>。

如果使用第三方的日志驱动,应该使用日志平台的原生工具查看日志。比如配置使用syslog驱动,需要在daemon.json配置文件中输入以下:

{
    "log-driver": "syslog"
}
通过在docker service create命令后传送--logdriver 和--log-opts 标志,可以强制服务使用不同的驱动。他们将会重写daemon.json中的任何设置。

 

 

转载于:https://my.oschina.net/niweiwei/blog/3065743

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值