Skip to content

Latest commit

 

History

History
403 lines (276 loc) · 25.6 KB

File metadata and controls

403 lines (276 loc) · 25.6 KB

十三、使用 Salt 解决方案解决管理问题

在本章中,我们将发现并讨论为什么企业需要为其基础架构提供集中管理工具,包括异构环境带来的高度复杂性。我们将讨论此问题的解决方案,例如:

  • 新技术如何为我们的业务带来复杂性
  • 我们如何集中系统管理。
  • 代码为 ( IaC )的基础设施如何帮助我们维护系统状态
  • 利用 IaC 的工具
  • SaltStack 平台及其组件

让我们开始系统管理之旅。

集中化系统管理

理解系统管理背后的原因很容易被认为是理所当然的。我们经常假设,仅仅因为一个企业有一个大的信息技术基础设施,它就需要一个管理其库存的解决方案。虽然这显然是真的,但事情远不止如此。作为架构师,我们的工作包括倾听客户的问题,了解他们到底在寻找什么。

新技术和系统管理

在这个不断发展的信息技术世界里,变化来得很快。新技术几乎每天都会出现。虚拟化、物联网和云等技术正在通过指数级增长我们的基础设施来塑造和改变我们使用信息技术的方式,这是裸机时代从未见过的。

所有这些变化和指数级增长意味着,IT 经理要管理的东西要多得多,而培训员工支持这些技术的时间要少得多,因此许多企业几乎跟不上步伐。这可能导致他们不愿意采用新技术。但许多人别无选择,只能采用它们,因为担心变得无关紧要,无法满足客户的需求。如果他们的竞争对手拥有优势并提供更好更快的服务,他们很可能会倒闭。

公司希望尽快采用这些技术,以获得超过竞争对手的优势,但新技术往往伴随着巨大的学习曲线。在此期间,信息技术人员需要学习如何管理和维护新系统,因此保持关键系统和工作负载可用成为一项挑战。不遵守我们的服务级别协议会成为真正的威胁;想象一下这样一种情况,一个开发人员需要操作团队将一个库补丁应用到我们的开发环境系统中,以便测试一个新版本,并且因为我们的操作人员(或者至少一半)正在接受培训,所以开发人员很想绕过标准化的变更请求过程,自己应用更新。这种情况下的影子 IT 真的很常见,我们需要不惜一切代价避免。影子 IT 会让我们公司不符合监管标准。

虽然信息技术领导者推动采用新技术,但他们通常只有非常少且不断减少的预算来完成这种转型。这也直接影响到我们的关键系统和工作负载,因为对系统管理的投资下降,并转向创新。走向创新并不是一件坏事,因为它最终将使我们能够提供更好的服务,但重要的是要理解,它也会对我们现有环境的维护产生影响。

新技术带来新的基础设施;混合环境每天都在变得越来越普遍,了解如何以最佳和最有效的方式管理这些混合环境至关重要。

恢复对我们自己的基础架构的控制

控制我们的基础设施是系统管理的主要目标。但是拥有控制权意味着什么呢?清单、版本控制、自动修补和软件分发都是系统管理的一部分。所有这些都是一个更大图景的一部分,在这个图景中,信息技术重新获得了对其基础架构的控制,并可以确保其系统的合规性和标准化,无论它们运行的是什么样的 Linux 发行版。

通常我们的系统是分离的;这种分离是因为它们的特性可能不同。我们可以拥有基于红帽企业 Linux 发行版或基于 Debian 发行版的系统,拥有不同架构的系统,例如 x86、power servers,甚至 ARM。所有这些系统甚至可能不会相互对话或服务于相同的目的;所有这些都变成了信息技术必须维护和管理的孤岛。

想象一下,在没有集中和自动化任务的工具的情况下,在每个单独的思洛存储器上手动执行系统管理涉及的所有不同任务。人为错误是此类场景最直接的威胁,其次是 IT 企业为培训员工、雇佣员工以及为每种不同的系统类型购买特定的管理工具而必须承担的巨大复杂性、时间和成本。

