运维工作中,经常需要对几十台甚至上百台服务器执行相同的操作:安装软件包、修改配置文件、重启服务、部署应用、收集日志。如果手动登录每台服务器操作,效率低、容易出错,且无法追溯变更历史。
Ansible 是一款基于 SSH 的自动化运维工具,无需在目标服务器安装 Agent,通过 YAML 编写剧本(Playbook),实现批量配置管理、应用部署、任务编排。
这篇文章面向初中级运维工程师,从环境搭建到实战案例,逐步讲解如何使用 Ansible 管理 Linux 服务器。
Ansible 由以下组件组成:
yum、copy、service安装 Ansible ↓ 配置 SSH 免密登录 ↓ 编写 Inventory 清单 ↓ 测试连通性 ↓ 使用 Ad-Hoc 命令执行简单任务 ↓ 编写 Playbook 执行复杂任务 ↓ 使用 Role 组织可复用任务 ↓ 集成版本控制和 CI/CD ↓ 监控和日志收集 在控制节点(运维机器)上安装 Ansible。
bash
yum install epel-release -y yum install ansible -y bash
apt update apt install ansible -y bash
pip3 install ansible 验证安装:
bash
ansible --version 输出示例:
ansible [core 2.14.2] config file = /etc/ansible/ansible.cfg configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python3.9/site-packages/ansible ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections executable location = /usr/bin/ansible python version = 3.9.7 (default, Sep 16 2021, 1358) [GCC 8.5.0 20210514 (Red Hat 8.5.0-3)] jinja version = 3.1.2 libyaml = True Ansible 通过 SSH 连接目标服务器,建议配置免密登录。
生成 SSH 密钥对:
bash
ssh-keygen -t rsa -b 4096 -C "ansible@example.com" -f ~/.ssh/ansible_rsa -N "" 将公钥复制到目标服务器:
bash
ssh-copy-id -i ~/.ssh/ansible_rsa.pub root@192.168.1.10 ssh-copy-id -i ~/.ssh/ansible_rsa.pub root@192.168.1.11 ssh-copy-id -i ~/.ssh/ansible_rsa.pub root@192.168.1.12 测试免密登录:
bash
ssh -i ~/.ssh/ansible_rsa root@192.168.1.10 如果无需输入密码即可登录,说明配置成功。
配置 SSH 客户端使用该密钥:
编辑 ~/.ssh/config:
Host 192.168.1.* IdentityFile ~/.ssh/ansible_rsa User root StrictHostKeyChecking no UserKnownHostsFile=/dev/null Inventory 定义受控节点的列表,支持 INI 和 YAML 格式。
创建 /etc/ansible/hosts(默认位置):
ini
[webservers] web1 ansible_host=192.168.1.10 web2 ansible_host=192.168.1.11 [dbservers] db1 ansible_host=192.168.1.12 db2 ansible_host=192.168.1.13 [all:vars] ansible_user=root ansible_ssh_private_key_file=~/.ssh/ansible_rsa 或使用 YAML 格式:
yaml
all: children: webservers: hosts: web1: ansible_host: 192.168.1.10 web2: ansible_host: 192.168.1.11 dbservers: hosts: db1: ansible_host: 192.168.1.12 db2: ansible_host: 192.168.1.13 vars: ansible_user: root ansible_ssh_private_key_file: ~/.ssh/ansible_rsa 也可以使用自定义 Inventory 文件:
bash
ansible -i /path/to/inventory all -m ping
使用 ping 模块测试目标主机是否可达:
bash
ansible all -m ping 输出示例:
web1 | SUCCESS => { "changed": false, "ping": "pong" } web2 | SUCCESS => { "changed": false, "ping": "pong" } db1 | SUCCESS => { "changed": false, "ping": "pong" } db2 | SUCCESS => { "changed": false, "ping": "pong" }
如果显示 SUCCESS 和 pong,说明连接成功。
如果显示 UNREACHABLE,检查:
Ad-Hoc 命令用于快速执行单个任务,不需要编写 Playbook。
bash
ansible all -m setup 输出包含目标主机的详细信息,如操作系统、内核版本、IP 地址、CPU、内存等。
过滤输出:
bash
ansible all -m setup -a "filter=ansible_distribution*" 输出示例:
web1 | SUCCESS => { "ansible_facts": { "ansible_distribution": "CentOS", "ansible_distribution_major_version": "7", "ansible_distribution_release": "Core", "ansible_distribution_version": "7.9" }, "changed": false } bash
ansible all -m shell -a "uptime" 输出示例:
web1 | CHANGED | rc=0 >> 1025 up 10 days, 2:15, 1 user, load average: 0.08, 0.03, 0.05 web2 | CHANGED | rc=0 >> 1025 up 5 days, 8:45, 1 user, load average: 0.12, 0.05, 0.02 bash
ansible webservers -m yum -a "name=nginx state=present" name=nginx:软件包名称state=present:确保已安装state=absent:确保已卸载state=latest:确保是最新版本bash
ansible webservers -m service -a "name=nginx state=started enabled=yes" state=started:启动服务state=stopped:停止服务state=restarted:重启服务enabled=yes:设置开机自启bash
ansible webservers -m copy -a "src=/tmp/index.html dest=/usr/share/nginx/html/index.html owner=nginx group=nginx mode=0644" src:源文件路径(控制节点)dest:目标路径(受控节点)owner:文件所有者group:文件所属组mode:文件权限bash
ansible all -m user -a "name=deploy state=present shell=/bin/bash" state=present:确保用户存在state=absent:删除用户shell:默认 Shellgroups:附加组append=yes:追加到附加组,不覆盖现有组bash
ansible all -m file -a "path=/data/backup state=directory owner=root group=root mode=0755" state=directory:确保目录存在state=absent:删除目录或文件state=touch:创建空文件bash
ansible all -m get_url -a "url=https://example.com/file.tar.gz dest=/tmp/file.tar.gz mode=0644" bash
ansible all -m script -a "/tmp/init.sh" 脚本在控制节点,Ansible 会将其传输到目标主机并执行。
Playbook 是 YAML 格式的任务编排文件,支持变量、循环、条件判断、错误处理。
创建 install_nginx.yml:
yaml
--- - name: Install and configure Nginx hosts: webservers become: yes tasks: - name: Install Nginx yum: name: nginx state: present - name: Start and enable Nginx service: name: nginx state: started enabled: yes - name: Copy index.html copy: src: /tmp/index.html dest: /usr/share/nginx/html/index.html owner: nginx group: nginx mode: 0644 - name: Restart Nginx service: name: nginx state: restarted 执行 Playbook:
bash
ansible-playbook install_nginx.yml 输出示例:
PLAY [Install and configure Nginx] ********************************************* TASK [Gathering Facts] ********************************************************* ok: [web1] ok: [web2] TASK [Install Nginx] *********************************************************** changed: [web1] changed: [web2] TASK [Start and enable Nginx] ************************************************** changed: [web1] changed: [web2] TASK [Copy index.html] ********************************************************* changed: [web1] changed: [web2] TASK [Restart Nginx] *********************************************************** changed: [web1] changed: [web2] PLAY RECAP ********************************************************************* web1 : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 web2 : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 在 Playbook 中定义变量:
yaml
--- - name: Install packages hosts: all become: yes vars: packages: - vim - git - curl - wget tasks: - name: Install packages yum: name: "{{ item }}" state: present loop: "{{ packages }}" 或在 Inventory 中定义变量:
ini
[webservers] web1 ansible_host=192.168.1.10 nginx_port=80 web2 ansible_host=192.168.1.11 nginx_port=8080 在 Playbook 中使用:
yaml
--- - name: Configure Nginx hosts: webservers become: yes tasks: - name: Update Nginx config lineinfile: path: /etc/nginx/nginx.conf regexp: 'listens+d+;' line: " listen {{ nginx_port }};" backrefs: yes yaml
--- - name: Install package based on OS hosts: all become: yes tasks: - name: Install package on CentOS yum: name: httpd state: present when: ansible_distribution == "CentOS" - name: Install package on Ubuntu apt: name: apache2 state: present when: ansible_distribution == "Ubuntu" yaml
--- - name: Create multiple users hosts: all become: yes tasks: - name: Create users user: name: "{{ item }}" state: present loop: - user1 - user2 - user3
创建 Jinja2 模板 nginx.conf.j2:
nginx
server { listen {{ nginx_port }}; server_name {{ server_name }}; location / { root {{ document_root }}; index index.html; } } 在 Playbook 中使用:
yaml
--- - name: Deploy Nginx config hosts: webservers become: yes vars: nginx_port: 80 server_name: example.com document_root: /usr/share/nginx/html tasks: - name: Deploy config from template template: src: nginx.conf.j2 dest: /etc/nginx/conf.d/example.conf owner: root group: root mode: 0644 notify: Restart Nginx handlers: - name: Restart Nginx service: name: nginx state: restarted
Handlers 是特殊的任务,只有在被 notify 触发时才执行,且只执行一次。
yaml
--- - name: Update config and restart service hosts: webservers become: yes tasks: - name: Copy config file copy: src: /tmp/nginx.conf dest: /etc/nginx/nginx.conf notify: Restart Nginx - name: Copy another config copy: src: /tmp/vhost.conf dest: /etc/nginx/conf.d/vhost.conf notify: Restart Nginx handlers: - name: Restart Nginx service: name: nginx state: restarted
即使两个任务都触发了 Restart Nginx,Nginx 也只会重启一次。
忽略错误:
yaml
--- - name: Run command and ignore errors hosts: all tasks: - name: Stop service service: name: non_existent_service state: stopped ignore_errors: yes 注册变量并判断:
yaml
--- - name: Check if file exists hosts: all tasks: - name: Check file stat: path: /etc/myconfig.conf register: file_status - name: Print message if file exists debug: msg: "Config file exists" when: file_status.stat.exists Role 是 Ansible 的最佳实践,将任务、变量、模板、文件、Handlers 组织成目录结构,便于复用和维护。
roles/ └── nginx/ ├── tasks/ │ └── main.yml ├── handlers/ │ └── main.yml ├── templates/ │ └── nginx.conf.j2 ├── files/ │ └── index.html ├── vars/ │ └── main.yml ├── defaults/ │ └── main.yml └── meta/ └── main.yml tasks/main.yml:任务列表handlers/main.yml:Handlerstemplates/:Jinja2 模板files/:静态文件vars/main.yml:变量(优先级高)defaults/main.yml:默认变量(优先级低)meta/main.yml:元信息(依赖关系)
使用 ansible-galaxy 初始化 Role:
bash
ansible-galaxy init roles/nginx 输出:
- Role roles/nginx was created successfully
编辑 roles/nginx/tasks/main.yml:
yaml
--- - name: Install Nginx yum: name: nginx state: present - name: Deploy config template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf owner: root group: root mode: 0644 notify: Restart Nginx - name: Deploy index.html copy: src: index.html dest: /usr/share/nginx/html/index.html owner: nginx group: nginx mode: 0644 - name: Start and enable Nginx service: name: nginx state: started enabled: yes
编辑 roles/nginx/handlers/main.yml:
yaml
--- - name: Restart Nginx service: name: nginx state: restarted
编辑 roles/nginx/defaults/main.yml:
yaml
--- nginx_port: 80 server_name: localhost document_root: /usr/share/nginx/html
创建 roles/nginx/templates/nginx.conf.j2:
nginx
user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; server { listen {{ nginx_port }}; server_name {{ server_name }}; location / { root {{ document_root }}; index index.html; } } }
创建 roles/nginx/files/index.html:
html
html> <html> <head> <title>Welcometitle> head> <body> <h1>Nginx is runningh1> body> html>
创建 site.yml:
yaml
--- - name: Deploy Nginx hosts: webservers become: yes roles: - nginx 执行:
bash
ansible-playbook site.yml 在 Playbook 中覆盖变量:
yaml
--- - name: Deploy Nginx hosts: webservers become: yes roles: - role: nginx nginx_port: 8080 server_name: example.com
创建 site.yml:
yaml
--- - name: Configure web servers hosts: webservers become: yes roles: - common - nginx - php - monitoring - name: Configure database servers hosts: dbservers become: yes roles: - common - mysql - backup - monitoring Ansible Vault 用于加密敏感数据,如密码、密钥、证书。
创建 secrets.yml:
yaml
--- db_password: MySecretPassword123 api_key: abc123xyz456 加密文件:
bash
ansible-vault encrypt secrets.yml 输入密码后,文件内容被加密。
bash
ansible-vault view secrets.yml bash
ansible-vault edit secrets.yml bash
ansible-vault decrypt secrets.yml yaml
--- - name: Deploy application hosts: webservers become: yes vars_files: - secrets.yml tasks: - name: Configure database connection template: src: db_config.j2 dest: /etc/app/db.conf 执行时需要提供密码:
bash
ansible-playbook site.yml --ask-vault-pass 或使用密码文件:
bash
echo "MyVaultPassword" > .vault_pass chmod 600 .vault_pass ansible-playbook site.yml --vault-password-file .vault_pass 动态 Inventory 从云平台 API 或 CMDB 获取主机列表。
创建 dynamic_inventory.py:
python
#!/usr/bin/env python3 import json inventory = { "webservers": { "hosts": ["192.168.1.10", "192.168.1.11"] }, "dbservers": { "hosts": ["192.168.1.12"] }, "_meta": { "hostvars": {} } } print(json.dumps(inventory)) 赋予执行权限:
bash
chmod +x dynamic_inventory.py 测试:
bash
./dynamic_inventory.py 使用动态 Inventory:
bash
ansible -i dynamic_inventory.py all -m ping Ansible 支持多种云平台插件,如 AWS EC2、Azure、GCP、阿里云。
安装插件:
bash
ansible-galaxy collection install amazon.aws
创建 aws_ec2.yml:
yaml
--- plugin: amazon.aws.aws_ec2 regions: - us-east-1 filters: tag production keyed_groups: - key: tags.Role prefix: role 使用:
bash
ansible-inventory -i aws_ec2.yml --list ansible -i aws_ec2.yml all -m ping
编辑 /etc/ansible/ansible.cfg:
ini
[defaults] # Inventory 文件路径 inventory = /etc/ansible/hosts # 并发执行数量 forks = 10 # SSH 超时时间 timeout = 30 # 日志文件 log_path = /var/log/ansible.log # 禁用主机密钥检查 host_key_checking = False # 使用的传输方式 transport = ssh # 重试文件路径 retry_files_enabled = False # 角色路径 roles_path = /etc/ansible/roles # Gathering facts 策略 gathering = smart fact_caching = jsonfile fact_caching_connection = /tmp/ansible_facts fact_caching_timeout = 86400 [privilege_escalation] # 使用 sudo become = True become_method = sudo become_user = root become_ask_pass = False [ssh_connection] # SSH 参数 ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no pipelining = True
创建 deploy_webapp.yml:
yaml
--- - name: Deploy web application hosts: webservers become: yes vars: app_name: myapp app_version: v1.0.0 app_dir: /opt/{{ app_name }} app_user: www-data nginx_port: 80 tasks: - name: Install dependencies yum: name: - nginx - python3 - python3-pip - git state: present - name: Create app user user: name: "{{ app_user }}" system: yes shell: /sbin/nologin state: present - name: Create app directory file: path: "{{ app_dir }}" state: directory owner: "{{ app_user }}" group: "{{ app_user }}" mode: 0755 - name: Clone application from Git git: repo: https://github.com/example/myapp.git dest: "{{ app_dir }}" version: "{{ app_version }}" become_user: "{{ app_user }}" - name: Install Python dependencies pip: requirements: "{{ app_dir }}/requirements.txt" executable: pip3 - name: Deploy Nginx config template: src: nginx_webapp.conf.j2 dest: /etc/nginx/conf.d/{{ app_name }}.conf owner: root group: root mode: 0644 notify: Reload Nginx - name: Deploy systemd service template: src: webapp.service.j2 dest: /etc/systemd/system/{{ app_name }}.service owner: root group: root mode: 0644 notify: Restart webapp - name: Start and enable webapp service systemd: name: "{{ app_name }}" state: started enabled: yes daemon_reload: yes - name: Start and enable Nginx service: name: nginx state: started enabled: yes handlers: - name: Reload Nginx service: name: nginx state: reloaded - name: Restart webapp systemd: name: "{{ app_name }}" state: restarted daemon_reload: yes
创建模板 templates/nginx_webapp.conf.j2:
nginx
upstream {{ app_name }} { server 127.0.0.1:8000; } server { listen {{ nginx_port }}; server_name {{ ansible_hostname }}; access_log /var/log/nginx/{{ app_name }}_access.log; error_log /var/log/nginx/{{ app_name }}_error.log; location / { proxy_pass http://{{ app_name }}; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /static/ { alias {{ app_dir }}/static/; } }
创建模板 templates/webapp.service.j2:
ini
[Unit] Description={{ app_name }} web application After=network.target [Service] Type=simple User={{ app_user }} Group={{ app_user }} WorkingDirectory={{ app_dir }} ExecStart=/usr/bin/python3 {{ app_dir }}/app.py Restart=on-failure RestartSec=5s [Install] WantedBy=multi-user.target 执行部署:
bash
ansible-playbook deploy_webapp.yml
创建 rollback_webapp.yml:
yaml
--- - name: Rollback web application hosts: webservers become: yes vars: app_name: myapp app_dir: /opt/{{ app_name }} app_user: www-data rollback_version: v0.9.0 tasks: - name: Stop webapp service systemd: name: "{{ app_name }}" state: stopped - name: Checkout previous version git: repo: https://github.com/example/myapp.git dest: "{{ app_dir }}" version: "{{ rollback_version }}" force: yes become_user: "{{ app_user }}" - name: Install Python dependencies pip: requirements: "{{ app_dir }}/requirements.txt" executable: pip3 - name: Start webapp service systemd: name: "{{ app_name }}" state: started - name: Wait for service to be ready wait_for: port: 8000 delay: 2 timeout: 30 - name: Test service health uri: url: http://127.0.0.1:8000/health status_code: 200 register: health_check retries: 3 delay: 2 - name: Print rollback status debug: msg: "Rollback to {{ rollback_version }} successful" when: health_check.status == 200 执行回滚:
bash
ansible-playbook rollback_webapp.yml -e "rollback_version=v0.9.0" Ansible 日志默认不开启,需要在配置文件中启用:
ini
[defaults] log_path = /var/log/ansible.log 查看日志:
bash
tail -f /var/log/ansible.log
使用 -v、-vv、-vvv 增加详细程度:
bash
ansible-playbook site.yml -vvv -v:显示任务执行结果-vv:显示任务执行详情和连接信息-vvv:显示完整调试信息,包括 SSH 命令-vvvv:显示连接插件调试信息
使用 --check 模拟执行,不实际修改目标主机:
bash
ansible-playbook site.yml --check
使用 --diff 显示配置文件的变更内容:
bash
ansible-playbook site.yml --check --diff 只对部分主机执行:
bash
ansible-playbook site.yml --limit webservers ansible-playbook site.yml --limit web1,web2 ansible-playbook site.yml --limit 192.168.1.10
使用 profile_tasks 回调插件:
编辑 /etc/ansible/ansible.cfg:
ini
[defaults] callback_whitelist = profile_tasks 执行 Playbook 后会显示每个任务的执行时间。
使用 json 回调插件生成 JSON 格式报告:
bash
ANSIBLE_STDOUT_CALLBACK=json ansible-playbook site.yml > report.json 执行 Playbook ↓ 任务失败 ↓ 查看错误信息 ↓ 如果是连接失败: 检查 SSH 连接 检查防火墙 检查 Inventory 配置 ↓ 如果是模块执行失败: 检查目标主机是否满足前置条件 检查模块参数是否正确 检查权限是否足够 使用 -vvv 查看详细日志 ↓ 如果是幂等性问题: 检查任务是否重复执行 使用 changed_when 控制变更状态 ↓ 如果是性能问题: 调整并发数 forks 开启 pipelining 开启 fact caching ↓ 记录问题和解决方案 风险:
批量执行命令可能影响生产环境。
预防措施:
--check 和 --diff 模拟执行--limit 限制执行范围,先在测试环境验证yaml
- name: Confirm before proceeding pause: prompt: "Press Enter to continue or Ctrl+C to abort" serial 控制批量执行的并发数:yaml
--- - name: Deploy application hosts: webservers serial: 1 tasks: - name: Deploy code git: repo: https://github.com/example/myapp.git dest: /opt/myapp 这样每次只操作一台主机,发现问题可及时中止。
风险:
SSH 私钥泄露会导致所有受控节点被入侵。
预防措施:
bash
chmod 600 ~/.ssh/ansible_rsa 风险:
YAML 格式错误导致执行失败。
预防措施:
ansible-playbook --syntax-check 检查语法:bash
ansible-playbook site.yml --syntax-check ansible-lint 检查最佳实践:bash
pip3 install ansible-lint ansible-lint site.yml 风险:
变量优先级不清楚,导致使用错误的值。
优先级(从高到低):
-evarsvars/main.ymldefaults/main.yml预防措施:
使用 ansible-playbook site.yml -e "debug=yes" 打印变量:
yaml
- name: Debug variables debug: var: nginx_port 风险:
多次执行 Playbook 产生不同结果。
预防措施:
yum、service、copy)而非命令式模块(shell、command)creates 和 removes 参数控制执行条件:yaml
- name: Extract archive unarchive: src: /tmp/app.tar.gz dest: /opt/ creates: /opt/app/bin/app changed_when 控制变更状态:yaml
- name: Check service status shell: systemctl is-active nginx register: result changed_when: false failed_when: result.rc != 0 bash
ansible all -m ping bash
ansible webservers -m shell -a "rpm -qa | grep nginx" bash
ansible webservers -m shell -a "systemctl status nginx" bash
ansible webservers -m shell -a "nginx -t" bash
ansible webservers -m uri -a "url=http://localhost:80 status_code=200" 对比配置文件内容:
bash
ansible webservers -m shell -a "md5sum /etc/nginx/nginx.conf" 所有主机的 MD5 应该一致。
在修改配置文件前备份:
yaml
- name: Backup config before change copy: src: /etc/nginx/nginx.conf dest: /etc/nginx/nginx.conf.bak.{{ ansible_date_time.epoch }} remote_src: yes - name: Update config template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf notify: Reload Nginx 回滚时恢复备份:
yaml
- name: Restore config from backup copy: src: /etc/nginx/nginx.conf.bak.1234567890 dest: /etc/nginx/nginx.conf remote_src: yes notify: Reload Nginx 卸载软件包:
bash
ansible webservers -m yum -a "name=nginx state=absent" 安装指定版本:
bash
ansible webservers -m yum -a "name=nginx-1.20.1 state=present" 使用 Git 回滚到指定版本,参考前文回滚 Playbook 示例。
将 Playbook、Role、Inventory 纳入 Git 管理:
bash
git init git add . git commit -m "Initial commit" 每次变更提交到 Git,便于追溯和回滚。
使用不同的 Inventory 文件管理不同环境:
inventories/ ├── production/ │ ├── hosts │ └── group_vars/ │ └── all.yml ├── staging/ │ ├── hosts │ └── group_vars/ │ └── all.yml └── development/ ├── hosts └── group_vars/ └── all.yml 执行时指定 Inventory:
bash
ansible-playbook site.yml -i inventories/production/hosts 在任务中添加标签:
yaml
- name: Install Nginx yum: name: nginx state: present tags: install - name: Configure Nginx template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf tags: configure 只执行特定标签的任务:
bash
ansible-playbook site.yml --tags install ansible-playbook site.yml --tags configure ansible-playbook site.yml --skip-tags install 集成监控系统,记录 Playbook 执行结果:
使用 json 回调插件输出结果,解析后写入监控系统。
使用 Ansible Tower 或 AWX 提供 Web 界面和 API。
检查:
在配置文件中设置:
ini
[defaults] forks = 10 或在 Playbook 中设置:
yaml
--- - name: Deploy application hosts: webservers serial: 5 tasks: - name: Deploy code git: repo: https://github.com/example/myapp.git dest: /opt/myapp Ansible Tower(商业版)和 AWX(开源版)提供:
安装 AWX:
bash
git clone https://github.com/ansible/awx.git cd awx/installer ansible-playbook -i inventory install.yml bash
# 测试连通性 ansible all -m ping # 查看主机信息 ansible all -m setup ansible all -m setup -a "filter=ansible_distribution*" # 执行命令 ansible all -m shell -a "uptime" ansible all -m command -a "df -h" # 安装软件 ansible webservers -m yum -a "name=nginx state=present" # 启动服务 ansible webservers -m service -a "name=nginx state=started enabled=yes" # 复制文件 ansible webservers -m copy -a "src=/tmp/index.html dest=/usr/share/nginx/html/" # 创建用户 ansible all -m user -a "name=deploy state=present" # 创建目录 ansible all -m file -a "path=/data state=directory" bash
# 执行 Playbook ansible-playbook site.yml # 检查语法 ansible-playbook site.yml --syntax-check # 模拟执行 ansible-playbook site.yml --check # 显示变更内容 ansible-playbook site.yml --check --diff # 限制执行范围 ansible-playbook site.yml --limit webservers ansible-playbook site.yml --limit web1 # 指定标签 ansible-playbook site.yml --tags install ansible-playbook site.yml --skip-tags configure # 传递变量 ansible-playbook site.yml -e "nginx_port=8080" ansible-playbook site.yml -e "@vars.yml" # 使用 Vault ansible-playbook site.yml --ask-vault-pass ansible-playbook site.yml --vault-password-file .vault_pass # 增加详细输出 ansible-playbook site.yml -v ansible-playbook site.yml -vvv # 指定 Inventory ansible-playbook site.yml -i inventories/production/hosts bash
# 列出所有主机 ansible-inventory --list # 列出主机(YAML 格式) ansible-inventory --list -y # 列出指定组的主机 ansible-inventory --list --limit webservers # 查看主机变量 ansible-inventory --host web1 bash
# 加密文件 ansible-vault encrypt secrets.yml # 查看加密文件 ansible-vault view secrets.yml # 编辑加密文件 ansible-vault edit secrets.yml # 解密文件 ansible-vault decrypt secrets.yml # 修改密码 ansible-vault rekey secrets.yml bash
# 初始化 Role ansible-galaxy init roles/nginx # 安装 Role ansible-galaxy install geerlingguy.nginx # 从文件安装 Role ansible-galaxy install -r requirements.yml # 列出已安装 Role ansible-galaxy list # 删除 Role ansible-galaxy remove geerlingguy.nginx Ansible 是运维自动化的利器,无需 Agent,基于 SSH,易于上手。
核心概念:
实施路径:
最佳实践:
--check 和 --diff 模拟执行--limit 限制执行范围serial 控制并发风险控制:
changed_when 控制幂等性Ansible 的核心是幂等性和声明式,描述期望状态,Ansible 自动判断是否需要变更。多练习,积累经验,才能驾驭大规模环境的批量管理。
全部0条评论
快来发表一下你的评论吧 !