다중 데이터 센터 Ansible 로드 밸런서 템플릿

다중 데이터 센터 Ansible 로드 밸런서 템플릿

기존 다중 데이터 센터 설정의 관리를 Ansible로 마이그레이션하고 있지만 처음 사용하기 때문에 이를 모델링하는 가장 좋은 방법이 무엇인지 잘 모르겠습니다.

3개의 데이터 센터 D1, D2, D3이 있습니다. 각각에서 동일한 구성이 동일하게 반복됩니다.

  • nginx 로드 밸런서(lb.D[n]) 공용 IP에 바인딩됨
  • 애플리케이션 서버(as[1-2].D[n])은 로컬 로드 밸런서에서만 트래픽을 수신합니다.
  • 슬레이브(읽기 전용)DB 서버(db.D[n]) 두 앱 서버 모두에서 읽습니다.

지금까지 만든 호스트 파일은 다음과 같습니다.

# 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

DNS를 사용하는 대신 순수한 Ansible 솔루션이 어떻게 작동하는지 이해하고 싶기 때문에 여기에 의도적으로 IP 주소만 남겨 두었습니다.

문제는 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 %}
 }

우선 호스트 파일이 완전히 의미가 있는지 확신할 수 없습니다(대신 개별 항목에 변수를 추가해야 합니까? 현재 구성에서는 확실하지 않더라도 [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 바인딩 및 기타 일부를 설치하는 기본 역할을 호출합니다. 클라우드의 모든 시스템에 공통적인 내용을 입력한 다음 실제 웹 서버 역할을 호출합니다.

---
- 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 }

"웹 서버" 역할은 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}};필요에 따라 변경하세요 .

관련 정보