Ansible 详细笔记
Ansible 详细笔记
一、Ansible 基础概述
1.1 定义与定位
Ansible 是由 Red Hat 主导开发的开源自动化运维工具,基于 Python 语言实现,专注于简化 IT 基础设施的配置管理、应用部署、任务编排等操作。它采用无代理架构,通过 SSH 协议与被控节点通信,避免了传统代理模式下的部署和维护成本。
1.2 核心优势
-
轻量易用:无需在被控节点安装客户端,仅需控制节点部署 Ansible 即可。
-
幂等性保障:相同操作多次执行结果一致,避免重复操作导致的系统异常。
-
模块化扩展:内置数千个模块,覆盖系统管理、云服务、网络设备等场景,同时支持自定义模块。
-
声明式配置:通过 YAML 格式的 Playbook 描述目标状态,而非具体操作步骤,降低学习和维护成本。
-
跨平台兼容:支持 Linux、Windows、macOS 等操作系统,以及 AWS、Azure、GCP 等云平台。
二、核心组件深度解析
2.1 控制节点(Control Node)
-
作用:运行 Ansible 命令和 Playbook,负责发起和管理自动化任务。
-
要求:需安装 Python 3.8+ 及 Ansible 软件包,可通过 SSH 连接被控节点。
-
注意:一个环境中可部署多个控制节点,但需确保 Inventory 和 Playbook 同步。
2.2 被控节点(Managed Node)
-
作用:被 Ansible 管理的目标设备,包括服务器、网络设备、虚拟机等。
-
要求:
-
开启 SSH 服务(Linux/Unix)或 WinRM 服务(Windows)。
-
安装 Python 2.7 或 3.5+(部分模块需特定版本支持)。
-
控制节点与被控节点之间网络可达,且控制节点拥有登录权限(密码或密钥认证)。
2.3 Inventory(主机清单)
-
定义:用于存储被控节点的信息,支持静态文件和动态生成两种方式。
-
静态 Inventory 格式:
# 简单主机列表
# 直接列出单个主机,Ansible将使用默认SSH端口(22)连接
webserver1.example.com# 带自定义端口的主机表示方式
# 格式:主机名:端口号,这里指定使用2222端口进行SSH连接
webserver2.example.com:2222 # 自定义SSH端口# 主机组定义
# [组名] 表示定义一个主机组
[webservers]
# 将以下主机加入webservers组
webserver1.example.com
webserver2.example.com[dbservers]
# 将以下主机加入dbservers组
dbserver1.example.com
dbserver2.example.com# 嵌套组
# :children 表示这是一个组的组(组包含其他组)
[all_servers:children]
# 将webservers组加入all_servers组
webservers
# 将dbservers组加入all_servers组
# 此时all_servers组包含了webservers和dbservers组中的所有主机
dbservers# 变量定义
# :vars 表示为该组定义变量,这些变量会应用到组内所有主机
[webservers:vars]
# 定义HTTP端口变量,可在Playbook中通过{{ http_port }}引用
http_port=80
# 定义最大请求数变量
max_requests=1000
- 动态 Inventory:通过脚本(如 Python、Shell)从云平台(AWS EC2、VMware)或 CMDB 中动态获取主机信息,适合大规模动态环境。
2.4 Module(模块)
-
分类:
-
核心模块(Core Modules):由 Ansible 官方维护,覆盖常见操作(如 copy、service、yum)。
-
扩展模块(Extras Modules):由社区贡献,需通过 ansible-galaxy 安装。
-
自定义模块:通过 Python 或其他语言编写,满足特定业务需求。
-
执行逻辑:模块以独立脚本形式在被控节点上临时运行,执行完成后自动清理,无需常驻内存。
2.5 Playbook(剧本)
-
结构:由一个或多个 Play 组成,每个 Play 包含目标主机、变量、任务等信息。
-
YAML 语法规则:
-
缩进使用空格(推荐 2 个空格),不支持 Tab。
-
列表项以 - 开头。
-
键值对用 key: value 表示,值为字符串时可加引号(特殊字符需加引号)。
-
示例:
- name: 部署 Nginx 服务hosts: webserversbecome: yes # 切换为root权限vars:nginx_version: 1.21.6tasks:- name: 安装 Nginxyum:name: "nginx-{{ nginx_version }}"state: present- name: 配置 Nginx 服务template:src: ./nginx.conf.j2dest: /etc/nginx/nginx.confnotify: 重启 Nginx 服务 # 配置文件变化时触发Handlerhandlers:- name: 重启 Nginx 服务service:name: nginxstate: restarted
2.6 Role(角色)
-
作用:将 Playbook、变量、模板、文件等按功能模块化,实现代码复用和标准化。
-
目录结构:
roles/
└── nginx/├── defaults/ # 默认变量(优先级低)│ └── main.yml├── vars/ # 角色变量(优先级高)│ └── main.yml├── tasks/ # 任务列表│ └── main.yml├── handlers/ # 处理器│ └── main.yml├── templates/ # 模板文件(.j2后缀)│ └── nginx.conf.j2└── files/ # 静态文件└── index.html
- 使用方式:在 Playbook 中通过 roles 关键字引用角色。
三、工作流程详解
- 准备阶段:
-
控制节点编写 Inventory,定义被控节点信息。
-
编写 Playbook 或准备临时命令,明确需要执行的任务。
- 执行阶段:
-
控制节点解析 Playbook 或命令,确定目标主机和模块。
-
通过 SSH/WinRM 连接被控节点,传输模块和参数。
-
被控节点执行模块,将结果(成功 / 失败、输出信息)返回给控制节点。
- 结果处理:
-
控制节点汇总所有被控节点的执行结果,以人类可读的格式展示。
-
若配置了 handlers 且任务触发了变化,执行相应的 handler 操作(如重启服务)。
四、安装与配置
4.1 控制节点安装(CentOS 7)
# 安装 EPEL 源
yum install -y epel-release# 安装 Ansible
yum install -y ansible# 验证安装
ansible --version
# 输出示例:
# ansible [core 2.14.3]
# 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.6/site-packages/ansible
# ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
# executable location = /usr/bin/ansible
# python version = 3.6.8 (default, Nov 16 2020, 16:55:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
# jinja version = 3.1.2
# libyaml = True
4.2 被控节点配置
- Linux 节点:
# 安装 Python
yum install -y python3# 配置 SSH 免密登录(控制节点操作)
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
ssh-copy-id root@被控节点IP
-
Windows 节点:
-
启用 WinRM 服务,配置 PowerShell 远程管理。
-
控制节点安装 pywinrm 模块:pip install pywinrm。
4.3 核心配置文件(ansible.cfg)
主要配置项:
[defaults]
inventory = /etc/ansible/hosts # 默认Inventory路径
remote_user = root # 默认远程用户名
become = yes # 自动切换为root权限
become_method = sudo # 提权方式
become_user = root # 目标用户
timeout = 30 # SSH连接超时时间(秒)
host_key_checking = False # 禁用主机密钥检查(测试环境用)
五、常用模块实战
5.1 文件操作模块
- copy:复制文件到被控节点
ansible webservers -m copy -a "src=/local/path/file dest=/remote/path/file mode=0644 owner=root group=root"
- file:管理文件 / 目录属性
# 创建目录
ansible webservers -m file -a "path=/data/logs state=directory mode=0755"
# 删除文件
ansible webservers -m file -a "path=/tmp/test.txt state=absent"
- template:基于 Jinja2 模板生成文件
# Playbook中使用
- name: 生成Nginx配置文件template:src: ./nginx.conf.j2dest: /etc/nginx/nginx.confmode: 0644
5.2 包管理模块
- yum(RedHat 系)
# 安装指定版本
ansible webservers -m yum -a "name=httpd-2.4.6 state=present"
# 卸载软件
ansible webservers -m yum -a "name=httpd state=absent"
# 更新所有包
ansible webservers -m yum -a "name=* state=latest"
- apt(Debian 系)
ansible dbservers -m apt -a "name=mysql-server state=installed update_cache=yes"
5.3 服务管理模块
- service
# 启动服务并设置开机自启
ansible webservers -m service -a "name=httpd state=started enabled=yes"
# 重启服务
ansible webservers -m service -a "name=httpd state=restarted"
5.4 命令执行模块
- command:不支持管道和环境变量
ansible all -m command -a "ls /home"
- shell:支持 bash 特性
ansible all -m shell -a "ps aux | grep nginx"
- script:在被控节点执行本地脚本
ansible webservers -m script -a "/local/path/script.sh arg1 arg2"
六、Playbook 高级特性
6.1 变量管理
-
变量来源:
-
Inventory 变量(主机 / 组变量)
-
Playbook 中 vars 关键字定义
-
命令行 -e 参数传递(优先级最高)
-
角色变量(defaults/vars)
-
变量引用:使用 {{ variable_name }} 语法,如 {{ http_port }}。
6.2 条件判断(when)
tasks:- name: 仅在CentOS系统安装httpdyum:name: httpdstate: presentwhen: ansible_os_family == "RedHat"
6.3 循环(loop)
tasks:- name: 创建多个目录file:path: "{{ item }}"state: directorymode: 0755loop:- /data/logs- /data/backup- /data/tmp
6.4 处理器(handlers)
用于在任务发生变化时执行操作(如配置文件更新后重启服务):
tasks:- name: 更新Nginx配置template:src: nginx.conf.j2dest: /etc/nginx/nginx.confnotify: 重启Nginx # 触发handlerhandlers:- name: 重启Nginxservice:name: nginxstate: restarted
七、常用命令详解
7.1 ansible
-
功能:执行临时命令,适合快速测试。
-
常用参数:
-
-i:指定 Inventory 文件路径。
-
-m:指定模块名称。
-
-a:模块参数。
-
-u:远程用户名。
-
-b:提权执行(sudo)。
-
示例:
ansible webservers -i ./my_hosts -u admin -b -m yum -a "name=httpd state=present"
7.2 ansible-playbook
-
功能:执行 Playbook。
-
常用参数:
-
-C/–check:模拟执行,不实际修改系统。
-
-v:显示详细输出(-vvv 最详细)。
-
-e:传递额外变量。
-
-t:只执行指定标签的任务。
-
示例:
ansible-playbook -C -e "env=test" deploy.yml
7.3 ansible-galaxy
-
功能:管理 Ansible 角色和集合。
-
常用命令:
# 安装角色
ansible-galaxy install geerlingguy.nginx
# 列出已安装角色
ansible-galaxy list
# 创建新角色
ansible-galaxy init myrole
八、高级应用场景
8.1 滚动更新(Rolling Updates)
通过 serial 关键字控制每次更新的主机数量,实现零 downtime 部署:
- name: 滚动更新Web服务hosts: webserversserial: 2 # 每次更新2台主机tasks:- name: 停止服务service:name: httpdstate: stopped- name: 部署新版本copy:src: ./new_version/dest: /var/www/html/- name: 启动服务service:name: httpdstate: started
8.2 集成云服务
以 AWS 为例,使用 amazon.aws 集合管理 EC2 实例:
- name: 创建EC2实例hosts: localhostgather_facts: nocollections:- amazon.awstasks:- name: 启动实例ec2:aws_access_key: "{{ aws_access_key }}"aws_secret_key: "{{ aws_secret_key }}"region: us-east-1instance_type: t2.microimage: ami-0c55b159cbfafe1f0count: 1key_name: my_keyvpc_subnet_id: subnet-123456assign_public_ip: yesstate: running
九、最佳实践与注意事项
- 目录结构标准化:
project/
├── inventory/ # 主机清单(按环境分文件)
│ ├── dev.yml
│ └── prod.yml
├── playbooks/ # 主Playbook
│ ├── deploy.yml
│ └── backup.yml
├── roles/ # 角色目录
│ ├── web/
│ └── db/
├── group_vars/ # 组变量
│ └── webservers.yml
├── host_vars/ # 主机变量
│ └── webserver1.yml
└── ansible.cfg # 项目级配置
- 变量加密:使用 ansible-vault 加密敏感信息(如密码、API 密钥):
# 创建加密文件
ansible-vault create secrets.yml
# 编辑加密文件
ansible-vault edit secrets.yml
# 执行Playbook时解密
ansible-playbook --ask-vault-pass deploy.yml
-
版本控制:将 Playbook、角色等代码纳入 Git 管理,实现变更追踪和协作。
-
测试策略:
-
使用 --check 模拟执行,验证逻辑正确性。
-
在测试环境完全验证后再部署到生产环境。
-
采用 Molecule 等工具进行角色单元测试。
- 性能优化:
- 启用 SSH 长连接(ControlPersist)