HAProxy 负载均衡部署

本节将演示如何使用 Ansible 自动化部署 HAProxy 负载均衡器,并结合 Apache Web 服务器实现后端服务的负载均衡。我们将通过配置主机清单、编写 Playbook 以及使用 Jinja2 模板动态生成 HAProxy 配置文件来完成整个部署流程。

配置主机清单

首先,在 Ansible 的主机清单文件 hosts 中定义两个主机组:[webservers] 用于存放后端 Web 服务器,[haproxy] 用于部署负载均衡器。同时,为 webservers 组设置变量 http_port。

ini 复制代码
[kyy@server1 ansible]$ vim hosts
[webservers]
server2
host1
[webservers:vars]
http_port=80
[haproxy]
server1

编写 Keepalived 配置

(此部分为可选的高可用配置示例,用于停止 Keepalived 服务。)

yaml 复制代码
[kyy@server1 ansible]$ vim keepalived.yml
    - name: Start service keepalived
      ansible.builtin.service:
        name: keepalived
        state: stopped
        enabled: no
      tags: t1

编写主部署 Playbook

创建主 Playbook 文件 haproxy.yml,其核心逻辑是:在 haproxy 组的主机上部署 HAProxy,在 webservers 组的主机上部署 Apache。

yaml 复制代码
[kyy@server1 ansible]$ vim haproxy.yml
---
- hosts: haproxy,webservers
  tasks:
    - name: deploy haproxy
      block:
        - name: install haproxy
          ansible.builtin.yum:
            name: haproxy
            state: present
    - name: configure the haproxy
      ansible.builtin.template:
        src: haproxy.cfg.j2
        dest: /etc/haproxy/haproxy.cfg
      notify: restart service haproxy
- name: enable service haproxy
  ansible.builtin.service:
    name: haproxy
    state: started
    enabled: yes
when: ansible_hostname == 'server1'
name: deploy apache
block:
name: Install the Apache
ansible.builtin.yum:
name: httpd
state: present
name: Ensure the default Apache port is {{ http_port }}
ansible.builtin.template:
src: httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
notify: restart service httpd
name: Start service httpd, if not started
ansible.builtin.service:
name: httpd
state: started
enabled: yes
name: create index.html
ansible.builtin.copy:
content: "{{ ansible_hostname }}\n"
dest: /var/www/html/index.html
when: ansible_hostname in groups['webservers']
handlers:
name: restart service haproxy
ansible.builtin.service:
name: haproxy
state: restarted
name: restart service httpd
ansible.builtin.service:
name: httpd
state: restarted</code></pre>
6.4 准备 HAProxy 配置模板
将现有的 HAProxy 配置文件复制为 Jinja2 模板 haproxy.cfg.j2,并修改其内容,使其能动态引用 webservers 组中所有主机的信息。
[kyy@server1 ansible]$ ansible-playbook haproxy.yml --syntax-check
playbook: haproxy.yml
[kyy@server1 ansible]$ cp /etc/haproxy/haproxy.cfg .
[kyy@server1 ansible]$ mv haproxy.cfg haproxy.cfg.j2
[kyy@server1 ansible]$ vim haproxy.cfg.j2
frontend main
bind *:80
default_backend             app
#---------------------------------------------------------------------
round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
balance     roundrobin
{% for host in groups['webservers'] %}
server {{ hostvars[host].ansible_hostname }} {{ hostvars[host].ansible_eth0.ipv4.address }}:{{ hostvars[host].http_port }} check
{% endfor %}
6.5 执行 Playbook 并验证
执行 Playbook,Ansible 将根据主机名自动判断任务执行目标:在 server1(haproxy组)上安装并配置 HAProxy,在 server2 和 host1(webservers组)上安装 Apache。
[kyy@server1 ansible]$ ansible-playbook haproxy.yml
PLAY [haproxy,webservers]
TASK [Gathering Facts]
ok: [host1]
ok: [server2]
ok: [server1]
TASK [install haproxy]
skipping: [server2]
skipping: [host1]
ok: [server1]
TASK [configure the haproxy]
skipping: [server2]
skipping: [host1]
changed: [server1]
TASK [enable service haproxy]
skipping: [server2]
skipping: [host1]
changed: [server1]
TASK [Install the Apache]
skipping: [server1]
ok: [host1]
ok: [server2]
TASK [Ensure the default Apache port is {{ http_port }}]
skipping: [server1]
ok: [host1]
ok: [server2]
TASK [Start service httpd, if not started]
skipping: [server1]
ok: [host1]
ok: [server2]
TASK [create index.html]
skipping: [server1]
ok: [host1]
ok: [server2]
RUNNING HANDLER [restart service haproxy]
changed: [server1]
PLAY RECAP
host1                      : ok=5    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0
server1                    : ok=5    changed=3    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0
server2                    : ok=5    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0
部署完成后,在浏览器中访问负载均衡器的 IP 地址(例如 192.168.223.161:80),HAProxy 将按照轮询(round-robin)策略将请求分发到后端的 Apache 服务器,从而实现负载均衡。

