OpenEuler系统全栈自动化部署实战
一、前言
在之前的Playbook系列文章中,我们学习了Ansible的基础语法、变量、条件判断、循环和Handlers等核心概念。本文将通过一个综合性的实战案例,演示如何使用Ansible Playbook在OpenEuler系统上一键部署一个完整的企业级服务集群,包括:远程获取SSH密钥认证、部署Nginx Web服务、搭建Keepalived高可用反向代理集群、配置DNS域名解析服务以及DHCP动态IP分配服务。
本文将按照CSDN博客的完整格式,带你从环境规划、目录结构设计到Playbook编写,一步步完成整个自动化部署项目。
二、环境规划
2.1 主机清单(Inventory)
在Ansible控制节点192.168.64.128上,编辑/etc/ansible/hosts文件:
[all:vars] ansible_user=root ansible_password=openeuler123 # ansible_ssh_private_key_file=/root/.ssh/id_rsa # 密钥认证后可切换为私钥认证 [webservers] 192.168.64.100 192.168.64.101 [loadbalancers] 192.168.64.200 priority=100 state=MASTER vip=192.168.64.250 192.168.64.201 priority=90 state=BACKUP vip=192.168.64.250 [dnsserver] 192.168.64.108 [dhcpserver] 192.168.64.1092.2 服务器角色规划
| IP地址 | 主机名建议 | 角色说明 |
|---|---|---|
| 192.168.64.100 | web01 | Nginx Web服务器(主) |
| 192.168.64.101 | web02 | Nginx Web服务器(备) |
| 192.168.64.108 | dns01 | DNS域名解析服务器 |
| 192.168.64.109 | dhcp01 | DHCP动态IP分配服务器 |
| 192.168.64.200 | lb01 | Keepalived + Nginx反向代理(Master) |
| 192.168.64.201 | lb02 | Keepalived + Nginx反向代理(Backup) |
| 192.168.64.128 | ansible | Ansible控制节点 |
2.3 VIP规划
VIP地址:192.168.64.250
作用:Keepalived虚拟IP,作为整个集群的统一入口,客户端访问此VIP即可获得Nginx反向代理服务
三、项目目录结构
在Ansible控制节点上创建如下目录结构:
mkdir -p /ansible/playbooks/roles/{common,nginx,keepalived,dns,dhcp}/{tasks,handlers,templates,files,vars} mkdir -p /ansible/playbooks/{group_vars,host_vars}完整目录结构:
/ansible/playbooks/ ├── site.yml # 主入口Playbook ├── ssh_key_distribution.yml # SSH密钥分发Playbook ├── inventory # 主机清单文件 ├── group_vars/ │ └── all.yml # 全局变量 ├── roles/ │ ├── common/ │ │ └── tasks/ │ │ └── main.yml # 通用任务(防火墙、SELinux等) │ ├── nginx/ │ │ ├── tasks/ │ │ │ └── main.yml # Nginx安装配置任务 │ │ ├── handlers/ │ │ │ └── main.yml # Nginx服务重启处理 │ │ ├── templates/ │ │ │ ├── nginx.conf.j2 # Nginx主配置模板 │ │ │ └── index.html.j2 # Web页面模板 │ │ └── vars/ │ │ └── main.yml │ ├── keepalived/ │ │ ├── tasks/ │ │ │ └── main.yml │ │ ├── handlers/ │ │ │ └── main.yml │ │ └── templates/ │ │ ├── keepalived.conf.j2 │ │ └── nginx-lb.conf.j2 # 反向代理配置模板 │ ├── dns/ │ │ ├── tasks/ │ │ │ └── main.yml │ │ └── templates/ │ │ ├── named.conf.j2 │ │ └── zone.db.j2 │ └── dhcp/ │ ├── tasks/ │ │ └── main.yml │ └── templates/ │ └── dhcpd.conf.j2 └── files/ └── id_rsa.pub # Ansible控制节点的SSH公钥四、SSH密钥远程分发
在执行所有自动化部署任务之前,首先需要将Ansible控制节点的SSH公钥分发到所有目标主机,实现免密登录。这一步是后续Playbook顺畅执行的基础。
4.1 生成SSH密钥对
在Ansible控制节点上执行:
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa4.2 编写SSH密钥分发Playbook
创建/ansible/playbooks/ssh_key_distribution.yml:
--- - name: 分发SSH公钥到所有目标主机 hosts: all gather_facts: no vars: ansible_user: root ansible_password: "openeuler123" # 首次连接使用的密码 tasks: - name: 确保目标主机.ssh目录存在 ansible.builtin.file: path: /root/.ssh state: directory owner: root group: root mode: '0700' - name: 读取控制节点的SSH公钥 ansible.builtin.slurp: src: /root/.ssh/id_rsa.pub register: ssh_pub_key delegate_to: localhost run_once: true - name: 将公钥添加到目标主机的authorized_keys ansible.posix.authorized_key: user: root state: present key: "{{ ssh_pub_key.content | b64decode }}" exclusive: no manage_dir: yes - name: 关闭SSH密码认证(可选,提高安全性) ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^PasswordAuthentication' line: 'PasswordAuthentication no' state: present notify: restart sshd handlers: - name: restart sshd ansible.builtin.service: name: sshd state: restarted执行命令:
ansible-playbook /ansible/playbooks/ssh_key_distribution.yml注意:
authorized_key模块位于ansible.posix集合中,如果未安装,先执行:bash
ansible-galaxy collection install ansible.posix
密钥分发成功后,可以将inventory中的密码认证注释掉,改用私钥认证:
[all:vars] ansible_user=root ansible_ssh_private_key_file=/root/.ssh/id_rsa # ansible_password=openeuler123 # 已注释五、全局变量配置
创建/ansible/playbooks/group_vars/all.yml:
--- # 网络配置 domain_name: "example.local" dns_server: "192.168.64.108" dhcp_server: "192.168.64.109" gateway: "192.168.64.2" netmask: "255.255.255.0" network: "192.168.64.0" # Nginx Web配置 nginx_version: "1.20.1" web_domain: "www.example.local" web_root: "/usr/share/nginx/html" # Keepalived配置 vip_address: "192.168.64.250" vip_interface: "ens33" # 根据实际网卡修改 vrid: 51 # DNS配置 dns_zone: "example.local" dns_network_reverse: "64.168.192" dns_forwarders: - "114.114.114.114" - "8.8.8.8" # DHCP配置 dhcp_subnet: "192.168.64.0" dhcp_netmask: "255.255.255.0" dhcp_range_start: "192.168.64.150" dhcp_range_end: "192.168.64.200" dhcp_lease_time: 3600 dhcp_max_lease_time: 7200六、通用角色(common)
创建/ansible/playbooks/roles/common/tasks/main.yml:
--- - name: 关闭SELinux ansible.builtin.selinux: state: disabled - name: 停止并禁用firewalld ansible.builtin.service: name: firewalld state: stopped enabled: no ignore_errors: yes - name: 安装基础工具包 ansible.builtin.dnf: name: - vim - wget - curl - net-tools - lsof - tcpdump - bash-completion state: present - name: 配置hosts文件 ansible.builtin.lineinfile: path: /etc/hosts line: "{{ item }}" state: present loop: - "192.168.64.100 web01 web01.example.local" - "192.168.64.101 web02 web02.example.local" - "192.168.64.108 dns01 dns01.example.local" - "192.168.64.109 dhcp01 dhcp01.example.local" - "192.168.64.200 lb01 lb01.example.local" - "192.168.64.201 lb02 lb02.example.local" - "{{ vip_address }} vip.example.local"七、Nginx Web服务器角色
7.1 Nginx安装配置任务
创建/ansible/playbooks/roles/nginx/tasks/main.yml:
--- - name: 安装Nginx依赖包 ansible.builtin.dnf: name: - gcc - pcre - pcre-devel - zlib - zlib-devel - openssl - openssl-devel state: present - name: 安装Nginx(使用openEuler官方源) ansible.builtin.dnf: name: nginx state: present - name: 创建Web根目录 ansible.builtin.file: path: "{{ web_root }}" state: directory owner: nginx group: nginx mode: '0755' - name: 配置Nginx主配置文件 ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf owner: root group: root mode: '0644' notify: restart nginx - name: 部署自定义首页 ansible.builtin.template: src: index.html.j2 dest: "{{ web_root }}/index.html" owner: nginx group: nginx mode: '0644' - name: 启动Nginx服务并设置开机自启 ansible.builtin.service: name: nginx state: started enabled: yes7.2 Nginx配置模板
创建/ansible/playbooks/roles/nginx/templates/nginx.conf.j2:
nginx
user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; events { worker_connections 1024; use epoll; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server_tokens off; gzip on; gzip_vary on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript; server { listen 80; server_name {{ ansible_default_ipv4.address }} {{ ansible_hostname }} {{ web_domain }}; root {{ web_root }}; location / { index index.html index.htm; } location /health { access_log off; return 200 "healthy\n"; add_header Content-Type text/plain; } } }7.3 自定义首页模板
创建/ansible/playbooks/roles/nginx/templates/index.html.j2:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Ansible自动化部署 - Nginx Web服务器</title> <style> body { font-family: Arial, sans-serif; margin: 40px; background: #f5f5f5; } .container { max-width: 800px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } h1 { color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; } .info { background: #ecf0f1; padding: 15px; border-radius: 5px; margin: 20px 0; } .footer { margin-top: 30px; color: #7f8c8d; font-size: 14px; text-align: center; } </style> </head> <body> <div class="container"> <h1>🚀 Ansible自动化部署成功!</h1> <div class="info"> <p><strong>服务器信息:</strong></p> <ul> <li>主机名:{{ ansible_hostname }}</li> <li>IP地址:{{ ansible_default_ipv4.address }}</li> <li>操作系统:{{ ansible_distribution }} {{ ansible_distribution_version }}</li> <li>内核版本:{{ ansible_kernel }}</li> <li>部署时间:{{ ansible_date_time.iso8601 }}</li> </ul> </div> <p>🎉 恭喜!Nginx Web服务器已通过Ansible Playbook成功部署在OpenEuler系统上。</p> <div class="footer"> <p>Powered by Ansible | OpenEuler | Nginx</p> </div> </div> </body> </html>7.4 Handlers
创建/ansible/playbooks/roles/nginx/handlers/main.yml:
--- - name: restart nginx ansible.builtin.service: name: nginx state: restarted八、Keepalived + Nginx反向代理角色
在两台负载均衡器(192.168.64.200和192.168.64.201)上部署Keepalived实现高可用,同时配置Nginx作为反向代理,将请求转发到后端Web服务器。Keepalived基于VRRP协议实现故障切换与健康检查功能。
8.1 Keepalived安装配置任务
创建/ansible/playbooks/roles/keepalived/tasks/main.yml:
--- - name: 安装Nginx(反向代理) ansible.builtin.dnf: name: nginx state: present - name: 安装Keepalived ansible.builtin.dnf: name: keepalived state: present - name: 启用IP转发 ansible.builtin.sysctl: name: net.ipv4.ip_forward value: '1' sysctl_set: yes state: present reload: yes - name: 配置Nginx反向代理 ansible.builtin.template: src: nginx-lb.conf.j2 dest: /etc/nginx/conf.d/loadbalancer.conf owner: root group: root mode: '0644' notify: reload nginx - name: 备份原有Keepalived配置 ansible.builtin.copy: src: /etc/keepalived/keepalived.conf dest: /etc/keepalived/keepalived.conf.bak remote_src: yes force: no ignore_errors: yes - name: 配置Keepalived ansible.builtin.template: src: keepalived.conf.j2 dest: /etc/keepalived/keepalived.conf owner: root group: root mode: '0644' notify: restart keepalived - name: 启动Nginx服务 ansible.builtin.service: name: nginx state: started enabled: yes - name: 启动Keepalived服务 ansible.builtin.service: name: keepalived state: started enabled: yes8.2 Nginx反向代理配置模板
创建/ansible/playbooks/roles/keepalived/templates/nginx-lb.conf.j2:
# Nginx反向代理配置 - 负载均衡器 upstream backend_web { # 使用加权轮询算法,将请求分发到后端Web服务器 server 192.168.64.100:80 weight=1 max_fails=3 fail_timeout=30s; server 192.168.64.101:80 weight=1 max_fails=3 fail_timeout=30s; # 开启会话保持 keepalive 32; } upstream backend_api { # API反向代理后端服务 server 192.168.64.100:8080 weight=1 max_fails=3 fail_timeout=30s; server 192.168.64.101:8080 weight=1 max_fails=3 fail_timeout=30s; keepalive 32; } server { listen 80; server_name {{ web_domain }} {{ vip_address }}; # 访问日志 access_log /var/log/nginx/lb_access.log main; error_log /var/log/nginx/lb_error.log; # Web流量转发 location / { proxy_pass http://backend_web; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Connection ""; # 超时设置 proxy_connect_timeout 5s; proxy_send_timeout 60s; proxy_read_timeout 60s; } # API流量转发 location /api/ { proxy_pass http://backend_api; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Connection ""; # 重写请求路径(可选) # rewrite ^/api/(.*)$ /$1 break; } # 健康检查端点 location /health { access_log off; return 200 "LB-{{ ansible_hostname }}-OK\n"; add_header Content-Type text/plain; } # Nginx状态页(仅内网访问) location /nginx_status { stub_status on; access_log off; allow 192.168.64.0/24; deny all; } }8.3 Keepalived配置模板
创建/ansible/playbooks/roles/keepalived/templates/keepalived.conf.j2:
! Configuration File for keepalived global_defs { router_id {{ ansible_hostname }} script_user root enable_script_security } vrrp_script check_nginx { script "/usr/bin/killall -0 nginx" interval 2 weight -20 fall 3 rise 2 } vrrp_instance VI_1 { state {{ state }} interface {{ vip_interface }} virtual_router_id {{ vrid }} priority {{ priority }} advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { {{ vip_address }}/24 dev {{ vip_interface }} } track_script { check_nginx } notify_master "/usr/bin/echo '{{ ansible_hostname }} became MASTER' | /usr/bin/logger -t keepalived" notify_backup "/usr/bin/echo '{{ ansible_hostname }} became BACKUP' | /usr/bin/logger -t keepalived" notify_fault "/usr/bin/echo '{{ ansible_hostname }} became FAULT' | /usr/bin/logger -t keepalived" }8.4 Handlers
创建/ansible/playbooks/roles/keepalived/handlers/main.yml:
--- - name: reload nginx ansible.builtin.service: name: nginx state: reloaded - name: restart keepalived ansible.builtin.service: name: keepalived state: restarted九、DNS域名解析角色
在DNS服务器(192.168.64.108)上部署BIND9,为内网提供域名解析服务。OpenEuler使用DNF包管理器,直接安装BIND即可。
9.1 DNS安装配置任务
创建/ansible/playbooks/roles/dns/tasks/main.yml:
--- - name: 安装BIND9 DNS服务 ansible.builtin.dnf: name: bind state: present - name: 创建正向解析区域文件目录 ansible.builtin.file: path: /var/named/zones state: directory owner: named group: named mode: '0750' - name: 配置named主配置文件 ansible.builtin.template: src: named.conf.j2 dest: /etc/named.conf owner: root group: named mode: '0640' notify: restart named - name: 配置正向解析区域文件 ansible.builtin.template: src: zone.db.j2 dest: "/var/named/zones/{{ dns_zone }}.db" owner: named group: named mode: '0640' notify: restart named - name: 配置反向解析区域文件 ansible.builtin.template: src: reverse.db.j2 dest: "/var/named/zones/{{ dns_network_reverse }}.db" owner: named group: named mode: '0640' notify: restart named - name: 配置防火墙规则(允许DNS查询) ansible.builtin.firewalld: service: dns permanent: yes state: enabled immediate: yes ignore_errors: yes - name: 启动named服务并设置开机自启 ansible.builtin.service: name: named state: started enabled: yes9.2 named主配置模板
创建/ansible/playbooks/roles/dns/templates/named.conf.j2:
options { listen-on port 53 { any; }; listen-on-v6 port 53 { ::1; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; secroots-file "/var/named/data/named.secroots"; recursing-file "/var/named/data/named.recursing"; allow-query { any; }; recursion yes; forwarders { {% for fwd in dns_forwarders %} {{ fwd }}; {% endfor %} }; dnssec-validation no; managed-keys-directory "/var/named/dynamic"; pid-file "/run/named/named.pid"; session-keyfile "/run/named/session.key"; }; logging { channel default_debug { file "data/named.run"; severity dynamic; }; }; zone "." IN { type hint; file "named.ca"; }; # 正向解析区域 zone "{{ dns_zone }}" IN { type master; file "zones/{{ dns_zone }}.db"; allow-update { none; }; }; # 反向解析区域 zone "{{ dns_network_reverse }}.in-addr.arpa" IN { type master; file "zones/{{ dns_network_reverse }}.db"; allow-update { none; }; }; include "/etc/named.rfc1912.zones"; include "/etc/named.root.key";9.3 正向解析区域文件模板
创建/ansible/playbooks/roles/dns/templates/zone.db.j2:
$TTL 86400 @ IN SOA dns01.{{ dns_zone }}. admin.{{ dns_zone }}. ( {{ ansible_date_time.epoch }} ; Serial 3600 ; Refresh 1800 ; Retry 604800 ; Expire 86400 ) ; Minimum TTL ; 名称服务器 @ IN NS dns01.{{ dns_zone }}. dns01 IN A {{ dns_server }} ; Web服务器 web01 IN A 192.168.64.100 web02 IN A 192.168.64.101 www IN CNAME web01 www2 IN CNAME web02 ; 负载均衡器 lb01 IN A 192.168.64.200 lb02 IN A 192.168.64.201 lb IN CNAME lb01 ; 虚拟IP vip IN A {{ vip_address }} portal IN CNAME vip ; DHCP服务器 dhcp01 IN A {{ dhcp_server }} dhcp IN CNAME dhcp01 ; 其他服务 api IN A {{ vip_address }}9.4 反向解析区域文件模板
创建/ansible/playbooks/roles/dns/templates/reverse.db.j2:
$TTL 86400 @ IN SOA dns01.{{ dns_zone }}. admin.{{ dns_zone }}. ( {{ ansible_date_time.epoch }} ; Serial 3600 ; Refresh 1800 ; Retry 604800 ; Expire 86400 ) ; Minimum TTL ; 名称服务器 @ IN NS dns01.{{ dns_zone }}. ; PTR记录 100 IN PTR web01.{{ dns_zone }}. 101 IN PTR web02.{{ dns_zone }}. 108 IN PTR dns01.{{ dns_zone }}. 109 IN PTR dhcp01.{{ dns_zone }}. 200 IN PTR lb01.{{ dns_zone }}. 201 IN PTR lb02.{{ dns_zone }}. 250 IN PTR vip.{{ dns_zone }}.9.5 Handlers
创建/ansible/playbooks/roles/dns/handlers/main.yml:
--- - name: restart named ansible.builtin.service: name: named state: restarted十、DHCP分配IP角色
在DHCP服务器(192.168.64.109)上部署DHCP服务,为内网客户端动态分配IP地址。DHCP服务器自身必须使用静态IP,否则服务会失效。
10.1 DHCP安装配置任务
创建/ansible/playbooks/roles/dhcp/tasks/main.yml:
--- - name: 安装DHCP服务 ansible.builtin.dnf: name: dhcp-server state: present - name: 从模板复制DHCP配置文件 ansible.builtin.template: src: dhcpd.conf.j2 dest: /etc/dhcp/dhcpd.conf owner: root group: root mode: '0644' notify: restart dhcpd - name: 配置DHCP监听网卡 ansible.builtin.lineinfile: path: /etc/sysconfig/dhcpd line: 'DHCPDARGS="{{ ansible_default_ipv4.interface }}"' regexp: '^DHCPDARGS=' state: present notify: restart dhcpd - name: 配置防火墙规则(允许DHCP服务) ansible.builtin.firewalld: service: dhcp permanent: yes state: enabled immediate: yes ignore_errors: yes - name: 启动DHCP服务并设置开机自启 ansible.builtin.service: name: dhcpd state: started enabled: yes10.2 DHCP配置模板
创建/ansible/playbooks/roles/dhcp/templates/dhcpd.conf.j2:
# 全局配置 option domain-name "{{ domain_name }}"; option domain-name-servers {{ dns_server }}; default-lease-time {{ dhcp_lease_time }}; max-lease-time {{ dhcp_max_lease_time }}; authoritative; # 禁用DNS动态更新 ddns-update-style none; # 日志配置 log-facility local7; # 子网配置 subnet {{ dhcp_subnet }} netmask {{ dhcp_netmask }} { range {{ dhcp_range_start }} {{ dhcp_range_end }}; option routers {{ gateway }}; option subnet-mask {{ dhcp_netmask }}; option broadcast-address 192.168.64.255; option domain-name-servers {{ dns_server }}; option domain-name "{{ domain_name }}"; } # 为特定MAC地址分配固定IP # 例如:为测试客户端分配固定IP host test-client { hardware ethernet 00:0C:29:XX:XX:XX; # 替换为实际MAC地址 fixed-address 192.168.64.210; option host-name "test-client"; }10.3 Handlers
创建/ansible/playbooks/roles/dhcp/handlers/main.yml:
--- - name: restart dhcpd ansible.builtin.service: name: dhcpd state: restarted十一、主入口Playbook(site.yml)
创建/ansible/playbooks/site.yml,作为整个自动化部署的入口:
--- - name: 1. 初始化所有服务器(通用配置) hosts: all gather_facts: yes roles: - common - name: 2. 部署Nginx Web服务器 hosts: webservers gather_facts: yes roles: - nginx - name: 3. 部署Keepalived + Nginx反向代理(高可用负载均衡) hosts: loadbalancers gather_facts: yes roles: - keepalived - name: 4. 部署DNS域名解析服务器 hosts: dnsserver gather_facts: yes roles: - dns - name: 5. 部署DHCP动态IP分配服务器 hosts: dhcpserver gather_facts: yes roles: - dhcp - name: 6. 部署后验证 hosts: localhost gather_facts: no tasks: - name: 显示部署完成信息 ansible.builtin.debug: msg: - "========================================" - "🎉 恭喜!全栈自动化部署已完成!" - "========================================" - "Nginx Web服务器: 192.168.64.100, 192.168.64.101" - "Keepalived高可用集群 (VIP: 192.168.64.250): 192.168.64.200(MASTER), 192.168.64.201(BACKUP)" - "DNS服务器: 192.168.64.108" - "DHCP服务器: 192.168.64.109" - "========================================" - "验证命令:" - " curl http://192.168.64.250" - " nslookup web01.example.local 192.168.64.108" - " ip addr show | grep 192.168.64.250" - " systemctl status dhcpd" - "========================================"十二、执行Playbook
12.1 语法检查
cd /ansible/playbooks ansible-playbook site.yml --syntax-check12.2 试运行(Dry Run)
ansible-playbook site.yml --check12.3 正式执行
ansible-playbook site.yml12.4 指定执行部分角色
# 仅部署Web服务器 ansible-playbook site.yml --tags nginx # 仅部署负载均衡器 ansible-playbook site.yml --tags keepalived十三、部署验证
13.1 验证Nginx Web服务
# 访问单台Web服务器 curl http://192.168.64.100 curl http://192.168.64.101 # 查看Nginx服务状态 ansible webservers -m shell -a "systemctl status nginx | head -3"13.2 验证Keepalived高可用集群
# 查看VIP所在节点 ansible loadbalancers -m shell -a "ip addr show | grep {{ vip_address }}" # 模拟故障切换测试 # 在MASTER节点上停止Keepalived服务 ansible 192.168.64.200 -m service -a "name=keepalived state=stopped" # 观察VIP是否漂移到BACKUP节点 ansible 192.168.64.201 -m shell -a "ip addr show | grep 192.168.64.250" # 恢复MASTER节点 ansible 192.168.64.200 -m service -a "name=keepalived state=started"13.3 验证反向代理
# 通过VIP访问(应该轮询分发到两台Web服务器) for i in {1..10}; do curl -s http://192.168.64.250 | grep "主机名"; done # 查看负载均衡器状态 curl http://192.168.64.250/nginx_status13.4 验证DNS解析
# 测试正向解析 nslookup web01.example.local 192.168.64.108 nslookup www.example.local 192.168.64.108 nslookup vip.example.local 192.168.64.108 # 测试反向解析 nslookup 192.168.64.100 192.168.64.10813.5 验证DHCP服务
# 查看DHCP服务状态 ansible dhcpserver -m shell -a "systemctl status dhcpd" # 查看DHCP租约文件 ansible dhcpserver -m shell -a "cat /var/lib/dhcpd/dhcpd.leases"十四、故障排查与优化建议
14.1 常见问题排查
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| SSH连接失败 | 密钥未正确分发 | 重新执行ssh_key_distribution.yml |
| Nginx启动失败 | 端口被占用 | netstat -tlnp | grep :80 |
| Keepalived VIP不漂移 | 防火墙阻止VRRP协议 | 确保firewalld已关闭或放行VRRP(协议号112) |
| DNS解析失败 | named服务未启动 | systemctl restart named |
| DHCP分配失败 | 网卡配置错误 | 检查/etc/sysconfig/dhcpd中的网卡名称 |
14.2 优化建议
使用Ansible Vault加密敏感信息:将密码等敏感变量放入加密文件中
开启Pipeline:在
ansible.cfg中设置pipelining = True可提升执行效率配置Fact缓存:设置
fact_caching = jsonfile加速重复执行使用Roles结构:将不同服务拆分为独立Role,便于维护和复用
十五、总结
本文通过一个完整的实战案例,演示了如何使用Ansible Playbook在OpenEuler系统上自动化部署一套企业级服务集群,涵盖:
SSH密钥分发:使用
authorized_key模块实现免密登录Nginx Web服务:通过模板部署Web服务器和自定义页面
Keepalived高可用集群:基于VRRP协议实现VIP漂移,配合Nginx实现反向代理和API转发
DNS域名解析:部署BIND9服务,实现内网正向/反向域名解析
DHCP动态IP分配:为内网客户端自动分配IP地址