Ansible学习总结

一、简介

Ansible是一个自动化运维的工具
基于python语言编写,因此机器需要具备python环境。
通过ssh的连接方式进行自动化部署,ansible优先使用OpenSSH,在使用python模块里的paramiko作为SSH工具

二、优缺点

2.1 优点:

1.入门快速,简单上手
2.基于Python语言
3.无代理(基于ssh,无需安装客户端,如zabbix的客户端要安装agent)
4.可读性强(采用YAML格式)

2.2 缺点:

1.对Windows系统的排斥(服务端无法安装在windows)
2.运行效率较低(task任务是串行运行;多台设备同时运行一个task,有并发数限制)

三、安装

安装的是基于Python2.7的Ansible

3.1 在Ubuntu上的安装

#1.增加PPA源,并安装Ansible
sudo apt-get unpdate
sudo apt-get install software-properties-common
sudo apt-add-repository --yes --update ppa:ansible/ansible
sudo apt-get install ansible

#2.查看版本,结果无报错
ansible --version

3.2 在Centos7上的安装

#1.安装EPEL扩展软件仓库
sudo yum -y install epel-release

#2.安装Ansible
sudo yum -y install ansible

#3. 检查ansible的版本和运行环境
ansible --version

四、框架介绍

4.1 框架图

image

4.2 各组件功能

ansible.cfg        #ansible的配置文件,包含各种Ansible全局性质的参数,可在不同项目下或者不同用户下创建一样的ansible.cfg文件,作为局部配置文件,检索顺序:局部-->全局
inventory        #设备列表,当跑脚本时,需要告诉Ansible针对哪些设备或设备组
variable        #变量
module        #模块,通过其他语言编写而成,能实现某个特定的功能的工具,例如思科配置接口的模块,修改ip地址的模块等等
Jinja2        #模板系统,Ansible可实现批量配置网络设备
Role        #角色,一套文件夹,里面定义了例如变量,具体任务task。Role里面定义的内容可以实现某些特殊功能,而你在使用不通的脚本过程中可以导入Role来实现某一个功能。而不用重复写

#以上的组件,会由以下的“客户”来使用
Ad-hoc    #即插即用,简易模式,一条命令,一次使用
playbook    #剧本,基于YAML文件格式书写,可以包含Ansible任意功能,无论是设备列表,变量,jinja2模板,条件循环,模块等等

五、模块

5.1 常用模块之文件操作

1.远程复制备份模块:copy

模块参数详解:

src: 指定源文件路径
dest: 目标地址(拷贝到哪里)
owner: 指定属主
group: 指定属组
mode: 指定权限,可以以数字指定比如0644
backup: 在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no
[root@ansible ~]# vim a.txt  #创建一个测试文件
123123
[root@ansible ~]# ansible weball -m copy -a 'src=/root/a.txt dest=/opt owner=root group=root mode=644' -o
[root@ansible ~]# vim a.txt  #追加如下内容
123123
234234
[root@ansible ~]# ansible weball -m copy -a 'src=/root/a.txt dest=/opt/ owner=root group=root mode=644 backup=yes' -o
登录被控制机器其中一台查看
[root@ansible-web1 ~]# cat /opt/a.txt

2.文件模块file

模块参数详解:

owner: 修改属主
group: 修改属组
mode: 修改权限
path: 要修改文件的路径
recurse:递归的设置文件的属性,只对目录有效
        yes: 表示使用递归设置
state:
    touch:创建一个新的空文件
    directory:创建一个新的目录,当目录存在时不会进行修改
# 创建一个文件
[root@ansible ~]# ansible webservers1 -m file -a 'path=/tmp/88.txt mode=777 state=touch'

# 创建一个目录
[root@ansible ~]# ansible webservers1 -m file -a 'path=/tmp/99 mode=777 state=directory' 

3.blockinfile模块
在文本文件中添加标记或删除标记
模块参数详解:

path: 必须参数,指定要操作的文件
block: 操作的文本
marker:标记
state:有两个可选值present和absent,表示新增block标记或删除block标记
backup: 是否在修改文件前备份文件
create:当操作的文件不存在时,是否创建文件
[root@ansible ~]# ansible all -m blockinfile -a 'path=/testdir/rc.local block="" marker="#{mark} serivce to start" '

4.lineinfile模块
在文本文件中添加行或者替换或删除行
模块参数详解:

path :必须参数,指定要操作的文件
line :  使用此参数指定文本内容
regexp :使用正则表达式匹配对应的行,当替换文本时,如果有多行文本都能被匹配,则只有最后面被匹配到的那行文本才会被替换,当删除文本时,如果有多行文本都能被匹配,这么这些行都会被删除
state:当想要删除对应的文本时,需要将state参数的值设置为absent,absent为缺席之意,表示删除,state的默认值为present
backup:是否在修改文件之前对文件进行备份
create :当要操作的文件并不存在时,是否创建对应的文件
[root@ansible-master playbooks]# ansible all -m lineinfile -a 'path=/testdir/test line="test text"'

