摘要:ansible


一. 云计算

云计算
openstack
docker
kvm
虚拟化技术:在本身物理机的基础上虚拟出云主机
#唯一的不好是 安全性不高 数据保存在别人那里的 (影响不大)

#trouble shooting的能力 问题解答的能力

#注:ssh开启2种验证 - 先公钥认证 再密码认证 密码认证失败 提示permit deny


二. ansible不是守护进程

#ansible 不是守护进程 执行ansible命令的时候才会执行ansible
#守护进程:一直在内存里面,等待别人连接
#ssh是守护进程
#执行1条命令 命令不是守护进程

#ansible不是一个守护进程(守护进程:起来后一直在内存中运行,等待其他人访问)
#ansible就是一个命令脚本,使用Python写的

#[root@cPen_A ansible]# sudo -i #注:直接回到root用户


三. ansible的模块

ansible的模块

1. copy模块

从本地copy文件分发到目录主机路径
参数说明:
src= 源文件路径 # 注:source 源

​ dest= 目标路径 # 注:destination 目的地

​ 注意src= 路径后面带/ 表示带里面的所有内容复制到目标目录下,不带/是目录递归复制过去
​ content= 自行填充的文件内容
​ owner 属主
​ group 属组
​ mode权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
示例1:shell模块、copy模块
---------------------------------------------------------------------------------------------------------------------------------
#示例1:使用ansible 在B、C主机创建/lianxi 目录
#-m 指定模块
#-a 传的参数
ansible 接 指定主机 -m 指定模块 -a 执行的参数
[root@cPen_A ansible]# ansible all -m shell -a "mkdir /lianxi -p"
#注:rc ==> reutrn code --> 为0表示执行成功
#注:rc ==> reutrn code --> 为1表示执行失败

#示例2:将ansible-copy文件 复制到主机B、C/lianxi/ansible目录下,指定权限属主数组
[root@cPen_A lianxi]# vim ansible-copy
[root@cPen_A lianxi]# ansible all -m copy -a "src=/lianxi/ansible-copy dest=/lianxi/ansible mode=777 owner=sanchuang group=sanchuang"
#注:确认B、C主机 指定的用户sanchuang和组sanchuang存在
#md5sum 一般来说 是 信息的摘要 判定文件是否被修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
示例2:指定webser组,将/etc/passwd 赋值到主机/tmp目录下,指定权限777
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A lianxi]# ansible webser -m copy -a "src=/etc/passwd dest=/tmp mode=777"

===========================================================================================

示例3:copy src路径后面带/不带/的区别
---------------------------------------------------------------------------------------------------------------------------------
#注:src= 路径后面带/ 表示带里面的所有内容复制到目标目录下,不带/是目录递归复制过去
#注:不带/
[root@cPen_A copy_dir]# ansible all -m copy -a "src=/lianxi/copy_dir dest=/lianxi/ansible"
#注:带/
[root@cPen_A copy_dir]# ansible all -m copy -a "src=/lianxi/copy_dir/ dest=/lianxi/ansible"

#带/表示拷贝目录下的子文件或者子文件夹
#不带/表示拷贝整个目录

2. fetch模块

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
示例
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A lianxi]# ansible webser -m fetch -a "src=/etc/hostname dest=/lianxi mode=644"
192.168.0.22 | CHANGED => {
"changed": true,
"checksum": "c468f7340237d9f531122f5b03345ce8ac5641b4", # 注:拉去下来后会比较
"dest": "/lianxi/192.168.0.22/etc/hostname",
"md5sum": "8d23b0947f191eb9c20728677271eb4d",
"remote_checksum": "c468f7340237d9f531122f5b03345ce8ac5641b4", # 注:和远程比较 内容是否变更
"remote_md5sum": null
}
#注:大文件传送中途 突然断掉了 ,文件没有传完 保存的md5sum和它的md5sum不一样
#注:如果2个值一致 说明传完了
[root@cPen_A lianxi]# ls # 注:路径自动加了个以ip地址为名的文件夹
192.168.0.20 192.168.0.22 ansible-copy copy_dir
[root@cPen_A lianxi]# cd 192.168.0.20
[root@cPen_A 192.168.0.20]# ls
etc
1
2
3
4
5
6
从远程主机拉取文件到本地
fetch会自动的在dest指定目录后加上远程主机命名的目录结构后面接src目录结构
fetch存储到本地的目录结构 dest + 远程主机名 + src

#注:md5可以判定 1、文件是否修改;2、文件是否传完
#注:或者使用任何hash算法中的其中一种,去比较值是否相等

3. command模块

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
示例1:command、shell
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A 192.168.0.20]# ansible all -m command -a "ifconfig"
[root@cPen_A 192.168.0.20]# ansible all -m shell -a "ifconfig"

