蚊章汇 - Swarm
type: channel
link: https://linuxcn.bwsl.wang/tag/Swarm/
items: 最小权限的容器编排
items: Docker 引擎的 Swarm 模式：添加工作者节点教程
items: Docker 引擎的 Swarm 模式：入门教程
items: 使用 Docker Swarm 部署可扩展的 Python3 应用
items: 如何配置一个 Docker Swarm 原生集群

最小权限的容器编排
type: item
date: 2018-06-04T05:57:35+08:00
description: Docker 平台和容器已经成为打包、部署、和管理应用程序的标准。为了在一个集群内协调跨节点的容器，必须有一个关键的能力：一个容器编排器。对于关键的集群化以及计划的任务，编排器是起重大作用的，比如：管理容器计划和资源分配。支持服务发现和无缝的应用程序部署。分配应用程序运行必需的资源。不幸的是，在这种环境下，编排器的分布式特性和资源的短暂性使得确保编排器的安全是一个极具挑战性的任务。在这篇文章中，我们将讨论容器编排器安全模型中没有考虑到的、但是很重要的这方面的详细情况，以及 Docker 企业版中如何使用内置的编排性能、Swarm 模式，去克服这些问题。诱因和威胁模型使用 swarm 模式的 Docker 企业版的其中一个主要目标是提供一个内置安全特性的编排器。为达到这个目标，我们部署了第一个在我们心目中认为的以最小权限原则设计的容器编排器。在计算机科学中，一个分布式系统所要求的最小权限原则是，系统中的每个参与者仅仅能访问它正当目的所需要的信息和资源。不是更多，也不是更少。“一个进程必须仅仅能去访问它的正当目的所需要的信息和资源”最小权限原则在一个 Docker 企业版集群中的每个节点分配的角色：既不是管理者（manager），也不是工人（worker）。这些角色为节点定义了一个很粗粒度的权限级别：分别进行管理和任务执行。尽管如此，不用理会它的角色，通过使用加密的方式，来保证一个节点仅仅有执行它的任务所需要的信息和资源。结果是，确保集群安全变得更容易了，甚至可以防止大多数的有经验的攻击者模式：攻击者控制了底层通讯网络，或者甚至攻陷了集群节点。内核缺省安全这是一个很老的安全最大化状态：如果它不是缺省的，就没人用它。Docker Swarm 模式将缺省安全这一概念融入了核心，并且使用这一机制去解决编排器生命周期中三个很难并且很重要的部分：可信引导和节点引入。节点身份发布和管理。认证、授权和加密的信息存储和传播。我们来分别看一下这三个部分：可信引导和节点引入确保集群安全的第一步，没有别的，就是严格控制成员和身份。管理员不能依赖它们节点的身份，并且在节点之间强制实行绝对的负载隔离。这意味着，未授权的节点不能允许加入到集群中，并且，已经是集群一部分的节点不能改变身份，突然去伪装成另一个节点。为解决这种情况，通过 Docker 企业版 Swarm 模式管理的节点，维护了健壮的、不可改变的身份。期望的特性是，通过使用两种关键的构建块去保证加密：为集群成员使用 安全加入令牌 Secure join token 。从一个集中化的认证机构发行的内嵌唯一身份的证书。加入 Swarm要加入 Swarm，节点需要一份 安全加入令牌 Secure join token 的副本。在集群内的每个操作角色的令牌都是独一无二的 —— 现在有两种类型的节点：工人（workers）和管理者（managers）。由于这种区分，拥有一个工人令牌的节点将不允许以管理者角色加入到集群。唯一得到这个特殊令牌的方式是通过 swarm 的管理 API 去向集群管理者请求一个。令牌是安全的并且是随机生成的，它还有一个使得令牌泄露更容易被检测到的特殊语法：一个可以在你的日志和仓库中很容易监视的特殊前缀。幸运的是，即便发现一个泄露，令牌也可以很容易去更新，并且，推荐你经常去更新它们 —— 特别是，在一段时间中你的集群不进行扩大的情况下。引导信任作为它的身份标识创建的一部分，一个新的节点将向任意一个网络管理者请求发布一个新的身份。但是，在我们下面的威胁模型中，所有的通讯可以被一个第三方拦截。这种请求存在的问题是：一个节点怎么知道与它进行对话的对方是合法的管理者？幸运的是，Docker 有一个内置机制可以避免这种情况。这个加入令牌被主机用于加入 Swarm，包含了一个根 CA 证书的哈希串。所以，主机可以使用单向 TLS，并且使用这个哈希串去验证它加入的 Swarm 是否正确：如果管理者持有的证书没有被正确的 CA 哈希串签名，节点就知道它不可信任。节点身份发布和管理在一个 Swarm 中，身份标识是内嵌在每个节点都单独持有的一个 x509 证书中。在一个最小权限原则的表现形式中，证书的私钥被绝对限制在主机的原始位置。尤其是，管理者不能访问除了它自己的私钥以外的任何一个私钥。身份发布要接收它们的证书而无需共享它们的私钥，新的主机通过发布一个证书签名请求（CSR）来开始，管理者收到证书签名请求之后，转换成一个证书。这个证书成为这个新的主机的身份标识，使这个节点成为 Swarm 的一个完全合格成员！当和安全引导机制一起使用时，发行身份标识的这个机制来加入节点是缺省安全的：所有的通讯部分都是经过认证的、授权的，并且非敏感信息从来都不会以明文方式进行交换。身份标识延期尽管如此，给一个 Swarm 中…

