SaltStack基础设施:为MySQL数据库服务器创建Salt状态

来自菜鸟教程
跳转至:导航、​搜索

介绍

SaltStack 或 Salt 是一个功能强大的远程执行和配置管理系统,可用于以结构化、可重复的方式轻松管理基础架构。 在本系列中,我们将演示一种从 Salt 部署管理开发、登台和生产环境的方法。 我们将使用 Salt 状态系统来编写和应用可重复的操作。 这将使我们能够安全地破坏我们的任何环境,因为我们知道我们可以在以后轻松地将它们以相同的状态重新上线。

在本系列的 上一篇指南 中,我们将 HAProxy 设置为 Web 服务器前的负载均衡器。 在本指南中,我们将重点转移到创建将在我们的每个环境中安装和管理我们的 MySQL 数据库服务器的状态。 本文将介绍 MySQL 的基本安装和设置。 在未来的指南中,我们将解决设置复制这一更复杂的任务。

使用 debconf-utils 获取 MySQL 提示信息

创建 MySQL 状态的过程将比我们之前使用 Nginx 和 MySQL 的示例复杂一些。 与其他两个安装步骤不同,MySQL 安装通常涉及回答一组提示以设置 MySQL 根密码。

在我们开始使用我们的状态文件之前,我们应该在我们的一个奴才上测试安装 MySQL。 然后我们可以使用 debconf-utils 包来获取我们需要填写的提示信息。

如果您还没有可用的登台环境,您可以使用我们之前创建的登台环境映射文件来启动环境:

sudo salt-cloud -P -m /etc/salt/cloud.maps.d/stage-environment.map

一旦您的数据库服务器启动并可用,请选择您的数据库服务器之一来安装 MySQL,以便我们可以从安装中获取相关信息:

sudo salt stage-db1 pkg.install mysql-server

为了方便在debconf数据库中查询到我们需要的提示信息,我们还要在数据库minion上安装debconf-utils包:

sudo salt stage-db1 pkg.install debconf-utils

安装此软件包后,Salt 中的 debconf 功能将可用。 我们可以使用debconf.get_selections执行模块函数从数据库minion中获取所有提示信息。 我们应该将其通过管道传输到 less 中,因为这将返回该主机上安装的软件包中的 all 信息:

sudo salt stage-db1 debconf.get_selections | less

在输出中,查找涉及 MySQL 的部分。 它应该看起来像这样:

Output. . .

mysql-server-5.5:
    |_
      - mysql-server/root_password
      - password
    |_
      - mysql-server/root_password_again
      - password
    |_
      - mysql-server-5.5/really_downgrade
      - boolean
      - false
    |_
      - mysql-server-5.5/start_on_boot
      - boolean
      - true

. . .

前两个条目包含我们需要的字段名称(mysql-server/root_passwordmysql-server/root_password_again)。 这些条目的第二行指定了我们需要在状态文件中指定的字段类型。

一旦你从 debconf 输出中复制了这些信息,我们还应该继续获取 /etc/mysql/my.cnf 文件。 稍后我们将在配置 MySQL 状态时需要它:

sudo salt stage-db1 cp.push /etc/mysql/my.cnf

/etc/mysql/my.cnf 文件推送回 Salt Master 后,我们可以删除该资源,以便在指南后面进行测试:

sudo salt-cloud -d stage-db1

删除服务器后,您可以通过键入以下内容在后台重新创建它。 此实例中的 sm 是我们的 Salt 主服务器的名称,它具有相应的云凭据:

sudo salt --async sm cloud.profile stage-db stage-db1

当您的数据库服务器正在重建时,我们可以开始构建 MySQL 状态文件。

创建主 MySQL 状态文件

我们将首先在 /srv/salt 目录中为我们的 MySQL 状态创建一个目录:

sudo mkdir -p /srv/salt/mysql

在这个目录中,我们可以创建并打开一个 init.sls 文件来存储我们的主 MySQL 状态文件:

sudo nano /srv/salt/mysql/init.sls

