SaltStack 基础设施:为 Nginx 网络服务器创建盐状态

介绍

SaltStack,或盐,是一个强大的远程执行和配置管理系统,可以用来轻松地以结构化、可重复的方式管理基础设施. 在本系列中,我们将展示一种方法来管理您的开发,舞台和生产环境,从盐部署。

在我们的 前一篇指南中,我们通过为盐云设置DigitalOcean服务器来扩展我们的盐主服务器的功能,我们创建了必要的文件,使我们能够为每个环境创建新服务器。

创建主 Nginx 状态文件

Salt 通过其状态系统来管理配置,在最简单的情况下,这些是由位于 Salt 文件服务器根中的文件控制的(我们将其配置为 /srv/salt)。

1sudo mkdir /srv/salt/nginx

状态文件具有.sls字符串.一个目录中的init.sls文件作为该特定盐状态或公式的主要配置文件。

考虑到这一点,在这个目录中创建并打开一个 init.sls 文件,以便开始:

1sudo nano /srv/salt/nginx/init.sls

Nginx 包和服务状态

我们将开始使用nginx标识符创建一个状态,这将作为盐状态系统中这个特定状态的唯一名称,因为我们不会包括我们的状态模块的名称属性,它也将作为安装的目标(对于pkg.installed函数)和运行的服务(对于service.running函数)。

我们希望 Nginx 在某些情况下自动重新加载:当包更新时,当主配置文件被更改时,或当默认服务器封锁文件被更改时。

1[label /srv/salt/nginx/init.sls]
2nginx:
3  pkg:
4    - installed
5  service.running:
6    - watch:
7      - pkg: nginx
8      - file: /etc/nginx/nginx.conf
9      - file: /etc/nginx/sites-available/default

pkg:file:watch:键下方的键代表了与要观看的资源相关的状态模块。

Nginx 配置文件状态

我们可以从 /etc/nginx/nginx.conf 文件开始,我们想把这个文件变成一个可管理的文件。在盐术语中,这只是意味着我们将在主服务器上定义文件的内容,并将其上传给需要的每个小伙子。我们将为该文件设置相当典型的权限和所有权。

 1[label /srv/salt/nginx/init.sls]
 2nginx:
 3  pkg:
 4    - installed
 5  service.running:
 6    - watch:
 7      - pkg: nginx
 8      - file: /etc/nginx/nginx.conf
 9      - file: /etc/nginx/sites-available/default
10
11/etc/nginx/nginx.conf:
12  file.managed:
13    - source: salt://nginx/files/etc/nginx/nginx.conf
14    - user: root
15    - group: root
16    - mode: 640

我们还想控制 /etc/nginx/sites-available/default 文件的内容. 这定义了控制我们的内容如何服务的服务器块。 状态块与后者相当相似. 主要的区别是,这个文件将是一个 Jinja 模板。

Jinja 模板允许 Salt 定制某些文件内容的细节,具体为每个小组将其放置在哪里。这意味着我们可以从每个主机中提取信息,并为每个网页服务器构建一个适当的定制版本的文件。我们表示此文件将使用 Jinja 与模板选项。我们还将使用源文件上的.jinja口号,以便我们可以一眼就能知道该文件是一个模板:

 1[label /srv/salt/nginx/init.sls]
 2. . .
 3
 4/etc/nginx/nginx.conf:
 5  file.managed:
 6    - source: salt://nginx/files/etc/nginx/nginx.conf
 7    - user: root
 8    - group: root
 9    - mode: 640
10
11/etc/nginx/sites-available/default:
12  file.managed:
13    - source: salt://nginx/files/etc/nginx/sites-available/default.jinja
14    - template: jinja
15    - user: root
16    - group: root
17    - mode: 640

我们有我们的默认服务器封锁文件计划被放置在网站可用目录上,但我们仍然需要将文件链接到网站可用目录来激活它。我们可以通过file.symlink函数来做到这一点。我们只需要提供原始文件位置作为目标。我们还需要要求该文件,以便此状态只在前一个状态成功完成后执行:

 1[label /srv/salt/nginx/init.sls]
 2. . .
 3
 4/etc/nginx/sites-available/default:
 5  file.managed:
 6    - source: salt://nginx/files/etc/nginx/sites-available/default.jinja
 7    - template: jinja
 8    - user: root
 9    - group: root
