一、特点

Ansible 的设计理念是 “简单、自动化、可扩展”,核心特点如下:

  1. 无代理架构(Agentless)
    无需在被管理节点安装任何 Agent 软件,仅依赖目标机器的 SSH(默认)或 WinRM 服务,减少了对目标系统的侵入性,降低了运维复杂度
  2. 基于 SSH/WinRM 协议
    Linux/Unix 节点默认使用 SSH 协议通信(支持密码或密钥认证),Windows 节点通过 WinRM 协议通信,无需额外开放端口,安全性高
  3. 声明式语法(YAML)
    核心配置文件(Playbook)采用 YAML 格式编写,语法简洁易懂,人类可读性强,即使是非开发背景的运维人员也能快速上手
  4. 幂等性
    任务执行结果具有 “幂等性”—— 即多次执行同一任务,最终结果一致(不会因重复执行导致异常)。例如:“确保 nginx 服务已启动”,无论执行多少次,结果都是 “nginx 启动”
  5. 模块化设计
    所有操作通过 “模块(Module)” 实现(如yum模块安装软件、copy模块复制文件、service模块管理服务),Ansible 官方提供超过 2000 个内置模块,同时支持自定义模块
  6. 支持多环境与变量
    通过 “inventory”(主机清单)划分不同环境(如开发、测试、生产),支持变量(全局变量、主机变量、组变量),可灵活适配不同场景
  7. 可扩展性
    支持 “角色(Role)” 封装复用(将复杂任务拆分为可复用的角色),通过 “Ansible Galaxy”(官方社区)共享角色;同时支持 API 集成,可与 Jenkins、GitLab、Prometheus 等工具联动

二、Ansible 核心架构与组件

Ansible 的架构简单轻量,主要包含控制节点和被管理节点两类角色,以及多个核心组件:

  1. 角色划分
  • 控制节点
    安装 Ansible 的机器,负责编写 Playbook、执行任务、管理被管理节点。仅需在控制节点安装 Ansible,被管理节点无需安装。
  • 被管理节点
    需被自动化管理的目标机器(如 Web 服务器、数据库服务器等),仅需开启 SSH或 WinRM服务,并确保控制节点能访问
  1. 核心组件详解
组件名称 作用说明
Host Inventory 主机清单,定义ansible管理的主机
/etc/ansible/hosts
Modules 实现一个个功能的程序,本质上就是一个一个的py文件,别人写好的程序
Plugins 依附于ansible的一个小软件,实现某个小功能,模块功能的补充
Playbooks 任务编排文件(YAML 格式),让主机清单里的主机去批量完成的任务,是 Ansible 自动化的核心

三、安装ansible

Ansible安装包在epel源中,需先配置epel源
yum install epel-release -y
yum install ansible -y

确认安装

