找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2157

积分

1

好友

295

主题
发表于 2025-12-25 03:36:45 | 查看: 33| 回复: 0

1.1 背景介绍

每个季度的安全补丁更新是运维团队的噩梦。上个季度我们还在用 SSH 跳板机 + xshell 批量执行脚本的方式给服务器打补丁,500 台机器分 10 批次,整整熬了三个通宵。中间还出了两次事故:一次是补丁依赖冲突导致某台数据库服务器重启失败,另一次是并发太高把内网带宽打满了。

痛定思痛,我们决定用 Ansible 重构整个补丁管理流程。这套方案跑了两个季度,现在 500 台服务器的补丁更新,从晚上 10 点开始,第二天早上 6 点收工,全程无人值守。

1.2 技术特点

  • 幂等性保障:Ansible 的 yum/apt 模块天然支持幂等操作,重复执行不会造成问题,中断后可以安全重试
  • 滚动更新:通过 serial 参数控制并发数,避免同时重启太多机器影响业务
  • 自动回滚:结合健康检查,发现异常自动停止后续批次,保留现场等待人工介入
  • 详细日志:每台机器的执行结果都有记录,事后审计和故障定位都很方便

1.3 适用场景

  • 场景一:季度/月度安全补丁批量更新,需要在维护窗口内完成大量服务器的系统升级
  • 场景二:紧急漏洞修复,比如 log4j 这种 0day,需要快速在全网推送修复补丁
  • 场景三:内核升级,需要有序重启服务器并验证业务恢复状态

1.4 环境要求

组件 版本要求 说明
Ansible 控制节点 CentOS 7+ / Ubuntu 18.04+ 建议使用专用的运维跳板机
Ansible 2.9+ (推荐 2.12+) 2.12 版本的性能优化明显
Python 3.6+ 目标机器需要安装 Python
目标服务器 CentOS 7/8、Ubuntu 18/20/22 混合环境需要区分 playbook
网络 控制节点到目标机器 SSH 可达 建议配置 SSH 密钥认证

二、详细步骤

2.1 准备工作

◆ 2.1.1 系统检查

# 检查 Ansible 版本
ansible --version
# 输出示例:
# ansible [core 2.14.3]
# python version = 3.9.16

# 检查控制节点到目标机器的连通性(抽样测试几台)
ansible -i inventory/prod.ini webservers -m ping --limit 'web-001,web-002,web-003'

# 检查目标机器的磁盘空间(补丁包需要空间)
ansible -i inventory/prod.ini all -m shell -a "df -h / | tail -1 | awk '{print \$5}'" --limit 'web-001'

◆ 2.1.2 安装依赖

# CentOS/RHEL 安装 Ansible
sudo yum install -y epel-release
sudo yum install -y ansible

# Ubuntu/Debian 安装 Ansible
sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install -y ansible

# 安装额外的 collection(用于更丰富的模块支持)
ansible-galaxy collection install ansible.posix
ansible-galaxy collection install community.general

◆ 2.1.3 配置 Ansible

# 创建项目目录结构
mkdir -p ~/ansible-patching/{inventory,group_vars,roles,logs}
cd ~/ansible-patching

# 生成 ansible.cfg
cat > ansible.cfg << 'EOF'
[defaults]
inventory = ./inventory/hosts.ini
remote_user = ops
private_key_file = ~/.ssh/ops_key
host_key_checking = False
timeout = 30
forks = 20
log_path = ./logs/ansible.log
callback_whitelist = profile_tasks

[privilege_escalation]
become = True
become_method = sudo
become_user = root

[ssh_connection]
pipelining = True
control_path = /tmp/ansible-%%h-%%p-%%r
EOF

2.2 核心配置

◆ 2.2.1 主机清单配置

# inventory/hosts.ini
# 按照业务分组,方便灰度发布
[webservers]
web-[001:100].prod.internal

[appservers]
app-[001:150].prod.internal

[dbservers]
db-[001:050].prod.internal

[cacheservers]
redis-[001:030].prod.internal
memcache-[001:020].prod.internal

# 按照机房/可用区分组
[dc1]
web-[001:050].prod.internal
app-[001:075].prod.internal

[dc2]
web-[051:100].prod.internal
app-[076:150].prod.internal

# 定义更新批次(第一批是金丝雀,数量少)
[canary]
web-001.prod.internal
app-001.prod.internal
redis-001.prod.internal

[batch1]
web-[002:020].prod.internal
app-[002:030].prod.internal