分散问题的集中工具

集中的配置管理可以帮助我们以受控、一致和稳定的方式控制对系统的更改。它非常适合运行集群或配置为高可用性的系统,因为集群中的所有节点都必须具有完全相同的配置。通过配置管理,我们还可以了解某些文件、安装在所有系统上的包甚至配置文件中的一行代码的权限背后的原因。

我们通过配置管理工具实现的这些更改或配置也可以回滚,因为市场上大多数可用的工具都带有版本控制,任何打字错误、人为错误或不兼容的更新都可以轻松回滚。

随着我们慢慢过渡到云环境,虚拟机和资源越来越成为一种商品和服务。可以帮助我们管理、调配和维护云基础架构的配置管理工具成为非常有价值的资产。有了这些类型的工具,我们可以以更有弹性的方式对待我们的基础设施,并以描述性的方式定义它,也就是说,我们可以拥有部署相同基础设施或基于定义实现更改的模板;这就是我们所说的基础设施代码 ( IaC )。

为期望的状态编码

IaC 背后的整个想法是在我们的环境中保持一致性和版本控制。IaC 寻求一种更具描述性和标准的资源调配方式,通过避免独特和特殊的部署来防止由于每个组件的独特性而导致重新创建环境非常复杂的情况。

IaC 工具通过特定语言或现有语言(如 YAML 或 JSON)定义配置;在下面,我们可以看到一个从 Terraform 模板中提取的示例,该模板在微软 Azure 中定义了虚拟机:

resource "azurerm_resource_group" "test" {
 name = "example"
 location = "East US 2"
}

resource "azurerm_kubernetes_cluster" "test" {
 name = "exampleaks"
 location = "${azurerm_resource_group.test.location}"
 resource_group_name = "${azurerm_resource_group.test.name}"
 dns_prefix = "acctestagent1"

 agent_pool_profile {
 name = "default"
 count = 1
 vm_size = "Standard_B1_ls"
 os_type = "Linux"
 os_disk_size_gb = 30
 }

 service_principal {
 client_id = "00000000-0000-0000-0000-000000000000"
 client_secret = "00000000000000000000000000000000"
 }

 tags = {
 Environment = "Production"
 }
}

output "client_certificate" {
 value = "${azurerm_kubernetes_cluster.test.kube_config}"
}

output "kube_config" {
 value = "${azurerm_kubernetes_cluster}"
}

在云基础设施领域,弹性是关键。现在,我们的数据中心没有现有资源可供使用。在云中,我们为自己使用的东西付费,让虚拟机或存储坐在那里增加我们的每月账单并不理想。有了 IaC,我们可以按需扩展或缩减这些环境。例如,我们知道我们有一个应用,它只在工作时间处于峰值消耗,需要额外的实例来支持负载。但是在工作时间之外,一个实例足以支持负载。有了 IaC,我们可以有一个脚本在早上创建额外的实例,并在一天结束时降低实例。每个实例都不是唯一的,我们可以利用通过 IaC 使用描述性文件的配置管理工具来实现这一点。

有几种工具可以完成上述示例,但许多工具不仅仅是在云中或虚拟化环境中调配基础架构。其他配置管理工具甚至做得更多;他们可以推送配置文件、安装软件包、创建用户,甚至文件系统。这些工具有几种方式和方法来执行它们的配置。许多工具需要代理,但其他一些工具是无代理的。

配置管理工具执行更改的方式基本上是通过来实现的。这将取决于(但不总是)工具是使用代理还是无代理。大多数无代理工具会推送您在 IaC 文件中声明的配置更改,并在您通过命令行或脚本执行工具时,将更改发送到云中的应用编程接口或 SSH。

另一方面,拉动几乎总是通过代理。代理不断向配置管理服务器咨询定义,验证所需的状态,以防发生变化,将这些变化从服务器中取出并应用到其主机上。

