Article Directory
1. Introduction to HAProxy
HAProxy provides high availability, load balancing, and proxy based on TCP and HTTP applications, and supports virtual hosts. It is a free, fast and reliable solution. HAProxy is especially suitable for web sites with heavy loads, which usually require session retention or seven-layer processing. HAProxy runs on current hardware and can fully support tens of thousands of concurrent connections. And its operating mode makes it easy and safe to integrate into your current architecture, while protecting your web server from being exposed to the network
2. Install and configure HAProxy
-
installation:
yum install haproxy -y
-
Configuration:
vim /etc/haproxy/haproxy.cfg
64 stats uri /status #设置统计页面的uri为/status
65 stats auth admin:westos #设置统计页面认证的用户和密码
68 #---------------------------------------------------------------------
69 frontend main #前端
70 bind *:80 #端口号
71 # acl url_static path_beg -i /static /images /javascript /stylesheets
72 # acl url_static path_end -i .jpg .gif .png .css .js
73 #
74 # use_backend static if url_static
75 default_backend app #默认后端为app
86 #---------------------------------------------------------------------
87 backend app #后端
88 balance roundrobin #调度算法
89 server app1 192.168.43.27:80 check
90 server app2 192.168.43.37:80 check
- Turn on the service:
systemctl start haproxy.service
netstat -antlupe
: You can see that the port number of haproxy is 80
- You can visit http://192.168.43.17/status
3. haproxy and ansible magic variables
visudo
: Add permissions
devops ALL=(ALL) NOPASSWD: ALL
-
cp /etc/haproxy/haproxy.cfg /mnt/ansible/
-
cp /mnt/ansible/haproxy.cfg /mnt/ansible/haproxy.cfg.j2
: Copy jinja2 template -
vim /mnt/ansible/hosts
: Add the local IP (haproxy service) to the host list
[lb]
192.168.43.17
vim haproxy.cfg.j2
: Add magic variables to the jinja2 template
87 backend app
88 balance roundrobin
89 {
% for host in groups['webserver'] %}
90 server {
{
hostvars[host]['ansible_facts']['hostname'] }} {
{
hostvars[host]['ansible_facts']['网卡名']['ipv4']['address'] }}:80 check
91 {
% endfor %}
#这些变量名可以通过 ansible 主机名 -m setup 查看
- Writing the script:
webserver.yml
#webserver.yaml
---
- hosts: webserver
tasks:
- name: 安装 apache
dnf:
name: httpd
state: present
- name: 创建index.html
copy:
content: "{
{ ansible_hostname }}\n"
dest: /var/www/html/index.html
- name: 开启 apache
service:
name: httpd
state: started
enabled: yes
- name: 开启 firewalld
service:
name: firewalld
state: started
enabled: yes
- name: 通过 http
firewalld:
service: http
permanent: yes
immediate: yes
state: enabled
- import_playbook: haproxy.yml
- Writing the script:
haproxy.yml
#haproxy.yml
---
- hosts: lb
tasks:
- name: 安装 haproxy
dnf:
name: haproxy
state: present
- name: 配置 haproxy
template:
src: haproxy.cfg.j2
dest: /etc/haproxy/haproxy.cfg
notify: restart haproxy
- name: 开启 haproxy
service:
name: haproxy
state: started
- name: 通过 haproxy
firewalld:
service: http
permanent: yes
immediate: yes
state: enabled
handlers:
- name: restart haproxy
service:
name: haproxy
state: reloaded
-
ansible-playbook webserver.yml
-
allowable /etc/haproxy/haproxy.cfgCheck, the variable was successfully modified
-
Visit: http://192.168.43.17/status
4. Automation example
- Add a new virtual machine server4 to the host list
hostname: server4
IP: 192.168.43.47
configuration without password
-
carried out
ansible-playbook webserver.yml
-
It is found that server4 is automatically added in /etc/haproxy/haproxy.cfg, and automatically added in http://172.25.17.1/status
5. Continuous delivery of rolling updates
- Problem: When the script is executed, it is updated at the same time, which may cause all the backends to fail to work
5.1 Manually close or open the backend
yum install socat -y
: Install socatvim /etc/haproxy/haproxy.cfg
: Increase permissions
systemctl restart haproxy.service
: Restart service
echo "disable server app/server4" | socat stdio /var/lib/haproxy/stats
:shut down
echo "enable server app/server4" | socat stdio /var/lib/haproxy/stats
:turn on
5.2 Set rolling upgrade
vim playbook.yml
---
- hosts: webserver
serial: 1#设置并发控制为1
pre_tasks:
- name: disable the server in haproxy
haproxy: 'state=disabled backend=app host={
{ inventory_hostname }} socket=/var/lib/haproxy/stats'
delegate_to: "{
{ item }}"
loop: "{
{ groups.lb }}"
roles:
- role: apache
post_tasks:
- name: wait for webserver to come up
wait_for: 'host={
{ inventory_hostname }} port=80 state=started timeout=80'
- name: enable the server in haproxy
haproxy: 'state=enabled backend=app host={
{ inventory_hostname }} socket=/var/lib/haproxy/stats'
delegate_to: "{
{ item }}"
loop: "{
{ groups.lb }}"
vim hosts
[test]
server2
#172.25.17.2
[prod]
server3
server4
#172.25.17.3
#172.25.17.4
[webserver:children]
test
prod
[lb]
server1
#172.25.17.1
- It can be found that at runtime, only one backend is updated at a time. After the task of this backend is completed, another backend task is started, which solves the problem of no backend and inability to work.