[batch2]
web-[021:050].prod.internal
app-[031:075].prod.internal
# ... 后续批次类似

说明:主机清单的设计很关键。我们按照三个维度分组:业务类型、机房位置、更新批次。这样在执行时可以灵活控制范围,比如只更新某个机房,或者只更新某类服务器。

◆ 2.2.2 变量配置

# group_vars/all.yml
---
# 补丁更新相关配置
patching:
  # 是否允许重启
  allow_reboot: true
  # 重启前等待时间(秒)
  reboot_delay: 30
  # 重启超时时间(秒)
  reboot_timeout: 600
  # 更新后健康检查等待时间
  health_check_delay: 60
  # 排除的包(某些包不想自动更新)
  exclude_packages:
    - kernel*
    - docker*
  # 仅安全更新
  security_only: true

# 通知配置
notification:
  webhook_url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"
  enabled: true
# group_vars/dbservers.yml
---
# 数据库服务器特殊配置
patching:
  allow_reboot: false  # 数据库服务器默认不自动重启
  exclude_packages:
    - kernel*
    - mysql*
    - mariadb*

参数说明

  • allow_reboot:是否允许自动重启。数据库这类有状态服务建议设为 false,手动处理
  • reboot_timeout:重启超时时间,老机器启动慢的话需要调大
  • exclude_packages:排除列表,避免误更新关键组件
  • security_only:只安装安全补丁,不做全量更新

◆ 2.2.3 核心 Playbook

# playbooks/patching.yml
---
- name: 系统补丁更新 - 预检查
  hosts: "{{ target_hosts | default('all') }}"
  gather_facts: yes
  serial: "{{ batch_size | default(50) }}"
  tasks:
    - name: 检查磁盘空间
      assert:
        that:
          - ansible_mounts | selectattr('mount', 'equalto', '/') | map(attribute='size_available') | first | int > 1073741824
      fail_msg: "根分区剩余空间不足 1GB,跳过此主机"
      tags: precheck

    - name: 检查系统负载
      assert:
        that:
          - ansible_processor_vcpus > 0
          - (ansible_load_average.1 / ansible_processor_vcpus) < 2.0
      fail_msg: "系统负载过高,跳过此主机"
      tags: precheck

    - name: 记录更新前的包版本
      shell: |
        rpm -qa --queryformat '%{NAME}-%{VERSION}-%{RELEASE}\n' | sort > /tmp/packages_before_{{ ansible_date_time.date }}.txt
      when: ansible_os_family == "RedHat"
      tags: precheck

