目录
一:ansible核心模块
1、主机连通性测试
我们使用ansible xxx -m ping
命令来进行主机连通性测试(xxx是主机的组名),效果如下:
[root@kafka-1 ansible]# vim /etc/ansible/hosts
# Ex 2: A collection of hosts belonging to the 'webservers' group
[webservers] #webservers为xxx
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110
192.168.149.152
192.168.149.153
[root@kafka-1 ansible]# ansible webservers -m ping
192.168.149.152 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.149.153 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
2、command模块
command模块可以直接在远程主机上执行命令,并将结果返回主机。如下:
[root@kafka-1 ansible]# ansible webservers -m command -a "ip a"
192.168.149.152 | CHANGED | rc=0 >>
1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:75:96:ae brd ff:ff:ff:ff:ff:ff
inet 192.168.149.152/24 brd 192.168.149.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::7f6a:2f24:7ab1:fd87/64 scope link noprefixroute
valid_lft forever preferred_lft forever
192.168.149.153 | CHANGED | rc=0 >>
1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:bf:e4:78 brd ff:ff:ff:ff:ff:ff
inet 192.168.149.153/24 brd 192.168.149.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::a92b:91d7:cb23:cb92/64 scope link noprefixroute
valid_lft forever preferred_lft forever
在远程主机上执行命令,属于裸执行,非键值对显示;不进行shell解析、 不会解析它的管道符号 会认为ifconfig|grep 是一个命令。该模块还有如下几个命令:
chdir # 在执行命令之前,先切换到该目录
executable # 切换shell来执行命令,需要使用命令的绝对路径
free_form # 要执行的Linux指令,一般使用Ansible的-a参数代替。
creates # 一个文件名,当这个文件存在,则该命令不执行,可以
用来做判断
removes # 一个文件名,这个文件不存在,则该命令不执行
[root@kafka-1 ansible]# ansible webservers -m command -a "chdir=/opt/ ls"
192.168.149.153 | CHANGED | rc=0 >>
apache-zookeeper-3.6.3-bin
apache-zookeeper-3.6.3-bin.tar.gz
dist
dist1
kafka_2.12-2.8.1
kafka_2.12-2.8.1.tgz
192.168.149.152 | CHANGED | rc=0 >>
apache-zookeeper-3.6.3-bin
apache-zookeeper-3.6.3-bin.tar.gz
celery_task
dist
dist1
kafka_2.12-2.8.1
kafka_2.12-2.8.1.tgz
3、shell模块
shell模块可以在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道等。
[root@kafka-1 ansible]# ansible webservers -m shell -a "cat /etc/passwd|grep bash"
192.168.149.152 | CHANGED | rc=0 >>
root:x:0:0:root:/root:/bin/bash
192.168.149.153 | CHANGED | rc=0 >>
root:x:0:0:root:/root:/bin/bash
只要是我们的shell命令,都可以通过这个模块在远程主机上运行。
4、copy模块
这个模块用于将文件复制到远程主机,同时支持给定内容生成文件和修改权限。其相关选项如下:
src #被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是一个目录,则会递归复制,用法类似于"rsync"
content #用于替换"src",可以直接指定文件的值
dest #必选项,将源文件复制到的远程主机的绝对路径
backup #当文件内容发生改变后,在覆盖之前把源文件备份,备份文件包含时间信息
directory_mode #递归设定目录的权限,默认为系统默认权限
force #当目标主机包含该文件,但内容不同时,设为"yes",表示强制覆盖;设为"no",表示目标主机的目标位置不存在该文件才复制。默认为"yes"
others #所有的 file 模块中的选项可以在这里使用
注意:#####src目录后面带/和不带/的区别
#带/ 表示拷贝目录下的子文件或者子文件夹
#不带/ 表示拷贝整个目录
带/---同时如果目的主机没有文件夹,会被新建
[root@kafka-1 lianxi]# ansible webservers -m copy -a "src=/lianxi/ dest=/lianxi1"
192.168.149.152 | CHANGED => {
"changed": true,
"dest": "/lianxi1/",
"src": "/lianxi/"
}
192.168.149.153 | CHANGED => {
"changed": true,
"dest": "/lianxi1/",
"src": "/lianxi/"
}
[root@kafka-3 lianxi1]# pwd
/lianxi1
[root@kafka-3 lianxi1]# ls
2022-08-20-log.tar ansible-copy-link-s a.txt nignx.sh test.sh
不带/
[root@kafka-1 lianxi]# ansible webservers -m copy -a "src=/lianxi dest=/lianxi1"
192.168.149.153 | CHANGED => {
"changed": true,
"dest": "/lianxi1/",
"src": "/lianxi"
}
192.168.149.152 | CHANGED => {
"changed": true,
"dest": "/lianxi1/",
"src": "/lianxi"
}
[root@kafka-3 lianxi1]# ls
2022-08-20-log.tar ansible-copy-link-s a.txt lianxi nignx.sh test.sh
5、file模块
该模块主要用于设置文件的属性,比如创建文件、创建链接文件、删除文件等。下面是一些常见的命令:
force #需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
group #定义文件/目录的属组。后面可以加上mode:定义文件/目录的权限
owner #定义文件/目录的属主。后面必须跟上path:定义文件/目录的路径
recurse #递归设置文件的属性,只对目录有效,后面跟上src:被链接的源文件路径,只应用于state=link的情况
dest #被链接到的路径,只应用于state=link的情况
path #目标路径
src #源文件路径
state #状态,有以下选项:
directory:如果目录不存在,就创建目录
file:即使文件不存在,也不会被创建
link:创建软链接
hard:创建硬链接
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent:删除目录、文件或者取消链接文件
创建链接文件
[root@kafka-1 lianxi]# ansible webservers -m file -a "path=/lianxi1/test.sh-link src=/lianxi1/test.sh state=link"
192.168.149.153 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/lianxi1/test.sh-link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 16,
"src": "/lianxi1/test.sh",
"state": "link",
"uid": 0
}
192.168.149.152 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/lianxi1/test.sh-link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 16,
"src": "/lianxi1/test.sh",
"state": "link",
"uid": 0
}
[root@kafka-3 lianxi1]# ls
2022-08-20-log.tar a.txt nignx.sh test.sh-link
ansible-copy-link-s lianxi test.sh
6、fetch模块
该模块用于从远程某主机获取(复制)文件到本地。有两个选项:
dest:用来存放文件的目录
src:在远程拉取的文件,并且必须是一个file,不能是目录
复制远端文件;本地没有文件夹时会新建,并且文件重名,文件会以远端ip地址命令
[root@kafka-1 lianxi]# ansible webservers -m fetch -a "src=/lianxi1/test.sh dest=/lianxi1"
192.168.149.152 | CHANGED => {
"changed": true,
"checksum": "e539312b99506f8532b313915f5b4a1a747f7c5c",
"dest": "/lianxi1/192.168.149.152/lianxi1/test.sh",
"md5sum": "0957874bbecbacc4aafd1905352a61e7",
"remote_checksum": "e539312b99506f8532b313915f5b4a1a747f7c5c",
"remote_md5sum": null
}
192.168.149.153 | CHANGED => {
"changed": true,
"checksum": "e539312b99506f8532b313915f5b4a1a747f7c5c",
"dest": "/lianxi1/192.168.149.153/lianxi1/test.sh",
"md5sum": "0957874bbecbacc4aafd1905352a61e7",
"remote_checksum": "e539312b99506f8532b313915f5b4a1a747f7c5c",
"remote_md5sum": null
}
[root@kafka-1 lianxi]# ls /lianxi1
192.168.149.152 192.168.149.153
7、cron模块
该模块适用于管理cron
计划任务的。其使用的语法跟我们的crontab
文件中的语法一致,同时,可以指定以下选项:
day= #日应该运行的工作( 1-31, *, */2, )
hour= # 小时 ( 0-23, *, */2, )
minute= #分钟( 0-59, *, */2, )
month= # 月( 1-12, *, /2, )
weekday= # 周 ( 0-6 for Sunday-Saturday,, )
job= #指明运行的命令是什么
name= #定时任务描述
reboot # 任务在重启时运行,不建议使用,建议使用special_time
special_time #特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)
state #指定状态,present表示添加定时任务,也是默认设置,absent表示删除定时任务
user # 以哪个用户的身份执行
开启任务:执行任务每一分钟输出data信息到/tmp/time.txt目录下
[root@kafka-1 lianxi]# ansible webservers -m cron -a "minute=*/1 job='date >>/tmp/time.txt' name=date_test state=present"
192.168.149.152 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"date_test"
]
}
192.168.149.153 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": [
"date_test"
]
}
[root@kafka-3 lianxi1]# cat /tmp/time.txt
2022年 08月 21日 星期日 15:30:01 CST
查看有哪些任务:
[root@kafka-1 lianxi]# ansible webservers -m shell -a "crontab -l"
192.168.149.153 | CHANGED | rc=0 >>
#Ansible: date_test
*/1 * * * * date >>/tmp/time.txt
192.168.149.152 | CHANGED | rc=0 >>
#Ansible: date_test
*/1 * * * * date >>/tmp/time.txt
关闭任务:
[root@kafka-1 lianxi]# ansible webservers -m cron -a "name=date_test state=absent"
192.168.149.152 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
192.168.149.153 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
[root@kafka-1 lianxi]# ansible webservers -m shell -a "crontab -l"
8、yum模块
顾名思义,该模块主要用于软件的安装。其选项如下:
name= #所安装的包的名称
state= #present--->安装, latest--->安装最新的, absent---> 卸载软件。
update_cache #强制更新yum的缓存
conf_file #指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
disable_pgp_check #是否禁止GPG checking,只用于presentor latest。
disablerepo #临时禁止使用yum库。 只用于安装或更新时。
enablerepo #临时使用的yum库。只用于安装或更新时。
安装nginx服务,如果有,不会报错,提示我已经安装
[root@kafka-1 lianxi]# ansible webservers -m yum -a "name=nginx state=present"
192.168.149.153 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"msg": "",
"rc": 0,
"results": [
"1:nginx-1.20.1-9.el7.x86_64 providing nginx is already installed"
]
}
192.168.149.152 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"msg": "",
"rc": 0,
"results": [
"1:nginx-1.20.1-9.el7.x86_64 providing nginx is already installed"
]
}
9、service模块
该模块用于服务程序的管理。其主要选项如下:
arguments #命令行提供额外的参数
enabled #设置开机启动。
name= #服务名称
runlevel #开机启动的级别,一般不用指定。
sleep #在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。(定义在剧本中。)
state #有四种状态,分别为:started--->启动服务, stopped--->停止服务, restarted--->重启服务, reloaded--->重载配置
关闭nginx服务
[root@kafka-1 lianxi]# ansible webservers -m service -a "name=nginx state=stopped"
192.168.149.152 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"name": "nginx",
"state": "stopped",
...
}
[root@kafka-3 lianxi1]# ps -ef|grep nginx
root 4400 1507 0 15:43 pts/0 00:00:00 grep --color=auto nginx
开启nginx服务,并设置开启自启
[root@kafka-1 lianxi]# ansible webservers -m service -a "name=nginx state=started enabled=true"
192.168.149.152 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"enabled": true,
"name": "nginx",
"state": "started",
"status": {
...
}
[root@kafka-3 lianxi1]# ps -ef|grep nginx
root 4603 1 0 15:44 ? 00:00:00 nginx: master process /usr/sbin/ngin
nginx 4604 4603 0 15:44 ? 00:00:00 nginx: worker process
nginx 4605 4603 0 15:44 ? 00:00:00 nginx: worker process
root 4615 1507 0 15:45 pts/0 00:00:00 grep --color=auto nginx
10、script
该模块用于将本机的脚本在被管理端的机器上运行。该模块直接指定脚本的路径即可,我们通过例子来看一看到底如何使用的,首先,我们写一个脚本,并给其加上执行权限:
将字符串写入目的主机的/tmp/ansible.txt文件里
[root@kafka-1 lianxi]# cat test.sh
#!/bin/bash
echo "test ansible" >> /tmp/ansible.txt
[root@kafka-1 lianxi]# chmod +x test.sh
[root@kafka-1 lianxi]# ansible webservers -m script -a "/lianxi/test.sh"
192.168.149.152 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.149.152 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.149.152 closed."
],
"stdout": "",
"stdout_lines": []
}
192.168.149.153 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.149.153 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.149.153 closed."
],
"stdout": "",
"stdout_lines": []
}
[root@kafka-3 lianxi1]# cat /tmp/ansible.txt
test ansible
二: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 运行
3、使用
创建yaml文件
[root@kafka-1 ansible]# pwd
/etc/ansible
[root@kafka-1 ansible]# ls
ansible.cfg ansible_playbook_sc.yaml roles
ansible_playbook_nginx.yaml hosts template_test.yaml
[root@kafka-1 ansible]# cat ansible_playbook_sc.yaml
- hosts: webservers
remote_user: root
tasks:
- name: upload file
copy: src=/etc/passwd dest=/tmp/passwd_tmp1
- name: ip get
shell: ip a
register: shell_result
- debug:
var: shell_result.stdout_lines
执行yaml文件
[root@kafka-1 ansible]# ansible-playbook ansible_playbook_sc.yaml
PLAY [all] ****************************************************************************
TASK [Gathering Facts] ****************************************************************
ok: [192.168.149.152]
ok: [192.168.149.153]
TASK [upload file] ********************************************************************
ok: [192.168.149.152]
ok: [192.168.149.153]
TASK [ip get] *************************************************************************
changed: [192.168.149.153]
changed: [192.168.149.152]
TASK [debug] **************************************************************************
ok: [192.168.149.152] => {
"shell_result.stdout_lines": [
"1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000",
" link/ether 00:0c:29:75:96:ae brd ff:ff:ff:ff:ff:ff",
" inet 192.168.149.152/24 brd 192.168.149.255 scope global noprefixroute ens33",
" valid_lft forever preferred_lft forever",
" inet6 fe80::7f6a:2f24:7ab1:fd87/64 scope link noprefixroute ",
" valid_lft forever preferred_lft forever"
]
}
ok: [192.168.149.153] => {
"shell_result.stdout_lines": [
"1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000",
" link/ether 00:0c:29:bf:e4:78 brd ff:ff:ff:ff:ff:ff",
" inet 192.168.149.153/24 brd 192.168.149.255 scope global noprefixroute ens33",
" valid_lft forever preferred_lft forever",
" inet6 fe80::a92b:91d7:cb23:cb92/64 scope link noprefixroute ",
" valid_lft forever preferred_lft forever"
]
}
PLAY RECAP ****************************************************************************
192.168.149.152 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.149.153 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看任务结果
[root@kafka-3 lianxi1]# cat /tmp/passwd_tmp1
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
...
使用palybook批量部署web服务
[root@kafka-1 ansible]# cat ansible_playbook_nginx.yaml
- hosts: webservers
remote_user: root
tasks:
- name: load nginx
yum: name=nginx state=installed
- name: move conf
copy: src=/opt/sc.conf dest=/etc/nginx/conf.d
- name: move html
copy: src=/opt/index.html dest=/opt/dist1/
- name: start
service: name=nginx state=started
4、template模块
根据一定的条件灵活的设置要复制文件中的部分关键内容,可以使用template模块,模板文件必须以j2结尾。
编写sc_template.conf.j2
[root@kafka-1 ansible]# cat sc_template.conf.j2
server {
listen {{ listen_port }} ;
server_name www.sc.com;
root /opt/dist;
access_log /var/log/nginx/sc_access.log main;
location / {
}
location =/api {
}
}
编写测试剧本
[root@kafka-1 ansible]# cat ansible_playbook_sc.yaml
- hosts: all
remote_user: root
tasks:
- name: upload file
copy: src=/etc/passwd dest=/tmp/passwd_tmp1
- name: ip get
shell: ip a
register: shell_result
- debug:
var: shell_result.stdout_lines
执行playbook
[root@kafka-1 ansible]# ansible-playbook ansible_playbook_sc.yaml
...
也可以直接在/etc/ansible/hosts里修改
[root@kafka-1 ansible]# vim hosts
# Ex 2: A collection of hosts belonging to the 'webservers' group
[webservers]
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110
192.168.149.152 listen_port=666
192.168.149.153 listen_port=777