5.find模块
远程主机中查找符合条件的文件
模块参数详解:

paths:必须参数,指定在哪个目录查找文件
recurse:是否递归查找文件
hidden:是否查找隐藏文件
file_type:文件类型(any,directory,file,link)
contains:正则表达式查找
[root@ansible-master playbooks]# ansible all -m find -a 'paths=/testdir contains=".*abc.*" '

6.replace模块
指定的正则表达式替换文件中的字符串
模块参数详解:

path:必须参数,指定要操作的文件
regexp:正则表达式
replace:最终要替换的字符串
backup:是否对源文件进行备份
[root@ansible-master playbooks]# ansible all -m replace -a 'path=/testdir/test regexp="ASM" replace=asm'

7.远程拉取fetch模块
模块参数详解:

src: 远程主机文件路径(必须为文件)
dest: 文件保存路径
[root@ansible-master playbooks]# ansible all -m fetch -a "src=/etc/hosts dest=/tmp"
192.168.70.102 | CHANGED => {
    "changed": true, 
    "checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa", 
    "dest": "/tmp/192.168.70.102/etc/hosts", 
    "md5sum": "54fb6627dbaa37721048e4549db3224d", 
    "remote_checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa", 
    "remote_md5sum": null
}
192.168.70.101 | CHANGED => {
    "changed": true, 
    "checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa", 
    "dest": "/tmp/192.168.70.101/etc/hosts", 
    "md5sum": "54fb6627dbaa37721048e4549db3224d", 
    "remote_checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa", 
    "remote_md5sum": null
}

5.2 常用模块之系统操作

1.用户管理user模块

添加用户并设置密码:
生成加密密码:
[root@ansible ~]# echo '777777' | openssl passwd -1 -stdin
$1$i2prOXuN$D9i18PZSb6IN5pt3lRXEM1
openssl passwd :目的是为了防止密码以明文的形式出现
-1:MD5加密算法
设置密码:
[root@ansible ~]# ansible ansible-web1 -m user -a 'name=qianfeng password="$1$XVzsJMDr$5wI4oUaQ.emxap6s.N272."'
"name=   "  #如:指定的用户名,要安装的软件
====================================================================
删除用户:
[root@ansible ~]# ansible ansible-web1 -m user -a "name=qianfeng state=absent" -o
absent #删除用户,但是不会删除家目录

2.软件包管理 yum模块

# 安装apache
[root@ansible ~]# ansible webservers1 -m yum -a "name=httpd state=latest" -o
state=     #状态是什么,干什么
state=absent        用于remove安装包
state=latest       表示最新的
state=removed      表示卸载
# 卸载软件:
[root@ansible ~]# ansible webservers1 -m yum -a "name=httpd state=removed" -o

3.服务管理service模块

[root@ansible ~]# ansible webservers1 -m service -a "name=httpd state=started" #启动
[root@ansible ~]# ansible webservers1 -m service -a "name=httpd state=stopped" #停止
[root@ansible ~]# ansible webservers1 -m service -a "name=httpd state=restarted" #重启
[root@ansible ~]# ansible webservers1 -m service -a "name=httpd state=started enabled=yes" #开机启动
[root@ansible ~]# ansible webservers1 -m service -a "name=httpd state=started enabled=no"  #开机关闭

4.收集信息模块setup

[root@ansible ~]# ansible webservers1 -m setup  #收集所有信息

[root@ansible ~]# ansible webservers1 -m setup -a 'filter=ansible_all_ipv4_addresses' #只查询ipv4的地址
filter:过滤

5.cron模块

管理远程主机中的计划任务
模块参数详解:

minute:此参数用于设置计划任务中分钟设定位的值,比如,上述示例1中分钟设定位的值为5,即minute=5,当不使用此参数时,分钟设定位的值默认为”*”

hour:此参数用于设置计划任务中小时设定位的值,比如,上述示例1中小时设定位的值为1,即hour=1,当不使用此参数时,小时设定位的值默认为”*”

day:此参数用于设置计划任务中日设定位的值,当不使用此参数时,日设定位的值默认为”*”

month:此参数用于设置计划任务中月设定位的值,当不使用此参数时,月设定位的值默认为”*”

weekday:此参数用于设置计划任务中周几设定位的值,当不使用此参数时,周几设定位的值默认为”*”