- name: 系统补丁更新 - 执行更新
  hosts: "{{ target_hosts | default('all') }}"
  gather_facts: yes
  serial: "{{ batch_size | default(50) }}"
  max_fail_percentage: 10
  pre_tasks:
    - name: 发送开始通知
      uri:
        url: "{{ notification.webhook_url }}"
        method: POST
        body_format: json
        body:
          msgtype: "text"
          text:
            content: "补丁更新开始: {{ inventory_hostname }} (批次 {{ ansible_play_batch }})"
      delegate_to: localhost
      when: notification.enabled | default(false)
      ignore_errors: yes
      run_once: yes

  tasks:
    - name: 更新 YUM 缓存
      yum:
        update_cache: yes
      when: ansible_os_family == "RedHat"

    - name: 安装安全补丁 (RHEL/CentOS)
      yum:
        name: '*'
        state: latest
        security: "{{ patching.security_only | default(true) }}"
        exclude: "{{ patching.exclude_packages | default([]) }}"
      register: yum_result
      when: ansible_os_family == "RedHat"

    - name: 更新 APT 缓存
      apt:
        update_cache: yes
        cache_valid_time: 3600
      when: ansible_os_family == "Debian"

    - name: 安装安全补丁 (Ubuntu/Debian)
      apt:
        upgrade: dist
        update_cache: yes
      register: apt_result
      when: ansible_os_family == "Debian"

    - name: 检查是否需要重启
      stat:
        path: /var/run/reboot-required
      register: reboot_required_file
      when: ansible_os_family == "Debian"

    - name: 检查是否需要重启 (RHEL)
      command: needs-restarting -r
      register: needs_restarting
      failed_when: false
      changed_when: false
      when: ansible_os_family == "RedHat"

    - name: 设置重启标志
      set_fact:
        needs_reboot: >-
          {{ (ansible_os_family == "Debian" and reboot_required_file.stat.exists | default(false)) or
             (ansible_os_family == "RedHat" and needs_restarting.rc == 1) }}

    - name: 重启服务器
      reboot:
        reboot_timeout: "{{ patching.reboot_timeout | default(600) }}"
        pre_reboot_delay: "{{ patching.reboot_delay | default(30) }}"
        post_reboot_delay: 30
        msg: "Ansible 补丁更新后重启"
      when:
        - needs_reboot | default(false)
        - patching.allow_reboot | default(true)

    - name: 等待服务恢复
      wait_for:
        port: "{{ item }}"
        timeout: 120
      loop: "{{ service_ports | default([22]) }}"
      when: needs_reboot | default(false)

  post_tasks:
    - name: 记录更新后的包版本
      shell: |
        rpm -qa --queryformat '%{NAME}-%{VERSION}-%{RELEASE}\n' | sort > /tmp/packages_after_{{ ansible_date_time.date }}.txt
        diff /tmp/packages_before_{{ ansible_date_time.date }}.txt /tmp/packages_after_{{ ansible_date_time.date }}.txt > /tmp/packages_diff_{{ ansible_date_time.date }}.txt || true
      when: ansible_os_family == "RedHat"

    - name: 健康检查
      uri:
        url: "http://localhost:{{ health_check_port | default(8080) }}/health"
        status_code: 200
        timeout: 30
      register: health_check
      retries: 3
      delay: 10
      until: health_check.status == 200
      when: health_check_port is defined
      ignore_errors: yes

    - name: 发送完成通知
      uri:
        url: "{{ notification.webhook_url }}"
        method: POST
        body_format: json
        body:
          msgtype: "text"
          text:
            content: "补丁更新完成: {{ inventory_hostname }} - 状态: {{ 'SUCCESS' if not (health_check.failed | default(false)) else 'FAILED' }}"
      delegate_to: localhost
      when: notification.enabled | default(false)
      ignore_errors: yes

2.3 启动和验证

◆ 2.3.1 执行补丁更新

# 先在金丝雀环境测试
ansible-playbook playbooks/patching.yml -e "target_hosts=canary" -e "batch_size=1" --check

# 确认无误后正式执行金丝雀批次
ansible-playbook playbooks/patching.yml -e "target_hosts=canary" -e "batch_size=1"

# 金丝雀通过后,分批次执行
ansible-playbook playbooks/patching.yml -e "target_hosts=batch1" -e "batch_size=10"
ansible-playbook playbooks/patching.yml -e "target_hosts=batch2" -e "batch_size=20"

# 或者一次性执行全部,由 serial 控制并发
ansible-playbook playbooks/patching.yml -e "target_hosts=all" -e "batch_size=30"

◆ 2.3.2 功能验证

# 查看执行日志
tail -f logs/ansible.log

# 检查更新结果汇总
ansible -i inventory/hosts.ini all -m shell -a "cat /tmp/packages_diff_*.txt 2>/dev/null | head -20" --limit 'web-001'

# 检查服务状态
ansible -i inventory/hosts.ini webservers -m shell -a "systemctl is-active nginx"
# 预期输出:每台机器都返回 active

三、示例代码和配置

3.1 完整配置示例

◆ 3.1.1 无人值守调度脚本

#!/bin/bash
# 文件路径:/opt/ansible-patching/run_patching.sh
# 功能:无人值守补丁更新调度脚本

set -e

WORK_DIR="/opt/ansible-patching"
LOG_DIR="${WORK_DIR}/logs"
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="${LOG_DIR}/patching_${DATE}.log"

cd ${WORK_DIR}

# 函数:发送通知
send_notification() {
    local message=$1
    local webhook_url="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"
    curl -s -X POST ${webhook_url} \
        -H 'Content-Type: application/json' \
        -d "{\"msgtype\": \"text\", \"text\": {\"content\": \"${message}\"}}" \
        > /dev/null 2>&1 || true
}

# 函数:执行单个批次
run_batch() {
    local batch_name=$1
    local batch_size=$2

    echo "[$(date)] 开始执行批次: ${batch_name}" | tee -a ${LOG_FILE}
    send_notification "[补丁更新] 开始执行批次: ${batch_name}"

    if ansible-playbook playbooks/patching.yml \
        -e "target_hosts=${batch_name}" \
        -e "batch_size=${batch_size}" \
        >> ${LOG_FILE} 2>&1; then
        echo "[$(date)] 批次 ${batch_name} 执行成功" | tee -a ${LOG_FILE}
        send_notification "[补丁更新] 批次 ${batch_name} 执行成功"
        return 0
    else
        echo "[$(date)] 批次 ${batch_name} 执行失败" | tee -a ${LOG_FILE}
        send_notification "[补丁更新] 批次 ${batch_name} 执行失败,请检查"
        return 1
    fi
}

