Linux —— ansible自动化运维工具

简介 

Ansible是一个部署一群远程主机的工具;Ansible通过SSH协议实现远程节点和管理节点之间的通信。理论上说,只要管理员通过ssh登录到一台远程主机上能做的操作,Ansible都可以做到。Ansible是python开发的,故依赖一些python库和组件,如:paramiko,PyYaml和jinja三个关键组件;

ansible是自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。

用途:批量的去完成日常运维的工作

日常linux运维工作:
    1.安装软件
    2.启动服务
    3.运行脚本
    4.修改配置
    5.升级软件
    6.备份复制文件
    等

ansible就是让什么主机使用什么工具做什么事情 --》自动化运维工具,批量部署,批量操作运维,目的是提升效率和降低人力成本

组成

    1.host inventory   主机清单 --》可以控制的其他的电脑的名单
    2.playbook   剧本(配置文件) --》让主机清单里的主机去批量完成的任务 --》脚本
    3.module  模块  实现一个个功能的程序
    4.plugins  插件 :依附于ansible的一个小软件,实现某个小功能。

host inventory 主机清单

 写明控制的机器的信息,例如ip地址、ssh端口号、域名、用户名和密码

[webservers]
192.168.0.190
192.168.0.191
[dbservers]
192.168.0.192:22  ansible_ssh_user='cali' 
[nfs]
192.168.0.139:2233  ansible_ssh_user='root' ansible_ssh_pass='123456'

指定用户名和密码的配置,需要连接一次,获取对方服务器的公钥到know_hosts文件

module 模块

在后面介绍

plugins 插件

playbook 

后面介绍

使用

host inventory 主机清单

定义客户机--》你需要去控制的客户机,可以对客户机进行分类:web组、db组、redis组、flask组、django组等

hosts 里面定义主机清单

[root@server ansible]# vim /etc/ansible/hosts 
[scweb]
192.168.223.205

ansible 使用格式

HOST-PATTERN      #匹配主机模式,如all表示所有主机
-m MOD_NAME       #模块名   如:ping
-a MOD_ARGS        #模块执行的参数
-f FORKS                  #生成几个子进行程执行
-C                               #(不执行,模拟跑)
-u Username             #某主机的用户名
-c  CONNection        #连接方式(default smart)    

完整示例:
[root@ansible ~]# ansible all -m shell -a "ifconfig|grep enp0s3"
172.16.3.152 | SUCCESS | rc=0 >>
enp0s3: flags=4163  mtu 1500

172.16.3.216 | SUCCESS | rc=0 >>
enp0s3: flags=4163  mtu 1500

执行的返回结果里不同的颜色:

绿色:曾经使用,命令执行的 效果,之前执行过,已经有了

黄色:没有使用,命令执行有效果

红色:失败

ansible-doc 获取帮助信息  

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

 使用方式:

准备2台服务器
server: 192.168.223.206
client: 192.168.223.205

1.先在server和client之间建立单向信任关系,server端产生密钥对,上传公钥到client

[root@server ~]# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:8/oghA3DLKP6/1FiJm77Z312AfEzhSNhcTS3uj9e95k root@server
The key's randomart image is:
+---[RSA 2048]----+
|            +++..|
|   o       .o.ooo|
|  o =        + + |
| . o =      . =  |
|.   o * S    o o |
|.  . = o o    o  |
|.   o o ...  . .o|
| . . . ooo. o o.*|
|  ..oooo...o ..Eo|
+----[SHA256]-----+
[root@server ~]# cd /root/.ssh/
[root@server .ssh]# ls
authorized_keys  boot  hosts  id_rsa  id_rsa_2048-de.pub  id_rsa_2048-feng.pub  id_rsa.pub  known_hosts
[root@server .ssh]# ll
总用量 28
-rw------- 1 root root 1153 5月  14 16:47 authorized_keys
dr-xr-xr-x 4 root root  246 5月  14 15:13 boot
-rw-r--r-- 1 root root  158 5月  14 15:12 hosts
-rw------- 1 root root 1675 5月  21 11:34 id_rsa
-rw-r--r-- 1 root root  380 5月  14 16:44 id_rsa_2048-de.pub
-rw-r--r-- 1 root root  380 5月  14 16:38 id_rsa_2048-feng.pub
-rw-r--r-- 1 root root  393 5月  21 11:34 id_rsa.pub
-rw-r--r-- 1 root root  361 5月  14 16:20 known_hosts