special_time:在上述示例3与示例4中,计划任务的时间设定格式为@reboot或者@hourly,@reboot表示重启时执行,@hourly表示每小时执行一次,相当于设置成”0 * * * *” ,这种@开头的时间设定格式则需要使用special_time参数进行设置,special_time参数的可用值有reboot(重启后)、yearly(每年)、annually(每年,与yearly相同)、monthly(每月)、weekly(每周)、daily(每天)、hourly(每时)

注意:当上述时间单位设定参数都未指定时,计划任务的时间设定默认会被设定为”* * * * *”,这样表示每分钟都会执行一次计划任务,所以,在使用cron模块时,我们应该确定对应的时间参数设置正确。

user参:此参数用于设置当前计划任务属于哪个用户,当不使用此参数时,默认为管理员用户

job:此参数用于指定计划的任务中需要实际执行的命令或者脚本,比如上例中的”echo test”命令。

name参数:此参数用于设置计划任务的名称,计划任务的名称会在注释中显示,当不指定计划任务的名称时,ansible会默认为计划任务加入注释,注释的内容为#Ansible: None,假设指定计划任务的名称为test,那么注释的内容为#Ansible: test,在一台机器中,计划任务的名称应该具有唯一性,方便我们以后根据名称修改或删除计划任务。

state:当计划任务有名称时,我们可以根据名称修改或删除对应的任务,当删除计划任务时,需要将state的值设置为absent

disabled:当计划任务有名称时,我们可以根据名称使对应的任务”失效”(注释掉对应的任务),注意,使用此参数时,除了需要指定任务的名称,还需要同时指定任务的job以及任务的时间设定,而且任务的时间设定必须和对应任务完全相同,否则在注释任务的同时,任务的时间设定会被修改,除非你确定这样做,如果你不明白这段话的意思,可以参考下文中的示例。

backup参数:如果此参数的值设置为yes,那么当修改或者删除对应的计划任务时,会先对计划任务进行备份,然后再对计划任务进行修改或者删除,cron模块会在远程主机的/tmp目录下创建备份文件,以crontab开头并且随机加入一些字符,具体的备份文件名称会在返回信息的backup_file字段中看到,推荐将此此参数设置为yes
[root@ansible ~]# ansible all -m cron -a " name='test crontab' minute=5 hour=1 job='echo test' "

5.3 常用模块之命令相关

1.command模块

执行远程命令

模块参数详解:

chdir: 指定一个目录,执行命令

2.shell模块

远程主机上执行命令,与command模块不同的是,shell模块在远程主机中执行命令时,会经过远程主机上的/bin/sh程序处理

[root@ansible ~]# ansible all -m shell -a "chdir=/testdir echo test > test"

3.script模块

远程主机上执行ansible主机上的脚本

[root@ansible ~]# ansible all -m script -a "chdir=/opt /testdir/atest.sh"

六、 Ansible Playbook

6.1 初识playbook

编写一个最基础的ansible playbook剧本

[root@ansible-master playbooks]# cat test.yml 
---
- hosts: all
  remote_user: root
  tasks:
  - name: Ping the hosts
    ping:
  - name: make dir test
    file: path=/testdir/test state=directory

编写完成之后可以使用以下命令检查yaml语法

[root@ansible-master playbooks]# ansible-playbook --syntax-check test.yml 

playbook: test.yml

使用一下命令进行模拟执行

[root@ansible-master playbooks]# ansible-playbook --check test.yml 

PLAY [all] ****************************************************************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************************************
ok: [192.168.70.101]
ok: [192.168.70.102]

TASK [Ping the hosts] *****************************************************************************************************************************************************************************
ok: [192.168.70.102]
ok: [192.168.70.101]

TASK [make dir test] ******************************************************************************************************************************************************************************
changed: [192.168.70.101]
changed: [192.168.70.102]

PLAY RECAP ****************************************************************************************************************************************************************************************
192.168.70.101             : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.70.102             : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

6.2 handlers的用法

当执行一个task的时候,需要修改完配置之后重启服务,就是可以使用handlers

[root@ansible-master playbooks]# cat handlers.yml 
---
- hosts: test
  remote_user: root
  tasks:
  - name: task1
    file: path=/testdir/testfile
          state=touch
    notify: handler group1
 
  handlers:
  - name: handler1
    listen: handler group1
    file: path=/testdir/ht1
          state=touch
  - name: handler2
    listen: handler group1
    file: path=/testdir/ht2
          state=touch

6.3 tags的用法

tags可以对任务进行打标签的操作,当任务存在标签以后,就可以在执行playbook时,借助标签,指定执行哪些任务,或者指定不执行哪些任务了