# 主流程
main() {
    send_notification "[补丁更新] 开始执行,预计耗时 6-8 小时"

    # 金丝雀批次
    if ! run_batch "canary" 1; then
        send_notification "[补丁更新] 金丝雀批次失败,终止后续更新"
        exit 1
    fi

    # 等待 10 分钟观察金丝雀
    echo "[$(date)] 等待 10 分钟观察金丝雀环境..." | tee -a ${LOG_FILE}
    sleep 600

    # 后续批次
    local batches=("batch1:10" "batch2:20" "batch3:30" "batch4:50" "batch5:50")

    for batch_config in "${batches[@]}"; do
        batch_name="${batch_config%%:*}"
        batch_size="${batch_config##*:}"

        if ! run_batch "${batch_name}" "${batch_size}"; then
            send_notification "[补丁更新] 批次 ${batch_name} 失败,终止后续更新"
            exit 1
        fi

        # 批次间间隔 5 分钟
        echo "[$(date)] 批次间隔等待 5 分钟..." | tee -a ${LOG_FILE}
        sleep 300
    done

    send_notification "[补丁更新] 全部完成!请检查各服务状态"
}

main "$@"

◆ 3.1.2 定时任务配置

# /etc/cron.d/ansible-patching
# 每月第一个周六晚上 22:00 执行补丁更新
0 22 1-7 * 6 root /opt/ansible-patching/run_patching.sh

3.2 实际应用案例

◆ 案例一:紧急漏洞修复

场景描述:2024 年某天早上收到安全团队通知,某个 glibc 漏洞需要紧急修复,要求当天完成全网更新。

实现代码

# playbooks/emergency_patch.yml
---
- name: 紧急补丁修复
  hosts: "{{ target_hosts | default('all') }}"
  gather_facts: yes
  serial: 100  # 紧急情况提高并发
  tasks:
    - name: 仅更新指定包
      yum:
        name: "{{ emergency_packages }}"
        state: latest
      when: ansible_os_family == "RedHat"

    - name: 验证补丁版本
      shell: "rpm -q {{ item }}"
      loop: "{{ emergency_packages }}"
      register: version_check
      when: ansible_os_family == "RedHat"

    - name: 显示更新后版本
      debug:
        msg: "{{ version_check.results | map(attribute='stdout') | list }}"

运行命令

ansible-playbook playbooks/emergency_patch.yml \
  -e "target_hosts=all" \
  -e '{"emergency_packages": ["glibc", "glibc-common"]}' \
  --forks 100

运行结果

PLAY RECAP *********************************************************************
web-001.prod.internal      : ok=4    changed=1    unreachable=0    failed=0    skipped=0
web-002.prod.internal      : ok=4    changed=1    unreachable=0    failed=0    skipped=0
...
500 台服务器全部更新完成,耗时 45 分钟

◆ 案例二:内核升级与滚动重启

场景描述:需要升级内核修复某个性能问题,但必须保证业务不中断,采用滚动重启方式。

实现步骤

  1. 首先修改配置,允许内核更新和自动重启
  2. 将主机按照业务分组,确保每组重启时有其他组提供服务
  3. 使用 serial: 1 逐台执行,配合负载均衡摘除
# playbooks/kernel_upgrade.yml
---
- name: 内核升级 - 滚动更新
  hosts: "{{ target_hosts }}"
  gather_facts: yes
  serial: 1  # 逐台执行
  tasks:
    - name: 从负载均衡摘除
      uri:
        url: "http://{{ lb_api }}/api/v1/upstream/{{ inventory_hostname }}/down"
        method: POST
      delegate_to: localhost
      when: lb_api is defined

    - name: 等待连接排空
      wait_for:
        timeout: 60

    - name: 升级内核
      yum:
        name: kernel
        state: latest
      register: kernel_update

    - name: 重启服务器
      reboot:
        reboot_timeout: 900
        msg: "Ansible 内核升级重启"
      when: kernel_update.changed

    - name: 验证内核版本
      shell: uname -r
      register: kernel_version

    - name: 重新加入负载均衡
      uri:
        url: "http://{{ lb_api }}/api/v1/upstream/{{ inventory_hostname }}/up"
        method: POST
      delegate_to: localhost
      when: lb_api is defined

    - name: 等待流量恢复
      wait_for:
        timeout: 30

