文档章节

八、Docker Swarm

倪伟伟
 倪伟伟
发布于 06/24 23:03
字数 3617
阅读 14
收藏 0

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。并且服务构造添加了诸如缩放、滚动更新和简单回滚等内容。



 


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

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

每一个节点上都需要安装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模式。

在单引擎模式的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必须使用分配的,不能更改),如下图所示:

根据提示,在此输入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后面的字符串会有所不同),如下所示:

执行完毕后,有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个工作者。如下所示:

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

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

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

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

如上图所示,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存储在一个安全的地方。如下图所示:

重新启动一个管理者节点,看是否可以自动的加入集群。用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,如下所示:

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

在返回后,管理者作为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节点上执行。

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

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

Replicated vs global 服务

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

扩展服务

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

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

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

删除服务

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

滚动跟新(Rolling updates)

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

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

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

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

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

上图显示了由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,如下所示:

向服务传递-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中的任何设置。

 

 

© 著作权归作者所有

倪伟伟
粉丝 22
博文 23
码字总数 29125
作品 0
西安
高级程序员
私信 提问
『中级篇』Docker-Secret管理和使用(51)

原创文章,欢迎转载。转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『中级篇』Docker-Secret管理和使用(51) 之前咱们写的docker-compose.yml里面,里面有mysql的时候有变量MYSQLRO...

IT人故事会
2018/08/18
0
0
Docker入门教程 Part 4 Swarms

前言 本篇笔记是官方Get Started入门教程的Part 4,主要介绍 Docker 集群 Swarm 的功能和使用。前面章节都是在单主机上使用Docker,这个章节将学会在集群中使用Docker容器。 我正在学习Docke...

iotisan
2017/11/16
0
0
大规模 WebSocket 集群项目 AnyIM 实战

一、概述 WebSocket 应用场景非常广泛,例如社交聊天、弹幕、多玩家游戏、协同编辑、股票基金实时报价、体育实况更新、视频会议/聊天、实时定位、在线教育、智能家居等,这些场景都与我们的生...

Anoyi
2017/11/17
0
0
docker 1.12版本的swarm集群使用

Docker 1.12版本后,Swarm变化比较大,更加简单、好用,而且采用了gossip协议后,支持多个Manager,也更加稳定可靠了。不需要单独安装,Swarm的集群功能已经成为Docker Engine的一部分。因此...

openthings
2016/11/20
31
0
docker~swarm搭建docker高可用集群

Swarm概念   Swarm是Docker公司推出的用来管理docker集群,它将一群Docker宿主机变成一个单一的,虚拟的主机。Swarm使用标准的Docker API接口作为其前端访问入口,换言之,各种形式的Docke...

mcy247
2017/12/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

用Python从0开始实现一个中文拼音输入法

众所周知,中文输入法是一个历史悠久的问题,但也实在是个繁琐的活,不知道这是不是网上很少有人分享中文拼音输入法的原因,接着这次NLP Project的机会,我觉得实现一发中文拼音输入法,看看...

计算机编程
23分钟前
3
0
阿里P7架构师对Java虚拟机、类加载机制是怎么理解的?

概述 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载 (Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化 (Initializat...

kx33389
41分钟前
0
0
日本软银孙正义表示从未命令ARM断供华为

华为虽然有自主研发的麒麟处理器,但在架构和指令集方面仍然基于 ARM,所以当 ARM 切断与华为一切联系的消息传来后,很多人对华为麒麟的未来忧心忡忡,也怀疑已经收购了 ARM 的日本软银在背后...

linuxCool
49分钟前
4
0
mongodb安装、连接,mongodb用户管理、创建集合、数据管理、备份恢复,副本集介绍、搭建、测试,分片介绍、搭建、测试,php的mongodb扩展、mongo扩展

21.26 mongodb介绍 21.27 mongodb安装 21.28 连接mongodb 21.29 mongodb用户管理 21.30 mongodb创建集合、数据管理 21.31 php的mongodb扩展 21.32 php的mongo扩展 21.33 mongodb副本集介绍 ...

tobej
今天
3
0
C++的变量初始化

C++中变量的初始化有很多种方式,如:默认初始化,值初始化,直接初始化,拷贝初始化,列表初始化。 1、默认初始化:默认初始化是指定义变量时没有指定初值时进行的初始化操作。 如:int a;...

天王盖地虎626
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部