推和拉有两种不同的应用方式:声明方式和命令方式。声明方式指定了期望的状态是什么,并且更改是按照 IaC 规范文件中的定义来应用的。命令式方法包括以特定的顺序运行一组指令或命令,告诉系统如何达到期望的状态。

通过 IaC 进行配置管理的一些开源工具如下:

  • 木偶
  • 厨师
  • 安塞波
  • 仿地成形
  • 无赖

我们将在第 14 章让你的手变咸中深入探讨盐及其成分。

理解氯化钠

我们了解了 IaC 是什么,以及系统管理背后的困难。但是作为未来解决方案的架构师,我们需要知道并了解哪些工具可以帮助我们的客户应对配置管理带来的挑战。

在本节中,我们将讨论如何使用 Salt ,或****Salt stack 平台**,帮助我们实现集中化、敏捷化和弹性化的管理基础架构。**

**# 引入盐

Salt 是一个用 Python 开发的开源项目,由 Tomas S Hatch 在 2011 年创建。最初,它并不是一个配置管理工具,而是一个利用ZeroMQ库的数据收集工具和远程命令执行软件。同年晚些时候,通过状态添加了配置管理功能,我们将在后面回顾。

由于 Salt 是用 Python 编写的,因此它具有高度的可扩展性和模块化,并且可以轻松编写定制的模块来进一步扩展其功能。

理解 Salt 不仅仅是一个配置管理工具是至关重要的,但是在这些章节中,由于手头主题的性质,我们将关注它的配置管理能力。在进一步阅读部分,如果你想了解更多关于其他 Salt 功能的信息,我将添加其他几本书的推荐。

您在 Salt 中定义所需状态的方式,或者换句话说,Salt 支持的语言是多种多样的。主要的默认语言是支持Jinja模板化的 YAML。

创建新用户的 YAML 定义示例如下:

doge:
 user.present:
 - fullname: much doge 
 - shell: /bin/bash
 - home: /home/doge

YAML 是绍特的数据渲染语言;数据呈现采用文件中的定义,然后将其转换为 Python 数据结构,供 Salt 使用。

以下是 Salt 支持的一些其他数据呈现语言:

  • dson
  • hjson
  • json5
  • json
  • pydsl
  • pyobjects
  • py
  • stateconf
  • yamlex

盐有两种渲染类型。第一个是我们刚刚谈到的:数据渲染。第二个是文本渲染,这是Jinja所属的类别。这个文本渲染不是返回一个 Python 数据结构,而是返回文本,这些文本随后被翻译用于数据渲染。

如果我们需要重复几个具有不同值但结构相同的定义,文本呈现对于设置变量或循环非常有用。例如,我们可以创建一个Jinja模板,用相同的文件创建几个用户,而不是为每个用户创建一个 YAML,如下所示:

{% for user in [dsala, eflores, elilu] %}
{{ user }}:
user.present:
 - home: /home/{{ user }}
 - shell: /bin/bash

前面的示例将创建三个用户,而不是通过文件或定义创建一个用户。这种方式效率更高,因为我们不仅通过不反复键入相同的定义来节省时间和工作,而且如果阵列中需要,我们还可以轻松添加更多用户,而不必为额外的用户创建全新的文件或定义。

除了Jinja,Salt 文本渲染支持其他模板引擎,例如:

  • Cheetah
  • Genshi
  • GPG
  • Jinja
  • Mako
  • NaCl
  • Pass
  • Py
  • Wempy

在接下来的章节中,我们将重点关注Jinja和 YAML。

SaltStack 平台

我们之前讨论过 IaC 的不同方法和途径。Salt 非常适合我们理解所有这些方法,因为 Salt 既使用了推拉方法,也使用了声明性命令性方法。

让我们概述一下 Salt 的基本功能:

