使用 Ansible 管理服务器集群

参见:How To Write Ansible Playbooks | DigitalOcean

典型项目结构

ansible-project/
├── ansible.cfg                # Ansible 配置文件
├── production                 # 生产环境主机清单
├── staging                    # 测试环境主机清单
├── group_vars/                # 组变量
│   ├── group1.yml
│   └── group2.yml
├── host_vars/                 # 主机变量
│   ├── hostname1.yml
│   └── hostname2.yml
├── roles/                     # 角色目录
│   ├── common/                # 通用角色
│   │   ├── tasks/main.yml
│   │   ├── handlers/main.yml
│   │   ├── templates/
│   │   ├── files/
│   │   ├── vars/main.yml
│   │   ├── defaults/main.yml
│   │   └── meta/main.yml
│   ├── webserver/
│   └── database/
├── playbooks/                 # Playbook 文件
│   ├── site.yml               # 主 playbook
│   ├── webservers.yml
│   └── databases.yml
├── filter_plugins/            # 自定义过滤器
├── callback_plugins/          # 自定义回调插件
├── library/                   # 自定义模块
├── requirements.yml           # Ansible Galaxy 依赖
└── README.md                  # 项目文档

参见:Sample Ansible setup | Ansible Community Documentation

Inventory

Ansible 使用 /etc/ansible/hosts 管理受控服务器列表:

---
ungrouped:
  hosts:
    node-1:
      ansible_host: 192.168.1.1
      ansible_user: john
    node-2:
      ansible_host: 192.168.1.2
      ansible_user: jane
    node-3:
      ansible_host: 192.168.1.3
      ansible_user: frank

关于 inventory 文件的字段说明,参见:Building an inventory | Ansible Core Documentation

ansible-inventory --list  # 列出 inventory

执行远程命令

Ansible 可以以如下方式临时执行一条远程命令:

ansible <group> -m ping                        # 测试连接
ansible <group> -m shell -a "df -h"            # 执行命令
ansible <group> -m copy -a "src=src dest=tgt"  # 上传文件

Playbook

对于复杂命令,可以通过 playbook 定义并执行:

---
- name: Create user
- hosts: ungrouped
  become: true
  tasks:
    - name: Update all packages
      ansible.builtin.apt:
        upgrade: dist

    - name: Greeting
      ansible.builtin.shell: "echo 'Hello, world!'"

关于 playbook 的字段说明,参见:Using Ansible playbooks | Ansible Core Documentation

运行 playbook:

ansible-playbook -bK playbook.yml              # 执行 playbook (sudo)
ansible-playbook -C playbook.yml -e "arg=val"  # 干运行
ansible-playbook --syntax-check playbook.yml   # 语法检查
  • -a:args,指定操作参数
  • -b:become,启用权限提升
  • -K:请求权限提升密码
  • -i:指定 inventory 文件

register

register 可以用来保存命令输出结果。

- name: command
  command: ls -la /home
  register: result

- name: debug
  debug:
    var: result.stdout
  • stdout: 标准输出内容
  • stderr: 标准错误内容
  • stdout_lines: 标准输出按行分割的列表
  • stderr_lines: 标准错误按行分割的列表
  • rc: 返回码
  • changed: 是否发生变化

模板

templates/test.j2:

My name is {{ ansible_facts['hostname'] }}

test.yml:

---
- name: Write hostname
  hosts: all
  tasks:
  - name: write hostname using jinja2
    ansible.builtin.template:
       src: templates/test.j2
       dest: /tmp/hostname

参考:

配置

Ansible 默认配置文件为 ansible.cfg~/.ansible.cfg

[defaults]
# 默认远程用户
remote_user = ubuntu
# 远程 Python 解释器
interpreter_python = auto_silent
# 请求 SSH 登录密码
ask_pass = False
# 私钥路径
;private_key_file = /home/ubuntu/.ssh/id_ed25519
# 检查主机密钥
host_key_checking = True
# 最大并发线程数
forks = 5
# 输出详细程度(0-4)
verbosity = 0
# 库存文件路径
inventory = hosts
# 密码文件路径
vault_password_file = .vault_pass

[privilege_escalation]
# 提权
become = True
# 提权用户
become_user = root
# 提权方法
become_method = sudo
# 请求提权密码
become_ask_pass = True
ansible-config view                    # 查看配置
ansible-config init --disabled -t all  # 生成默认配置

Troubleshooting

临时文件权限错误

问题描述:执行下面的任务时,提示:“Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user”。

- name: Install miniconda3
  shell: |
    bash /home/share/miniconda.sh -bup /home/{{ username }}/.local/opt/miniconda3
    /home/{{ username }}/.local/opt/miniconda3/bin/conda init bash
  become_user: "{{ username }}"
TASK [Install miniconda3] ********************************************************************************************************************************
[ERROR]: Task failed: Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chmod: invalid mode: ‘A+user:john:rx:allow’
Try 'chmod --help' for more information.
}). For information on working around this, see https://docs.ansible.com/ansible-core/2.19/playbook_guide/playbooks_privilege_escalation.html#risks-of-becoming-an-unprivileged-user
Origin: /ansible/create_user.yml:72:7

70     #     state: present
71
72     - name: Install miniconda3
         ^ column 7

fatal: [h101]: FAILED! => {"changed": false, "msg": "Task failed: Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chmod: invalid mode: ‘A+user:john:rx:allow’\nTry 'chmod --help' for more information.\n}). For information on working around this, see https://docs.ansible.com/ansible-core/2.19/playbook_guide/playbooks_privilege_escalation.html#risks-of-becoming-an-unprivileged-user"}

问题原因:ansible 尝试使用 ACL 语法运行 chmod:chmod A+user:john:rx:allow,然而当前系统不支持 ACL。

解决方法:安装 ACL

sudo apt install acl
posted @ 2025-09-18 02:35  Undefined443  阅读(10)  评论(0)    收藏  举报