[root@ansible-master playbooks]# cat tags.yml 
---
- hosts: test
  remote_user: root
  tasks:
  - name: task1
    file:
      path: /testdir/t1
      state: touch
    tags: t1
  - name: task2
    file: path=/testdir/t2
          state=touch
    tags: t2
  - name: task3
    file: path=/testdir/t3
          state=touch
    tags: t3

如上例所示,上例的play中有3个task,每个task都有对应的tags,为了方便示例,只是简单的把tags的值写成了t1、t2、t3,在实际的使用中,应该让tags的值能够见名知义,现在每个task都有了标签,假如在执行上述playbook时,只想执行task2,该怎样执行呢?可以使用如下命令

ansible-playbook --tags=t2 tags.yml

使用–tags选项指定某个标签,当指定标签后,只有标签对应的任务会被执行,其他任务都不会被执行,执行上述命令后,只有task2会执行,因为task2的标签值为t2,task1和task3都不会执行,这样就达到了只执行playbook中部分任务的目的

借助标签,除了能够指定”需要执行的任务”,还能够指定”不执行的任务”,示例命令如下。

ansible-playbook --skip-tags='t2' testtag.yml

6.3 变量

我们可以在play中使用vars关键字定义变量。示例如下:

---
- hosts: test
  vars:
    testvar1: testfile
  remote_user: root
  tasks:
  - name: task1
    file:
      path: /testdir/{{ testvar1 }}
      state: touch

在定义变量时,还能够以类似”属性”的方式定义变量,示例如下

---
- hosts: test
  remote_user: root
  vars:
    nginx:
      conf80: /etc/nginx/conf.d/80.conf
      conf8080: /etc/nginx/conf.d/8080.conf
  tasks:
  - name: task1
    file:
      path: "{{nginx.conf80}}"
      state: touch
  - name: task2
    file:
      path: "{{nginx.conf8080}}"
      state: touch

当我们需要引用这两个变量时,有两种语法可用
语法一:

"{{nginx.conf80}}"

语法二:

"{{nginx['conf8080']}}"

也可以使用文件定义变量,示例如下:

# cat nginx_vars.yml
nginx:
  conf80: /etc/nginx/conf.d/80.conf
  conf8080: /etc/nginx/conf.d/8080.conf

定义完相关变量文件后,在playbook中引入变量的文件时,使用‘‘vars_files’’,引入的文件需要以‘-’开头

---
- hosts: test
  remote_user: root
  vars_files:
  - /testdir/ansible/nginx_vars.yml
  tasks:
  - name: task1
    file:
      path={{nginx.conf80}}
      state=touch
  - name: task2
    file:
      path={{nginx['conf8080']}}
      state=touch

“vars”关键字和”vars_files”关键字可以同时使用,如下

 vars:
  - conf90: /etc/nginx/conf.d/90.conf
  vars_files:
  - /testdir/ansible/nginx_vars.yml

注册变量(将task的返回值写入变量的方法乘称作注册变量)示例如下

---
- hosts: test
  remote_user: root
  tasks:
  - name: test shell
    shell: "echo test > /var/testshellfile"
    register: testvar
  - name: shell module return values
    debug:
      var: testvar

提示用户输入信息并写入变量

---
- hosts: test
  remote_user: root
  vars_prompt:
    - name: "your_name"
      prompt: "What is your name"
    - name: "your_age"
      prompt: "How old are you"
  tasks:
   - name: output vars
     debug:
      msg: Your name is {{your_name}},You are {{your_age}} years old.

为提示信息设置默认值,即如果用户不输入任何信息,则将默认值赋予变量,示例playbook如下。

---
- hosts: test
  remote_user: root
  vars_prompt:
    - name: "solution"
      prompt: "Choose the solution you want \n
      A: solutionA\n
      B: solutionB\n
      C: solutionC\n"
      private: no
      default: A
  tasks:
   - name: output vars
     debug:
      msg: The final solution is {{solution}}.

通过命令行传入变量

---
- hosts: test
  remote_user: root
  tasks:
  - name: "Passing Variables On The Command Line"
    debug:
      msg: "{{pass_var}}"

上述示例中没有定义pass_var变量,调用palybook时可以从命令行引入该变量,方法如下
ansible-playbook cmdvar.yml --extra-vars "pass_var=cmdline pass var"
如上例所示,在调用playbook时使用 “–extra-vars” 选项可以传递对应的变量与变量值, “–extra-vars” 是长选项,对应的短选项是”-e”,我们也可以一次性传入多个变量,变量之间用空格隔开,如下
ansible-playbook cmdvar.yml -e 'pass_var="test" pass_var1="test1"'

6.4 循环

posted @ 2022-04-19 15:24  dqforgive-sudo  阅读(129)  评论(0)    收藏  举报