Ansible

默认分类 / 2023-08-18

Ansible

一、Ansible概述

(一)、简介

  • Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。

  • 它用Python写成,类似于saltstack和Puppet,但是我们不需要在节点中安装任何客户端。

  • 它使用SSH来和节点进行通信。Ansible基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用YMAL 及 Jinja2模板语言,更强的远程命令执行操作。

  • 官方网站:https://www.ansible.com/

(二)、特点

  • 部署简单,没有客户端,只需在主控端部署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等

202203081149226

(五)、Ansible执行逻辑

202203081149233

二、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 触发器