运维部署
使用 Ansible 做配置管理…
适用于需要通过 SSH 无代理、幂等地批量管理主机、部署应用或实现 IaC 的场景。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
使用 Ansible 做配置管理、应用部特定
解决思路
- 安装 Ansible:用 `pip install ansible`,Ubuntu/Debian 用 `sudo apt update && sudo apt install ansible`,RHEL/CentOS 用 `sudo yum install ansible`,最后用 `ansible --version` 验证。
- 按 Ansible 架构组织自动化:控制节点运行 Ansible,被管节点是目标系统,用 inventory 管理主机和组,用 playbook 写 YAML 自动化脚本,用 modules 执行具体工作,用 roles 做可复用单元,用 plugins 扩展功能。
- 利用关键特性:基于 SSH 无代理、操作幂等、声明式语法、人类可读 YAML、可用模块扩展、push 模式配置、并行执行。
- 把 Ansible 用于配置管理、应用部署、资源置备、持续交付、安全自动化和编排。
- 用 INI inventory:创建 `inventory/hosts`,定义 `[webservers]`、`[databases]`,在主机后设置 `ansible_host`、`ansible_user`,用 `[production:children]` 聚合组,用 `[production:vars]` 设置 `ansible_python_interpreter`、`ansible_connection`。
- 用 YAML inventory:创建 `inventory/hosts.yml`,按 `all.children.webservers.hosts`、`databases.hosts`、`production.children`、`production.vars` 结构定义主机、组变量和子组。
- 用动态 inventory:编写可执行脚本如 `inventory/aws_ec2.py`,用 boto3 查询 EC2 运行实例,输出 JSON,包含 `_meta.hostvars`、`all.hosts` 和按 Role 标签分组的组;设置 `ansible_host`、`instance_id`、`instance_type` 等 hostvars。
- 用 Jinja2 模板:创建 `templates/app.conf.j2`,用 `{{ app_name }}`、`{{ ansible_date_time.iso8601 }}`、`{{ ansible_default_ipv4.address }}`、`{{ app_port }}`、`{{ ansible_processor_vcpus }}` 等变量,用 `default` 过滤器、`lower` 过滤器、`{% if %}`、`{% for feature, enabled in features.items() %}` 生成配置文件。
- 按变量优先级从低到高覆盖:Role defaults、Inventory file/script group vars、Inventory group_vars/all、Playbook group_vars/all、Inventory group_vars/*、Playbook group_vars/*、Inventory file/script host vars、Inventory host_vars/*、Playbook host_vars/*、Host facts、Play vars、Play vars_prompt、Play vars_files、Role vars、Block vars、Task vars、Extra vars (-e flag)。
- 使用变量:在 play 中用 `vars` 定义 `app_name`、`app_version`,用 `vars_files` 引入 `vars/common.yml` 和 `vars/{{ environment }}.yml`。
- 用 `include_vars` 加载变量文件,如 `file: 'vars/{{ ansible_distribution }}.yml'`。
- 用 `set_fact` 设置事实,如 `full_app_name: '{{ app_name }}-{{ app_version }}'`。
- 用 `register` 保存命令输出,如 `command: hostname` 后 `register: hostname_output`,再通过 `{{ hostname_output.stdout }}` 使用。
- 用 `debug` 访问 facts:`ansible_distribution`、`ansible_distribution_version`、`ansible_kernel`、`ansible_processor_vcpus`、`ansible_memtotal_mb`、`ansible_default_ipv4.address`。
- 用 `ignore_errors: yes` 忽略可能失败的任务。
- 用 `block`/`rescue`/`always` 做错误处理:block 中尝试启动服务,rescue 中记录错误并尝试替代方案,always 中执行清理任务。
- 用 `assert` 校验条件,如 `ansible_memtotal_mb >= 2048`、`ansible_processor_vcpus >= 2`,并设置 `fail_msg`。
- 用 `fail` 在条件满足时主动失败,如 `environment == 'production'` 且 `app_version == 'latest'` 时失败。
- 用 `changed_when` 和 `failed_when` 自定义变更与失败判断,如 `changed_when: "'updated' in result.stdout"`、`failed_when: result.rc not in [0, 2]`。
- 用 Ansible Vault 管理密钥:`ansible-vault create secrets.yml` 创建、`ansible-vault edit secrets.yml` 编辑、`ansible-vault encrypt vars/production.yml` 加密已有文件、`ansible-vault decrypt vars/production.yml` 解密、`ansible-vault view secrets.yml` 查看、`ansible-vault rekey secrets.yml` 更换密码。
- 在 secrets 文件中用环境变量查找敏感值,如 `db_password: "{{ lookup('env', 'DB_PASSWORD') }}"`、`api_key: "{{ lookup('env', 'API_KEY') }}"`、`ssl_key: "{{ lookup('env', 'SSL_PRIVATE_KEY') }}"`;磁盘上保持密文,只在 `ansible-vault edit` 时明文,不要提交解密形式。
- 在 playbook 中用 `vars_files` 引入 `secrets.yml`,用 `no_log: yes` 避免记录敏感数据。
- 运行 playbook 时传入 Vault 密码:`ansible-playbook playbook.yml --ask-vault-pass`,或用 `--vault-password-file ~/.vault_pass`,或用多个 vault ID:`--vault-id prod@prompt --vault-id dev@~/.vault_dev`。
- 用 Molecule 测试 role:`pip install molecule molecule-docker`,在 `roles/myapp` 下 `molecule init scenario`,运行 `molecule test`,并按 `molecule create`、`molecule converge`、`molecule verify`、`molecule destroy` 工作流执行。
- 配置 `molecule/default/molecule.yml`:设置 `dependency.name: galaxy`、`driver.name: docker`、`platforms`(如 `ubuntu` 使用 `geerlingguy/docker-ubuntu2004-ansible` 且 `pre_build_image: yes`)、`provisioner.name: ansible`、`verifier.name: ansible`。
- 避免反模式并采用对应做法:用 roles 组织复用代码;能用模块时不要到处写 shell;用变量替代硬编码;用 blocks/rescue/always 做错误处理;用 Ansible Vault 存密钥;用 molecule 测试 role;保证任务幂等可重复运行;把复杂 playbook 拆成更小更专注的 playbook。
- 需要更细资料时按需读取:`references/BEST_PRACTICES.md`(Playbook 组织、幂等、性能、安全)、`references/PLAYBOOKS.md`(基础 Playbook、高级 Playbook、条件与循环)、`references/ROLES.md`(Role 结构、示例 Role、Role 依赖)。
- 参考资源:Ansible 文档 `https://docs.ansible.com/`、Ansible Galaxy `https://galaxy.ansible.com/`、Molecule `https://molecule.readthedocs.io/`、最佳实践 `https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html`。
适用边界 · 注意事项
- 目标主机不能通过 SSH 访问、没有可用 Python 解释器,或环境禁止无代理推送式配置时,不宜使用 Ansible。
- 需要实时事件驱动、持续在线收敛,或必须使用云厂商专有 IaC/图形化低代码平台且不允许自定义 YAML 与 SSH 凭据时,不宜使用。
- 只需要一次性简单命令、团队无法维护 playbook/role 测试与密钥管理时,不值得引入完整 Ansible 工作流。