Ansible之Playbook(六):实例部署实战
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_userroot ansible_passwordopeneuler123 # ansible_ssh_private_key_file/root/.ssh/id_rsa # 密钥认证后可切换为私钥认证 [webservers] 192.168.64.100 192.168.64.101 [loadbalancers] 192.168.64.200 priority100 stateMASTER vip192.168.64.250 192.168.64.201 priority90 stateBACKUP vip192.168.64.250 [dnsserver] 192.168.64.108 [dhcpserver] 192.168.64.1092.2 服务器角色规划IP地址主机名建议角色说明192.168.64.100web01Nginx Web服务器主192.168.64.101web02Nginx Web服务器备192.168.64.108dns01DNS域名解析服务器192.168.64.109dhcp01DHCP动态IP分配服务器192.168.64.200lb01Keepalived Nginx反向代理Master192.168.64.201lb02Keepalived Nginx反向代理Backup192.168.64.128ansibleAnsible控制节点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集合中如果未安装先执行bashansible-galaxy collection install ansible.posix密钥分发成功后可以将inventory中的密码认证注释掉改用私钥认证[all:vars] ansible_userroot ansible_ssh_private_key_file/root/.ssh/id_rsa # ansible_passwordopeneuler123 # 已注释五、全局变量配置创建/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.j2nginxuser 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 charsetUTF-8 titleAnsible自动化部署 - 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 classcontainer h1 Ansible自动化部署成功/h1 div classinfo pstrong服务器信息/strong/p ul li主机名{{ ansible_hostname }}/li liIP地址{{ 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 classfooter pPowered by Ansible | OpenEuler | Nginx/p /div /div /body /html7.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 weight1 max_fails3 fail_timeout30s; server 192.168.64.101:80 weight1 max_fails3 fail_timeout30s; # 开启会话保持 keepalive 32; } upstream backend_api { # API反向代理后端服务 server 192.168.64.100:8080 weight1 max_fails3 fail_timeout30s; server 192.168.64.101:8080 weight1 max_fails3 fail_timeout30s; 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.j2options { 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十一、主入口Playbooksite.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 - 十二、执行Playbook12.1 语法检查cd /ansible/playbooks ansible-playbook site.yml --syntax-check12.2 试运行Dry Runansible-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 -313.2 验证Keepalived高可用集群# 查看VIP所在节点 ansible loadbalancers -m shell -a ip addr show | grep {{ vip_address }} # 模拟故障切换测试 # 在MASTER节点上停止Keepalived服务 ansible 192.168.64.200 -m service -a namekeepalived statestopped # 观察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 namekeepalived statestarted13.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.ymlNginx启动失败端口被占用netstat -tlnp | grep :80Keepalived VIP不漂移防火墙阻止VRRP协议确保firewalld已关闭或放行VRRP协议号112DNS解析失败named服务未启动systemctl restart namedDHCP分配失败网卡配置错误检查/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地址