像任何其他客户机/服务器集群一样,Salt 由两种基本类型的节点组成:

  • :这个服务器,或者说一组服务器,负责协调喽啰,以及他们在哪里查询自己想要的状态。主人也是发送命令在奴才身上执行的人。
  • 仆从:主服务器管理的服务器。

主服务器从两个 TCP 端口监听:45054506。两个端口都有非常不同的角色和非常不同的连接类型。

4505端口或发布者是所有奴才监听来自主人的消息的地方。4506端口或请求服务器是爪牙通过安全方式直接请求特定文件或数据的地方。Salt 的网络传输利用了 ZeroMQ 消息队列系统,该系统使用椭圆曲线密码和 4,096 位 RSA 密钥,这些密钥是在主服务器和从属服务器中生成的,我们将在本章后面部分看到。

Salt 是一个基于代理的工具,主人和爪牙之间的所有通信都可以通过安装在爪牙上的代理来实现。爪牙负责启动与主人的通讯。

这很重要,因为在一个可能有也可能没有互联网的分段网络中,你的主人和奴才之间会有许多安全边界,每个奴才可能没有一个唯一的地址。在主机发起通信的场景中,您在栈中的所有爪牙可能都必须有一个公共 IP 地址,或者每次添加要管理的宠臣时都必须执行大量网络配置和网络地址转换 ( NAT )。

由于 Salt 通信的工作方式,您可以让您的主人在一个具有可公开寻址的 IP 地址的 DMZ 区域中,并且您的所有爪牙连接到这些 IP。您的主人总是比奴才少,因此需要实施的网络配置会大大减少。Salt 是一个高度可扩展的平台,一些栈包含数千个喽啰;想象一下,必须配置网络,这样三四个主人才能接触到成千上万的奴才。

拥有拥有公共 IP 的主机可能很可怕,但是请记住,只要您验证了 RSA 密钥指纹,您就可以确信,由于 ZeroMQ 的加密机制,节点之间的所有通信都是安全的。

盐能力

在简要概述了 Salt 的体系结构后,现在是时候了解它的不同功能和能力了。

远程命令执行模块

请记住,我们说过 Salt 同时使用了推和拉方法以及声明性和命令性方法。远程命令执行特性是我们如何以命令的方式利用 Salt 的 push 方法。

如果需要在多个喽啰或特定喽啰中远程运行一个命令,将使用执行模块。让我们看一个简单的例子:

dsala@master1:~$ salt ‘*’  cmd.run ‘ls /home’
minion-1:
 jdoe
 dev1
master:
 dsala 
 eflores

前一个命令将一个ls推送给注册到主人的爪牙。让我们仔细看看这些命令:

  • salt:这是 Salt 最基本的命令,在远程喽啰上并行执行命令。

  • '*':表示我们将在所有由我们的主服务器管理的服务器上运行该命令;您还可以定义特定的目标。

  • cmd.run:要调用的执行模块。

  • 'ls /home':执行模块的参数。

  • 输出:按照宠臣的名字排序,后面跟着那个服务器的输出。

执行模块是 Salt 使用其远程执行框架的最基本形式。你还记得盐是用 Python 写的吗?嗯,执行模块实际上是 Python 模块,有一组服务于共同目的的函数。Salt 附带了几个您可以使用的预构建模块,您甚至可以编写自己的模块并将它们添加到您的 SaltStack 平台。所有的执行模块都应该是与发行版无关的,但是你可以遇到一些发行版中没有的模块。特定于窗口的模块大多由函数开头的起始win_定义。

在前面的例子中,我们使用了带有run功能的cmd模块。我们处理模块中函数的格式包括定义要导入的模块,然后是句点和函数。每当调用一个函数时,Salt 都以下列方式进行:

  1. 执行命令的主机的发布者端口(4505)将命令发送到指定的目标。
  2. 目标喽啰评估命令并决定是否必须运行命令。
  3. 运行命令的奴才格式化输出,并将其发送到主服务器的请求服务器端口(4506)。