上传公钥
[root@server .ssh]# ssh-copy-id -i id_rsa.pub [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.

测试是否免密通道建立成功
[root@server .ssh]# ssh '[email protected]'
Last login: Sun May 21 11:31:37 2023 from 192.168.223.1
[root@web1 ~]# 

2.安装ansible,在管理节点上

[root@ansible .ssh]# yum install epel-release -y
[root@ansible .ssh]# yum  install ansible -y

[root@server ~]# cd /etc/ansible/
[root@server ansible]# ls
ansible.cfg  hosts  roles

ansible.cfg  是ansible的配置文件
hosts 里面定义主机清单

[root@server ansible]# vim hosts 
[scweb]
192.168.223.205
[root@server ansible]# ansible scweb  -m shell -a "ip add"  在scweb组的主机上执行ip add 命令
192.168.223.205 | CHANGED | rc=0 >>
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:27:30:f9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.223.205/24 brd 192.168.223.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe27:30f9/64 scope link 
       valid_lft forever preferred_lft forever
[root@server ansible]# 

在所有主机上执行 yum install epel-release命令
[root@server ansible]# ansible all -m yum  -a "name=epel-release state=installed"  

在所有主机上执行 yum istall htop命令
[root@server ansible]# ansible all -m yum  -a "name=htop state=installed"
在scweb组的主机上执行nohup bash /tmp/while.sh & 命令
[root@server test]# ansible  scweb  -m shell -a  "nohup bash /tmp/while.sh &"

在所有主机上新建/hehaotian 目录
[root@server test]# ansible all  -m file -a "path=/hehaotian state=directory"

在所有主机上新建/hehaotian/sc.txt空文件
[root@server test]# ansible all  -m file -a "path=/hehaotian/sc.txt state=touch"

在所有主机上创建链接文件/hehaotian/sc.txt.link  指向 /hehaotian/sc.txt
[root@server test]# ansible all  -m file -a "src=/hehaotian/sc.txt path=/hehaotian/sc.txt.link state=link"

常用模块

1、copy模块

从本地copy文件分发到目录主机路径
参数说明:
src= 源文件路径
dest= 目标路径
注意src= 路径后面带/ 表示带里面的所有内容复制到目标目录下,不带/是目录递归复制过去
content= 自行填充的文件内容
owner 属主
group 属组
mode权限

ansible all  -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible mode=600"
ansible all -m copy -a "content='hi there\n' dest=/tmp/hi.txt"
到node1上查看
[root@node1 tmp]# ll
-rw------- 1 root root 465 2月   9 14:59 fstab.ansible
-rw-r--r-- 1 root root   9 2月   9 14:58 hi.txt

 2、fetch模块

从远程主机拉取文件到本地

[root@ansible ~]# ansible all  -m fetch -a "src=/tmp/hi.txt dest=/tmp"
172.16.3.152 | SUCCESS => {
    "changed": true, 
    "checksum": "279d9035886d4c0427549863c4c2101e4a63e041", 
    "dest": "/tmp/172.16.3.152/tmp/hi.txt", 
    "md5sum": "12f6bb1941df66b8f138a446d4e8670c", 
    "remote_checksum": "279d9035886d4c0427549863c4c2101e4a63e041", 
    "remote_md5sum": null
}
.......省略

说明:fetch使用很简单,src和dest,dest只要指定一个接收目录,默认会在后面加上远程主机及src的路径

3、command模块

