Ansible
一、Ansible概述
(一)、简介
-
Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。
-
它用Python写成,类似于saltstack和Puppet,但是我们不需要在节点中安装任何客户端。
-
它使用SSH来和节点进行通信。Ansible基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用YMAL 及 Jinja2模板语言,更强的远程命令执行操作。
(二)、特点
- 部署简单,没有客户端,只需在主控端部署Ansible环境,被控端无需做任何操作
- 管理方便,支持大批量主机的并发控制
- 无需客户端,仅仅通过ssh连接,基于端口进行远程控制。
- 安全性高,针对所管理执行内容进行审计评估
- 可扩展性强,支持任何动态语言的扩展模块
- 具有幂等性:一个操作在一个主机上执行一遍和执行N遍的结果是一样的
(三)、企业常见的批量管理服务应用
- Ansible
- Saltstack
- Puppet
- Chef
- jumpserver
项目 | Puppet | Saltstack | Ansible |
---|---|---|---|
开发语言 | RUby | Python | Python |
是否有客户端 | 有 | 有 | 无 |
是否支持二次开发 | 否 | 是 | 是 |
是否相互验证 | 是 | 是 | 是 |
是否加密 | SSL协议 | AES协议 | ssh密钥对 |
是否有web UI | 是 | 是 | 支持tower(商业性,一次10台) |
配置文件格式 | Ruby | yaml | yaml |
是否支持命令行执行 | 否 | 是 | 是 |
(四)、Ansible程序结构
Ansible | 核心框架 |
---|---|
Core Modules | ansible自带的模块 |
Custom Modules | 核心模块功能不足时,用户可以添加扩展模块 |
Plugins | 通过插件来实现记录日志,发送邮件或其他功能 |
Playbooks | 剧本,YAML格式文件,多个任务定义在一个文件中,定义主机需要调用哪些模块来完成的功能 |
Connectior Plugins | ansible基于连接插件连接到各个主机上,默认是使用ssh |
Host Inventory | 记录由Ansible管理的主机信息,包括端口、密码、ip等 |
(五)、Ansible执行逻辑
二、Ansible安装及基本使用
(一)、安装
# yum安装Ansible
yum -y install ansible
# 查看Ansible的版本
ansible --version
# 主配置文件
/etc/ansible/ansible.cfg
# 主机清单
/etc/ansible/hosts
(二)、配置主机清单
1、直接配置主机清单
# 编辑主机清单文件
[root@manager ansible]# vim /etc/ansible/hosts
[web] # 定义主机组名
10.0.0.7 # 主机ip
10.0.0.8 # 主机ip
# 生成秘钥对
[root@manager ansible]# ssh-keygen
# 推送公钥
[root@manager ansible]# ssh-copy-id -i /root/.ssh/id_rsa.pub 172.16.1.7
[root@manager ansible]# ssh-copy-id -i /root/.ssh/id_rsa.pub 172.16.1.8
# 测试是否连通
[root@manager ansible]# ansible web -m ping
172.16.1.7 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
yes # 注意,如果是第一次远程连接该主机,需要在此处输入yes用来生成指纹文件,不要按回车
172.16.1.8 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
2、通过参数传递ssh认证信息
# 编辑主机清单文件
[root@manager ansible]# vim /etc/ansible/hosts
[web]
10.0.0.7 ansible_ssh_user=root ansible_ssh_pass=123 ansible_ssh_port=22
10.0.0.8 ansible_ssh_user=root ansible_ssh_pass=123 ansible_ssh_port=22
# ansible_ssh_user=root 指定用户
# ansible_ssh_pass=123 指定密码
# ansible_ssh_port=22 指定端口,默认端口可不添加
3、通过设置变量传递参数
# 编辑主机清单文件
[root@manager ansible]# vim /etc/ansible/hosts
[web]
10.0.0.7
10.0.0.8
[web:vars] # 指定连接信息的变量,注意“vars”不能更改
ansible_ssh_user=root
ansible_ssh_pass=123
ansible_ssh_port=22
4、通过主机组定义子组
# 编辑主机清单文件
[root@manager ansible]# vim /etc/ansible/hosts
[web:children] # 注意“children”不可以更改
web01
web02
[web01]
10.0.0.7
[web02]
10.0.0.8
[web:vars]
ansible_ssh_user=root
ansible_ssh_pass=123
ansible_ssh_port=22
三、Ansible的常用核心模块
(一)、基本使用
- 语法格式
- ansible 目标主机 -m 模块名 -a “模块的内置参数”
- 查找帮助
- ansible-doc 模块名
- 颜色含义
- 粉色:警告
- 红色:执行失败
- 绿色:执行成功,但是未对目标节点做任何修改操作
- 黄色:执行成功,真实修改了目标节点的数据
- 蓝色:跳过
- Ansible命令运行方式及常用参数和常用模块
(二)、command和shell模块
- command
- 作用:直接执行指定的shell命令
- 例:ansible web -m command -a ‘rm -rf /babifen’
- shell模块
- 作用:直接执行指定的shell命令
- 例:ansible web -m shell -a ‘rm -rf /babifen’
- shell模块与command模块的区别
- shell模块支持通配符,command不支持
- shell多了executable模块。默认使用的执行环境为sh,加入executable模块,可以指定执行环境为bash
(三)、copy模块
1、功能
远程传输功能,将本地文件传输到受控主机
2、常用参数
- backup # 在传输具有相同名称文件时,覆盖源文件前,先备份一下源文件,以时间戳命名
- src # 指定所需传输的文件路径
- dest # 指定所需拷贝到目标主机的路径
- mode # 指定传递到目标主机后的文件权限
- owner # 指定传递到目标主机后的文件的所有者信息,注意会覆盖原文件
- content # 对指定文件修改文件内容
- group # 指定传递到目标主机后的文件的属组信息
- remote_src # yes则远程在目标主机本机执行复制操作
- force # 默认强制覆盖,no则如果有同名文件,则不覆盖
## 例
ansible web -m copy -a "src=/etc/hostname dest=/ mode=777 owner=michael group=michael backup=yes remote_src=yes force=no"
(四)、file模块
1、功能
设置文件的属性,实现在目标主机创建指定的对象(文件、目录或链接文件等,在文件中写入内容)
2、常用参数
- path # 用于指定目标主机路径
- state # 指定动作
- absent # 代表当前在path中所指定的路径要删除
- directory # 代表当前在path中所指定的路径要作为目录去创建
- touch # 代表当前在path中所指定的路径要作为文件去创建
- hard # 代表当前在path中所指定的路径作为硬连接,src指定目标主机源文件
- link # 代表当前在path中所指定的路径作为软连接,src指定目标主机源文件
- src # 指定需要创建的源文件路径
- recuse # 递归创建目录和修改权限
- force # 如果目标主机存在同名文件,则覆盖
- mode # 定义文件目录的权限
- group # 定义文件的属组
- owner # 定义文件的属主
## 例
# 创建软连接
ansible web -m file -a 'src=/backup path=/backup_ying state=link'
# 创建硬连接
ansible web -m file -a 'src=/backup/ansible.txt path=/backup/ansible_ying state=hard'
# 在远程主机创建目录
ansible web -m file -a "path=/backup state=directory"
(五)、user模块
1、作用
管理远程主机上的用户,比如创建用户、修改用户、删除用户、为用户创建密钥对等操作。
2、常用参数
- name # 指定用户名
- home # 指定用户家目录位置
- shell # 指定shell解析器
- uid # 指定用户uid
- state # 指定动作
- present # 创建用户
- absent # 删除用户
## 例
# 批量删除nginx用户
ansible web -m user -a "name=nginx state=absent"
# 创建nginx用户,不创建家目录,不登录shell
ansible web -m user -a "name=nginx state=present create_home=no shell=/sbin/nologin uid=5438"
(六)、yum模块
1、作用
管理系统中的dnf仓库及管理软件,7的系统要用yum,8的系统用dnf
2、常用参数
- autoremove # 彻底删除
- name # 指定安装的服务名称
- state # 指定动作
- present # 安装
- latest # 更新
- absent # 删除
## 例
ansible web -m yum -a "name=cowsay,sl,telnet,net-tools,bash-completion state=present"
(七)、service模块
1、作用
管理系统服务状态
2、常用参数
- name # 指定服务名称
- enabled # 设定服务开机是否启动,yes开启启动,no开机不启动
- state # 指定动作
- reloaded # 平滑重启
- restarted # 重启
- started # 启动
- stopped # 停止
## 例
# 通过service管理php-fpm
ansible web -m service -a "name=php-fpm state=started enabled=yes"
(八)、unarchive模块
1、作用
实现解压缩功能
2、常用参数
- src # 指定本地的压缩包路径
- dest # 指定目标主机路径
- remote_src # 在远程主机本机找源文件
## 例
# 将本机的一个压缩包传输到目标主机并解压
ansible web -m unarchive -a "src=/root/test.tar.gz dest=/opt"
# 远程将目标主机的压缩包解压
ansible web -m unarchive -a "src=/root/jy.tar.gz dest=/opt remote_src=yes"
(九)、archive模块
1、作用
作用: 打包模块
2、常用参数
- dest # 目标打包到的路径
- path # 指定需要被打包的文件或目录
## 例
ansible web -m archive -a “path=/etc/hostname dest=/host.tar.gz”
(十)、cron模块
1、作用
用于对目标主机设置定时任务
2、常用参数
- name # 指定定时任务名字
- minute # 分
- hour # 时
- day # 日
- month # 月
- weekday # 周
- job #定时任务命令
- state # 指定动作
- present #
- absent #
- disabled # 禁用某一个任务
## 例
# 每月3号,凌晨3:00 创建一个/test.txt文件
ansible web -m cron -a "name='没什么卵用' minute=0 hour=3 day=3 job='touch /test.txt' state=present"
(十一)、mount模块
1、作用
挂载设备
2、常用参数
- src # 指定挂载的设备路径
- path # 挂载点信息
- fstype # 指定文件系统类型
- backup # 永久挂载前,备份
- state # 指定动作
- absent # 取消永久挂载并卸载当前挂载
- mounted # 挂载并永久写入fstab
- present # 不会立即挂载,设置永久挂载
- unmounted # 取消挂载 但是不清除fstab配置
## 例
ansible web -m mount -a "src=172.16.1.31:/data fstype=nfs path=/mnt state=present backup=true"
(十二)、script模块
1、作用
远程执行脚本
2、常用参数
- chdir # 执行对应的脚本之前,会先进入到chdir参数指定的目录中
## 例
ansible web -m script -a "脚本路径"
四、playbook
(一)、简介
类似于shell脚本,可以将N条ansible集成到一个文件中,基于yaml语言编写
(二)、注意事项
- 必须严格限制缩进,每一层级必须空两格
- 在yaml语法中有层级的概念,级与级包含,同一级的可以不缩进
- 每个冒号后要空一格
- yaml语言不识别tab键的缩进
(三)、剧本书写方式
1、基本写法
---
- hosts: web # 此处可以定义多个主机组,需要用逗号隔开
gather_facts: no # 在执行剧本任务之前,探测一下目标主机的基本信息
tasks:
- name: 测试
file: path=/test.txt state=touch
2、数据字典类写法
---
- hosts: web
gather_facts: no
tasks:
- name: 测试
file:
path:/test.txt
state:touch
(四)、常用命令
--syntax-check # 执行剧本前,语法检查
-C # 模拟执行
-v # 显示执行剧本的具体语句
-vv # 显示执行剧本的语句及所在剧本位置
-vvv # 详细显示执行过程
五、playbook进阶应用
(一)、应用变量功能
设置变量方式一:主机清单设置
vim /etc/ansible/hosts
...
[bianliang:vars] # 注意vars是固定的
file_name=/test.txt
...
设置变量方式二:剧本中直接定义
- hosts: web
vars: # 注意变量设置要和hosts同级
- file_name: /test.txt
...
设置变量方式三:执行剧本时指定变量内容
ansible-playbook -e file_name='/test.txt' test.yml # 此处应用变量需要加 -e 参数
例
- hosts: web
vars:
- file_name: /test1.txt
tasks:
- name: create file
file:
path: "{{ file_name }}" # 引用file_name 变量
state: touch
注:三种方式定义变量的优先级
- 命令行 > 剧本 > 主机清单
(二)、剧本调试功能
变量注册功能
- register:用于将某任务执行输出内容,赋值到变量中
- debug:模块实现以某种方式输出内容
- hosts: web
tasks:
- name: 输出
shell: "echo '/baby'"
register: chenghao # 进行shell模块的输出内容注册成变量
- name: 输出chenghao变量
debug:
msg: "{{ chenghao }}" # 将注册的变量输出
标签功能
- 指定某任务打标签,最终执行剧本时,只执行指定任务,或跳过指定任务
- hosts: web
tasks:
- name: 传输文件
copy:
src: /etc/passwd
dest: /mnt
tags: biaoqian # 对指定任务打标签,注意要和所处的模块同级
# 只执行指定标签的任务
ansible-playbook -t biaoqian,标签2 var.yaml
# 跳过指定标签任务
ansible-playbook --skip-tags biaoqian var.yaml
剧本触发器
- 指定某任务完成之后,立即触发一个新的指定任务,类似于直接插队
- hosts: web
tasks:
- name: 输出
shell: "echo '/baby'"
register: chenghao
notify: set chenghao # notify指定名称,建立触发器,监控上面的任务真实执行成功后才触发监控器
- name: 传输文件
copy:
src: /etc/passwd
dest: /mnt
- name: 创建文件
file:
path: /opt/test.txt
state: touch
...
handlers: # 指定要执行的模块
- name: set chenghao # 此处写的名字要和notify所指定名称的一样
copy:
content: "test handler"
dest: /opt/test.txt
(三)、判断功能
- 通过针对条件判断,对只符合要求的机器执行某任务
- setup模块
- 探测远程主机的基本信息
- 查看指定主机的基本信息:ansible backup -m setup |grep -i -A 10 ‘ansible_default’
- json格式:键值对的形式(keepalive的格式也是一样)
# 语法格式
when:
- ( ansible_default_ipv4.address=='10.0.0.41' )
查看的主机信息段 等于(==)或不等于(!=) 信息段后面的值 可以用 或者(or)并且(and) 来进行多个条件判断
# 例
- hosts: test
gather_facts: yes
tasks:
- name: install rsync
yum: name=rsync state=absent
when:
- (ansible_default_ipv4.address=='10.0.0.41') and (ansible_hostname=='nfs')
# 这里的条件判断意思是远程主机的ip等于10.0.0.41,并且远程主机的主机名为nfs则执行该模块任务
# 恒为假的应用场景
- name: 删除用户
user: name=michael state=absent
when: 2<1 # 这里的定义为恒为假,在执行时就会跳过这个模块任务,如果是恒为真(0=0),则绝对执行,某些特殊场景会用到
- name: 修改用户信息
user: name=michael uid=666
(四)、循环功能
- loop模块
- 作用: 基于定义内容进行循环
# 方法一:
systemd:name='{{item}}'
loop:
- nginx
- rsyncd
- rpcbind
- nfs
# 方法二:
with_items:
- {uname: 'test1',unum: '10000',ubash: '/bin/sh'}
- {uname: 'test2',unum: '10001',ubash: '/bin/bash'}
- {uname: 'test3',unum: '10002',ubash: '/sbin/nologin'}
# 例
- hosts: test
gather_facts: yes
tasks:
- name: start services # 批量启动服务
systemd:
name: '{{item}}'
state: started
loop:
- nginx
- rsyncd
- rpcbind
- nfs
- name: create user # 批量创建用户
user:
name: '{{item.uname}}'
uid: '{{item.unum}}'
shell: '{{item.ubash}}'
with_items:
- {uname: 'test1',unum: '10000',ubash: '/bin/sh'}
- {uname: 'test2',unum: '10001',ubash: '/bin/bash'}
- {uname: 'test3',unum: '10002',ubash: '/sbin/nologin'}
(五)、流程控制
wait_for模块详解
wait_for:
timeout: 300 # 设置任务等待300秒,之后继续运行接下来的任务
port: # 用于探测指定端口出现,只有端口出现后才继续进行接下来的任务
path: /tmp/foo # 当某路径或文件出现,才继续运行后面的任务
search_regex: michael # 当所指的文件中有michael字符串内容,才基于运行后面任务
delay: # 在探测某条件之前,等待一段时间再进行探测
pause模块详解 # 这个和wait_for模块功能一样
pause:
seconds: 9 # 指定等待时间,可以通过ctrl+c和c来跳过等待
echo: yes # 等待过程中是否开启输出文本
prompt: '正在启动数据库,请稍等!' # 指定输出文本内容
# 例:
- name: 传输文件
copy:
src: /etc/passwd
dest: /mnt
- name: 等一等
wait_for:
timeout: 5
# 忽略错误操作,注意和模块名同级,可以直接忽略所指定的报错模块接着往下执行剧本
ignore_errors: yes
(六)、jinja模板
- template模块
- 将本地文件推送到远端目标主机,参数和copy模块几乎一样,但是这个模块可以使用变量
- 归根结底就是把一些经常会改动的数值改成变量,集合成一个模板文件,然后在需要用的时候,直接定义变量就可以使用。
# 编写jinja模板文件
uid={{rsync_user}}
gid={{rsync_user}}
port=873
fake super=yes
use chroot=no
max connections=200
timeout=600
ignore errors
read only=false
list=true
auth users=rsync_backup
secrets file=/etc/rsync.password
log file=/var/log/rsync.log
###############################
[{{module1}}]
path='{{rsync_module1}}
[{{module2}}]
path={{rsync_module2}}
# 例
- hosts: nfs
tasks:
- name: 推送j2模板
template:
src: ./file/rsyncd.j2
dest: /rsyncd.conf
(七)、剧本整合
- 将多个剧本整合到一个yam文件中,达到最终只需要执行一个yml文件的目的
# 以下两种方法都行
import_playbook: 剧本路径 # 这是新的,嘎嘎好使
include: 剧本路径 # 这是旧的,建议用新的
# 例
- import_playbook: template.yaml
- import_playbook: test_when.yaml
- import_playbook: test.yaml
- import_playbook: var.yaml
(八)、角色应用
1、作用
- 为了将杂糅到一起的剧本项目,拆分,降低剧本耦合度,实现剧本模块化
- 耦合度:指的是多个东西,强依赖关联在一起
ansible-galaxy init 角色名字 # 初始化角色,相当于新建一个角色,会在playbook目录中生成一个角色名字相同的目录
# 格式
- hosts: nfs # 指定主机组
roles: # 指定角色
- rsync # 角色名字
2、角色目录结构
目录名 | 作用 |
---|---|
tasks | 定义任务 |
files | 存放角色使用的模块 |
vars | 定义变量 |
templates | jinja模板文件 |
handlers | 触发器 |