您现在的位置是:首页 > 文章详情

Docker 官方出品丨Docker 最佳实践系列指南(三)

日期:2018-05-29点击:323

screenshot

本文首发自“Docker公司”公众号(ID:docker-cn)
编译丨小东
每周一、三、五 与您不见不散!


Docker EE 中的高可用性

在生产环境中,尽量减少关键服务的停机时间是至关重要的。务必了解在 UCP 和 DTR 中如何实现高可用性 (HA),以及发生故障时该如何操作。UCP 和 DTR 使用相同的原理提供 HA,但 UCP 与 Swarm 的功能有更直接的关联。通用的原理是在集群中复制核心服务,这样一来,当一个节点发生故障时,其他节点就可以接管。负载均衡器向用户提供与处理请求的实际节点无关的稳定主机名,从而使服务对用户透明。这就是提供 HA 的基础集群机制。

  • Swarm

UCP HA 的基础是由 Swarm 提供的,它是 Docker 引擎的集群功能。Docker 引擎文档中已经详细说明,有两种算法参与管理 Swarm 集群:用于工作节点的 Gossip 协议和用于管理节点的 Raft 一致性算法。Gossip 协议是最终一致的,也就是说,当新信息在集群中传播时,集群的不同部分可以掌握同一个值的不同版本(这种协议也称为传染病协议,因为信息的传播就像病毒一样)。这样就可以实现非常大规模的集群,因为使用此类协议时不必等待整个集群就某个值达成一致,而且仍然可以实现信息的快速传播,在可以接受的时间内达成一致。管理节点处理需要以高度一致的信息为基础的任务,因为它们需要根据集群和服务的全局状态来作出决定。

在实践中,可能很难在不影响可用性的情况下实现高度一致,因为每次写操作都需要得到所有参与者的确认,而如果有一个参与者不可用或响应缓慢,就会影响整个集群。CAP 原理解释了这个问题,它(简洁地)指出,因为在分布式系统中存在分区 (P),所以我们必须在一致性 (C) 和可用性 (A) 之间抉择。Raft 之类的一致性算法使用法定多数机制来处理这种取舍:如果多数参与者就某个值达成一致,那么该值就足够正确,占少数的参与者最终会获得新值。也就是说,一次写操作只需要 3 个节点中的 2 个、5 个节点中的 3 个或 7 个节点中的 4 个确认即可。

因为以这种方式达成一致,所以在配置 Swarm 时建议节点数量为奇数。如果 Swarm 中有 3 个管理节点,该集群可以在暂时损失 1 个的情况下仍然保持运作功能,如果有 5 个,可以损失 2 个,以此类推。反过来,在有 3 个管理节点的集群中需要 2 个管理节点确认写操作,有 5 个管理节点的话就需要 3 个,所以增加管理节点并不会提高性能或可扩展性 — 您实际上要复制更多数据。拥有 4 个管理节点并不会带来什么好处,因为仍然只能损失 1 个节点(法定多数是 3),而比起只有 3 个管理节点的情况,要复制更多数据。实际上这样的节点更脆弱。

如果有 3 个管理节点,损失了 2 个,集群就无法发挥功能。现有的服务和容器会继续运行,但是无法处理新的请求。**如果集群中只剩下一个管理节点,并不会“切换”为单管理节点模式。它只不过是一个少数派节点。您也不能将工作节点提升为管理节点来重新达到法定多数。发生故障的节点仍然是一致性集的成员,需要重新联机。

  • UCP

UCP 跨所有集群节点运行一个全局服务,名为 ucp-agent。此代理程序在所有 Swarm 管理节点上各安装一个 UCP 控制器。Swarm 管理节点和 UCP 控制器之间存在一一对应的关系,但它们承担不同的角色。使用此代理程序的 UCP 依靠 Swarm 实现 Ha,但也包含一些复制的数据存储,它们依靠自身不同于 Swarm 的 raft 一致性集:ucp-auth-store(用于身份管理数据的复制数据库)和 ucp-kv(用于 UCP 配置数据的复制键-值存储)。

  • DTR

DTR 有工作原理类似于 UCP 的复制模式,但它不会与 Swarm 同步。它有一个复制的组件,即它的数据存储,后者也可能需要一次复制许多状态。它依靠 raft 一致性。