在远程主机上执行命令,属于裸执行,非键值对显示;不进行shell解析;

[root@ansible ~]# ansible all -m command -a "ifconfig"
172.16.3.152 | SUCCESS | rc=0 >>
enp0s3: flags=4163  mtu 1500
        inet 172.16.3.152  netmask 255.255.255.0  broadcast 172.16.3.255
        .....省略.....
172.16.3.216 | SUCCESS | rc=0 >>
enp0s3: flags=4163  mtu 1500
        inet 172.16.3.216  netmask 255.255.255.0  broadcast 172.16.3.255
        .....省略.....
[root@ansible ~]# ansible all -m command -a "ifconfig|grep lo"
172.16.3.152 | FAILED | rc=2 >>
[Errno 2] 没有那个文件或目录

172.16.3.216 | FAILED | rc=2 >>
[Errno 2] 没有那个文件或目录

这就是因为command模块不是shell解析属于裸执行导致的
为了能达成以上类似shell中的解析,ansible有一个shell模块;

4、shell模块

由于commnad只能执行裸命令(即系统环境中有支持的命令),至于管道之类的功能不支持,
shell模块可以做到

[root@ansible ~]# ansible all -m shell -a "ifconfig|grep lo"
172.16.3.152 | SUCCESS | rc=0 >>
lo: flags=73  mtu 65536
        loop  txqueuelen 0  (Local Loopback)

172.16.3.216 | SUCCESS | rc=0 >>
lo: flags=73  mtu 65536
        loop  txqueuelen 0  (Local Loopback)

5、file模块

设置文件属性(创建文件)
常用参数:
path目标路径
state directory为目录,link为软件链接
group 目录属组
owner 属主
等,其他参数通过ansible-doc -s file 获取

示例1:创建目录

[root@ansible ~]# ansible all -m file -a "path=/var/tmp/hello.dir state=directory"
172.16.3.152 | SUCCESS => {
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/var/tmp/hello.dir", 
    "size": 6, 
    "state": "directory", 
    "uid": 0
}
172.16.3.216 | SUCCESS => {
    "changed": true, 
     .....省略.....

示例2:创建软件链接

[root@ansible ~]# ansible all -m file -a "src=/tmp/hi.txt path=/var/tmp/hi.link state=link"
172.16.3.152 | SUCCESS => {
    "changed": true, 
    "dest": "/var/tmp/hi.link", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "size": 11, 
    "src": "/tmp/hi.txt", 
    "state": "link", 
    "uid": 0
}
172.16.3.216 | SUCCESS => {
    "changed": true, 
     .....省略.....

6、cron模块

通过cron模块对目标主机生成计划任务
常用参数:
除了分(minute)时(hour)日(day)月(month)周(week)外
name: 本次计划任务的名称
state: present 生成(默认) |absent 删除 (基于name)

ansible all -m cron -a "minute=0 hour=8-18  month=5 weekday=1-5 job='bash /root/iptables.sh' name=runiptables2"

示例:对各主机添加每隔3分钟从time.windows.com同步时间

[root@ansible ~]# ansible all -m cron -a "minute=*/3 job='/usr/sbin/update time.windows.com &>/dev/null'  name=update_time"
172.16.3.152 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "update_time"
    ]
}
172.16.3.216 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "update_time"
    ]
}

#到node1上查看
[root@node1 tmp]# crontab -l
#Ansible: update_time
*/3 * * * * /usr/sbin/update time.windows.com &>/dev/null

示例2:删除计划任务

[root@ansible ~]# ansible all -m cron -a "name=update_time state=absent"
172.16.3.152 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
172.16.3.216 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
#node1上查看
[root@node1 tmp]# crontab -l
会发现已经被删除了

创建计划任务
[root@server test]# ansible  all -m cron  -a "minute=30 hour=2 job='bash /tmp/backup.sh' name=backup_passwd state=present"
[root@web1 hehaotian]# crontab -l
#Ansible: backup_passwd
30 2 * * * bash /tmp/backup.sh
取消计划任务
[root@web1 hehaotian]# ansible  all -m cron  -a "name=backup_passwd state=absent"

