介绍
SaltStack 或 Salt 是一个功能强大的远程执行和配置管理系统,可用于以结构化、可重复的方式轻松管理基础架构。 在本系列中,我们将演示一种从 Salt 部署管理开发、登台和生产环境的方法。 我们将使用 Salt 状态系统来编写和应用可重复的操作。 这将使我们能够安全地破坏我们的任何环境,因为我们知道我们可以在以后轻松地将它们以相同的状态重新上线。
在我们的 上一篇指南 中,我们为安装和配置 Nginx 的 Web 服务器创建了 Salt 状态。 在本指南中,我们将为负载均衡器配置状态,该负载均衡器将位于我们的暂存和生产环境中的 Web 服务器前面。 我们的负载均衡器需要配置 Web 服务器地址才能正确传递流量。
让我们开始吧。
创建主 HAProxy 状态文件
我们的负载均衡器将使用 HAProxy 在环境中所有可用的 Web 服务器之间分配我们应用程序的流量。 与 Nginx 状态文件一样,我们将在 /srv/salt
目录中为此状态创建一个目录:
sudo mkdir /srv/salt/haproxy
我们将使用名称 init.sls
作为此目录中的主状态文件,以便我们可以通过目录名称引用状态:
sudo nano /srv/salt/haproxy/init.sls
在内部,我们可以使用与 Nginx 相同的模式来安装 haproxy
包并确保它正在运行。 我们将确保在包发生更改或 /etc/default/haproxy
文件或 /etc/haproxy/haproxy.cfg
文件发生更改时重新加载服务。 同样,要非常小心间距以避免 YAML 错误:
/srv/salt/haproxy/init.sls
haproxy: pkg: - installed service.running: - watch: - pkg: haproxy - file: /etc/haproxy/haproxy.cfg - file: /etc/default/haproxy
我们需要管理 haproxy
服务正在监视的两个文件。 我们可以为每个创建状态。
/etc/haproxy/haproxy.cfg
文件将是一个模板。 该文件将需要提取有关环境的信息,以填充其要向其传递流量的 Web 服务器列表。 我们的网络服务器在每次创建时都不会拥有相同的 IP。 每次应用此状态时,我们都需要动态创建列表。
/etc/default/haproxy
文件只是一个普通文件。 我们正在管理它,因为我们希望确保 HAProxy 在启动时启动。 不过,这不是动态信息,因此我们不需要将其设为模板:
/srv/salt/haproxy/init.sls
haproxy: pkg: - installed service.running: - watch: - pkg: haproxy - file: /etc/haproxy/haproxy.cfg - file: /etc/default/haproxy /etc/haproxy/haproxy.cfg: file.managed: - source: salt://haproxy/files/etc/haproxy/haproxy.cfg.jinja - template: jinja - user: root - group: root - mode: 644 /etc/default/haproxy: file.managed: - source: salt://haproxy/files/etc/default/haproxy - user: root - group: root - mode: 644
这实际上是我们需要的状态文件本身。 完成后保存并关闭文件。
安装 HAProxy 并将包文件传输到 Salt Master
我们将使用与 Nginx 相同的技术来获取我们需要的基本 HAProxy 文件。 我们将在 minion 上安装包,然后告诉服务器将文件推送回 master。
让我们使用 stage-lb
服务器,因为无论如何这将是这个包的最终目标。 如果您尚未启动并运行暂存机器,请键入:
sudo salt-cloud -P -m /etc/salt/cloud.maps.d/stage-environment.map
一旦您的服务器可用,您可以通过键入以下命令在 stage-lb
服务器上安装 haproxy
软件包:
sudo salt stage-lb pkg.install haproxy
安装完成后,我们可以告诉 minion 将我们需要的两个文件推送到主服务器:
sudo salt stage-lb cp.push /etc/default/haproxy sudo salt stage-lb cp.push /etc/haproxy/haproxy.cfg
minion 文件系统的相关部分将在 /var/cache/salt/master/minions/minion_id/files
目录中重新创建。 在这种情况下,minion ID 为 stage-lb
。 将整个 minion 文件结构复制到我们的 HAProxy 状态目录:
sudo cp -r /var/cache/salt/master/minions/stage-lb/files /srv/salt/haproxy
我们可以通过键入以下内容来查看文件结构:
find /srv/salt/haproxy -printf "%P\n"
Outputfiles files/etc files/etc/default files/etc/default/haproxy files/etc/haproxy files/etc/haproxy/haproxy.cfg init.sls
现在我们已经有了 Minion 的文件,我们可以销毁负载平衡服务器:
sudo salt-cloud -d stage-lb
然后,我们可以在后台重新创建服务器,以便我们稍后可以进行最终测试和确认。 使用此命令定位您的 Salt 主服务器,因为它可以访问相关的云文件:
sudo salt --async sm cloud.profile stage-lb stage-lb
当服务器正在重建时,我们可以继续对我们正在管理的 HAProxy 文件进行必要的修改。
配置 /etc/default/haproxy 文件
我们可以从 /etc/default/haproxy
文件开始。 在 Salt Master 上的 HAProxy 状态目录中,移动到包含默认文件的目录:
cd /srv/salt/haproxy/files/etc/default
将文件复制到 haproxy.orig
以便我们可以将文件保留为最初打包时的样子:
sudo cp haproxy haproxy.orig
现在,打开文件进行编辑:
sudo nano haproxy
将 ENABLED
更改为“1”。 这将告诉 Ubuntu 的初始化系统 Upstart 在服务器启动时启动 HAProxy 服务:
/srv/salt/haproxy/文件/etc/default/haproxy
# Set ENABLED to 1 if you want the init script to start haproxy. ENABLED=1 # Add extra flags here. #EXTRAOPTS="-de -m 16"
这是我们唯一需要做的改变。 保存并关闭文件。
配置 /etc/haproxy/haproxy.cfg 模板文件
接下来,让我们处理主 HAProxy 配置文件。 移动到 Salt Master 服务器上的相应目录:
cd /srv/salt/haproxy/files/etc/haproxy
同样,让我们复制配置以保存其原始状态:
sudo cp haproxy.cfg haproxy.cfg.orig
然后,重命名文件以反映这是一个 Jinja 模板文件:
sudo mv haproxy.cfg haproxy.cfg.jinja
在文本编辑器中打开模板文件:
sudo nano haproxy.cfg.jinja
在文件的顶部,我们可以从设置 Jinja 变量开始。 我们需要使用 network.interface_ip
执行函数来获取负载均衡器运行的环境。 稍后我们将使用它来使用来自同一环境的 Web 服务器填充服务器列表:
/srv/salt/haproxy/files/etc/haproxy/haproxy.cfg.jinja
{%- set env = salt['grains.get']('env') -%} global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy . . .
跳到文件的“默认”部分。 我们需要将 mode
更改为“tcp”,将第一个 option
更改为“tcplog”:
/srv/salt/haproxy/files/etc/haproxy/haproxy.cfg.jinja
. . . defaults . . . mode tcp option tcplog . . .
在文件的底部,我们需要创建我们的实际配置。 我们需要创建一个“前端”部分,它将描述 HAProxy 如何接受连接。 我们将此部分标记为“www”。
我们想将此绑定到服务器的公共 IP 地址。 我们可以使用带有 eth0
参数的 network.interface_ip
执行模块函数来获取它。 Web 请求将从端口 80 进入。 我们可以使用 default_backend
选项指定要传递给的默认后端。 我们将调用我们的后端 nginx_pool
:
/srv/salt/haproxy/files/etc/haproxy/haproxy.cfg.jinja
. . . frontend www bind {{ salt['network.interface_ip']('eth0') }}:80 default_backend nginx_pool
接下来,我们需要添加 nginx_pool
后端。 我们将使用传统的循环平衡模型并再次将模式设置为“tcp”。
之后,我们需要从我们的环境中填充后端 Web 服务器列表。 我们可以在 Jinja 中使用“for”循环来做到这一点。 我们可以使用mine.get
执行模块函数来获取internal_ip
挖矿函数的值。 我们将匹配 Web 服务器角色和环境。 ~ env
会将我们之前设置的 env
变量的值连接到它之前的匹配字符串。
对于循环的每次迭代,此查找的结果将存储在 server
和 addr
变量中。 在循环中,我们将使用这些循环变量添加服务器的详细信息。 最终结果如下所示:
/srv/salt/haproxy/files/etc/haproxy/haproxy.cfg.jinja
. . . frontend www bind {{ salt['network.interface_ip']('eth0') }}:80 default_backend nginx_pool backend nginx_pool balance roundrobin mode tcp {% for server, addr in salt['mine.get']('G@role:webserver and G@env:' ~ env, 'internal_ip', expr_form='compound').items() -%} server {{ server }} {{ addr }}:80 check {% endfor -%}
完成后保存并关闭文件。
测试 HAProxy 状态文件
我们的负载平衡状态是相当基本的,但很完整。 我们现在可以继续测试它。
首先,让我们使用 state.show_sls
来显示文件排序:
sudo salt stage-lb state.show_sls haproxy
我们可以通过输出中各种“order”值的顺序来判断包将被安装,服务将被启动,然后两个文件将被应用。 这是我们所期望的。 由于我们配置的“监视”设置,文件更改将触发服务重新加载。
接下来,我们可以对状态应用程序进行试运行。 这将捕获一些(但不是全部)会导致状态在运行时失败的错误:
sudo salt stage-lb state.apply haproxy test=True
检查所有状态是否都已通过。 无论底部的故障计数或输出如何,向上滚动并查看每个状态的“注释”行。 有时,这将包括有关潜在问题的额外信息,即使测试被标记为成功。
修复测试命令期间出现的任何问题后,您可以将您的状态应用到负载均衡器服务器。 确保在应用状态之前运行并配置了后端 Nginx Web 服务器:
sudo salt-cloud -P -m /etc/salt/cloud.maps.d/stage-environment.map sudo salt -G 'role:webserver' state.apply nginx
当您的 Web 服务器正在运行时,应用 haproxy
状态:
sudo salt -G 'role:lbserver' state.apply haproxy
您现在应该能够通过负载均衡器的公共 IP 地址访问您的两个后端 Web 服务器之一。 您可以使用以下命令显示负载均衡器的公共 IP 地址:
sudo salt -G 'role:lbserver' network.interface_ip eth0
如果你使用浏览器,它看起来像这样:
使用 curl
更容易看到负载均衡器在后端服务器之间传递流量:
curl load_balancer_public_IP
Output<!DOCTYPE html> <html> <head> <title>Welcome from stage-www2</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>Hello! This is being served from:</p> <h2>stage-www2</h2> </body> </html>
如果您再次键入该命令几次,它应该在您的两台服务器之间交换:
curl load_balancer_public_IP
Output<!DOCTYPE html> <html> <head> <title>Welcome from stage-www1</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>Hello! This is being served from:</p> <h2>stage-www1</h2> </body> </html>
如您所见,服务请求的服务器发生了变化,这意味着我们的负载均衡器运行正常。
结论
在这一点上,我们有一个正常工作的 HAProxy 状态,可以应用于我们的负载均衡器机器。 这可用于在所有后端 Nginx 服务器之间拆分我们应用程序的传入流量。 我们可以轻松地销毁负载均衡器,然后根据可用的 Web 服务器重建它们。
在 下一个指南 中,我们将专注于让 MySQL 启动并作为我们的后端数据库系统运行。 这将用于在我们的各种环境中存储应用程序数据。