10    - mode: 640
11
12/etc/nginx/sites-enabled/default:
13  file.symlink:
14    - target: /etc/nginx/sites-available/default
15    - require:
16      - file: /etc/nginx/sites-available/default

我们的默认网站内容的状态

现在,我们只需要为我们的index.html文件创建一个状态,这将是我们网站的实际内容。

此状态使用与我们之前的模板状态完全相同的格式. 唯一的差异是此文件上的标识符、源和权限模式:

 1[label /srv/salt/nginx/init.sls]
 2. . .
 3
 4/etc/nginx/sites-enabled/default:
 5  file.symlink:
 6    - target: /etc/nginx/sites-available/default
 7    - require:
 8      - file: /etc/nginx/sites-available/default
 9
10/usr/share/nginx/html/index.html:
11  file.managed:
12    - source: salt://nginx/files/usr/share/nginx/html/index.html.jinja
13    - template: jinja
14    - user: root
15    - group: root
16    - mode: 644

当你完成时,保存并关闭此文件. 目前我们已经完成了实际的 Nginx 状态信息。

安装 Nginx 并将原始文件转移到 Salt Master

我们已经创建了我们的主要 Nginx Salt 状态文件,但我们在 Salt master 文件服务器上创建的一些状态已经不存在的参考文件。

由于我们的文件将大多与Ubuntu的Nginx包安装的默认文件相同,我们开始最简单的方法是从该包的文件。

如果您还没有一个环境,请选择一个环境地图文件来部署,我们将在本系列中使用阶段环境,因为它是最小的环境,拥有我们所需要的所有服务器类型。

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

一旦您的服务器启动并运行,请选择您的 Web 服务器之一来安装 Nginx. 此时我们只会使用pkg执行模块,因为我们的状态尚未完全功能:

1sudo salt stage-www1 pkg.install nginx

当我们设置我们的盐主配置时,我们启用了file_recv选项,这使我们能够要求小伙子将某些文件推回主机。

1sudo salt stage-www1 cp.push /etc/nginx/nginx.conf
2sudo salt stage-www1 cp.push /etc/nginx/sites-available/default
3sudo salt stage-www1 cp.push /usr/share/nginx/html/index.html

这些文件现在应该在主机上可用。 这些文件的路径是在 /var/cache/salt/master/minions/minion_id/files 目录中重新创建的。 在我们的情况下,minion ID 将是 stage-www1. 我们可以通过键入将这个位置下的目录复制到我们的 Salt 状态目录,这代表了 minion 上的文件路径:

1sudo cp -r /var/cache/salt/master/minions/stage-www1/files /srv/salt/nginx

如果你看看你的状态目录的内容,你会看到一个名为文件的新目录。在这个目录下,minion的文件系统中的相关目录和我们复制的三个文件可用:

1find /srv/salt/nginx -printf "%P\n"
 1[secondary_label Output]
 2files
 3files/usr
 4files/usr/share
 5files/usr/share/nginx
 6files/usr/share/nginx/html
 7files/usr/share/nginx/html/index.html
 8files/etc
 9files/etc/nginx
10files/etc/nginx/sites-available
11files/etc/nginx/sites-available/default
12files/etc/nginx/nginx.conf
13init.sls

这就是我们所有管理的文件将被保留的地方,这与我们在 Nginx 状态文件中设置的位置一致。

由于我们现在已经从安装了 Nginx 的 minion 中提取了所有我们需要的文件,所以我们可以摧毁 minion 并重建它,从而确保以后,我们的状态文件可以在清洁的服务器上进行测试。

1sudo salt-cloud -d stage-www1

等待事件进行处理后,我们可以重建小组。

我们通常会用地图文件来做这件事,但因为我们只重建一个服务器,所以实际上最好直接使用阶段网配置文件,然后我们可以使用cloud.profile盐执行函数而不是salt-cloud,这使我们可以添加--async旗帜。

1sudo salt --async sm cloud.profile stage-web stage-www1

虽然我们的舞台-www1节点正在后台重建,但我们可以继续。

设置 /etc/nginx/nginx.conf 文件

