使用 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.builtin.template module | Ansible Community Documentation
- How To Create and Use Templates in Ansible Playbooks | DigitalOcean
配置
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

浙公网安备 33010602011771号