Docker 引擎的 Swarm 模式：添加工作者节点教程
type: item
date: 2017-09-23T17:04:00+08:00
description: 让我们继续几周前在 CentOS 7.2 中开始的工作。 在本指南中，我们学习了如何初始化以及启动 Docker 1.12 中内置的原生的集群以及编排功能。但是我们只有 管理者 （ manager ） 节点还没有其它 工作者 （ worker ） 节点。今天我们会展开讲述这个。我将向你展示如何将不对称节点添加到 Sawrm 中，比如一个与 CentOS 相邻的 Fedora 24，它们都将加入到集群中，还有相关很棒的负载均衡等等。当然这并不是轻而易举的，我们会遇到一些障碍，所以它应该是非常有趣的。先决条件在将其它节点成功加入 Swarm 之前，我们需要做几件事情。理想情况下，所有节点都应该运行相同版本的 Docker，为了支持原生的编排功能，它的版本至少应该为 1.12。像 CentOS 一样，Fedora 内置的仓库没有最新的构建版本，所以你需要手动构建，或者使用 Docker 仓库手动添加和安装正确的版本，并修复一些依赖冲突。我已经向你展示了如何在 CentOS 中操作，经过是相同的。此外，所有节点都需要能够相互通信。这就需要有正确的路由和防火墙规则，这样 管理者 （ manager ） 和 工作者 （ worker ） 节点才能互相通信。否则，你无法将节点加入 Swarm 中。最简单的解决方法是临时清除防火墙规则 （iptables -F），但这可能会损害你的安全。请确保你完全了解你正在做什么，并为你的节点和端口创建正确的规则。Error response from daemon: Timeout was reached before node was joined. The attempt to join the swarm will continue in the background. Use the "docker info" command to see the current swarm status of your node.守护进程的错误响应：节点加入之前已超时。尝试加入 Swarm 的请求将在后台继续进行。使用 “docker info” 命令查看节点的当前 Swarm 状态。你需要在主机上提供相同的 Docker 镜像。在上一个教程中我们创建了一个 Apache 映像，你需要在你的 工作者 （ worker ） 节点上执行相同操作，或者分发已创建的镜像。如果你不这样做，你会遇到错误。如果你在设置 Docker 上需要帮助，请阅读我的介绍指南和网络教程。7vwdxioopmmfp3amlm0ulimcu \_ websky.11 my-apache2:latest localhost.localdomain Shutdown Rejected 7 minutes ago "No such image: my-apache2:lat&" 现在开始现在我们有一台启动了 CentOS 机器，并成功地创建了容器。你可以使用主机端口连接到该服务，这一切都看起来很好。目前，你的 Swarm 只有 管理者 （ manager ） 。加入 工作者 （ worker ） 要添加新的节点，你需要使用 join 命令。但是你首先必须提供令牌、IP 地址和端口，以便 工作者 （ woker ） 节点能正确地对 Swarm 管理器进行身份验证。接着（在 Fedora 上）执行：[root@localhost ~]# docker swarm join-token worker To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-0xvojvlza90nrbihu6gfu3qm34ari7lwnza ... \ 192.168.2.100:2377 如果你不修复防火墙和路由规则，你会得到超时错误。如果你已经加入了 Swarm，重复 join 命令会收到错误：Error response from daemon: This node is already part of a swarm. Use "docker swarm leave" to leave this swarm and join another one. 如果有疑问，你可以离开 Swarm，然后重试：[root@localhost ~]# docker swarm leave Node left the swarm. docker swarm join --token SWMTKN-1-0xvojvlza90nrbihu6gfu3qnza4 ... 192.168.2.100:2377 This node joined a swar…