UCP 控制器和 DTR 从节点在(重新)加入集群时需要复制的状态都可能大大增加。某些重新配置操作可能使集群成员暂时不可用。如果有 3 个成员,聪明的做法是先等待重新配置的一个成员恢复同步,然后再配置第二个,否则它们可能失去法定多数。暂时失去法定多数是很容易恢复的,但是这仍然意味着集群处于非健康状态。务必监视控制器的状态,确保集群不处于这样的状态。


备份与还原

使用多个节点的 HA 设置在发生暂时故障(包括计划的节点维护停机时间)时可以很好地提供连续可用性。在其他情况下(包括损失整个集群,永久失去法定多数,以及存储器故障造成数据损失),则必须从备份还原。

  • UCP 备份

UCP 备份是使用 docker/ucp backup 命令在控制器节点上完成的。该命令会停止节点上的 UCP 容器,并执行 UCP 的配置和状态的完全备份。有些这样的信息是很敏感的,因此您一定要使用 --passphrase 选项对备份加密。备份还包括 DTR 以及 UCP 所使用的组织、团队和用户。应该安排定期备份。下面是一个示例,显示了如何在无用户输入的情况下运行命令:

UCPID=$(docker run --rm -i --name ucp -v /var/run/docker.sock:/var/run/docker.sock docker/ucp id) docker run --rm -i --name ucp -v /var/run/docker.sock:/var/run/docker.sock docker/ucp backup --id $UCPID --passphrase "secret" > /tmp/backup.tar 

有两种使用备份的方式:- 使用 docker/ucp restore 命令还原控制器(仅可使用来自该控制器的备份) - 使用 docker/ucp install --from-backup 命令安装新集群(保留用户和配置)

  • DTR 备份

DTR 备份包含配置信息、镜像元数据和证书。镜像本身需要直接从存储器另作备份。请记住,用户和组织是由 UCP 管理和备份的。
该备份只能用于通过 docker/dtr restore 命令创建新的 DTR。


身份管理

访问 Docker EE 的组件(UCP 和 DTR)中的资源(镜像、容器、存储卷、网络,等等)至少需要一个帐户和相应的密码。Docker EE 中的帐户是存储在内部数据库中的身份,但是创建这些帐户和相关访问控制的源可以是手动源(受管或内部),也可以是通过与目录服务器 (LDAP) 或 Active Directory (AD) 连接的外部源。对这些帐户的授权管理是下面各节中描述的粗粒度和细粒度权限的延伸。

  • RBAC 和管理对资源的访问

UCP 提供基于角色的强大访问控制功能,可以无缝地与企业身份管理工具集集成,满足企业安全需求。除了方便粗粒度和细粒度安全访问控制之外,此功能也可用于促成单一 UCP 集群中的多租户,共享分组为不同集合的各种资源。

UCP 中的访问权限是通过向使用者授予角色来管理的,各种角色对这些资源集合有不同的访问权限。访问权限定义了用户在系统中可以或不可以执行的操作。

UCP 中的默认角色为无、仅查看、有限控制、调度器和完全控制。在参考架构保护 Docker EE 和安全最佳实践中详细说明了这些角色以及它们的相互关系。这些角色各自都有一组操作,定义了与角色关联的权限。通过组合出独特的权限集合,还可以定义附加的定制角色。可以利用定制角色实现某些组织和安全控制规章所要求的细粒度访问控制。

使用者是组织中的个人用户或团队。团队通常基于 LDAP/AD 组或搜索过滤器。也可以手动向团队添加用户。但是团队不能有混合的用户组成。也就是说,团队中的用户列表应该产生自目录服务器(例如 AD),或者应该手动添加,但是不能同时使用这两种方式。

集合是 UCP 中的对象分组。一个集合可以包含一个或多个节点、应用栈、容器、服务、存储卷、网络、涉密信息或配置 — 也可以包含其他集合。要使节点、应用栈或任何其他资源与集合关联,该资源必须与集合共享标记 com.docker.ucp.access.label。一个资源可以与零个或多个集合关联,而一个集合可以包含零个或多个资源或其他子集合。在集合中包含集合可以实现资源对象的层级性结构,从而显著简化访问控制。在最高级别集合提供的访问权会被其所有子代继承,包括所有子集合。