扩展 supervisor

Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。 

看服务是否运行?
    1.看进程
    2.看端口
    3.直接访问

如何知道服务做了哪些事情?
    1.看日志

crond 服务:去检查计划任务的最短时间间隔 1分钟

如何让某个事情每隔1秒钟去做一次呢?
    1.编写一个脚本watch.sh,死循环 一直运行,每隔一秒钟去执行
            while  
            sleep 1
    2.监控软件监控脚本watch.sh -->监控软件 supervisor

[root@master lianxi]# cat watch.sh
#!/bin/bash


#while :
while true
do
	sleep 1
        mkdir -p /test
	touch /test/$RANDOM-SC.txt
done

 

7、yum模块

故名思义就是yum安装软件包的模块;
常用参数说明:
enablerepo,disablerepo表示启用与禁用某repo库
name 安装包名
state (present' orinstalled', latest')表示安装, (absent' or `removed') 表示删除
示例:通过安装epel扩展源并安装nginx

[root@ansible ~]# ansible all -m yum -a "name=epel-release state=installed"
[root@ansible ~]# ansible all -m yum -a "name=nginx state=installed"

8、service模块

服务管理模块
常用参数:
name:服务名
state:服务状态
enabled: 是否开机启动 true|false
runlevel: 启动级别 (systemed方式忽略)

[root@ansible ~]# ansible all -m service -a "name=nginx state=started enabled=true"
到node1上查看
[root@node1 tmp]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since 五 2018-02-09 15:54:29 CST; 1min 49s ago
 Main PID: 10462 (nginx)
   CGroup: /system.slice/nginx.service
           ├─10462 nginx: master process /usr/sbin/nginx
           └─10463 nginx: worker process
......省略......

9、script模块

把本地的脚本传到远端执行;前提是到远端可以执行,不要把Linux下的脚本同步到windows下执行;
直接上示例:

[root@ansible ~]# cat test.sh 
#!/bin/bash
echo "ansible script test!" > /tmp/ansible.txt
[root@ansible ~]# ansible all -m script -a "/root/test.sh"
172.16.3.152 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 172.16.3.152 closed.\r\n", 
    "stdout": "", 
    "stdout_lines": []
}
172.16.3.216 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 172.16.3.216 closed.\r\n", 
    "stdout": "", 
    "stdout_lines": []
}
到node1上查看
[root@node1 tmp]# ls
ansible.txt  fstab.ansible  hi.txt 
[root@node1 tmp]# cat ansible.txt
ansible script test!

script模块这个功能可以做很多事,就看你怎么用了~
以上是常用模块,至于其他模块的使用可通过官方模块列表获得~

Playbook

playbook是Ansible的配置,部署和编排的语言。他们可以描述你所希望的远程系统强制执行的政策,或者在一般的IT流程的一组步骤;形象点的说就是:如果ansible的各模块(能实现各种功能)是车间里的各工具;playbook就是指导手册,目标远程主机就是库存和原料对象.
playbook是基于YAML语言格式配置,关于YAML
更多playbook官方说明参考

1、playbook的核心元素


hosts : playbook配置文件作用的主机
tasks: 任务列表
variables: 变量
templates:包含模板语法的文本文件 jinja2是一种模板语言

handlers 和notity结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行

tags 标签,指定某条任务执行,用于选择运行playbook中的部分代码。
roles :用于层次性、结构化地组织playbook。roles 能够根据层次型结构自动装载变量文件、tasks以及handlers等;做一个事情就相当于演一个角色,需要准备一个对应的文件夹和yaml文件,适合于大的项目,部署安装修改的内容非常多;可以完成更加复杂的任务,需要多个任务同时或者按照顺序去执行,需要很多的源文件和多个playbook的yaml文件,需要定义自定义的变量,来完成这件复杂的事情(比较大的项目)

2、Playbook语法

playbook使用yaml语法格式,后缀可以是yaml,也可以是yml

  • 在单一一个playbook文件中,可以连续三个连子号(---)区分多个play。还有选择性的连续三个点好(...)用来表示play的结尾,也可省略。
  • 次行开始正常写playbook的内容,一般都会写上描述该playbook的功能。
  • 使用#号注释代码。
  • 缩进必须统一,不能空格和tab混用。
  • 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行实现的。
  • YAML文件内容和Linux系统大小写判断方式保持一致,是区分大小写的,k/v的值均需大小写敏感
  • k/v的值可同行写也可以换行写。同行使用:分隔。
  • v可以是个字符串,也可以是一个列表
  • 一个完整的代码块功能需要最少元素包括 name: task

 示例:

# 创建playbook文件
[root@ansible ~]# cat playbook01.yml
---                       #固定格式
- hosts: 192.168.1.31     #定义需要执行主机
  remote_user: root       #远程用户
  vars:                   #定义变量
    http_port: 8088       #变量

  tasks:                             #定义一个任务的开始
    - name: create new file          #定义任务的名称
      file: name=/tmp/playtest.txt state=touch   #调用模块,具体要做的事情
    - name: create new user
      user: name=test02 system=yes shell=/sbin/nologin
    - name: install package
      yum: name=httpd
    - name: config httpd
      template: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf
      notify:                 #定义执行一个动作(action)让handlers来引用执行,与handlers配合使用
        - restart apache      #notify要执行的动作,这里必须与handlers中的name定义内容一致
    - name: copy index.html
      copy: src=/var/www/html/index.html dest=/var/www/html/index.html
    - name: start httpd
      service: name=httpd state=started
  handlers:                                    #处理器:更加tasks中notify定义的action触发执行相应的处理动作
    - name: restart apache                     #要与notify定义的内容相同
      service: name=httpd state=restarted      #触发要执行的动作

#测试页面准备
[root@ansible ~]# echo "

playbook test file

" >>/var/www/html/index.html #配置文件准备 [root@ansible ~]# cat httpd.conf |grep ^Listen Listen {{ http_port }} #执行playbook, 第一次执行可以加-C选项,检查写的playbook是否ok [root@ansible ~]# ansible-playbook playbook01.yml PLAY [192.168.1.31] ********************************************************************************************* TASK [Gathering Facts] ****************************************************************************************** ok: [192.168.1.31] TASK [create new file] ****************************************************************************************** changed: [192.168.1.31] TASK [create new user] ****************************************************************************************** changed: [192.168.1.31] TASK [install package] ****************************************************************************************** changed: [192.168.1.31] TASK [config httpd] ********************************************************************************************* changed: [192.168.1.31] TASK [copy index.html] ****************************************************************************************** changed: [192.168.1.31] TASK [start httpd] ********************************************************************************************** changed: [192.168.1.31] PLAY RECAP ****************************************************************************************************** 192.168.1.31 : ok=7 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 # 验证上面playbook执行的结果 [root@ansible ~]# ansible 192.168.1.31 -m shell -a 'ls /tmp/playtest.txt && id test02' 192.168.1.31 | CHANGED | rc=0 >> /tmp/playtest.txt uid=990(test02) gid=985(test02) 组=985(test02) [root@ansible ~]# curl 192.168.1.31:8088

playbook test file

3、playbook运行方式


ansible-playbook --check 只检测可能会发生的改变,但不真执行操作
ansible-playbook --list-hosts 列出运行任务的主机
ansible-playbook --syntax-check playbook.yaml 语法检测
ansible-playbook -t TAGS_NAME playbook.yaml 只执行TAGS_NAME任务
ansible-playbook playbook.yaml 运行

4、Handlers与Notify 

很多时候当我们某一个配置发生改变,我们需要重启服务,(比如httpd配置文件文件发生改变了)这时候就可以用到handlersnotify了;
(当发生改动时)notify actions会在playbook的每一个task结束时被触发,而且即使有多个不同task通知改动的发生,notify actions知会被触发一次;比如多个resources指出因为一个配置文件被改动,所以apache需要重启,但是重新启动的操作知会被执行一次。

[root@ansible ~]# cat httpd.yml 
#用于安装httpd并配置启动
---
- hosts: 192.168.1.31
  remote_user: root

  tasks:
  - name: install httpd
    yum: name=httpd state=installed
  - name: config httpd
    template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify:
      - restart httpd
  - name: start httpd
    service: name=httpd state=started

  handlers:
    - name: restart httpd
      service: name=httpd state=restarted

#这里只要对httpd.conf配置文件作出了修改,修改后需要重启生效,在tasks中定义了restart httpd这个action,然后在handlers中引用上面tasks中定义的notify。

5、通过playbook安装管理redis服务

#在家目录下创建playbooks
[root@ansible ~]# mkidr playbooks
[root@ansible ~]# cd playbooks
[root@ansible playbooks]# cat redis_first.yaml
- hosts: all 
  remote_user: root
  tasks:
  - name: install redis
    yum: name=redis state=latest

  - name: start redis
    service: name=redis state=started

语法检测:

[root@ansible playbooks]# ansible-playbook --syntax-check redis_first.yaml 

playbook: redis_first.yaml

说明语法没有 问题
将要执行的主机:

[root@ansible playbooks]# ansible-playbook --list-hosts redis_first.yaml
playbook: redis_first.yaml
  play #1 (all): all    TAGS: []
    pattern: [u'all']
    hosts (2):
      172.16.3.216
      172.16.3.152

执行

[root@ansible playbooks]# ansible-playbook redis_first.yaml
PLAY [all] *****************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************
ok: [172.16.3.216]
ok: [172.16.3.152]
TASK [install redis] *******************************************************************************************************
changed: [172.16.3.216]
changed: [172.16.3.152]
TASK [start redis] *********************************************************************************************************
changed: [172.16.3.152]
changed: [172.16.3.216]
PLAY RECAP *****************************************************************************************************************
172.16.3.152               : ok=3    changed=2    unreachable=0    failed=0   
172.16.3.216               : ok=3    changed=2    unreachable=0    failed=0   

说明:
自上而下列出了三个任务,分别是[Gathering Facts] , [install redis], [start redis],其中各主机上成功为ok=3,有两项任务执行结果是changed
不可达 和失败的任务均为0;

由于上面的操作是直接安装redis服务并启动,并没有配置文件,这还不能往生产环境中使用,生产环境中的redis肯定有不同的配置项,因此需要在安装时提供配置文件

6、带配置文件的安装管理redis


首先复制一个redis.conf到本地并进行修改

[root@ansible ~]# ansible 172.16.3.152 -m fetch -a "src=/etc/redis.conf dest=./"
[root@ansible ~]# mv /root/172.16.3.152/etc/redis.conf  /root/playbooks/redis.conf
修改bind 0.0.0.0

cat redis_second.yaml
- hosts: all                   #所有远程主机
  remote_user: root      #以远程主机上root用户执行
  tasks:                        #任务
  - name: install redis      #任务之安装
    yum: name=redis state=latest        #动作调用yum模块安装
  - name: copy config file     #任务之复制同步配置文件到远程目标主机
    copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf owner=redis       #动作copy模块执行
    notify: restart redis      #触发的动作
    tags: configfile         #任务标记名configfile
  - name: start redis      #任务之启动redis
    service: name=redis state=started    #动作调用sevice模块
  handlers:              #特定情况下,接收到其他任务的通知时被触发
  - name: restart redis
    service: name=redis state=restarted

再次测试并执行

[root@ansible playbooks]# ansible-playbook  redis_second.yaml 

PLAY [all] ****************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [172.16.3.152]
ok: [172.16.3.216]
TASK [install redis] ******************************************************************************************************
ok: [172.16.3.216]
ok: [172.16.3.152]
TASK [copy config file] ***************************************************************************************************
changed: [172.16.3.152]
changed: [172.16.3.216]
TASK [start redis] ********************************************************************************************************
ok: [172.16.3.152]
ok: [172.16.3.216]
RUNNING HANDLER [restart redis] *******************************************************************************************
changed: [172.16.3.152]
changed: [172.16.3.216]
PLAY RECAP ****************************************************************************************************************
172.16.3.152               : ok=5    changed=2    unreachable=0    failed=0   
172.16.3.216               : ok=5    changed=2    unreachable=0    failed=0 

可以发现只是加了一个配置文件,所有的任务都执行了,可否只应用新添加的任务?当然可以
这里就要通过
ansible-playbook -t TAGS_NAME 来执行了
可以把redis.conf中添加一个登录密码再执行测试下:

[root@ansible playbooks]# ansible-playbook -t configfile redis_second.yaml 
PLAY [all] ****************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [172.16.3.152]
ok: [172.16.3.216]
TASK [copy config file] ***************************************************************************************************
changed: [172.16.3.216]
changed: [172.16.3.152]
RUNNING HANDLER [restart redis] *******************************************************************************************
changed: [172.16.3.152]
changed: [172.16.3.216]
PLAY RECAP ****************************************************************************************************************
172.16.3.152               : ok=3    changed=2    unreachable=0    failed=0   
172.16.3.216               : ok=3    changed=2    unreachable=0    failed=0 

以上执行结果就没有 了安装与启动的步骤~只有更新和重启!

变量和模板的使用

参考: https://www.cnblogs.com/yanjieli/p/10969299.html

参考: https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html

示例:

[root@server playbook]# cat redis4.yaml 
- hosts: scweb
  remote_user: root
  vars:
  - scredis: /playbook/redis.conf.j2  #定义变量
  - redis_port: 63790

  tasks:
  - name: copy config file
    copy: src={{ scredis }} dest=/etc/redis.conf owner=redis
    notify: restart redis
    tags: configfile
  handlers:
  - name: restart redis
    service: name=redis state=restarted 

[root@server playbook]# cp redis.conf redis.conf.j2  获得模板文件

[root@server playbook]# vim redis.conf.j2 

bind {{ ansible_facts["ens33"]["ipv4"]["address"] }}  #不同的机器上获取的ip地址不一样,从而达到差异化
port {{ redis_port }}   #使用自定义的变量
[root@server playbook]# cat redis.conf.j2 |egrep -v "^#|^$"
bind {{ ansible_facts["ens33"]["ipv4"]["address"] }}
protected-mode yes
port {{ redis_port }}
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
[root@server playbook]# cat redis4.yaml 
- hosts: scweb
  remote_user: root
  vars:
  - scredis: /playbook/redis.conf.j2
  - redis_port: 63790
  tasks:
  - name: template use
    template: src={{ scredis }} dest=/etc/redis.conf owner=redis
    notify: restart redis
    tags: configfile
  handlers:
  - name: restart redis
    service: name=redis state=restarted 
[root@server playbook]# ansible-playbook redis4.yaml 

PLAY [scweb] ************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************
ok: [192.168.223.205]
ok: [192.168.223.206]

TASK [template use] *****************************************************************************************************
changed: [192.168.223.205]
changed: [192.168.223.206]

RUNNING HANDLER [restart redis] *****************************************************************************************
changed: [192.168.223.205]
changed: [192.168.223.206]

PLAY RECAP **************************************************************************************************************
192.168.223.205            : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.223.206            : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@server playbook]# 
[root@server playbook]# netstat -anputl|grep redis
tcp        0      0 192.168.223.206:63790   0.0.0.0:*               LISTEN      48216/redis-server  

你可能感兴趣的:(运维,linux,ansible)