我们需要确保在 minion 上安装了 debconf-utils 包,以便轻松设置我们需要的值。 我们可以使用 pkg.installed 状态模块来做到这一点:

/srv/salt/mysql/init.sls

debconf-utils:
  pkg.installed

安装 debconf-utils 包后,我们可以使用 debconf.set 状态模块预播提示的答案。 我们将使用 name 属性来指定我们希望为其设置提示的包名称。 然后,我们创建一个 data 结构,其中包含可用于填写提示的信息字典。

data 结构基本上使用了我们从测试 MySQL 安装中查询的提示信息。 我们知道应该用于这些字段的字段名称和数据类型。 要指定实际密码,我们将从具有 pillar.get 执行模块功能的 Salt Pillar 系统中提取。

稍后我们将在支柱系统中设置密码。 这将允许我们将密码数据与我们的配置分开。

笔记

密切注意存储在 data 中的字典的缩进。 整个块缩进了一个额外的 四个 空格,而不是典型的两个空格缩进。 当字典嵌入到 YAML 列表中时,就会发生这种情况。 您可以访问此链接了解更多信息。


/srv/salt/mysql/init.sls

debconf-utils:
  pkg.installed

mysql_setup:
  debconf.set:
    - name: mysql-server
    - data:
        'mysql-server/root_password': {'type': 'password', 'value': '{{ salt['pillar.get']('mysql:root_pw', '') }}' }
        'mysql-server/root_password_again': {'type': 'password', 'value': '{{ salt['pillar.get']('mysql:root_pw', '') }}' }
    - require:
      - pkg: debconf-utils

为了与 MySQL 进行实际交互,数据库服务器上必须有适当的 Python 库。 我们可以安装 ptyhon-mysqldb 包以确保我们可以访问 Salt 的 MySQL 功能。 之后,我们就可以安全地安装实际的 MySQL 服务器软件了。 我们将使用 require 来确保 debconf 和 Python 库可用。

安装后,我们可以添加一个服务状态来确保服务正在运行。 这将监视 MySQL 服务器包中的更改。 它还将监视基本的 MySQL 配置文件,并在检测到更改时重新加载服务:

/srv/salt/mysql/init.sls

debconf-utils:
  pkg.installed

mysql_setup:
  debconf.set:
    - name: mysql-server
    - data:
        'mysql-server/root_password': {'type': 'password', 'value': '{{ salt['pillar.get']('mysql:root_pw', '') }}' }
        'mysql-server/root_password_again': {'type': 'password', 'value': '{{ salt['pillar.get']('mysql:root_pw', '') }}' }
    - require:
      - pkg: debconf-utils

python-mysqldb:
  pkg.installed

mysql-server:
  pkg.installed:
    - require:
      - debconf: mysql-server
      - pkg: python-mysqldb

mysql:
  service.running:
    - watch:
      - pkg: mysql-server
      - file: /etc/mysql/my.cnf

我们需要使用 MySQL 管理一些文件。 我们需要管理的最明显的文件是我们上面提到的 /etc/mysql/my.cnf 文件。 我们需要根据变量信息进行一些更改,所以这个文件必须是一个 Jinja 模板。

我们需要管理的其他文件与 Salt 对 MySQL 系统的管理有关。 为了管理数据库,Salt minion 必须有关于如何连接到 RDBMS 的信息。 首先,我们可以在/etc/salt/minion.d目录下创建一个简单的文件。 这将简单地列出可以找到我们的连接详细信息的文件。 包含数据库连接详细信息的文件是我们需要管理的另一个文件。 数据库连接文件需要是一个模板:

/srv/salt/mysql/init.sls

. . .

mysql:
  service.running:
    - watch:
      - pkg: mysql-server
      - file: /etc/mysql/my.cnf

/etc/mysql/my.cnf:
  file.managed:
    - source: salt://mysql/files/etc/mysql/my.cnf.jinja
    - template: jinja
    - user: root
    - group: root
    - mode: 640
    - require:
      - pkg: mysql-server