示例2:command裸执行 (后面传的参数不会做解析)
---------------------------------------------------------------------------------------------------------------------------------
#注:把ifconfig|grep inet整个当做1个命令去执行
[root@cPen_A 192.168.0.20]# ansible all -m command -a "ifconfig|grep inet"
192.168.0.22 | FAILED | rc=2 >>
[Errno 2] 没有那个文件或目录
#属于裸执行,不会解析它的管道符号 会认为ifconfig|grep inet 是一个命令

#注:shell可以 (后面传的参数会做解析)
[root@cPen_A 192.168.0.20]# ansible all -m shell -a "ifconfig|grep inet"

============================================================================================
[root@cPen_A ansible]# ifconfig # 注:查看网卡(看的东西多一点)
#注:可以看接收包、返回包、字节,有多少错误
[root@cPen_A ansible]# ip a # 注:查看网卡

4. shell模块

1
2
3
4
示例
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A 192.168.0.20]# ansible all -m shell -a "ifconfig|grep inet"
command一样,只不过shell模块可以解析管道之类的功能

5. file模块

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

state –
absent 删除文件和目录的
directory 目录
touch 新建空文件
link 软链接
hard 硬链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
示例1:查看file文件帮助信息
--------------------------------------------------------------------------------------------
[root@cPen_A lianxi]# ansible-doc -s file # 注:查看file文件帮助信息
============================================================================================

示例2:在目标主机/tmp目录下创建目录
#注:创建文件目录
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A lianxi]# ansible all -m file -a "path=/tmp/sanchuang state=directory"
============================================================================================

示例3:设置修改文件属性
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A lianxi]# ansible all -m file -a "path=/tmp/passwd owner=sanchuang"

6. cron模块

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

1
2
3
4
5
6
7
8
#注:首先查看程序有没有起来
[root@cPen_A ~]# ps -ef |grep crond
root 702 1 0 10:59 ? 00:00:00 /usr/sbin/crond -n
root 3582 3553 0 14:41 pts/3 00:00:00 grep --color=auto crond
#注:学会看日志
[root@cPen_A ~]# cd /var/log/
[root@cPen_A log]# less cron
Nov 25 12:01:01 cPen_A run-parts(/etc/cron.hourly)[3498]: finished 0anacron
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
示例1:添加计划任务
---------------------------------------------------------------------------------------------------------------------------------
#注:每三分钟输出当前时间,到/tmp/time.txt文件中
[root@cPen_A log]# ansible all -m cron -a "minute=*/3 job='date >>/tmp/time.txt' name=date_test state=present" # 注:minute=*/3 指定每3分钟 date >>/tmp/time.txt 命令
[root@cPen_B ~]# crontab -l
#Ansible: date_test
*/3 * * * * date >>/tmp/time.txt

[root@cPen_A log]# ansible 192.168.0.20 -m cron -a "minute=*/3 job='date >>/tmp/time.txt' name=date_test state=present" # 注:可以单独为某个主机设置 并非一定批量处理

============================================================================================

示例2:删除计划任务
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A log]# ansible 192.168.0.20 -m cron -a "name=date_test state=absent"
1
2
3
4
5
6
ntp服务是一个时间管理服务器
示例:ntp服务 系统时间管理服务
[root@cPen_A log]# yum install ntp # 注:centos7
[root@cPen_B ~]# yum install chrony # 注:centos8里面 ntp已被 chrony取代
[root@cPen_A log]# ntpdate ntp1.aliyun.com # 注:同步阿里云的时间
#注:使用ntp客户端 同步ntp的服务器 把时间同步

7. yum模块

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

#注:name安装的包名 state 安装还是卸载

1
2
3
4
示例:安装wget
[root@cPen_A log]# ansible all -m yum -a "name=wget state=installed"
示例:卸载wget
[root@cPen_A log]# ansible all -m yum -a "name=wget state=absent"

8. service模块

服务管理模块
常用参数:
name:服务名
state:服务状态 started(启动) stopped(关闭) restarted(重启) reloaded(重新加载)
enabled: 是否开机启动 true|false
runlevel: 启动级别 (systemed方式忽略)

1
2
3
4
5
6
7
#安装文件传输服务vsftpd
[root@cPen_A log]# ansible all -m yum -a "name=vsftpd state=installed"

示例:关闭vsftpd服务
[root@cPen_A log]# ansible all -m service -a "name=vsftpd state=stopped"
示例:开启vsftpd服务
[root@cPen_A log]# ansible all -m service -a "name=vsftpd state=started"

9. script模块

1、把本地的脚本传到远端执行;前提是到远端可以执行,不要把Linux下的脚本同步到windows下执行;

