多数据中心 Ansible 负载均衡器模板

多数据中心 Ansible 负载均衡器模板

我正在将现有多数据中心设置的管理迁移到 Ansible,但我不确定对其进行建模的最佳方法是什么,因为我对此还不熟悉。

我有三个数据中心 D1、D2 和 D3。在每个数据中心中,相同的配置都重复相同:

  • 一个nginx 负载均衡器(lb.D[n])绑定到公共 IP
  • 应用服务器(as[1-2].D[n])仅从本地负载均衡器接收流量
  • 从属(只读)数据库服务器(db.D[n])两个应用服务器都从中读取。

我目前制作的 hosts 文件如下所示:

# DC1 -----------
[dc_1_webservers]
10.43.0.10

[dc_1_appservers]
10.43.0.20
10.43.0.21

[dc_1_dbservers]
10.43.0.30

[dc_1:children]
dc_1_webservers
dc_1_appservers
dc_1_dbservers

# DC2 -----------
[dc_2_webservers]
10.43.10.10

[dc_2_appservers]
10.43.10.20
10.43.10.21

[dc_2_dbservers]
10.43.10.30

[dc_2:children]
dc_2_webservers
dc_2_appservers
dc_2_dbservers

# DC3 -----------
[dc_3_webservers]
10.43.20.10

[dc_3_appservers]
10.43.20.20
10.43.20.21

[dc_3_dbservers]
10.43.20.30

[dc_3:children]
dc_3_webservers
dc_3_appservers
dc_3_dbservers

[webservers:children]
dc_1_webservers
dc_2_webservers
dc_3_webservers

[appservers:children]
dc_1_appservers
dc_2_appservers
dc_3_appservers

我特意在这里只留下了 IP 地址,因为我想了解纯 Ansible 解决方案如何工作,而不是诉诸 DNS。

问题在于正确填充 nginx 的反向代理上游,以便仅添加每个 DC 本地的应用服务器当 nginx 角色运行并且配置文件模板被复制到负载均衡器机器上时。具体来说,是否可以做这样的事情?

# file /etc/nginx/sites-enabled/loadbalancer.conf in lb.D[n] (i.e. lb.D2)
 upstream backend  {
 # Iterate over the app servers in the current data center (i.e. D2)
 {% for host in [datacenters][current_datacenter][appservers] %}
     # Add each local app server IP to the load balancing pool 
     # (i.e. 10.43.10.20 and 10.43.10.21 for DC2)
     server {{ hostvars[host]['ansible_eth0']['ipv4']['address'] }};
 {% endfor %}
 }

首先,我不确定 hosts 文件是否完全有意义(我是否应该向各个条目添加变量?在当前配置中,我无法执行类似 [dc][3][appservers] 的操作,尽管我不确定解决方案在哪里。)

非常感谢!

编辑1:

该剧本的结构如下:

main.yml
hosts
vars.yml
servers/
    webservers.yml
    appservers.yml
roles/
   base/
     files/
       ssh/
       newrelic/
     tasks/
       main.yml
     handlers/
       main.yml
   webserver/
     files/
       ssl_certs/
     templates/
       nginx/
          loadbalancer.j2
     tasks/
       main.yml
     handlers/
       main.yml
   appserver/
     files/
       pip/
         requirements.txt
     templates/
       supervisor/
          gunicorn.j2
     tasks/
        main.yml
     handlers/
        main.yml

main.yml 入口点只有两行:

---
- include: servers/webservers.yml
- include: servers/appservers.yml

webservers.yml 收集有关应用服务器的事实(我认为这对于实现我的目标是必要的,即使我还不完全确定如何实现),然后首先调用一个基本角色,该角色仅安装一些共享的 SSH 密钥、NewRelic 绑定和其他东西在我们云中的每台机器上都是通用的,然后调用实际的 Web 服务器角色。

---
- name: Gather data about appservers
  hosts:  appservers
  gather_facts: yes
  tasks:
    - debug: Gather Facts

- name: Configure all frontend web servers
  hosts: webservers
  sudo: yes
  roles:
    - { role: base }
    - { role: webserver }

所述“webserver”角色安装 nginx,复制 SSL 证书,然后最终复制 jinja2 nginx 配置模板。

 - name: Install nginx configuration file.
    template: src=files/loadbalancer.j2 dest=/etc/nginx/sites-available/{{ project_name }} backup=yes

答案1

您可以利用魔法变量 group_namesgroups查找清单中定义的组:

---
- hosts: webservers
  vars:
    dcs: [dc_1, dc_2, dc_3]
  tasks:
  - debug:
      msg: |
        upstream backend {
        {%- for dc in dcs %}
        {%-   if dc in group_names %}
        {%-     for host in groups[dc+'_appservers'] %}
        server {{host}};
        {%-     endfor %}
        {%-   endif %}
        {%- endfor %}
        }

该剧本将为您提供以下输出。

TASK: [debug ]     **************************************************************** 
ok: [10.43.0.10] => {
    "msg": "upstream backend { server 10.43.0.20; server 10.43.0.21;}"
}
ok: [10.43.10.10] => {
    "msg": "upstream backend { server 10.43.10.20; server 10.43.10.21;}"
}
ok: [10.43.20.10] => {
    "msg": "upstream backend { server 10.43.20.20; server 10.43.20.21;}"
}

server {{host}};根据需要进行更改。

相关内容