/etc/salt/minion.d/mysql.conf:
  file.managed:
    - source: salt://mysql/files/etc/salt/minion.d/mysql.conf
    - user: root
    - group: root
    - mode: 640
    - require:
      - service: mysql

/etc/mysql/salt.cnf:
  file.managed:
    - source: salt://mysql/files/etc/mysql/salt.cnf.jinja
    - template: jinja
    - user: root
    - group: root
    - mode: 640
    - require:
      - service: mysql

最后,我们需要包含一个 service.restart 状态,它将重新加载 salt-minion 进程本身。 为了让我们的奴才拾取 /etc/salt/minion.d/mysql.conf 文件,这是必要的。 我们只希望在 /etc/salt/minion.d/mysql.conf 文件本身发生更改时重新启动 salt-minion。 我们可以使用 watch 来完成它:

/srv/salt/mysql/init.sls

. . .

/etc/mysql/salt.cnf:
  file.managed:
    - source: salt://mysql/files/etc/mysql/salt.cnf.jinja
    - template: jinja
    - user: root
    - group: root
    - mode: 640
    - require:
      - service: mysql

restart_minion_for_mysql:
  service.running:
    - name: salt-minion
    - watch:
      - file: /etc/salt/minion.d/mysql.conf

添加完上述详细信息后,保存并关闭文件。

为 MySQL 创建支柱

在我们的 MySQL 状态中,我们使用 pillar.get 执行模块函数来使用来自支柱系统的值填充 MySQL 根密码。 我们需要设置此支柱,以便状态可以提取必要的数据以构建数据库凭据。

支柱系统非常适合这种类型的用例,因为它允许您将数据分配给某些主机。 不匹配的主机将无法访问敏感数据。 到目前为止,我们的状态只需要root密码。 我们将支柱系统内的位置指定为 mysql:root_pw。 我们现在将着手设置该密钥。

为支柱系统创建顶层文件

在我们创建我们需要的 MySQL 支柱文件之前,我们需要创建一个支柱“顶部”文件。 顶部文件用于将 Salt minions 与支柱数据进行匹配。 Salt Minions 将无法访问它们在顶部文件中不匹配的任何支柱数据。

/srv/pillar 目录应该已在安装指南期间创建。 我们可以在这个目录下创建一个 top.sls 文件来开始:

cd /srv/pillar
sudo nano top.sls

在内部,我们需要指定 base 环境(由于复杂性和一些未记录的行为,我们在本系列中不使用 Salt 的环境概念。 我们所有的服务器都在base环境下运行,并使用grain进行环境标识)。 我们将使用复合匹配来匹配节点。 我们将匹配服务器角色和服务器环境,以确定分配给每个主机的支柱。

支柱使用点符号来表示目录中的文件。 例如,柱子系统的根是 /srv/pillar。 要分配位于 dev 目录中的 mysql.sls 支柱,我们使用 dev.mysql

本指南所需的作业如下所示:

/srv/pillar/top.sls

base:
  'G@env:dev and G@role:dbserver':
    - match: compound
    - dev.mysql

  'G@env:stage and G@role:dbserver':
    - match: compound
    - stage.mysql

  'G@env:prod and G@role:dbserver':
    - match: compound
    - prod.mysql

完成后保存并关闭文件。

创建特定环境的支柱

上面,我们根据角色和环境为服务器分配了支柱。 这允许我们为不同的环境指定不同的连接和凭证信息。

首先创建支柱顶部文件中引用的目录:

sudo mkdir /srv/pillar/{prod,stage,dev}

接下来,我们应该在每个目录中创建一个 myslq.sls 文件。 我们可以从 /srv/salt/stage/mysql.sls 文件开始,因为我们目前正在使用暂存环境进行测试:

sudo nano /srv/pillar/stage/mysql.sls

我们创建的状态文件想要使用 mysql:root_pw 键从支柱系统中提取 MySQL root 密码。 这实际上是一个嵌套键,这意味着 root_pwmysql 键的子键。 考虑到这一点,我们可以为 MySQL root 用户选择一个密码并将其设置在文件中,如下所示:

/srv/pillar/stage/mysql.sls

mysql:
  root_pw: staging_mysql_root_pass

选择您想使用的任何密码。 完成后,保存并关闭文件。 这就是我们现在所需要的。

在您的开发支柱中创建一个类似的文件:

sudo nano /srv/pillar/dev/mysql.sls

/srv/pillar/dev/mysql.sls

mysql:
  root_pw: development_mysql_root_pass

对您的生产环境支柱执行相同操作:

sudo nano /srv/pillar/prod/mysql.sls

/srv/pillar/prod/mysql.sls

mysql:
  root_pw: production_mysql_root_pass

为这些环境中的每一个选择不同的密码。

我们稍后会回到这些支柱,因为我们需要更多不属于配置本身的数据。 现在,保存并关闭任何打开的文件。

创建 /etc/mysql/my.cnf.jinja 模板

我们之前创建了基本的 MySQL 状态文件,但我们从未为安装创建托管文件。

当我们之前在我们的 stage-db1 服务器上进行 mysql-server 的测试安装时,我们将 /etc/mysql/my.cnf 文件推送回主服务器。 这应该在我们的 Salt Master 缓存中仍然可用。 我们可以通过键入以下命令将导致该缓存文件的整个目录结构复制到我们的 /srv/salt/mysql 目录:

sudo cp -r /var/cache/salt/master/minions/stage-db1/files /srv/salt/mysql

转到 MySQL 状态目录中包含复制的 mycnf 文件的目录:

cd /srv/salt/mysql/files/etc/mysql

将当前存在的文件复制到 .orig 后缀,以便我们可以在必要时恢复更改:

sudo cp my.cnf my.cnf.orig

接下来,将 my.cnf 文件重命名为具有 .jinja 后缀。 这将向我们表明,这个文件是一个模板,而不是一个可以在不渲染的情况下拖放到主机上的文件:

sudo mv my.cnf my.cnf.jinja

打开 Jinja 模板文件开始进行必要的编辑:

sudo nano my.cnf.jinja

我们现在希望创建的所有更改都与允许远程 MySQL 连接有关。 就目前而言,MySQL 绑定到本地环回接口。 我们希望将其设置为侦听节点的私有网络地址。

为此,请在 [mysqld] 部分中找到 bind-address 行。 我们将使用network.interface_ip执行模块函数来获取分配给minion的eth1接口的地址。

/srv/salt/mysql/files/etc/mysql/my.cnf.jinja

. . .

[mysqld]

. . .

bind-address            = {{ salt['network.interface_ip']('eth1') }}

我们需要做的另一个补充是关闭我们服务器的 DNS 名称解析。 通过添加 skip-name-resolve 选项,MySQL 在无法完成名称和反向名称解析的情况下不会失败:

/srv/salt/mysql/files/etc/mysql/my.cnf.jinja

. . .

[mysqld]

. . .

bind-address            = {{ salt['network.interface_ip']('eth1') }}
skip-name-resolve

完成后保存并关闭文件。

创建 /etc/salt/minion.d/mysql.conf 文件

接下来,我们需要创建用于修改 minion 配置的托管文件,并了解如何连接到 MySQL 数据库。 代替将配置保存在 /etc/salt/minion 文件本身,我们将在 /etc/salt/minion.d 目录中放置一个新文件,告诉 minion 在哪里可以找到连接信息。

首先使用 /srv/salt/mysql/files 目录创建必要的目录结构:

sudo mkdir -p /srv/salt/mysql/files/etc/salt/minion.d

我们可以在这个目录中创建一个名为 mysql.conf 的文件:

sudo nano /srv/salt/mysql/files/etc/salt/minion.d/mysql.conf

在里面,我们只需要设置一个选项:连接信息文件的位置。 在我们的例子中,我们将把它设置为 /etc/mysql/salt.cnf 的文件:

