Ansible 自动化运维
概述
Playbook 编写、角色管理、动态 inventory 等技能。
基础命令
Ad-hoc 命令
测试连通性
ansible all -m ping ansible webservers -m ping
执行命令
ansible all -m command -a "uptime" ansible all -m shell -a "df -h | grep /dev"
复制文件
ansible all -m copy -a "src=/local/file dest=/remote/file"
安装软件
ansible all -m apt -a "name=nginx state=present" --become ansible all -m yum -a "name=nginx state=present" --become
管理服务
ansible all -m service -a "name=nginx state=started" --become
收集信息
ansible all -m setup ansible all -m setup -a "filter=ansible_distribution*"
常用参数
-i inventory # 指定 inventory -m module # 指定模块 -a arguments # 模块参数 -b, --become # 提权 -K # 询问 sudo 密码 -u user # 指定用户 -k # 询问 SSH 密码 --limit host # 限制主机 -v, -vv, -vvv # 详细输出 --check # 检查模式(不执行) --diff # 显示差异
Inventory
静态 inventory
inventory/hosts
[webservers] web1.example.com web2.example.com ansible_host=192.168.1.10
[dbservers] db1.example.com ansible_user=admin db2.example.com
[production:children] webservers dbservers
[all:vars] ansible_python_interpreter=/usr/bin/python3
YAML 格式
inventory/hosts.yml
all: children: webservers: hosts: web1.example.com: web2.example.com: ansible_host: 192.168.1.10 dbservers: hosts: db1.example.com: ansible_user: admin vars: ansible_python_interpreter: /usr/bin/python3
动态 inventory
使用脚本
ansible-inventory -i inventory.py --list
AWS EC2
ansible-inventory -i aws_ec2.yml --list
示例 aws_ec2.yml
plugin: amazon.aws.aws_ec2 regions:
- us-east-1 filters: tag:Environment: production keyed_groups:
- key: tags.Role prefix: role
Playbook
基础结构
playbook.yml
-
name: Configure web servers hosts: webservers become: yes vars: http_port: 80
tasks:
-
name: Install nginx apt: name: nginx state: present update_cache: yes
-
name: Start nginx service: name: nginx state: started enabled: yes
-
name: Copy config template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf notify: Restart nginx
handlers:
- name: Restart nginx service: name: nginx state: restarted
-
执行 Playbook
执行
ansible-playbook playbook.yml
指定 inventory
ansible-playbook -i inventory/hosts playbook.yml
限制主机
ansible-playbook playbook.yml --limit web1
检查模式
ansible-playbook playbook.yml --check --diff
指定标签
ansible-playbook playbook.yml --tags "install,config" ansible-playbook playbook.yml --skip-tags "test"
传递变量
ansible-playbook playbook.yml -e "version=1.0" ansible-playbook playbook.yml -e "@vars.yml"
条件与循环
tasks:
条件
-
name: Install on Debian apt: name: nginx when: ansible_os_family == "Debian"
-
name: Install on RedHat yum: name: nginx when: ansible_os_family == "RedHat"
循环
- name: Install packages
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- git
- curl
字典循环
- name: Create users
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
loop:
- { name: 'user1', groups: 'admin' }
- { name: 'user2', groups: 'developers' }
变量与模板
vars/main.yml
http_port: 80 server_name: example.com workers: 4
templates/nginx.conf.j2
server { listen {{ http_port }}; server_name {{ server_name }};
{% for upstream in upstreams %}
upstream {{ upstream.name }} {
{% for server in upstream.servers %}
server {{ server }};
{% endfor %}
}
{% endfor %}
}
Roles
角色结构
roles/ └── nginx/ ├── tasks/ │ └── main.yml ├── handlers/ │ └── main.yml ├── templates/ │ └── nginx.conf.j2 ├── files/ ├── vars/ │ └── main.yml ├── defaults/ │ └── main.yml └── meta/ └── main.yml
创建角色
创建角色骨架
ansible-galaxy init roles/nginx
使用角色
playbook.yml
- hosts: webservers
become: yes
roles:
- nginx
- { role: app, tags: ['app'] }
- role: database vars: db_name: mydb
Ansible Galaxy
安装角色
ansible-galaxy install geerlingguy.nginx ansible-galaxy install -r requirements.yml
requirements.yml
roles:
- name: geerlingguy.nginx version: 3.1.0
- name: geerlingguy.mysql
collections:
- name: community.general
常见场景
场景 1:部署应用
-
name: Deploy application hosts: appservers become: yes vars: app_version: "1.0.0"
tasks:
-
name: Pull code git: repo: https://github.com/user/app.git dest: /opt/app version: "{{ app_version }}"
-
name: Install dependencies pip: requirements: /opt/app/requirements.txt virtualenv: /opt/app/venv
-
name: Copy systemd service template: src: app.service.j2 dest: /etc/systemd/system/app.service notify: Restart app
handlers:
- name: Restart app systemd: name: app state: restarted daemon_reload: yes
-
场景 2:滚动更新
-
name: Rolling update hosts: webservers serial: 1 # 每次更新一台 max_fail_percentage: 0
tasks:
-
name: Remove from load balancer
...
-
name: Update application
...
-
name: Add back to load balancer
...
-
场景 3:密钥管理
创建加密文件
ansible-vault create secrets.yml
编辑加密文件
ansible-vault edit secrets.yml
加密现有文件
ansible-vault encrypt vars.yml
解密
ansible-vault decrypt vars.yml
使用加密变量
ansible-playbook playbook.yml --ask-vault-pass ansible-playbook playbook.yml --vault-password-file=.vault_pass
故障排查
问题 排查方法
SSH 连接失败 检查 inventory、SSH 配置
权限不足 使用 --become 、检查 sudo
模块错误 使用 -vvv 查看详情
变量未定义 检查变量文件、优先级
调试模式
ansible-playbook playbook.yml -vvv
检查语法
ansible-playbook playbook.yml --syntax-check
列出任务
ansible-playbook playbook.yml --list-tasks
列出主机
ansible-playbook playbook.yml --list-hosts