Docker 引擎的 Swarm 模式：入门教程
type: item
date: 2017-09-21T16:54:00+08:00
description: Swarm，听起来像是一个朋克摇滚乐队。但它确实是个新的编排机制，抑或者是，一个 Docker 现有编排体制的改进。简单来讲，如果你在用一个旧版本的 Docker，你必须手动配置 Swarm 来创建 Docker 集群。从 1.12 版开始，Docker 引擎集成了一个原生的实现（LCTT 译注：见下文）来支持无缝的集群设置。也就是为什么会有这篇文章。在这篇教程中，我将带你体验一下编排后的 Docker 将能做的事情。这篇文章并不是包含所有细节（如 BnB 一般）或是让你对其全知全能，但它能带你踏上你的集群之路。在我的带领下开始吧。技术概要如果把 Docker 详细而又好用的文档照搬到这里那将太丢人了，所以我将简要概括下这个技术的概要。我们已经有了 Docker，对吧。现在，你想要更多的服务器作为 Docker 主机，但同时你希望它们属于同一个逻辑上的实体。也就是说，你想建立一个集群。我们先从一个主机组成的集群开始。当你在一个主机上初始化一个 Swarm 集群，这台主机将成为这个集群的 管理者 （ manager ） 。从技术角度来讲，它成为了 共识组 （ consensus group ） 中的一个 节点 node 。其背后的数学逻辑建立在 Raft 算法之上。 管理者 （ manager ） 负责调度任务。而具体的任务则会委任给各个加入了 Swarm 集群的 工作者 （ worker ） 节点。这些操作将由 Node API 所管理。虽说我讨厌 API 这个词汇，但我必须在这里用到它。Service API 是这个实现中的第二个组件。它允许 管理者 （ manager ） 节点在所有的 Swarm 集群节点上创建一个分布式的服务。这个服务可以 被复制 （ replicated ） ，也就是说它们（LCTT 译注：指这些服务）会由平衡机制被分配到集群中（LCTT 译注：指 replicated 模式，多个容器实例将会自动调度任务到集群中的一些满足条件的节点），或者可以分配给全局（LCTT 译注：指 global 模式），也就是说每个节点都会运行一个容器实例。此外还有更多的功课需要做，但这些信息已经足够你上路了。现在，我们开始整些实际的。我们的目标平台是 CentOS 7.2，有趣的是在我写这篇教程的时候，它的软件仓库中只有 1.10 版的 Docker，也就是说我必须手动更新以使用 Swarm。我们将在另一篇教程中讨论这个问题。接下来我们还有一个跟进的指南，其中涵盖了如何将新的节点加入我们现有的集群（LCTT 译注：指刚刚建立的单节点集群），并且我们将使用 Fedora 进行一个非对称的配置。至此，请确保正确的配置已经就位，并有一个工作的集群启动并正在运行（LCTT 译注：指第一个节点的 Docker 已经安装并已进入 Swarm 模式，但到这里笔者并没有介绍如何初始化 Swarm 集群，不过别担心下章会讲）。配置镜像和服务我将尝试配置一个负载均衡的 Apache 服务，并使用多个容器实例通过唯一的 IP 地址提供页面内容。挺标准的吧（LCTT 译注：指这个负载均衡的网页服务器）。这个例子同时也突出了你想要使用集群的大多数原因：可用性、冗余、横向扩展以及性能。当然，你同时需要考虑网络和储存这两块，但它们超出了这篇指南所涉及的范围了。这个 Dockerfile 模板其实可以在官方镜像仓库里的 httpd 下找到。你只需一个最简单的设置来起步。至于如何下载或创建自己的镜像，请参考我的入门指南，链接可以在这篇教程的顶部可以找到。docker build -t my-apache2 . Sending build context to Docker daemon 2.048 kB Step 1 : FROM httpd:2.4 Trying to pull repository docker.io/library/httpd ... 2.4: Pulling from docker.io/library/httpd 8ad8b3f87b37: Pull complete c95e1f92326d: Pull complete 96e8046a7a4e: Pull complete 00a0d292c371: Pull complete 3f7586acab34: Pull complete Digest: sha256:3ad4d7c4f1815bd1c16788a57f81b413...a915e50a0d3a4 Status: Downloaded newer image for docker.io/httpd:2.4 ---> fe3336dd034d Step 2 : COPY ../public-html/ /usr/lo…