#注:只在远程服务器执行脚本,不上传脚本到远程服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@cPen_A ~]# vim test.sh
#!/bin/bash
echo "test ansible" >>/tmp/ansible.txt
[root@cPen_A ~]# ansible all -m script -a "/root/test.sh" # 注:/root/test.sh脚本路径

--------------------------------------------------------------------------------------------
示例:执行慢 机器多 怎么解决
答:可以使用多进程去执行
-f 6 指定6个进程去执行

command模块不能识别管道符号、shell模块 可以识别
copy模块 推送
script模块 不需要上传脚本,在远程服务器执行脚本

四. 查看系统版本

1
2
3
4
5
示例:查看系统版本
[root@cPen_B ~]# uname -r # 注:查看系统内核
4.18.0-193.el8.x86_64
[root@cPen_B ~]# cat /etc/redhat-release # 注:查看/etc/redhat-release 去查看系统版本
CentOS Linux release 8.2.2004 (Core)

五. 链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
示例:软链接
[root@cPen_A lianxi]# ln -s ansible-copy ansible-copy-likcs-s #注:前面原文件 后面链接文件
[root@cPen_A lianxi]# ls -al # 注:-s soft软
lrwxrwxrwx 1 root root 12 11月 25 11:30 ansible-copy-likcs-s -> ansible-copy
#注:软连接 相当于快捷方式
#注:软链接删掉不会影响原文件,软链接的原文件删掉了会影响链接文件

示例:硬链接
[root@cPen_A lianxi]# ln ansible-copy ansible-copy-link
[root@cPen_A lianxi]# ls -al
-rw-r--r-- 2 root root 20 11月 25 10:12 ansible-copy-link
rm -rf 删除源文件 硬链接文件 依旧没事
#注:硬链接 可以去做备份
#注:硬链接的原文件删掉了不会影响链接文件

#软链接、硬链接
#创建一个硬链接 文件的链接数会+1
#删除硬链接文件或者是源文件 只是把文件的链接数-1 文件不会被真正删除
#创建一个硬链接
[root@cPen_A lianxi]# ls -al
-rw-r--r-- 2 root root 20 11月 25 10:12 ansible-copy # 注:链接为2
#注:软链接
lrwxrwxrwx 1 root root 12 11月 25 11:30 ansible-copy-likcs-s -> ansible-copy # 注:链接为1
#注:硬链接
-rw-r--r-- 2 root root 20 11月 25 10:12 ansible-copy-link # 注:链接为2
符号链接数 1 是
rm -rf 删除的是 文件名 和 磁盘里面data的链接
data还存在于磁盘里 ,过一段时间 新的数据会覆盖 data
#注:为1表示删除了后就没有了,为2表示删除后还有

六. playbook

如果ansible的各模块(能实现各种功能)是车间里的各工具;playbook就是指导手册,目标远程主机就是库存和原料对象
#注:语法 yaml格式配置

1、playbook的核心元素
hosts : playbook配置文件作用的主机
tasks: 任务列表
variables: 变量
templates:包含模板语法的文本文件
handlers :由特定条件触发的任务
roles :用于层次性、结构化地组织playbook。roles 能够根据层次型结构自动装载变量文件、tasks以及handlers等
2、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 运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
示例:编写/执行 playbook
--------------------------------------------------------------------------------------------
#注:把A机器的/etc/passwd复制到其他机器的/tmp/passwd_tmp下
[root@cPen_A ~]# vim ansible_playbook_sc.yaml #注:编写playbook
- hosts: all
remote_user: root
tasks:
- name: up file
copy: src=/etc/passwd dest=/tmp/passwd_tmp
#执行playbook
[root@cPen_A ~]# ansible-playbook ansible_playbook_sc.yaml
============================================================================================

示例:yaml文件怎么去编写
--------------------------------------------------------------------------------------------
#第1步 先安装python3:yum install python3
#第2步 使用pip3安装PyYaml模块
[root@cPen_A ~]# pip3 install PyYaml
[root@cPen_A ~]# python3
>>> import yaml
>>> fp = open("ansible_playbook_sc.yaml")
>>> dict = yaml.load(fp)
>>> dict
[{'hosts': 'all', 'remote_user': 'root', 'tasks': [{'name': 'up file', 'copy': 'src=/etc/passwd dest=/tmp/passwd_tmp'}]}]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#注:使用
1、创建yaml文件
[root@cPen_A ~]# cat ansible_playbook_sc.yaml # 注:类似于字典形式 - 相当于list ;里面相当于字典
- hosts: all # 注:对所有主机生效(什么组)
remote_user: root # 注:root用户执行
tasks: # 注:让它做什么事情
- name: up file # 注:事情名字叫up file
copy: src=/etc/passwd dest=/tmp/passwd_tmp # 注:使用copy模块 执行源 目的地址
2、可以使用Python解析yaml
>>> import yaml
>>> fp = open("ansible_playbook_sc.yaml")
>>> dict = yaml.load(fp)
>>> dict
[{'hosts': 'all', 'remote_user': 'root', 'tasks': [{'name': 'up file', 'copy': 'src=/etc/passwd dest=/tmp/passwd_tmp'}]}]
#注:使用copy模块 来指定src dest
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
示例:多个操作
--------------------------------------------------------------------------------------------
[root@cPen_A ~]# vim ansible_playbook_sc.yaml # 注:编写
- hosts: all
remote_user: root
tasks:
- name: up file
copy: src=/etc/passwd dest=/tmp/passwd_tmp
- name: download redis
yum: name=redis state=installed
- hosts: webser
tasks:
- name: remove file
shell: rm -rf /tmp/passwd_tmp
[root@cPen_A ~]# ansible-playbook ansible_playbook_sc.yaml # 注:运行