知道什么是执行模块并不足以让我们知道我们拥有什么。许多预定义的模块是最常用的,值得看看它们以及它们的主要功能是什么。

系统模块

该模块相当于man命令。借助sys,我们可以查阅、列出,甚至检查哪个参数接受每个函数。您会发现自己主要使用sys模块的以下功能:

  • list_modules:该功能将列出目标宠臣可用的模块。需要注意的是,执行模块是在奴才身上执行的,而不是在执行命令的主服务器上。
  • list_functions:通过list_functions,可以列出某个模块的可用功能。
  • argspec:列出所需函数的可用参数和默认值。

现在我们可以运行sys模块前面的一个函数来查看一个真实的例子:

dsala@master1:~$ sudo salt 'minion1' sys.argspec pkg.install
minion1:
 ----------
 pkg.install:
 ----------
 args:
 - name
 - refresh
 - fromrepo
 - skip_verify
 - debconf
 - pkgs
 - sources
 - reinstall
 - ignore_epoch
 defaults:
 - None
 - False
 - None
 - False
 - None
 - None
 - None
 - False
 - False
 kwargs:
 True
 varargs:
 None

pkg 模块

现在我们已经使用了一个pkg函数作为sys模块的例子,我想谈谈pkg模块。这是 Salt 提供的另一个最常见和最常用的模块。该模块处理所有相关的包任务,从安装和升级到删除包。由于 Salt 试图尽可能不依赖于发行版,因此pkg模块实际上在引擎盖下调用了一组不同的模块和函数,具体到模块被调用的发行版。例如,如果一个pkg.install在奴才们收到消息时瞄准了基于 Ubuntu 的系统,那么实际上aptpkg模块就是将在奴才中调用的模块。这就是为什么pkg被称为虚拟模块的原因。

pkg调用的一些不同模块如下:

  • aptpkg:对于有apt-get包管理的 Debian 发行版。
  • brew:对于自带自制包管理的 macOS。
  • yumpkg:以yumdnf为包装经理的红帽配送。
  • zypper:对于以zypper为包管理器的基于 SUSE 的发行版。

以下是用pkg安装nginx网络服务器的例子:

dsala@master1:~$ sudo salt 'minion1' pkg.install nginx
minion1:
 ----------
 nginx:
 ----------
 new:
 1.15.10
old:

测试模块

最后,也是最重要的,我想和你谈谈测试模块。测试模块将允许我们测试我们的 SaltStack 平台。通过测试模块,可以检查奴才的健康状况、他们运行的 Salt 版本,甚至只是让他们发送一个回声。

通过sys.list_functions功能可以找到测试模块的不同功能,但值得一提的是一些您可能会非常频繁使用的最常见的功能:

  • ping:ping 功能测试喽啰的响应;这不是 ICMP ping 命令。
  • 版本:返回绍特版本的你的爪牙。
  • versions_information :返回 Salt 的所有依赖项、内核版本、发行版和 Salt 版本的完整列表。

盐州

现在我们已经了解了远程执行框架,我们可以开始探索 Salt 必须提供的其余系统。远程执行框架是所谓的状态系统的基础。状态系统是一种声明性的幂等方式,它利用 IaC 文件来配置一个宠臣想要的状态。状态系统使用的状态模块很像执行模块,但不同的是 Salt 状态实际上检查所需的配置是否已经存在于 minion 中。例如,让我们看看下面的状态定义:

dsala@master:/srv/salt/httpd $ cat httpd.sls
 httpd_package:
 pkg.installed:
 -  name: httpd

上述状态将在运行时在目标服务器中安装httpd (Apache)包,但前提是该包不存在。如果包不存在,状态模块将调用本地pkg.install执行功能,并将包安装在迷你包中。

看看我们cat那个文件来自一个/srv/salt目录的事实。该目录是 Salt 的状态目录树的默认位置,状态定义放置在该目录中。您将在该目录中创建包含公式的文件夹,公式是一组 Salt 状态,包含部署应用所需的所有配置。例如,我们不仅可以安装httpd,我们还可以配置虚拟主机并下载包含将在该 Apache 网络服务器上运行的实际网站的 Git 回购。