使用 Docker Swarm 部署可扩展的 Python3 应用
type: item
date: 2016-08-24T17:00:00+08:00
description: Ben Firshman 最近在 Dockercon 做了一个关于使用 Docker 构建无服务应用的演讲，你可以在这里查看详情（还有视频）。之后，我写了一篇关于如何使用 AWS Lambda 构建微服务系统的文章。今天，我想展示给你的就是如何使用 Docker Swarm 部署一个简单的 Python Falcon REST 应用。这里我不会使用dockerrun 或者是其他无服务特性，你可能会惊讶，使用 Docker Swarm 部署（复制）一个 Python（Java、Go 都一样）应用是如此的简单。注意：这展示的部分步骤是截取自 Swarm Tutorial，我已经修改了部分内容，并且增加了一个 Vagrant Helper 的仓库来启动一个可以让 Docker Swarm 工作起来的本地测试环境。请确保你使用的是 1.12 或以上版本的 Docker Engine。我写这篇文章的时候，使用的是 1.12RC2 版本。注意的是，这只是一个测试版本，可能还会有修改。你要做的第一件事，就是如果你想本地运行的话，你要保证 Vagrant 已经正确的安装和运行了。你也可以按如下步骤使用你最喜欢的云服务提供商部署 Docker Swarm 虚拟机系统。我们将会使用这三台 VM：一个简单的 Docker Swarm 管理平台和两台 worker。安全注意事项：Vagrantfile 代码中包含了部分位于 Docker 测试服务器上的 shell 脚本。这是一个潜在的安全问题，它会运行你不能控制的脚本，所以请确保你会在运行代码之前审查过这部分的脚本。$ git clone https://github.com/chadlung/vagrant-docker-swarm $ cd vagrant-docker-swarm $ vagrant plugin install vagrant-vbguest $ vagrant up Vagrant up 命令需要一些时间才能完成。SSH 登录进入 manager1 虚拟机：$ vagrant ssh manager1 在 manager1 的 ssh 终端会话中执行如下命令：$ sudo docker swarm init --listen-addr 192.168.99.100:2377 现在还没有 worker 注册上来：$ sudo docker node ls 让我们注册两个新的 worker，请打开两个新的终端会话（保持 manager1 会话继续运行）：$ vagrant ssh worker1 在 worker1 的 ssh 终端会话上执行如下命令：$ sudo docker swarm join 192.168.99.100:2377 在 worker2 的 ssh 终端会话上重复这些命令。在 manager1 终端上执行如下命令：$ docker node ls 你将会看到：在 manager1 的终端里部署一个简单的服务。sudo docker service create --replicas 1 --name pinger alpine ping google.com 这个命令将会部署一个服务，它会从 worker 之一 ping google.com。（或者 manager，manager 也可以运行服务，不过如果你只是想 worker 运行容器的话，也可以禁用这一点）。可以使用如下命令，查看哪些节点正在执行服务:$ sudo docker service tasks pinger 结果会和这个比较类似：所以，我们知道了服务正跑在 worker1 上。我们可以回到 worker1 的会话里，然后进入正在运行的容器：$ sudo docker ps 你可以看到容器的 id 是: ae56769b9d4d，在我的例子中，我运行如下的代码：$ sudo docker attach ae56769b9d4d 你可以按下 CTRL-C 来停止服务。回到 manager1，然后移除这个 pinger 服务。$ sudo docker service rm pinger 现在，我们将会部署可复制的 Python 应用。注意，为了保持文章的简洁，而且容易复制，所以部署的是一个简单的应用。你需要做的第一件事就是将镜像放到 Docker Hub上，或者使用我已经上传的一个。这是一个简单的 Python 3 Falcon REST 应用。它有一个简单的入口: /hello 带一个 value 参数。放在 chadlung/hello-app 上的 Python 代码看起来像这样：import json from wsgiref import simple_server import f…