[root@dns-nfs-prom-ansible ~]# ansible --version
ansible [core 2.14.18]
  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.21 (main, Feb 10 2025, 00:00:00) [GCC 11.5.0 20240719 (Red Hat 11.5.0-5)] (/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True

四、主机清单

位置:/etc/ansible/hosts

格式

# Ex 1: Ungrouped hosts, specify before any group headers:

## green.example.com
## blue.example.com
## 192.168.100.1
## 192.168.100.10

# Ex 2: A collection of hosts belonging to the 'webservers' group:

## [webservers]
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110

4.1 不配置免密通道

需指定user、passwd和端口(非22号默认端口)

[root@dns-nfs-prom-ansible ansible]# vim hosts 
[web]
192.168.168.136 ansible_ssh_user='root' ansible_ssh_pass='123456'
192.168.168.137 ansible_ssh_user='root' ansible_ssh_pass='123456'

[LB]
192.168.168.133  ansible_ssh_port=2233 ansible_ssh_user='root' ansible_ssh_pass='123456'
192.168.168.132  ansible_ssh_user='root' ansible_ssh_pass='123456'

[db]
192.168.168.140:2233
ansible_ssh_user='root' ansible_ssh_pass='123456'

密码是明文的,不推荐


4.2 配置免密通道(推荐)

ssh-keygen
ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.168.136

[root@dns-nfs-prom-ansible ansible]# vim hosts 
[web]
192.168.168.136
192.168.168.137

[LB]
192.168.168.133:2233
192.168.168.132

[db]
192.168.168.140:2233

4.3 子组和变量

# 子组,通过children关键字将其他组列为该组的子组,对该组的操作会在子组的每个节点上进行
[nodes:children]    
web
LB

# 组变量,统一定义组内变量,all代表所有组,可以单指定某个组
[all:vars]		
ansible_ssh_port=22
ansible_ssh_user=root		# 相当于指定密码的第二种方式
ansible_ssh_pass='123456'

ansible_become变量在hosts使用

这些选项通常在hosts中定义,但可以用作正常变量来使用

(1)ansible_become
相当于成为指令,决定是否使用特权升级

(2)ansible_become_method
允许设置权限升级方法

(3)ansible_become_user
允许通过权限升级来设置你成为用户,记得同时使用ansible_become:true

(4)ansible_become_pass
假如要使用root账户,则这里要写的就是root账户的密码!

一般用来先登录普通用户,再从普通用户切换为root用户

下面是使用su的方式提升权限

[web1]
192.168.168.136

[web1:vars]
ansible_ssh_user = tang  
ansible_ssh_pass = '123123'  #tang用户的密码
ansible_become_user = root
ansible_become = true 
ansible_become_method = su
ansible_become_pass = '123456'  #root用户的密码

使用sudo方法提升权限

将feng用户授权,可以使用sudo命令执行linux命令
[root@web1 sshd_config.d]# vim /etc/sudoers
feng ALL=(ALL) ALL #添加这一行

[web1]
192.168.168.136
[web1:vars]
ansible_ssh_user = feng
ansible_ssh_pass = '123456789'  #feng用户的密码
ansible_become_user = root
ansible_become = true 
ansible_become_method = sudo
ansible_become_pass = '123456789'  
#也是feng用户的密码,因为sudo执行命令的时候,输入的密码,不是root用户的密码

在ansible机器上执行命令,测试效果

[root@dns-nfs-prom-ansbile ansible]# ansible web1 -m shell -a “date”
192.168.100.158 | CHANGED | rc=0 >>
2025年 09月 03日 星期三 15:03:28 CST


五、模块的使用

ansible模块比较多,可以通过 ansible-doc 显示帮助信息
ansible-doc -l 获取所有当前版本下的可用模块及简要信息
ansible-doc -s 模块名 获取指定模块帮助信息说明,包括支持参数

[root@dns-nfs-prom-ansbile ansible]# ansible-doc -s shell
- name: Execute shell commands on targets
  shell:
      chdir:                 # Change into this directory before running the command.
      cmd:                   # The command to run followed by optional arguments.
      creates:               # A filename, when it already exists, this step will *not* be run.
      executable:            # Change the shell used to execute the command. This expects an
                             # absolute path to the executable.
      free_form:             # The shell module takes a free form command to run, as a string.
                             # There is no actual parameter named
                             # 'free form'. See the examples on how
                             # to use this module.
      removes:               # A filename, when it does not exist, this step will *not* be run.
      stdin:                 # Set the stdin of the command directly to the specified value.
      stdin_add_newline:     # Whether to append a newline to stdin data.

-m:指定要使用的模块
-a:指定模块的参数

5.1 copy 模块

将ansible服务器上的文件复制到远程服务器上,即可以拷贝文件也可以拷贝文件夹

[root@@dns-nfs-prom-ansbile ~]# ansible web -m copy -a “src=/root/test.sh dest=/root”
[root@dns-nfs-prom-ansbile ~]# ansible LB -m copy -a “src=/root/test.sh dest=/root mode=600”

src本地源文件,dest目标目录,如目标文件存在默认覆盖
mode 指定文件拷贝到远程主机后的权限

注意src= 路径后面带/ 表示带里面的所有内容复制到目标目录下,不带/是目录递归复制过去

5.2 script 模块

可以在远程主机上执行本地主机的脚本。脚本将在控制节点上进行复制,然后通过SSH传输到远程主机并在那里执行。执行完毕后会删除脚本

[root@dns-nfs-prom-ansible ansible]# ansible web -m script -a “/root/test.sh”

5.3 fetch 模块

从远程主机拉取文件到本地,与copy相反

fetch的src指定的路径是一个文件,而不是目录

[root@dns-nfs-prom-ansible ansible]# ansible webnodes -m fetch -a “src=/etc/passwd dest=/tmp”

5.4 command 模块

默认模块,可以忽略-m选项

不支持重定向、管道符等,/ARNAME<>|;&等可以用shell模块实现

[root@dns-nfs-prom-ansible ~]# ansible all -a “chdir=/root/ ls”

chdir=/root/表示进入到指定目录下,类似于cd命令

5.5 shell 模块

和command相似,用shell执行命令支持重定向和管道符

执行命令中如果有变量则需要用单引号引起来

[root@dns-nfs-prom-ansible ~]# ansible LB -m shell -a "cat /etc/passwd|grep ss"
192.168.168.133 | CHANGED | rc=0 >>
dbus:x:81:81:System message bus:/:/sbin/nologin
sssd:x:998:996:User for sssd:/:/sbin/nologin
tss:x:59:59:Account used for TPM access:/:/usr/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/usr/share/empty.sshd:/usr/sbin/nologin
192.168.168.132 | CHANGED | rc=0 >>
dbus:x:81:81:System message bus:/:/sbin/nologin
sssd:x:998:998:User for sssd:/:/sbin/nologin
tss:x:59:59:Account used for TPM access:/:/usr/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/usr/share/empty.sshd:/usr/sbin/nologin

[root@dns-nfs-prom-ansible ~]# ansible LB -a "cat /etc/passwd|grep ss"
192.168.168.133 | FAILED | rc=1 >>
cat: '/etc/passwd|grep': 没有那个文件或目录
cat: ss: 没有那个文件或目录non-zero return code
192.168.168.132 | FAILED | rc=1 >>
cat: '/etc/passwd|grep': 没有那个文件或目录
cat: ss: 没有那个文件或目录non-zero return code

5.6 file 模块

设置文件属性/创建文件/删除文件
常用参数:

  • path -> 目标路径
  • state -> directory为目录,file指更新文件(默认),link为软链接,touch为创建文件,hard为硬链接,absent为删除文件
  • src -> 当修改文件是软链接时,用于指定源文件路径
  • group -> 目录属组
  • owner -> 属主
  • mode -> 权限
  • recurse=yes 递归修改目录文件的属性

其他参数可通过ansible-doc -s file 获取

创建目录

[root@dns-nfs-prom-ansible ~]# ansible all -m file -a “path=/var/tmp/hello.dir state=directory”
[root@dns-nfs-prom-ansible ~]# ansible all -m file -a “path=/a/b/c state=directory”

5.7 service 模块

服务管理模块,管理远程主机上的服务
常用参数:

  • name:服务名
  • state:服务状态 started、restarted、stopped、reloaded
    enabled: yes|no -> 是否开机启动
  • runlevel:启动级别 (systemed方式忽略) 2|3|4|5 如果设定了enabled开机自启,则要定义在哪些运行级别下自动启动

[root@dns-nfs-prom-ansbile ~]# ansible LB -m service -a “name=crond state=started enabled=yes”
[root@dns-nfs-prom-ansbile ~]# ansible LB -m service -a “name=crond state=stopped enabled=no”

5.8 systemd 模块

同样是服务管理模块,相当于systemctl命令

常用参数:

  • name:指定服务的名称
  • state:控制服务状态,可以是 started、stopped、restarted、reloaded 等
  • daemon_reload:是否执行systemctl daemon-reload重新加载服务,可以是 yes 或 no

systemd模块与service模块的主要区别是:

  • systemd模块是推荐在最近的系统中使用,如RHEL 7、Debian 9等发行版
  • service模块可兼容较老的init系统,如RHEL 6等

总之,systemd模块是更推荐的选择,可以对系统服务进行状态管理及开机启动的控制。重启服务时加上daemon_reload可以确保服务的配置生效

[root@dns-nfs-prom-ansible ~]# ansible LB -m systemd -a “name=crond state=restarted enabled=yes daemon_reload=yes”

5.9 yum 模块

常用参数说明:

  • enablerepo=,disablerepo=表示在yum安装时临时启用与禁用某个repo仓库,指明仓库的ID
  • name 安装软件包名,可以带上版本号,不指明版本即为默认版本,多个包可以用","分隔
  • state (present’ or installed’, latest’)表示安装, (absent’ or `removed’) 表示删除
  • conf_file 指定yum运行时采用的配置文件,而不采用默认配置文件
  • disable_gpg_check=yes|no 是否启用gpg-check

[root@dns-nfs-prom-ansbile ~]# ansible LB -m yum -a “name=tree state=present”
[root@dns-nfs-prom-ansbile ~]# ansible LB -m yum -a “name=tree state=removed”

ubuntu 为 apt 模块

5.10 template 模块

在Ansible中,“template” 模块是用于渲染Jinja2模板的核心模块

通过将模板与变量结合,可以根据每台主机的变量渲染成不同的文件;只能通过playbook使用,因为命令行不会收集facts变量

常用于生成配置文件、脚本以及其他需要动态生成内容的文件

基本语法

- name: Render a template
  template:
  	src: path/to/template.j2
  	dest: /path/to/output/file

使用 src 参数指定要渲染的模板文件,dest 参数指定要生成的输出文件的路径

模板文件通常使用 .j2.jinja2 扩展名,并使用Jinja2模板语法编写

Jinja2 是一种模板引擎,主要用于生成动态内容(如配置文件、HTML 页面等),其语法基于 Python,包含以下独特的标记规则:

  • 变量用双大括号包裹:{{ variable }}
  • 控制结构(条件、循环等)用 {% %} 包裹:{% if condition %}、{% for item in list %}
  • 注释用 {# #} 包裹:{# 这是Jinja2注释 #}

总结

Ansible 是一款由 Red Hat 主导开发的开源自动化工具,主要用于配置管理、应用部署、任务编排和 IT 基础设施自动化。它基于 Python 开发,采用 “无代理(Agentless)” 架构,通过 SSH 协议(Linux/Unix)或 WinRM(Windows)与目标节点通信,无需在被管理机器上安装额外客户端,极大降低了部署和维护成本

其他自动化运维工具

  • Puppet:一种成熟的配置管理工具,采用客户端 - 服务器架构,有自己独特的声明式语言。客户端定期向服务器请求配置信息并执行相应任务,在大规模企业级环境中应用广泛,能有效管理复杂的配置环境,确保配置的一致性
  • Chef:基于 Ruby 开发,以灵活性著称,使用 Cookbook 和 Recipe 的概念来组织配置管理内容。它支持多种平台,客户端在被管理节点上执行配置任务,通过与 Chef 服务器交互获取配置信息
  • SaltStack:基于 Python 语言,由 Salt Master 和 Salt Minions 客户端组成,采用推送式配置管理,具有并行执行命令的能力,执行效率高,扩展性和灵活性强,适用于大规模主机管理场景
工具 Ansible Puppet Chef SaltStack
架构模式 无代理 C/S C/S C/S
通信协议 SSH(默认)、WinRM HTTPS HTTPS ZeroMQ(消息队列)、SSH
配置语法 YAML(Playbook)
简洁易懂,类自然语言
自定义声明式语言(Puppet DSL)
语法较独特
Ruby 语法(Cookbook/Recipe)
偏编程风格
YAML(States)、Jinja2 模板
支持 Python 扩展
执行方式 推送式
控制节点主动触发任务
拉取式
Agent 定期向服务器拉取配置
拉取式
Client 定期拉取配置
推送式为主
支持拉取模式
幂等性 天然支持(模块设计保证) 天然支持(声明式语言特性) 需手动实现(依赖开发者经验) 天然支持
并行效率 中等(默认串行,可通过 forks 优化并行数) 较低(Agent 轮询拉取,串行执行) 中等(Client 并行拉取,依赖配置) 极高(ZeroMQ 异步通信,原生支持大规模并行)
学习曲线 平缓(YAML 易读,适合新手) 较陡(需学习自定义 DSL) 较陡(需掌握 Ruby 语法) 中等(YAML 基础 + 部分 Python 知识)
社区生态 活跃(Red Hat 支持,模块数量多) 成熟(企业级用户多,文档完善) 活跃(Ruby 社区支持,插件丰富) 活跃(云原生场景适配好)
典型适用场景 中小规模环境、快速自动化、混合云管理 大规模企业级环境、严格合规性要求 复杂定制化场景、开发者主导的运维 超大规模集群(如千级节点)、实时响应需求
敏感信息管理 Ansible Vault(文件级加密) Hiera(层级化数据存储,支持加密) Data Bags(加密存储) Pillar(加密数据存储)

核心差异总结:

  1. 架构复杂度:
    Ansible 无代理架构最轻量化,部署和维护成本最低;Puppet、Chef、SaltStack 需在被管理节点安装客户端,初期部署稍复杂,但长期管理大规模节点时更可控
  2. 语法风格:
    Ansible 的 YAML 语法对非开发人员更友好;Chef 依赖 Ruby 编程,更适合有开发背景的团队;Puppet 的自定义 DSL 需专门学习;SaltStack 兼顾 YAML 简洁性和 Python 扩展性
  3. 执行效率:
    SaltStack 基于 ZeroMQ 异步通信,并行效率最高,适合超大规模节点管理;Ansible 因 SSH 协议开销,在数千节点场景下效率较低;Puppet/Chef 拉取式架构效率中等,但稳定性强
  4. 灵活性:
    Chef 和 SaltStack 更适合复杂定制化需求(如自定义模块开发);Ansible 和 Puppet 更侧重标准化配置,减少人为干预

选择建议:

  • 若团队以运维人员为主、追求快速上手:优先选 Ansible
  • 若需管理超大规模节点(如数千台服务器):优先选 SaltStack
  • 若企业有严格合规性要求、需长期稳定运行:可考虑 Puppet
  • 若团队熟悉 Ruby 开发、需高度定制化:可考虑 Chef
Logo

更多推荐