四、最佳实践和注意事项

4.1 最佳实践

◆ 4.1.1 性能优化

  • 开启 SSH Pipelining:减少 SSH 连接次数,大幅提升执行速度
# ansible.cfg
[ssh_connection]
pipelining = True
  • 调整 forks 数量:根据控制节点性能和网络情况调整并发数
    • 4 核 8G 的机器,forks 设置 50-100 比较合适
    • 网络带宽充足时可以适当调高
    • 更新包比较大时要降低,避免打满带宽
  • 使用 Mitogen 加速:Mitogen 是一个 Ansible 加速插件,实测能提升 2-5 倍速度
pip install mitogen
# ansible.cfg 添加
[defaults]
strategy_plugins = /path/to/mitogen/ansible_mitogen/plugins/strategy
strategy = mitogen_linear

◆ 4.1.2 安全加固

  • 使用 Vault 加密敏感信息
# 创建加密的变量文件
ansible-vault create group_vars/all/vault.yml
# 内容示例
vault_webhook_key: "your-secret-key"
vault_ssh_password: "your-password"
  • 限制 sudo 权限:运维账号的 sudoers 配置只开放必要权限
# /etc/sudoers.d/ops
ops ALL=(root) NOPASSWD: /usr/bin/yum, /usr/bin/apt, /usr/sbin/reboot, /usr/bin/systemctl
  • 审计日志:所有操作都要有日志记录,方便事后追溯

◆ 4.1.3 高可用配置

  • 多控制节点:部署多个 Ansible 控制节点,避免单点故障
  • AWX/Tower:生产环境建议使用 AWX 或 Ansible Tower,提供 Web 界面、权限控制、执行历史等功能
  • 备份 Playbook:将 Playbook 代码托管到 Git,做好版本管理

4.2 注意事项

◆ 4.2.1 配置注意事项

警告:补丁更新可能导致服务中断,务必在维护窗口执行,并提前做好回滚准备!

  • 注意事项一:数据库、消息队列等有状态服务,建议单独处理,不要混在批量更新里
  • 注意事项二:更新前一定要检查磁盘空间,空间不足会导致更新失败甚至系统损坏
  • 注意事项三:生产环境务必先在金丝雀/预发布环境验证,确认无问题再推全量

◆ 4.2.2 常见错误

错误现象 原因分析 解决方案
SSH 连接超时 目标机器 SSHD 服务异常或网络不通 检查网络连通性和 SSHD 服务状态
sudo 密码错误 密码过期或权限配置问题 检查 sudoers 配置,考虑使用 NOPASSWD
yum lock 错误 其他进程占用 yum 锁 kill 掉占用进程或等待其完成
重启后连接失败 启动时间过长或启动失败 增加 reboot_timeout,检查启动日志
包依赖冲突 第三方源与官方源冲突 使用 exclude 排除问题包,手动处理

◆ 4.2.3 兼容性问题

  • 版本兼容:CentOS 7 和 CentOS 8 的包管理命令有差异(yum vs dnf),Ansible 的 yum 模块会自动处理
  • 平台兼容:混合环境(RHEL + Ubuntu)需要用 when 条件判断,或者拆分成多个 playbook
  • 组件依赖:某些包更新后可能需要重启服务才能生效,需要在 playbook 中处理

五、故障排查和监控

5.1 故障排查

◆ 5.1.1 日志查看

# 查看 Ansible 执行日志
tail -f /opt/ansible-patching/logs/ansible.log

# 查看详细输出(调试用)
ansible-playbook playbooks/patching.yml -vvv

# 查看目标机器的 yum 日志
ssh web-001 "tail -100 /var/log/yum.log"

# 查看系统日志(排查重启问题)
ssh web-001 "journalctl -b -1 --no-pager | tail -100"

◆ 5.1.2 常见问题排查

问题一:部分主机执行失败但没有详细错误信息

# 单独对失败主机执行,增加详细输出
ansible-playbook playbooks/patching.yml -e "target_hosts=web-001" -vvv

解决方案

  1. 查看 -vvv 输出找到具体错误
  2. SSH 到目标机器手动执行命令验证
  3. 检查目标机器的系统日志

问题二:重启后服务没有自动恢复