编写haproxy.cfg.j2:模板源文件

编辑 Jinja2 模板,在 backend 段添加循环代码,实现自动读取主机组信息生成后端节点。

HAProxy 前端配置:监听本机所有网卡的 80 端口,所有请求默认转发至后端组 app。

Jinja2 循环语句:

groups['webservers'] 获取清单中 webservers 分组全部主机;

循环逐个取出主机存入变量 host,利用hostvars读取对应主机信息,自动生成多条后端 server 配置;

{% endfor %}结束循环。

实现无需手动书写每一台后端节点,动态生成 HAProxy 后端服务器列表。

cpp 复制代码
[kyy@server1 ansible]$ ansible-playbook haproxy.yml --syntax-check

playbook: haproxy.yml
[kyy@server1 ansible]$ cp /etc/haproxy/haproxy.cfg  .
[kyy@server1 ansible]$ mv haproxy.cfg haproxy.cfg.j2
[kyy@server1 ansible]$ vim haproxy.cfg.j2
frontend main
    bind *:80
    default_backend             app

#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
    balance     roundrobin
{% for host in groups['webservers'] %}
    server {{ hostvars[host].ansible_hostname }} {{ hostvars[host].ansible_eth0.ipv4.address }}:{{ hostvars[host].http_port }} check 
{% endfor %}
    

运行playbook,成功

java 复制代码
[kyy@server1 ansible]$ ansible-playbook haproxy.yml

[kyy@server1 ansible]$ ansible-playbook haproxy.yml
PLAY [haproxy,webservers] 

TASK [Gathering Facts] 
ok: [host1]
ok: [server2]
ok: [server1]

TASK [install haproxy] 
skipping: [server2]
skipping: [host1]
ok: [server1]

TASK [configure the haproxy] 
skipping: [server2]
skipping: [host1]
changed: [server1]

TASK [enable service haproxy] 
skipping: [server2]
skipping: [host1]
changed: [server1]

TASK [Install the Apache] 
skipping: [server1]
ok: [host1]
ok: [server2]

TASK [Ensure the default Apache port is {{ http_port }}] 
skipping: [server1]
ok: [host1]
ok: [server2]

TASK [Start service httpd, if not started] 
skipping: [server1]
ok: [host1]
ok: [server2]

TASK [create index.html] 
skipping: [server1]
ok: [host1]
ok: [server2]

RUNNING HANDLER [restart service haproxy] 
changed: [server1]

PLAY RECAP 
host1                      : ok=5    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0
server1                    : ok=5    changed=3    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0
server2                    : ok=5    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0

浏览器访问192.168.223.161:80

出现的效果是server2,host1轮换出现,说明haproxy部署成功,实现了负载均衡

相关推荐
虎头金猫5 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
AI职业加油站5 天前
AI智能体应用工程师证书:政策红利下的职业新风口
大数据·运维·人工智能·学习·职场发展
此冬歌咏5 天前
K8s 节点故障实战:优雅驱逐 31 秒,硬故障 331 秒,以及那个永远 Pending 的 Pod
运维·k8s
-梅5 天前
linux(8) 软硬链接
linux·运维·服务器
张洛闻Eren5 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
其实防守也摸鱼5 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
布裘5 天前
【银河麒麟】V4桌面图标消失,右击鼠标没反应排查
运维·银河麒麟·桌面环境
懂软件的胡子个哥5 天前
微信机器人为什么需要“回复候选”而不是所有 AI 内容直接发送
运维·微信·自动化·wechatapi·个人微信号二次开发
云贝贝贝5 天前
腾讯云 TDSQL(MySQL 版)性能优化与慢查询排障实战 6 招
运维·腾讯云
Lsetea5 天前
证书没到期却报certificate has expired:OpenSSL定位中间证书与系统时间
运维·https·ssl证书·openssl·证书链