目录树为您调用状态模块和运行公式遵循一组规则,但这将是第 14 章让你的手变咸的主题,我们将深入研究配置和实际使用。

盐粒

我们了解到,在所有喽啰上运行时,可以通过定义喽啰名称或者通过*来运行执行模块。但是在栈中的所有奴才上运行盐状态和执行模块,或者在单个奴才上运行盐状态和执行模块,当你有数百甚至数千个奴才由你的主人管理时,就不太理想了。

这里是 Salt 引入grains界面的地方,通过这个界面我们可以通过特定的特征来识别喽啰,甚至可以将自己的标签类型或者角色设置给一群有着相同目的或者特征的喽啰,这样我们就可以进行更有针对性的配置管理。

我们可以利用与在 Salt 中执行任何命令相同的语法来利用grains接口:

dsala@master:~$ salt “minion1” grains.items

使用前面的命令,我们列出了目标系统的所有不同硬件和软件特征。在输出中,我们可以看到操作系统系列、系统架构,甚至是我们用来运行虚拟机的虚拟机管理程序。

这将有助于我们通过所谓的top文件创建针对特定系统的状态定义,我们将在第 14 章中讨论。使用grains并以所有Debian家族虚拟机为目标的绍特州顶级文件定义示例如下:

 base:
 'os_family:Debian:
 - match: grain
 - httpd

如前所述,我们还可以在我们的喽啰中创建自定义grains来定义角色,并用唯一的值对标记我们的喽啰。这对于在特定任务中对喽啰进行分组很有用;例如,质量保证团队的所有虚拟机都可以用键值对进行标记,例如departement: qa。另一种分组方式可以是按角色分组,比如appfoo: frontend,等等。有许多方法可以使用谷物目标,所有这些都将取决于我们想要如何管理或推动并保持期望的状态。

盐柱

借助,我们可以针对特定的喽啰,但最后,我们定义了那些位于顶层文件中的目标策略,它们构成了一个公式的一部分。公式通常存储在 Git 库中,有时甚至存储在公共库中。这就是为什么我们不能,或者更确切地说,我们不应该在绍特州宣布敏感信息。正如我们在前面章节中看到的,Dockerfiles 也发生了同样的情况,Kubernetes 通过 Secrets API 对象解决了这个问题。盐有自己版本的秘密,它被称为柱子

与谷物不同,柱子储存在主人手中,而不是奴才手中。只有成为支柱目标的爪牙才能访问支柱中的信息。这也让它非常适合敏感信息。当存储敏感信息时,柱子也可以在静止时加密,由于 Salt 的渲染系统,柱子将在柱子编译期间被解密。

通过仅将敏感数据存储在母版中,柱子减少了敏感数据的表面积:

借助 Salt 支柱,我们完成了 SaltStack 平台必须提供的基本组件的简要概述。我们将更深入地讨论它们,并在第 14 章让你的手变咸中使用真实的例子,这样你就可以通过 Salt 进行动手并开始管理系统。

摘要

在本章中,我们介绍了企业在维护基础架构时面临的不同问题。我们经历了不同的技术,如 IaC 和集中式系统管理。我们通过不同的方法,IaC 的变更引入托管系统,并了解了几个利用 IaC 的应用。

我们还讨论了什么是 Salt 及其不同的组件,这些组件有助于我们实现集中化的托管基础架构。

在下一章中,我们将学习如何设计 Salt 解决方案并安装软件。

问题

  1. 什么是系统管理?
  2. 系统管理背后的挑战是什么?
  3. 哪些应用可以帮助我们进行系统管理?
  4. 什么是基础设施即代码?
  5. 我们可以通过哪些不同类型的方法来管理我们的系统?
  6. 盐是什么?
  7. 盐的不同成分是什么?

进一步阅读