请思考这种思路的一个非常简单的应用场景。假设您定义了一个名为 Prod 的最高级别集合,以及分别与 Prod 中每个应用对应的子集合。这些子集合包含应用的实际资源对象,例如应用栈、服务、容器、存储卷、网络、涉密信息等。现在假设 IT 运维团队的所有成员都需要访问所有 Prod 资源。在这种设置下,即使存在大量的应用(因而在 Prod 集合中也就存在大量子集合),也可以对 UCP 中的 IT 运维团队授予仅对 Prod 集合的完全控制角色。访问权将适用于 Prod 集合中包含的每一个集合。与此同时,可以对特定应用开发团队的成员提供仅对应于该应用集合的细粒度访问权。这种模式实现了传统的基于角色的访问控制 (RBAC),即对团队分配对于特定资源集合的角色。

  • 受管(内部)身份验证

受管的身份验证和授权模式是 Docker EE 标准版和高级版中的默认模式。在这种模式下,帐户是使用 Docker EE API 直接创建的。可以通过从 UCP UI 访问用户管理 —> 用户 —> 创建用户表单来手动创建用户帐户。也可以通过向名为 eNZi 的身份验证和授权 RESTful 服务提出 HTTP 请求,自动地创建和管理帐户。

建议仅将使用“受管”模式的用户管理用于演示目的,或者需要访问 Docker EE 的用户人数非常少的情况。

优点:

  1. 设置方便且快捷
  2. 便于故障排除
  3. 适合用于具有静态角色的少数用户
  4. 不需要离开 UCP 界面即可管理

缺点:

  1. 如果用户人数较多,或者需要管理多种应用的角色,用户帐户管理就会变得很麻烦。
  2. 所有的生命周期更改,例如添加 / 删除用户权限的操作,都需要一个个用户地手动完成。
  3. 必须手动删除用户,这意味着无法快速清除访问权,降低了系统的安全性。
  4. 无法通过 LDAP 或外部系统实现复杂的集成式应用创建和部署设置。
  • LDAP / AD 集成

可以使用用户帐户身份验证的 LDAP 方法来管理用户访问。顾名思义,这种模式实现了用户帐户从 Active Directory 或 OpenLDAP 等目录服务器的自动同步。

这种方法特别适用于这样的应用场景:组织内有大量用户,通常在集中的身份存储中维护用户帐户,管理身份验证以及授权。这类身份存储大多基于目录服务器,例如 Microsoft 的 Active Directory 或支持 LDAP 协议的系统。此外,此类企业已经有成熟的流程用于处理员工入职、员工离职和用户与系统帐户的生命周期更改管理。可以利用所有这些流程,在 Docker EE 中提供无缝而高效的访问控制流程。

优点:

  1. 能够利用既定的访问控制流程授予和撤销权限
  2. 能够继续从基于 LDAP 的集中系统继续管理用户和权限
  3. 能够利用这种模式的自清除性质,在下一次同步时自动从 Docker EE 删除不存在的 LDAP 用户,从而提高安全性
  4. 能够使用 LDAP 代理配置复杂的上游系统(例如平面文件、数据库表),并通过 AD/LDAP 组自动进行基于时间的访问配置解除

缺点:

  1. 与受管模式相比提高了复杂性
  2. 对管理员有更高的要求,因为他们必须了解外部系统 (LDAP)
  3. 由于在混合中增加了组件 (LDAP),发生问题时需要花更多时间进行故障排除
  4. 对上游 LDAP/AD 系统的更改会导致对 Docker EE 的意外更改,可能对 Docker EE 造成意外影响

建议的最佳实践是使用组成员资格来控制用户帐户对资源的访问。理想情况下,对此类组成员资格的管理是通过集中的身份管理或基于角色的访问控制系统实现的。这就提供了一个标准、灵活且可扩展的模式,用于通过集中的目录服务器在 Docker EE 中控制身份验证和授权规则。通过身份管理系统,此目录服务器保持与用户入职、离职和角色及职责变更的同步。

要更改身份验证模式,请在 UCP UI 中使用管理 —> 管理设置 —> 身份验证和授权表单。在此表单中,将启用 LDAP 字段切换为是。

对于从目录服务器发现继而同步的帐户,系统可以自动分配对于其自身私有集合的默认权限。要分配对于非私有集合的其他权限,需要将这些用户添加到分配了所需角色的相应团队。

screenshot