/srv/salt/mysql/files/etc/salt/minion.d/mysql.conf

mysql.default_file: '/etc/mysql/salt.cnf'

完成后保存并关闭文件。

创建 /etc/mysql/salt.cnf 模板文件

现在,我们需要创建我们的 minion 配置引用的文件。 这将是一个模板文件,因为我们需要从支柱系统中获取一些连接细节。 我们将此文件放在 /srv/salt/mysql/files/etc/mysql 目录中:

sudo nano /srv/salt/mysql/files/etc/mysql/salt.cnf.jinja

在里面,我们需要打开一个 [client] 部分来指定我们定义的信息类型。 在此标头下方,我们可以指定客户端以 MySQL root 用户在位于 /var/run/mysqld/mysqld.sock 的 Unix 套接字上连接到本地计算机。 这些都是默认的 MySQL 值:

/srv/salt/mysql/files/etc/mysql/salt.cnf.jinja

[client]
host                = localhost
user                = root
socket              = /var/run/mysqld/mysqld.sock

我们现在唯一需要添加的是密码。 同样,我们将直接从支柱系统中提取它,就像我们在 MySQL 状态文件的 debconf 部分中所做的那样。 它看起来像这样:

/srv/salt/mysql/files/etc/mysql/salt.cnf.jinja

[client]
host                = localhost
user                = root
socket              = /var/run/mysqld/mysqld.sock
password            = {{ salt['pillar.get']('mysql:root_pw', '') }}

完成后保存并关闭文件。

测试安装和健全性检查

现在我们已经配置了基本的安装状态和支持文件,我们应该快速测试我们的设置以确保它正常运行。

我们将从完成典型的测试过程开始。 使用 state.show_sls 执行模块功能确保它可以渲染您的状态文件:

sudo salt stage-db1 state.show_sls mysql

查看输出以确保 Salt 在解析 /srv/salt/mysql/init.sls 文件时没有问题。

接下来,通过在 state.apply 执行模块函数的末尾添加 test=True 来进行状态应用程序的空运行:

sudo salt stage-db1 state.apply mysql test=True

此命令预计会失败。 因为我们文件中的某些状态函数在安装特定软件包之前不可用,因此预计在试运行期间会失败。 在实际运行期间,状态排序将确保先安装必备软件包 ,然后再调用使用它们的状态

除了 mysql_setup 状态之外,所有失败状态的注释都应表明“一个或多个必要条件失败”,该状态应因 debconf.set 不可用而失败(这只是另一个先决条件失败)。 使用此处的输出确保没有其他不相关的错误出现。

运行测试后,我们可以通过键入以下内容来应用状态:

sudo salt stage-db1 state.apply mysql

这应该会导致成功的状态运行。

我们需要测试 Salt 是否能够连接和查询 MySQL 数据库。 确保您可以通过键入以下内容列出默认数据库:

sudo salt stage-db1 mysql.db_list

你应该得到一个看起来像这样的列表:

Outputstage-db1:
    - information_schema
    - mysql
    - performance_schema

这表明 Salt 能够使用 /etc/mysql/salt.cnf 文件中指定的信息连接到 MySQL 实例。

现在我们已经验证了我们的基本 MySQL 状态可以正常工作,我们可以删除 stage-db1 服务器:

sudo salt-cloud -d stage-db1

在后台重新创建服务器,以便我们稍后对其进行进一步测试。 同样,sm 是本例中 Salt 主服务器的名称:

sudo salt --async sm cloud.profile stage-db stage-db1

现在,我们的基本 MySQL 设置已经完成。

结论

您现在应该拥有将在您的 minions 上安装 MySQL 的状态。 这些还将在每个服务器上启动 salt-minion 进程,以便 Salt 可以连接和管理所涉及的数据库。

虽然我们目前的状态是安装 MySQL 并配置我们的 minions 来控制数据库系统,但目前我们的数据库是完全独立的。 在未来的指南中,我们将处理 MySQL 数据库复制,以便我们的数据在每个环境中的每个数据库中保持一致。