# 检查服务状态
ansible -i inventory/hosts.ini webservers -m shell -a "systemctl status nginx"
# 检查服务是否设置了开机自启
ansible -i inventory/hosts.ini webservers -m shell -a "systemctl is-enabled nginx"

解决方案:确保关键服务都设置了 enable,在 playbook 中增加服务状态检查

问题三:某些包被跳过没有更新

  • 症状:yum 报告某些包没有更新,但实际上有新版本
  • 排查:检查 exclude 配置和 yum 仓库配置
  • 解决:确认包名没有被意外排除,检查仓库优先级

◆ 5.1.3 调试模式

# 开启 Ansible 调试模式
export ANSIBLE_DEBUG=1
ansible-playbook playbooks/patching.yml -vvv

# 使用 --step 逐步执行
ansible-playbook playbooks/patching.yml --step

# 从某个任务开始执行(之前任务跳过)
ansible-playbook playbooks/patching.yml --start-at-task="重启服务器"

5.2 性能监控

◆ 5.2.1 关键指标监控

# 监控 Ansible 控制节点资源
top -p $(pgrep -f ansible)

# 监控网络带宽使用
iftop -i eth0

# 监控执行进度
watch -n 5 'grep -c "ok=" /opt/ansible-patching/logs/ansible.log'

◆ 5.2.2 监控指标说明

指标名称 正常范围 告警阈值 说明
批次成功率 100% < 95% 单批次失败率超过 5% 需要人工介入
单机执行时间 3-10 分钟 > 30 分钟 执行时间过长可能有问题
控制节点 CPU < 50% > 80% CPU 过高需要降低 forks
网络带宽 < 70% > 90% 带宽打满需要降低并发

◆ 5.2.3 监控告警配置

# Prometheus 告警规则示例
groups:
  - name: ansible-patching
    rules:
      - alert: PatchingBatchFailed
        expr: ansible_batch_failed_hosts > 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "补丁更新批次失败"
          description: "批次 {{ $labels.batch }} 有 {{ $value }} 台主机失败"

5.3 备份与恢复

◆ 5.3.1 备份策略

#!/bin/bash
# 补丁更新前的快照备份脚本

HOSTS_FILE=$1
DATE=$(date +%Y%m%d)

# 对虚拟机创建快照(需要 vCenter API 或 cloud provider API)
while read host; do
    echo "Creating snapshot for ${host}..."
    # VMware 示例
    # govc vm.snapshot.create -vm="${host}" "pre-patching-${DATE}"
    # AWS 示例
    # aws ec2 create-snapshot --volume-id $(get_volume_id ${host}) --description "pre-patching-${DATE}"
done < ${HOSTS_FILE}

◆ 5.3.2 恢复流程

  1. 停止服务ansible -i inventory/hosts.ini target_host -m service -a "name=nginx state=stopped"
  2. 恢复快照:通过虚拟化平台或云平台恢复到补丁前的快照
  3. 验证完整性:启动服务器,检查服务状态和数据完整性
  4. 重启服务ansible -i inventory/hosts.ini target_host -m service -a "name=nginx state=started"

六、总结

6.1 技术要点回顾

  • 要点一:合理设计主机清单分组,支持灵活的灰度发布策略
  • 要点二:使用 serial 和 max_fail_percentage 控制更新节奏和容错
  • 要点三:更新前后做好检查和记录,便于追溯和回滚
  • 要点四:区分处理有状态和无状态服务,数据库等关键服务单独处理

6.2 进阶学习方向

  1. AWX/Ansible Tower:生产环境建议使用,提供更好的可视化和权限管理
  2. Ansible Collections:学习使用官方和社区的 Collection,避免重复造轮子
  3. 配合 CI/CD 流水线:将补丁更新集成到 GitOps 流程中
    • 学习资源:Jenkins/GitLab CI 与 Ansible 集成
    • 实践建议:补丁更新 playbook 提交到 Git,通过 MR 审批后自动执行

6.3 参考资料

  • Ansible 官方文档 - 最权威的参考
  • Red Hat 补丁管理最佳实践 - 企业级方案参考
  • Ansible for DevOps - 推荐书籍
  • r/ansible - 社区讨论



上一篇:杭州黑岩科技跨界开发战棋游戏《荒渊暗涌》:动画公司的单机游戏探索之路
下一篇:AI年度进展与AGI路径深度分析:技术瓶颈与经济影响展望
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-11 11:55 , Processed in 0.227701 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表