七. 总结

ansible通过常用模块在命令行就可以针对主机清单来管理配置远程主机,无需要代理客户端程序,但需要目标主机有ssh和python2.4+;基于ssh协议既可以通过用户名和密码,也可以通过私钥,推荐使用私钥;
windows上需要安装powershell及winrm服务也可以做到,关于这方面 可以参考我之前的博客 ansible自动化管理windows
通过ansib-doc来获取模块信息及指定模块帮助信息;
ansible-playbook 基于YAML语法配置;可以对playbook文件进行测试,解析并执行应用于指定无端主机;非常方便我们统一编排分发管理远程主机;

八. 练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
示例:每天凌晨1点 检查/etc/passwd 文件是否被修改,并且生成检查报告

示例:编写脚本 实现ansible node节点(管理的主机)服务器备份 备份/var/log/messages日志 备份到/backup目录下,并且取名2020-11-25-01-log.tar.gz,每一个小时执行一次
############################################################################################
示例:每天凌晨1点 检查/etc/passwd 文件是否被修改,并且生成检查报告
-----------------------------------------------------------------------------------------------------------
方法1 md5sum 检查文件是否修改 md5sum -c --status
check_file.sh
md5sum -c --status d.md5 &&echo "文件未被修改" ||echo "文件已被修改"
md5sum /etc/passwd &> d.md5 #注:文件名必须是 d.md5
-----------------------------------------------------------------------------------------------------------
方法2
check_ectpasswd.sh
a='md5sum /etc/passwd' #注:现在的md5值
b='tail -n1 /root/b' #注:上次的md5值
[[ $a==$b ]]&&echo "文件未被修改!" >> /root/c||echo "文件已被修改!" >> /root/c
$a >> /root/b
-----------------------------------------------------------------------------------------------------------
方法3
touch /tmp/passwd.log
touch /tmp/passwd.txt
a=`md5sum /etc/passwd`
b=`md5sum /tmp/passwd.txt`
c=${a:0:32} #注:因为md5sum是任意长度的输入 固定长度的输出
d=${b:0:32}
if [ $c = $d ]
then
echo "$(date)文件未被修改" >>/tmp/passwd.log
cat /etc/passwd >/tmp/passwd.txt
else
echo "$(date)文件已被修改" >>/tmp/passwd.log
cat /etc/passwd >/tmp/passwd.txt
fi
===========================================================================================================
ansible_playbook_zuoye.yaml
- hosts: all
remote_user: root
tasks:
- name: check file
cron: hour=1 day=*/1 job='/usr/bin/bash ~/check_file.sh'
#注:需要把脚本file到各个虚拟机,没有写这一步
1
2
3
4
5
6
示例:编写脚本 实现ansible node节点(管理的主机)服务器备份 备份/var/log/messages日志 备份到/backup目录下,并且取名2020-11-25-01-log.tar.gz,每一个小时执行一次
- hosts: all
remote_user: root
tasks:
- name: backup messages
cron: hour=1 job='tar czf /backup/$(date +%Y-%m-%d-%H-log.tar.gz) /var/log/messages'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
示例:md5sum 检查文件是否修改 md5sum -c --status
[root@cPen_A lianxi]# man md5sum
-c, --check
read MD5 sums from the FILEs and check them
--status
don't output anything, status code shows success
[root@cPen_A lianxi]# md5sum /etc/passwd > d.md5 #注:写进这个文件 文件名必须是这个 不能变
[root@cPen_A lianxi]# cat d.md5
28b2503e7fb565ddc0b8ec1f9ad6a9c7 /etc/passwd
[root@cPen_A lianxi]# md5sum -c --status d.md5 #注:检查文件是否修改
[root@cPen_A lianxi]# echo $? #注:文件未修改,返回0
0
[root@cPen_A lianxi]# useradd chen223344
[root@cPen_A lianxi]# md5sum -c --status d.md5
[root@cPen_A lianxi]# echo $? #注:文件修改,返回1
1