Holy Null 's Blog
Holy Null!
Toggle navigation
Holy Null 's Blog
主页
机器学习
Flume
Nginx
Hadoop
Apache Shiro
架构理论
Docker
Spring Cloud
关于我
归档
标签
Docker Swarm 深入浅出
? Docker ?
? Swarm ?
? 集群 ?
? 容器 ?
Service
? task ?
? 跨主机 ?
2018-01-19 11:14:16
534
0
0
holynull
? Docker ?
? Swarm ?
? 集群 ?
? 容器 ?
Service
? task ?
? 跨主机 ?
**更多内容请关注:[gitbook.com](https://www.gitbook.com/book/holynull/docker-swarm/details)** # 前言 2018年初,于北京 当我学会如何使用Doker来发布一个容器,以及学会如何使用docker-compose来发布和管理服务时,我很惊讶Docker容器真的是一个好东西!在研究分布式系统、微服务框架时,Docker确实是一个很好的帮手。我们通过Docker能够在单主机上模拟分布式集群环境,当然你的主机在CPU/内存/硬盘等系统资源的性能如果能够尽可能高的话,你会感到你的学习和研究过程是多么的流畅,让人心旷神怡! 在开发环境或者实验环境中,我们通过单主机Docker Engine来模拟集群环境,可以很容易的将分布式系统的理论付诸于实践,帮助我们理解各种分布式系统的应用原理。但是在实际的生产环境中,我们不可能使用单主机来部署我们的任何应用。那么,在生产环境中如何做到Docker Engine跨主机互联呢? 后来,带着这个问题在百度上查了一些资料。百度上搜索出来的各大论坛和博客的文章大多在将需要使用Zookeeper等类似的组件做一个Discovery机制的数据中心,然后经过一系列的配置使多主机上的Docker Engine能够通过注册发现彼此,形成一个Docker Engine集群。这样在Docker Engine的集群中创建`overlay network`,容器之间就可以分布式部署在不同主机的Docker Engine上,并能够通过overlay network互通。我当时就想,What's the hell! 这么复杂!故障点岂不是越来越多?怎么保证稳定性!? 还有诸如使用虚拟网络交换机组件的方案,就不说了。最后看到使用Kubernetes、Mesos来集成管理的方案。好歹一个是Google的项目,一个是Apache的项目。具体优劣也是众说纷纭,而且学习成本也很大。我一直有一个直觉Docker本身应该有一个多主机集群的方案。最后,我在Docker v17.12的Guides中找到了关于Swarm的介绍。 读者将要阅读到的内容翻译来至Docker官网的指南关于Swarm部分的内容,也揉入了译者的理解。水平有限,还望大家指教斧正。作者的联系方式:holynull@126.com **这里要向Docker项目的所有开发者和文档的编撰者致以崇高的敬意。尤其Guides的编撰者值得赞扬。Guides的语言简单明了,内容精细准确,为我们的学习提供了很大的帮助。** # > 引用 概述 Docker在1.12.0和以上版本中增加了`swarm`模式。通过`swarm`模式管理的Docker Engines集群称之为“Swarm”。并可以通过Docker CLI来创建Swarm,在Swarm中部署应用服务,以及管理Swarm。 ## 功能特点 - **在Docker Engines中集成了集群管理功能:**通过Docker CLI可以创建一个用来发布应用`services`的`swarm`,而不需要安装其他任何额外的软件来管理`swarm`。 - **分散式设计:**与在部署时确定节点角色的处理方式不同,Docker Engines在运行时才会有节点角色的区分。我们可以把节点部署成为即是`mananger`节点同样也是`worker`节点,这意味着我们可以在一个单一的磁盘镜像上创建一个Swarm。 - **规模扩展和收缩:**对于每一个`service`可以定义运行`task`的数量,即`service`的运行规模。当我们对`service`运行的数量进行调整时,`manager`节点会自动的增加或者移除`task`来实现我们所指定的`service`运行规模。 - **状态维持:**manager节点会不断的监视我们设定的swarm的状态和实际状态的变化。例如,我们设定一个service的一个container需要有10个副本,但是其中保存2个副本的workder节点崩溃了,这是manager节点会在其他可用的worker节点上分配两个新副本,并将崩溃的副本移除掉。 - **多宿主机网络:**可以指定`overlay network`给所有的service。当初始化时或者更新应用时,manager节点会为每一个container分配一个在`overlay network`上的地址。 - **服务发现:**manager节点会为每一个swarm中的service分配一个唯一的DNS name,对service的调用会通过负载均衡策略,指向其中一个container上。我们可以通过swarm内部的DNS服务器查询到swarm中正在运行的每一个container。 - **负载均衡:**我们可以通过暴露service的端口给外部的负载均衡设备。而在swarm内部我们可以指定service的container如何在节点上分布。 - **默认安全机制:**在swarm中节点和节点间的通信强制使用TLS协议进行安全通信。用户可以使用自己签署的证书,或者其他CA中心的证书。 - **回滚更新:**在发布应用服务更新时,部署的更新会从一个节点逐渐蔓延到整个swarm。manager节点可以让你控制蔓延的时延,一但更新过程中发生问题,可以使task回滚到之前的一个版本。 # Swarm模式关键概念 本章主要介绍一些Docker Engines1.12集群管理和业务流程特性的独特概念。 ## Swarm是什么? Docker Engines的集群管理和业务流程功能是由[swarmkit](https://github.com/docker/swarmkit/)构建的。Swarmkit是一个独立的项目,由Docker直接调用来实现Docker的业务流程层。 Swarm由多个运行了swarm模式Docker Engine的宿主机组成,每一个宿主机扮演了manager角色或者worker角色,再或者即扮演了manager角色也扮演了worker角色。Manager是管理节点关系和委托的节点,而worker是用来运行service的节点。创建service前,我们需要定义一些参数来使service运行时达到一个期望的最优状态,包括副本数,网络,可用的存储资源,service对外暴露的端口,等等。Docker将不断的监控service的运行状态,一旦运行状态发生变化,Docker将对service进行调整使状态回到预设状态。例如,当一个worker节点不可用时,Docker将调度这个节点上的task到其他可用的节点上。Swarm Service由很多个container组成。而`task`是swarm service中的一个container,并由manager节点进行管理,而不是一个独立的container。 Swarm service不同于独立的container的一个好处是可以修改service的配置,包括网络、存储挂载,而不用手动重启service。Docker将会更新配置,停止所有过期配置的service的task,然后根据新配置创建新的task。 当Docker以swarm模式运行时,也可以在Docker下运行独立的container。独立的contianer和swarm service一个主要的不同点是,只有swarm的manager才能管理swarm,而独立的container可以在任何一个daemon上启动。Docker daemon可以以manager身份、worker身份,或者同时以两种身份加入到swarm中。 就像使用Docker Compose一样,我们可以使用Swarm service stacks来定义和运行container。 下面我们将继续介绍关于Docker swarm services的相关概念,包括:nodes、services、tasks和load balancing。 ## Nodes Node是组成swarm的Docker engine的一个实例。你也可以这样理解,我们可以运行多个node在单独的一个物理计算机服务器上或者云服务器上,但是生产环境通常会要求我们将Docker node分散部署在多个物理主机或者云服务器上。 部署应用到swarm时,首先需要向manager提交要发布的service的定义(配置)。manager节点会对worker节点派发task。 manager节点同时具有执行业务流程的功能,以及为了维持swarm状态而必须的集群管理功能。所有的manager节点会推选一个节点作为leader来实施业务流程任务。 worker节点接收并执行manager节点分配的任务。manager节点默认是可以运行service的,除非我们设置manager节点仅作为manager角色执行管理任务。每个worker节点上会有一个agent,并且不断的汇报分配到这个节点上的task执行情况。woker节点向manager节点汇报分配给它的任务的当前状态,manager节点才能根据task的运行的情况来维持每一个worker上的状态。 ## Services and tasks Service是将要在manager或者worker节点上执行的task的定义。它在swarm系统的结构中处于中心位置,并且是用户的主要操作对象。 当创建service时,你可以执行container使用哪个镜像,并设定将在container内执行哪些命令。 在service的副本模式情况下,manager会使swarm生成n个任务,并分配到所有的node上执行,n等于指定的副本数量。副本数量就是service的container的数量(即,service的scale)。 对于全局services,swarm会在集群的每一个node上执行一个任务。 每一个task包括一个运行的container,以及在container内部运行的命令。task是swarm调度的原子单元。manager将根据副本数生成的task分配到所有worker节点上。一定一个task被分配到一个node上,将不能在移动到其他节点上。所以,task状态的原子性在于task只能在一个node上运行或者失败。 ## Load balancing manager使用入口负载均衡向swarm之外暴露service的端口。manager可以自动为service分配PublishedPort,也可以通过设置指定PublishedPort。如果没有指定端口号,manager将从30000到32767之间选择一个端口号分配给service。 外部组件,例如cloud load balancers,可以通过service的PublishedPort访问到集群中的某一个节点,然而这个节点并不一定正在运行端口对应service的task。但是,swarm中所有的节点都会将入口链接路由指向到对应的service上正在运行的task实例。 Swarm拥有一个内部的DNS组件,这个组件会为每一个service分配一个DNS入口。manager使用内部负载均衡,基于service的DNS name,将请求分发到service集群。 # 开始使用Swarm 本教程将介绍一些Docker Engine在Swarm模式下的一些功能特性。并引导读者完成如下操作: - 在Swarm模式下初始化Docker Engine集群。 - 给Swarm添加节点 - 部署应用服务到Swarm - 管理Swarm 本教程将使用Docker Engine CLI的命令行来进行操作。读者首先需要在一个网络环境中的服务器上安装Docker,并能够在服务器的shell中运行命令。 # 安装 请注意本教程有如下要求: - 3台在同一个网络中的预装Linux操作系统的宿主机,并且宿主机上安装Docker。 - Docker Engine的版本1.12+ - 需要清楚作为Manager的主机的IP地址 - 主机之间需要能够互相开放端口 ## 3个联网的宿主机 本教程要求具备3台联网的Linux操作系统的宿主机,并且安装Docker。这些宿主机可以是物理服务器,也可以是虚拟机或者各种云服务器。读者也可使用Docker Machine来简历主机。 3台宿主机中的一台将作为Manager,我们这里称作manager1。其他两台将作为Worker,分别称作worker1和worker2。 > **注意:** 读者同样可以通过教程的步骤实验创建一个单节点的swarm,这种情况下你只需要一台宿主机。但是多节点命令将不能运行,但是你可以初始化一个swarm、创建service和设定service的scale。 ## Docker Engine 1.12 or newer 本教程要求要求每台宿主机上安装Docker Engine 1.12 +。安装完成以后确定Docker Engine Daemon成功启动运行。 ## Manager宿主机的IP地址 宿主机必须被分配一个固定的IP地址。Swarm中的节点必须能够通过IP地址访问到Manager节点。 如果使用Docker Machine建立的宿主机,我们可以通过`docker-machine ls`或者`docker-machine -ip <MACHINE-NAME>`来获得IP地址。 本教程中的manager1的IP地址是: 192.168.99.100. ## Open protocols and ports between the hosts 宿主机需要开发如下端口,某些操作系统中这些端口是默认开放的: - TCP 2377 - 集群管理通信端口 - TCP and UDP 7946 - 节点之间的通信端口 - UDP 4789 - Overlay Network数据传输端口 如果你计划创建加密的Overlay Network,还需要设置IP协议支持50 (ESP) traffic。 # 创建Swarm 在完成安装步骤以后,就可以准备创建Swarm。首先要确定Docker Engine 已经在所有的主机上已经运行起来。 1. 打开终端通过ssh进入到manager节点,即进入本教程称之为manager1的宿主机。如果你使用Docker Machine,你可以通过如下命令进入宿主机manager1: ``` $ docker-machine ssh manager1 ``` 2. 执行如下命令创建一个新的Swarm: ``` docker swarm init --advertise-addr <MANAGER-IP> ``` > **注意:**如果你使用Docker for Mac或者Docker for Windows实验单节点Swarm,那么命令后面就不要加任何参数。这种情况下不需要指定`--advertise-addr`。 在本教程重,执行如下命令在manager1主机上创建一个swarm: ``` $ docker swarm init --advertise-addr 192.168.99.100 Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager. To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. ``` 参数`--advertise-addr`将功能对外公布manager节点的IP地址为`192.168.99.100`。其他节点必须能够通过这个IP地址访问到该节点。 我们可以看见输出的结果包含了一条在Swarm中添加新节点的命令。节点将依赖参数`--token`,作为manager或者worker加入Swarm。 3. 运行`docker info`命令查看Swarm的当前状态。 ``` $ docker info Containers: 2 Running: 0 Paused: 0 Stopped: 2 ...snip... Swarm: active NodeID: dxn1zf6l61qsb1josjja83ngz Is Manager: true Managers: 1 Nodes: 1 ...snip... ``` 4. 运行`docker node ls`命令查看节点的信息。 ``` $ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS dxn1zf6l61qsb1josjja83ngz * manager1 Ready Active Leader ``` `*`表示当前链接的节点,即我们执行操作命令的节点。 Docker Engine在swarm模式下,使用宿主机的host name来命名节点。 # 增加节点 在manager节点上创建了Swarm之后,我们就可以来添加worker节点了。 1. 通过ssh登录到worker节点所在的主机上。本教程中则登录到worker1主机上。 2. 执行创建Swarm时,运行命令`docker swarm init`输出产生的,用来加入Swarm的命令。我们将创建一个worker节点并加入到之前创建的Swarm中。 ``` $ docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377 This node joined a swarm as a worker. ``` 如果命令无法执行,可以在manager节点上执行下面的命令,重新获得以worker身份加入Swarm的命令。 ``` $ docker swarm join-token worker To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377 ``` 3. 通过ssh登录到第二个要以worker身份加入Swarm的宿主机上。本教程中我们登录到worker2主机上。 4. 执行创建Swarm时,运行命令`docker swarm init`输出产生的,用来加入Swarm的命令。我们将创建第二个worker节点并加入到之前创建的Swarm中。 ``` $ docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377 This node joined a swarm as a worker. ``` 5. 通过ssh登录到manager节点,执行`docker node ls`命令,查看节点信息。 ``` ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 03g1y59jwfg7cf99w4lt0f662 worker2 Ready Active 9j68exjopxe7wfl6yuxml7a7j worker1 Ready Active dxn1zf6l61qsb1josjja83ngz * manager1 Ready Active Leader ``` `MANAGER`列标记哪些节点是manager节点。worker节点该列则为空。 Swarm相关的管理命令,如`docker node ls`只能在manager节点上运行。 # 发布service 在创建了Swarm之后,我们就可以发布一个service了。虽然我们之前创建了worker节点,但是对于发布service来说这并不是必须的。 1. 通过ssh登录到manager节点上,本教程中我们登录到manager1主机上。 2. 执行如下命令: ``` $ docker service create --replicas 1 --name helloworld alpine ping docker.com 9uk4639qpg7npwf3fn2aasksr ``` - `docker service create`命令创建了一个service - `--name`将service命名为`helloworld` - `--replicas`指定运行1个实例 - `alpine ping docker.com`定义了service将以`Alpine Linux`为镜像的container运行,并在container内部执行命令`ping docker.com` 3. 执行`docker service ls`命令,查看正在运行的service。 ``` $ docker service ls ID NAME SCALE IMAGE COMMAND 9uk4639qpg7n helloworld 1/1 alpine ping docker.com ``` **更多内容请关注:[gitbook.com](https://www.gitbook.com/book/holynull/docker-swarm/details)**
上一篇: 无
下一篇:
Spring Cloud 教程|第四篇 Feign客户端
0
赞
534 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
提交评论
立即登录
, 发表评论.
没有帐号?
立即注册
0
条评论
More...
文档导航
没有帐号? 立即注册