让我们先看看主要的 Nginx 配置文件,在我们的小组中将放置在 `/etc/nginx/nginx.conf 上。

1cd /srv/salt/nginx/files/etc/nginx

我们目前实际上不会修改此文件,但我们可以为自己做一个好事,并立即备份原始文件:

1sudo cp nginx.conf nginx.conf.orig

这将为我们在未来可能进行的定制提供一个很好的参考点,我们可以通过键入快速看到我们所做的任何更改:

1diff nginx.conf nginx.conf.orig

在未来,如果我们发现我们需要在我们的各种环境中定制 Nginx 的配置(例如,我们可能希望将worker_processes与我们生产服务器上的CPU数量相匹配),我们可能希望过渡到使用模板文件。

正如我们之前所说,我们目前不需要任何修改,让我们继续前进。

配置 /etc/nginx/sites-available/default 模板

接下来,让我们看看我们的默认服务器封锁模板,我们可以在本目录中找到原始:

1cd /srv/salt/nginx/files/etc/nginx/sites-available

再次,我们应该将原件复制到备份位置,如果我们需要它以后:

1sudo cp default default.orig

然后我们可以更名该文件,以便它具有.jinja扩展. 这将视觉提醒我们,这个文件是一个模板,而不是一个可用文件本身:

1sudo mv default default.jinja

现在,我们可以打开模板文件以进行一些更改:

1sudo nano default.jinja

在文件的顶部,我们需要开始利用Jinja的模板功能. 我们的默认服务器块需要根据Web服务器是否在负载平衡器背后渲染不同的文件。

当通过负载平衡器接收连接时,我们希望我们的Web服务器将其流量限制在私人界面上。 然而,当我们处于开发环境中时,我们没有负载平衡器,所以我们希望在公共界面上服务。

我们将创建一个名为接口的变量,该变量应该包含我们想要的地址的接口。我们将测试小组的环境是否设置为dev,在这种情况下我们将使用eth0接口。否则,我们将它设置为eth1,服务器的私人接口。

1[label /srv/salt/nginx/files/etc/nginx/sites-available/default.jinja]
2{%- set interface = 'eth0' if salt['grains.get']('env') == 'dev' else 'eth1' -%}
3{%- set addr = salt['network.interface_ip'](interface) -%}
4# You may add here your
5# server {
6#       ...
7# }
8
9. . .

接下来,我们可以更进一步地编辑文件中的服务器块,我们可以使用我们在倾听服务器名称指令的顶部设置的addr变量,我们已经删除了IPv6和默认服务器部分,以限制该块的服务:

 1[label /srv/salt/nginx/files/etc/nginx/sites-available/default.jinja]
 2{%- set interface = 'eth0' if salt['grains.get']('env') == 'dev' else 'eth1' -%}
 3{%- set addr = salt['network.interface_ip'](interface) -%}
 4
 5. . .
 6
 7server {
 8    listen {{ addr }}:80;
 9
10    root /usr/share/nginx/html;
11    index index.html index.htm;
12
13    server_name {{ addr }};
14
15    location / {
16        try_files $uri $uri/ =404;
17    }
18}

保存并关闭文件,当你完成。

设置 /usr/share/nginx/html/index.html 模板

现在我们可以转到 index.html 文件,转到包含该文件的 Salt 主机上的目录:

1cd /srv/salt/nginx/files/usr/share/nginx/html

内部,我们需要从上次使用的相同程序开始。我们应该存储原始文件的副本,以进行审计和备份。

1sudo cp index.html index.html.orig
2sudo mv index.html index.html.jinja

打开模板文件,我们可以做我们需要的更改:

1sudo nano index.html.jinja

在顶部,我们将使用Jinja设置另一个变量。我们将使用grains.get执行模块函数来抓住小伙子的主机名。

1{% set host = salt['grains.get']('host') -%}
2<!DOCTYPE html>
3<html>
4
5. . .

然后,我们将在整个文件中使用此值,以便我们可以轻松地知道哪个网页服务器正在服务我们的请求。

1{% set host = salt['grains.get']('host') -%}
2<!DOCTYPE html>
3<html>
4<head>
5<title>Welcome from {{ host }}</title>
6. . .

让我们把身体的文字改成这个:

 1. . .
 2
 3<body>
 4<h1>Welcome to nginx!</h1>
 5<p>Hello!  This is being served from:</p>
 6
 7<h2>{{ host }}</h2>
 8
 9</body>
10</html>

保存并关闭文件,当你完成。

测试 Nginx 状态文件

我们现在已经完成了我们的 Nginx 配置,我们可以测试状态的某些方面,以确保它正常工作。

首先,我们可以使用state.show_sls执行模块函数来查看 Salt 将如何解释我们的 Nginx 状态文件。我们可以使用我们的stage-www1服务器作为目标。

1sudo salt stage-www1 state.show_sls nginx

你应该得到回来的输出看起来像这样的东西:

 1[secondary_label Output]
 2stage-www1:
 3    ----------
 4    /etc/nginx/nginx.conf:
 5        ----------
 6        __env__:
 7            base
 8        __sls__:
 9            nginx
10        file:
11            |_
12              ----------
13              source:
14                  salt://nginx/files/etc/nginx/nginx.conf
15            |_
16              ----------
17              user:
18                  root
19            |_
20              ----------
21              group:
22                  root
23            |_
24              ----------
25              mode:
26                  640
27            - managed
28            |_
29              ----------
30              order:
31                  10002
32
33. . .

它主要是从我们的 /srv/salt/nginx/init.sls 文件中提供的信息,加上一些有趣的补充。 检查没有任何解释错误,Salt 不知道如何读取命令。 每个部分的顺序是另一个很好的检查。 这决定了文件中的每个个别状态的运行时间。 第一个状态将有序号为10000。 每个额外的状态将从那里计算起来。 请注意, __env__ 与我们使用谷物设置的 env 不同。 我们在本指南中不使用Salt 的环境概念。

接下来,我们可以做一个干燥的应用我们的状态文件. 我们可以用state.apply函数与test=True选项。

1sudo salt stage-www1 state.apply nginx test=True

这将向您展示如果删除 test=True 选项所做的更改。请仔细检查,以确保这些更改是有意义的,并且 Salt 能够正确地解释您的所有文件。

如果干燥运行没有显示任何问题,您可以通过键入来尝试将状态应用到所有可用的Web服务器中:

1sudo salt -G 'role:webserver' state.apply nginx

如果您将 Nginx 状态应用到您的制作或制作 Web 服务器中,您将需要获取其内部 IP 地址。

1sudo salt-call mine.get 'role:webserver' internal_ip expr_form=grain
1[secondary_label Output]
2local:
3    ----------
4    stage-www1:
5        ip_address
6    stage-www2:
7        ip_address

如果,另一方面,你把你的开发网页服务器翻开并应用了 Nginx 状态,你会想要抓住外部地址,因为:

1sudo salt-call mine.get 'role:webserver' external_ip expr_form=grain

您可以使用curl测试您的服务器:

1curl ip_address

您应该看到我们修改的 index.html 页面:

 1[secondary_label Output]
 2<!DOCTYPE html>
 3<html>
 4<head>
 5<title>Welcome from stage-www1</title>
 6<style>
 7    body {
 8        width: 35em;
 9        margin: 0 auto;
10        font-family: Tahoma, Verdana, Arial, sans-serif;
11    }
12</style>
13</head>
14<body>
15<h1>Welcome to nginx!</h1>
16<p>Hello!  This is being served from:</p>
17
18<h2>stage-www1</h2>
19
20<p><em>Thank you for using nginx.</em></p>
21</body>
22</html>

正如你所看到的,当Jinja被渲染时,minion的主机名被放置在文件中,我们的Nginx状态现在已经完成。

结论

您现在应该拥有一个功能齐全的 Nginx 状态,这将使您能够快速轻松地将任何由 Salt 控制的机器转化为具有您的规格的 Web 服务器,我们将将此作为我们更大的基础设施管理策略的一部分,以便在我们的环境中轻松构建 Web 服务器。

下一个指南中,我们将继续前进并构建负载平衡器的状态,这些负载平衡器将导向我们的网络服务器前面的流量,我们将使用我们在本指南中使用的一些相同技术来使我们的负载平衡器灵活。

Published At
Categories with 技术
comments powered by Disqus