以下列表强调了设置 LDAP 身份验证时应考虑的重要配置选项:

  1. 在 LDAP 身份验证模式中,如果发现了帐户,要等到用户登录系统时才会在 UCP 中创建相应帐户。这是由 LDAP 配置中的实时用户配置设置控制的。建议打开此设置。
  2. 必须在目录服务器上配置一个用户帐户,才能从目录服务器发现和导入帐户。此用户帐户不必是权限非常高的帐户。实际上,它最好是一个可以查看必要的 organizationalUnit (ou) 并查询组成员资格的只读帐户。此帐户的详细信息是使用字段读取帐户 DN 和读取帐户密码来配置的。读取帐户 DN 必须使用专有名称格式。
  3. 尽可能使用安全 LDAP。
  4. 在切换到 LDAP 身份验证之前,使用 LDAP 配置的 LDAP 测试登录部分来确认您是否能连接。
  5. 在填写完表单并且测试连接成功之后,同步按钮会提供一个选项,可以立即运行同步,不必等待下次间隔。执行此同步就会启动 LDAP 连接,并运行过滤器来导入用户。
  6. 在完成并保存配置之后,应该可以使用符合同步条件的有效 LDAP/AD 帐户登录。系统支持的登录属性只有 uid 和 sAMAccountName。要在 Docker EE 中成功登录,帐户在 LDAP/AD 系统中应该处于正常状态。
  7. 可以通过在控制器上运行下列命令来查看和分析同步的进度/状态和出现的任何问题:docker logs ucp-controller

  • 组织和团队

在 Docker EE 中存在的用户帐户,无论是通过 LDAP 同步还是手动受管,都可以组织为各种团队。团队需要包含在组织中。可以为创建的每个团队授予关于集合的角色,允许团队成员在关联的集合中进行操作。

要创建团队,需要先创建组织。可以在用户管理 —> 组织和团队 —> 创建组织中创建组织。

请思考此示例,它创建了一个名为 enterprise-applications 的组织:

screenshot

在 UCP UI 中,可以通过单击组织,然后单击创建团队来创建团队。也可以使用后文中描述的 eNZi API 实现同样的目的。可以将成员逐一添加到团队。如果使用 LDAP 身份验证模式,还可以用另一种方法向团队添加成员。这种方法的基础是从配置为启用 LDAP 身份验证模式的目录服务器自动同步发现的帐户。可以在此时应用更精细的过滤器来确定将发现的帐户归入哪些团队。一个团队可以有多个用户,而一个用户可以是零个到多个团队的成员。下面是一个示例,在 enterprise-applications 组织中创建两个团队:Dev Team 和 Ops Team。

首先创建组织:

screenshot

创建完组织后,就可以在其中创建 dev team:

screenshot

然后还可以创建 ops team:

screenshot


  • 集合

集合是一种逻辑构造,可用于任意地聚集前文描述的一组资源。要创建集合,请使用位于集合 —> 创建集合的表单。下面是一个示例,创建了一个名为 production 的集合。

screenshot

此示例中的 production 集合仅用于包含其他应用集合。有一个这样的集合是 Billing Application,可以通过单击集合 —> production —> 查看子集 —> 创建集合在 production 集合中创建该集合,如下图所示。

screenshot

此时可以创建授权,依据团队在集合中的职能向其分配角色。

参考下面的具体示例会更方便理解:

假设您有一个简单的应用名叫 www,它是基于 nginx 官方镜像的 Web 服务器。再假设 www 应用是部署到生产中的收费应用之一。有三个团队需要访问此应用 — developers、testers 和 operations。通常,testers 只需仅查看访问权即可,operations 团队为了管理和维护环境,需要完全控制。而 developers 团队需要对应用进行故障排除、重启和控制生命周期的访问权,但是应该禁止他们进行其他任何需要访问主机文件系统或启动特权容器的活动。这种特殊的访问权叫做有限控制。


  • 授权

可以在 UCP 中的用户管理 —> 授权 —> 创建授权,使用向导创建授权。Swarm 集合是所有集合的根。单击查看子集可显示所有子集合。 production 集合应该是显示的集合之一。单击与 production 集合对应的查看子集来访问 Billing Application集合。单击选择集合以选择它。屏幕应该类似于如下所示:

screenshot

本节演示一个典型的应用场景,它使用“最低特权/权限”原则以及“责任分离”原则。它旨在满足上一节描述的示例应用 www 的访问需求。

还是在创建授权界面,单击角色。从下拉菜单选择有限控制角色。然后单击使用者。选择组织,然后从组织下拉菜单选择 enterprise-applications,从团队下拉菜单选择 Dev Team。单击创建。