如何配置一个 Docker Swarm 原生集群
type: item
date: 2015-07-29T22:30:00+08:00
description: 嗨，大家好。今天我们来学一学Swarm相关的内容吧，我们将学习通过Swarm来创建Docker原生集群。Docker Swarm是用于Docker的原生集群项目，它可以将一个Docker主机池转换成单个的虚拟主机。Swarm工作于标准的Docker API，所以任何可以和Docker守护进程通信的工具都可以使用Swarm来透明地伸缩到多个主机上。就像其它Docker项目一样，Swarm遵循“内置电池，并可拆卸”的原则（LCTT 译注：batteries included，内置电池原来是 Python 圈里面对 Python 的一种赞誉，指自给自足，无需外求的丰富环境；but removable，并可拆卸应该指的是非强制耦合）。它附带有一个开箱即用的简单的后端调度程序，而且作为初始开发套件，也为其开发了一个可插拔不同后端的API。其目标在于为一些简单的使用情况提供一个平滑的、开箱即用的体验，并且它允许切换为更强大的后端，如Mesos，以用于大规模生产环境部署。Swarm配置和使用极其简单。这里给大家提供Swarm 0.2开箱的即用一些特性。Swarm 0.2.0大约85%与Docker引擎兼容。它支持资源管理。它具有一些带有限制和类同功能的高级调度特性。它支持多个发现后端（hubs，consul，etcd，zookeeper）它使用TLS加密方法进行安全通信和验证。那么，我们来看一看Swarm的一些相当简单而简用的使用步骤吧。1. 运行Swarm的先决条件我们必须在所有节点安装Docker 1.4.0或更高版本。虽然各个节点的IP地址不需要要公共地址，但是Swarm管理器必须可以通过网络访问各个节点。注意：Swarm当前还处于beta版本，因此功能特性等还有可能发生改变，我们不推荐你在生产环境中使用。2. 创建Swarm集群现在，我们将通过运行下面的命令来创建Swarm集群。各个节点都将运行一个swarm节点代理，该代理会注册、监控相关的Docker守护进程，并更新发现后端获取的节点状态。下面的命令会返回一个唯一的集群ID标记，在启动节点上的Swarm代理时会用到它。在集群管理器上运行：# docker run swarm create 3. 启动各个节点上的Docker守护进程我们需要登录进我们将用来创建集群的每个节点，并在其上使用-H标记启动Docker守护进程。它会保证Swarm管理器能够通过TCP访问到各个节点上的Docker远程API。要启动Docker守护进程，我们需要在各个节点内部运行以下命令。# docker -H tcp://0.0.0.0:2375 -d 4. 添加节点在启用Docker守护进程后，我们需要添加Swarm节点到发现服务，我们必须确保节点IP可从Swarm管理器访问到。要完成该操作，我们需要在各个节点上运行以下命令。# docker run -d swarm join --addr=<node_ip>:2375 token://<cluster_id> 注意：我们需要用步骤2中获取到的节点IP地址和集群ID替换这里的和。5. 开启Swarm管理器现在，由于我们已经获得了连接到集群的节点，我们将启动swarm管理器。我们需要在集群管理器中运行以下命令。# docker run -d -p <swarm_port>:2375 swarm manage token://<cluster_id> 6. 检查配置一旦管理运行起来后，我们可以通过运行以下命令来检查配置。# docker -H tcp://<manager_ip:manager_port> info 注意：我们需要替换为运行swarm管理器的主机的IP地址和端口。7. 使用docker CLI来访问节点在一切都像上面说得那样完美地完成后，这一部分是Docker Swarm最为重要的部分。我们可以使用Docker CLI来访问节点，并在节点上运行容器。# docker -H tcp://<manager_ip:manager_port> info # docker -H tcp://<manager_ip:manager_port> run ... 8. 监听集群中的节点我们可以使用swarm list命令来获取所有运行中节点的列表。# docker run --rm swarm list token://<cluster_id> 尾声Swarm真的是一个有着相当不错的功能的docker，它可以用于创建和管理集群。它相当易于配置和使用，当我们在它上面使用限制器和类同器时它更为出色。高级调度程序是一个相当不错的特性，它可以应用过滤器来通过端口、标签、健康状况来排除节点，并且它使用策略来挑选最佳节点。那么，如果你有任何问题、评论、反馈，请在下面的评…