![マルチデータセンター Ansible ロードバランサー テンプレート](https://rvso.com/image/658734/%E3%83%9E%E3%83%AB%E3%83%81%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BB%E3%83%B3%E3%82%BF%E3%83%BC%20Ansible%20%E3%83%AD%E3%83%BC%E3%83%89%E3%83%90%E3%83%A9%E3%83%B3%E3%82%B5%E3%83%BC%20%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88.png)
既存のマルチデータセンター設定の管理を Ansible に移行していますが、初心者なので、モデル化に最適な方法がわかりません。
データ センター D1、D2、D3 の 3 つがあります。それぞれで、同じ構成が同じように繰り返されます。
- アンnginx ロードバランサー(lb.D[n]) パブリックIPにバインドされている
- 二アプリケーションサーバー(as[1-2].D[n]) ローカルロードバランサからのみトラフィックを受信する
- スレーブ(読み取り専用)DBサーバー(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 アドレスのみを残しておいた理由は、DNS に頼るのではなく、純粋な Ansible ソリューションがどのように機能するかを理解したいからです。
問題は、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 エントリ ポイントは 2 行だけです。
---
- 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_names
groups
インベントリに定義されているグループを検索するには:
---
- 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}};
必要に応じて変更してください。