重复同样的步骤以创建另一个授权,但是只选择 production 集合,并且选择角色完全控制,选择 Ops Team 作为使用者。

重复同样的步骤以创建另一个授权,但是只选择 Billing Application 集合,并且选择角色仅查看,选择 Test Team 作为使用者。

screenshot

有了以上的授权设置,团队对于 Billing Applications 集合中的应用就有了基于其职能的相应访问级别。

要使 www 应用与 Billing Applications 集合关联,应以同样方式创建服务,但在按下图所示创建服务前要选择集合:

screenshot

选择集合:

screenshot


  • 使用 LDAP 过滤器的策略

需要访问 UCP 的用户都是源于企业 Directory Server 系统的。这些用户是需要管理 Docker EE 基础架构的管理员用户,以及每个在 UCP 中配置的团队的全体成员。再假设需要访问 Docker EE 的整个用户群体(包括管理员、开发人员、测试人员和运维人员)是 Directory Server 中所有用户的一个子集。

在组织用户时建议使用的策略是创建一个总括的成员资格组,标识出所有 Docker EE 用户,不论他们属于哪个团队。姑且称这个组为 Docker_Users。不应该让任何用户直接成为这个组的成员。相反,应该让 Docker_Users 包含其他组,只有这些组才能作为它的成员。按照我们的示例,姑且就称这些组为 dev、test 和 ops。在我们的示例中,这些组是目录服务器中被称作嵌套组的结构的一部分。嵌套组允许权限从一个组继承至它的所有子组。

注:有些目录服务器在默认情况下不支持嵌套组的功能,甚至也不支持 memberOf 属性。如果是这样,那就需要启用它们。如果选择的目录服务器完全不支持这些功能,那就应该用其他方法来组织用户和查询他们。Microsoft Active Directory 默认支持这两种功能。

在目录服务器中,应该将用户帐户作为这些子组的成员添加。这不应该影响组织单位的任何现有布局,也不应该影响这些用户的既有组成员资格。在定义团队时,应该将子组用作组 DN 的值。

最后,如果需要终止任何用户帐户的一切访问,只要将该帐户的组成员资格从 Docker_Users 这一个组删除,就会删除该用户的所有访问权。由于嵌套组的工作原理,在 Docker 中的所有其他访问权都会自动清除 — 在下一次同步时,系统将会从所有团队成员资格中删除该用户帐户,不需要手动干预或执行其他步骤。在企业身份管理系统中,可以将这一步骤整合到标准的入职/离职自动化配置步骤中。


  • 身份验证 API (eNZi)

AuthN API(在内部也叫 eNZi,发音是 N-Z)是一种用于 Docker EE 的集中式身份验证和授权服务及框架。此 API 完全集成和配置到 Docker EE 中,可以与 UCP 以及 DTR 无缝地协同工作。这是在后台工作的组件和服务,它通过标记、经由 OpenID Connect 的单点登录 (Web SSO) 以及帐户详细信息从基于 LDAP 的外部系统到 Docker EE 的同步,来管理帐户、团队和组织,用户会话、权限和访问控制。

用户和操作人员在进行普通的日常活动时,不需要关心 AuthN API 及其工作原理。但是,可以利用其功能使许多常用功能自动化和/或完全绕过 UCP UI 以直接管理和操纵数据。

在 AuthN API Docker 文档中记述了 RESTFul AuthN API 终端。

与 AuthN 的交互可以通过两种方式实现:经由暴露的 RESTful AuthN API 通过 HTTP 交互,或通过 enzi 命令交互。

例如,下面的命令使用 curl 和 jq 经由 AuthN API 通过 HTTP 获取 Docker EE 中的所有用户帐户:

$ curl --silent --insecure --header "Authorization:Bearer $(curl --silent --insecure \ --data '{"username":"","password":""}' \ https:///auth/login | jq --raw-output .auth_token)" \ https:///enzi/v0/accounts | jq . 

也可以在 UCP 控制器上用 CLI 调用 AuthN 服务。要连接该服务,请在 UCP 控制器上运行下列命令:

$ docker exec -it ucp-auth-api sh 

在得到的提示符 (#) 下面,输入 enzi 命令及子命令,例如下面示例中用于列出数据库表状态的命令:

# enzi db-status 

请参阅恢复 Docker EE 标准版和高级版的管理员密码获取详细示例。

原文链接:https://yq.aliyun.com/articles/598344
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章