Linux-ansible
Posted 缘之世界
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux-ansible相关的知识,希望对你有一定的参考价值。
集群自动化维护-必备工具-Ansible
一、概述
自动化运维:批量管理,批量分发,批量执行,维护......
Ansible 是python写的
批量管理工具 | 说明 |
---|---|
Ansible | 无客户端,基于ssh进行管理与维护 |
Saltstack | 需要安装客户端,基于ssh进行管理,与ansible |
terraform | tf批量管理基础设施(主要用于创建公有云) |
二、Ansible管理架构
Inventory 主机清单:被管理主机的ip列表,分类
ad-hoc 模式:命令行批量管理(使用ansible模块),临时任务
playbook 剧本模式:类似把操作写成脚本,可以重复运行这个脚本
三、部署与配置
1.部署
[root@m01 ~]# yum -y install ansible
2.配置
[root@m01 ~]# egrep -vn "^#|^$" /etc/ansible/ansible.cfg
10:[defaults]
#修改配置文件关机主机验证(就是远程连接时的yes/no):host_key_checking
71:host_key_checking = False #解开注释即可
#修改配置文件开启日志功能
111:log_path = /var/log/ansible.log #解开注释即可
327:[inventory]
340:[privilege_escalation]
346:[paramiko_connection]
370:[ssh_connection]
431:[persistent_connection]
445:[accelerate]
460:[selinux]
469:[colors]
485:[diff]
四、Ans-inventory 主机清单
什么是主机清单:让ansible管理的节点的列表
ansible 默认读取在/etc/ansible/hosts文件,并非/etc/hosts
实际使用中一般我们会把主机清单文件存放在指定的目录中,运行ansible的时候,通过-i来指定主机清单文件
1.主机清单必会格式
主机清单格式:
[分类或分组的名字] #注意分类要体现出服务器的作用 分组:一般按照层次,功能,业务进行分组
ip地址或主机名或域名 #注意主机名要能解析才行
#对主机分组并进行连接测试
[root@m01 ~]# cat /etc/ansible/hosts
[web]
172.16.1.7
[nfs]
172.16.1.31
[backup]
172.16.1.41
[root@m01 ~]# ansible all -m ping
172.16.1.41 | SUCCESS =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": false,
"ping": "pong"
172.16.1.7 | SUCCESS =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": false,
"ping": "pong"
172.16.1.31 | SUCCESS =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": false,
"ping": "pong"
ansible命令格式:
ansible 主机ip或分组或all -m 指定使用的模块名字
这里的ping模块用于检查被管理端是否可以访问
2.子组
#创建新的分组包含已有的分组backup和nfs
[root@m01 ~]# cat /etc/ansible/hosts
[web]
172.16.1.7
[nfs]
172.16.1.31
[backup]
172.16.1.41
[data:children]
nfs
backup
[root@m01 ~]# ansible data -m ping
172.16.1.41 | SUCCESS =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": false,
"ping": "pong"
172.16.1.31 | SUCCESS =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": false,
"ping": "pong"
子组使用children关键词创建
格式:
[data:children] #子组名字:children
3.指定用户,密码
不推荐,推荐先配置密钥认证,然后进行管理
#没有设置密钥认证,主机清单如何书写
[root@m01 ~]# ssh 172.16.1.7 hostname
root@172.16.1.7\'s password:
#172.16.1.7已经没有密钥认证
[root@m01 ~]# cat /etc/ansible/hosts
[web]
172.16.1.7 ansible_user=root ansible_password=1 ansible_port=22 #书写格式
[nfs]
172.16.1.31
[backup]
172.16.1.41
[data:children]
nfs
backup
[root@m01 ~]# ansible web -m ping
172.16.1.7 | SUCCESS =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": false,
"ping": "pong"
五、Ansible必知必会模块
1. ansible模块概述
- ansible中模块就类似于Linux中的命令,我们Linux命令管理系统,我们通过ansible模块实现批量管理
- ansible中模块一般相当于Linux中的一些命令,yum模块,file模块,user模块
- ansible中模块拥有不同的选项,这些选项一般都一些单词,拥有自己的格式与要求
模块分类 | 模块 |
---|---|
命令和脚本模块 | command模块,ansible默认的模块,执行简单的命令,不支持特殊符号 |
shell模块 执行命令,支持特殊符号 | |
script模块 分发脚本并执行 | |
文件 | file 创建目录,文件,软链接 |
copy 远程分发文件,修改权限,所有者,备份 | |
服务 | systemd服务管理 |
service 服务管理 | |
软件包 | yum_repository yum源 |
yum命令 | |
get_url 下载软件 | |
系统管理 | mount模块 挂载 |
cron模块 定时任务 | |
用户管理 | group模块 管理用户组 |
user模块 管理用户 | |
其他 | unarchive 压缩解压 |
synchronize rsync模块 | |
mysql_db,mysql_user 数据库模块 | |
ansible管理docker,k8s,zabbix,grafana | |
用于调试模块 | ping 模块检查,ansible与其他节点的联通性 |
debug 模块 用于检查/显示 变量 |
2. 命令格式
ansible | |||
---|---|---|---|
ansible | 主机清单(all/web/172.16.1.7) | -m 模块名 | -a 模块中的选项 |
-i 指定主机清单文件 | -m 指定模块 | -a 指定模块中的选项 |
温馨提示:
-a 选项的内容中如果有 \' \' ,那么-a 的 \' \' 要变成 " " ,或者内容中的变成 " "
3. 命令与脚本类模块
3.1 command模块
ansible默认的模块,适用于执行简单的命令,不支持特殊符号
#批量获取所有主机的主机名
[root@m01 ~]# ansible web -m command -a \'hostname\'
172.16.1.7 | CHANGED | rc=0 >>
web01
[root@m01 ~]# ansible web -a \'hostname\'
172.16.1.7 | CHANGED | rc=0 >>
web01
3.2 shell模块
与command模块类似,但是shell支持特殊符号
#批量删除/tmp/下面所有内容
[root@m01 ~]# ansible web -m shell -a \'rm -rf /tmp/*\'
[WARNING]: Consider using the file module with state=absent rather than running \'rm\'. If you need to use command because file is insufficient you can
add \'warn: false\' to this command task or set \'command_warnings=False\' in ansible.cfg to get rid of this message.
172.16.1.7 | CHANGED | rc=0 >>
注意事项:
-a 后边的命令不能用别名,如果有特殊符号要使用撬棍
温馨提示:
shell 模块不推荐执行较为复杂的指令,如果需要执行放在脚本中执行
避免因为特殊符号和引号导致的问题
3.3 script模块
执行流程:
分发脚本(传输脚本),在被管理端运行脚本
[root@m01 ~]# cat /server/scripts/ansible_script.sh
#!/bin/bash
#author: wh
#desc: 系统巡检脚本
hostname
hostname -I
ip a s eth0 |awk -F\'[ /]+\' \'NR==3print $3\'
uptime
whoami
date +%F
sleep 5
#执行脚本
[root@m01 ~]# ansible web -m script -a \'/server/scripts/ansible_script.sh\'
172.16.1.7 | CHANGED =>
"changed": true,
"rc": 0,
"stderr": "Shared connection to 172.16.1.7 closed.\\r\\n",
"stderr_lines": [
"Shared connection to 172.16.1.7 closed."
],
"stdout": "web01\\r\\n10.0.0.7 172.16.1.7 \\r\\n10.0.0.7\\r\\n 17:30:35 up 14:57, 3 users, load average: 0.06, 0.15, 0.14\\r\\nroot\\r\\n2023-02-02\\r\\n",
"stdout_lines": [
"web01",
"10.0.0.7 172.16.1.7 ",
"10.0.0.7",
" 17:30:35 up 14:57, 3 users, load average: 0.06, 0.15, 0.14",
"root",
"2023-02-02"
]
#执行脚本被控端流程
#把脚本先放在临时目录,执行完在删除
[root@web01 ~]# ps -ef|grep ansible
root 10621 10513 0 09:18 pts/2 00:00:00 /bin/sh -c /root/.ansible/tmp/ansible-tmp-1675300696.78-5875-246300159085630/ansible_script.sh && sleep 0
root 10632 10621 0 09:18 pts/2 00:00:00 /bin/bash /root/.ansible/tmp/ansible-tmp-1675300696.78-5875-246300159085630/ansible_script.sh
root 10642 10203 0 09:18 pts/1 00:00:00 grep --color=auto ansible
[root@web01 ~]# cd /root/.ansible/tmp
[root@web01 ~/.ansible/tmp]# ll
total 0
4.文件相关模块
4.1 file模块
file模块不仅可以管理文件,还可以管理目录,管理软链接
file模块相当于把touch命令,mkdir命令,rm命令,ln -s命令结合在一起
模块选项 | 说明 |
---|---|
path |
路径(目录,文件) |
src | source源,源文件一般用于link(创建软链接),用于指定源文件 |
state |
状态:具体要做什么,创建/删除,操作文件/操作目录 state=directory 创建目录 state=file (默认)更新文件,如果文件不存在也不创建 state=link 创建软链接 state=touch 创建文件 state=absent 删除(如果是目录,递归删除目录) |
mode | 创建并修改权限 |
owner | 设置属主 |
group | 设置属组 |
#创建/opt/test.txt
[root@m01 ~]# ansible web -m file -a \'path=/opt/test.txt state=touch\'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": true,
"dest": "/opt/test.txt",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
[root@m01 ~]# ansible web -a \'ls /opt/\'
172.16.1.7 | CHANGED | rc=0 >>
test.txt
#创建目录/test/a/b/c/
[root@m01 ~]# ansible web -m file -a \'path=/test/a/b/c/ state=directory\'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/test/a/b/c/",
"size": 6,
"state": "directory",
"uid": 0
[root@m01 ~]# ansible web -a \'tree /test/\'
172.16.1.7 | CHANGED | rc=0 >>
/test/
└── a
└── b
└── c
3 directories, 0 files
#创建软连接 /etc/hosts创建软连接到/opt/下
[root@m01 ~]# ansible web -m file -a \'src=/etc/hosts path=/opt/hosts state=link\'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": true,
"dest": "/opt/hosts",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 10,
"src": "/etc/hosts",
"state": "link",
"uid": 0
[root@m01 ~]# ansible web -a \'ls -l /opt/\'
172.16.1.7 | CHANGED | rc=0 >>
total 0
lrwxrwxrwx 1 root root 10 Feb 2 17:47 hosts -> /etc/hosts
-rw-r--r-- 1 root root 0 Feb 2 17:43 test.txt
#创建/ans-backup/目录 所有者是test,权限是700
[root@m01 ~]# ansible web -m file -a \'path=/ans-backup mode=700 owner=test state=directory\'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": true,
"gid": 0,
"group": "root",
"mode": "0700",
"owner": "test",
"path": "/ans-backup",
"size": 6,
"state": "directory",
"uid": 2001
[root@m01 ~]# ansible web -a \'ls -ld /ans-backup\'
172.16.1.7 | CHANGED | rc=0 >>
drwx------ 2 test root 6 Feb 2 17:49 /ans-backup
#删除/test/目录
[root@m01 ~]# ansible web -m file -a \'path=/test/ state=absent\'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": true,
"path": "/test/",
"state": "absent"
[root@m01 ~]# ansible web -a \'ls /test/\'
172.16.1.7 | FAILED | rc=2 >>
ls: cannot access /test/: No such file or directorynon-zero return code
温馨提示:
查看模块帮助,可以通过 ansible-doc -s 模块名 来查看。
[root@m01 ~]# ansible-doc -s file
4.2 copy模块
批量分发:scp,1个节点(管理节点)发送文件或压缩包到所有被管理端。注意:copy是单向的传输
模块选项 | 说明 |
---|---|
src |
source 源文件,管理端的某个文件 |
dest |
destination 目标,被管理端的目录/文件 |
backup | backup=yes 会在覆盖前进行备份,文件内容要有变化与区别 |
mode | 修改权限 |
owner | 修改为指定的所有者 |
group | 修改为指定的用户组 |
#分发书写好的/etc/hosts文件,如果文件存在则备份下
[root@m01 ~]# ansible web -m copy -a \'src=/etc/hosts dest=/etc/hosts backup=yes\'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"backup_file": "/etc/hosts.25211.2023-02-02@17:56:27~",
"changed": true,
"checksum": "665a4fa576811b11d78028074633acaddc8c292e",
"dest": "/etc/hosts",
"gid": 0,
"group": "root",
"md5sum": "b304c1bff962a2f1aaa79a4b5c618126",
"mode": "0644",
"owner": "root",
"size": 334,
"src": "/root/.ansible/tmp/ansible-tmp-1675331786.28-9824-177488215351037/source",
"state": "file",
"uid": 0
[root@web01 ~]# ll -d /etc/hosts*
-rw-r--r-- 1 root root 334 Feb 2 17:56 /etc/hosts
-rw-r--r-- 1 root root 330 Feb 2 10:38 /etc/hosts.25211.2023-02-02@17:56:27~ #备份文件
补充:
copy是推送,批量推送
fetch是拉取,批量拉取,使用较少
4.3 lineinfile
类似于sed \'cai\'.
模块选项 | 说明 |
---|---|
path | 要修改的文件,指定文件 |
regexp | 修改正则匹配的内容,如果匹配多行,修改最后一行 |
line | 写入的内容 |
create | yes 如果文件不存在,进行创建 |
4.4 replace
类似于sed -i \'sg\'
4.5 unarchive
模块 | 说明 |
---|---|
creates | 一个文件名,当它已经存在时,这个步骤将不会被运行 |
copy | 默认为yes,拷贝的文件从ansible主机复制到远程主机,no在远程主机上寻找src源文件解压 |
src | tar源路径,可以是ansible主机上的路径,也可以是远程主机上的路径,如果是远程主机上的路径,则需设置copy=no |
dest | 远程主机上的目标绝对路径 |
mode | 设置解压缩后的文件权限 |
exec | 列出需要排除的目录和文件 |
remote_src | 设置remote_src=yes为解包目标上已经存在的档案。对于Windows目标,改用win_unzip模块。 |
owner | 解压后文件或目录的属主 |
group | 解压后的目录或文件的属组 |
5.服务管理模块
systemd相当于Linux systemctl命令
systemd模块 | 说明 |
---|---|
name |
用于指定服务名称 |
enabled |
yes开机自启动(yes/no) |
state |
表示服务开,关,重启... state=started 开启 state=stopped 关闭 state=reloaded 重读配置文件 state=restarted 重启(关闭再开启) |
daemon-reload | yes是否重新加载对应的服务的管理配置文件 |
#开启firewalld服务并设置开机自启动
[root@m01 ~]# ansible web -m systemd -a \'name=firewalld enabled=yes state=started\'
[root@m01 ~]# ansible web -a \'systemctl status firewalld\'
172.16.1.7 | CHANGED | rc=0 >>
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2023-02-02 19:02:37 CST; 49s ago
Docs: man:firewalld(1)
Main PID: 26620 (firewalld)
CGroup: /system.slice/firewalld.service
└─26620 /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid
Feb 02 19:02:37 web01 systemd[1]: Starting firewalld - dynamic firewall daemon...
Feb 02 19:02:37 web01 systemd[1]: Started firewalld - dynamic firewall daemon.
Feb 02 19:02:37 web01 firewalld[26620]: WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option. It will be removed in a future release. Please consider disabling it now.
#关闭firewalld服务并不让开机自启动
[root@m01 ~]# ansible web -m systemd -a \'name=firewalld enabled=no state=stopped\'
[root@m01 ~]# ansible web -a \'systemctl status firewalld\'
172.16.1.7 | FAILED | rc=3 >>
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)
Feb 02 10:59:31 web01 systemd[1]: Starting firewalld - dynamic firewall daemon...
Feb 02 10:59:33 web01 systemd[1]: Started firewalld - dynamic firewall daemon.
Feb 02 10:59:34 web01 firewalld[13868]: WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option. It will be removed in a future release. Please consider disabling it now.
Feb 02 10:59:48 web01 systemd[1]: Stopping firewalld - dynamic firewall daemon...
Feb 02 10:59:48 web01 systemd[1]: Stopped firewalld - dynamic firewall daemon.
Feb 02 19:02:37 web01 systemd[1]: Starting firewalld - dynamic firewall daemon...
Feb 02 19:02:37 web01 systemd[1]: Started firewalld - dynamic firewall daemon.
Feb 02 19:02:37 web01 firewalld[26620]: WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option. It will be removed in a future release. Please consider disabling it now.
Feb 02 19:03:54 web01 systemd[1]: Stopping firewalld - dynamic firewall daemon...
Feb 02 19:03:54 web01 systemd[1]: Stopped firewalld - dynamic firewall daemon.non-zero return code
补充:
systemd模块适用于目前大部分的Linux系统
service模块适用于管理旧的Linux系统
6.软件管理模块
6.1 yum模块
yum模块并不只是yum命令,包含了yum/apt命令
模块选项 | 说明 |
---|---|
name | 指定的软件包名字,可以指定多个,通过","分隔 |
state | installed 安装(也可以写为present)默认 removed 删除 (也可以写为absent) lastest 安装或更新 |
update_cache | 可以设置为no,表示不更新本地yum缓存,这样下载快。实际应用建议开启 |
#安装常用的软件htop,tree,lrzsz,sshpass
[root@m01 ~]# ansible web -m yum -a \'name=tree,lrzsz\'
172.16.1.7 | SUCCESS =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": false,
"msg": "",
"rc": 0,
"results": [
"tree-1.6.0-10.el7.x86_64 providing tree is already installed",
"lrzsz-0.12.20-36.el7.x86_64 providing lrzsz is already installed"
]
6.2 get_url模块
相当于wegt命令,所有主机能访问网络才行
推荐在管理节点下载号,使用copy仅分发即可
模块选项 | 说明 |
---|---|
url | 指定要下载的地址 |
dest | 下载到哪个目录 |
#下载zabbix-agent的软包到/app/tools下面
zabbix-agent地址为:
https://mir rors.aliyun.com/zabbix/zabbix/6.0/rhel/7/x86_64/zabbix-agent-6.0.13-release1.el7.x86_64.rpm
[root@m01 ~]# ansible web -m file -a \'path=/app/tools state=directory\'
[root@m01 ~]# ansible web -m get_url -a \'url="https://mirrors.aliyun.com/zabbix/zabbix/6.0/rhel/7/x86_64/zabbix-agent-6.0.13-release1.el7.x86_64.rpm" dest=/app/tools \'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": true,
"checksum_dest": null,
"checksum_src": "19d3cab2ee9d0f69d0d8752165def185615c9607",
"dest": "/app/tools/zabbix-agent-6.0.13-release1.el7.x86_64.rpm",
"elapsed": 1,
"gid": 0,
"group": "root",
"md5sum": "ee1fb29f984b12a1bb381e881293e154",
"mode": "0644",
"msg": "OK (543376 bytes)",
"owner": "root",
"size": 543376,
"src": "/root/.ansible/tmp/ansible-tmp-1675337078.76-10471-19543799047354/tmpIEKEMp",
"state": "file",
"status_code": 200,
"uid": 0,
"url": "https://mirrors.aliyun.com/zabbix/zabbix/6.0/rhel/7/x86_64/zabbix-agent-6.0.13-release1.el7.x86_64.rpm"
如果要安装,可以调用yum模块安装本地的软件
name=/app/tools/zabbix-agent-6.0.13-release1.el7.x86_64.rpm
6.3 yum_repository模块
一般都是写好yum配置文件,copy分发过去,很少用这个模块
模块选项 | 说明 |
---|---|
name | yum源中的名字[epel] |
description | yum源的注释说明,对应的是name的内容 |
baseurl | yum源中的baseurl下载地址 |
enabled | 是否启动这个源yes/no |
gpgcheck | 是否启动gpgcheck功能 no |
file | 指定yum源的文件 自动添加.repo 默认与模块的名字一样 |
[root@web01 ~]# cat /etc/yum.repos.d/epel.repo
[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=http://mirrors.aliyun.com/epel/7/$basearch
failovermethod=priority
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
yum配置文件内容 | yum源的模块的选项 |
---|---|
[epel] | name=epel #默认yum源文件的名字和这个一致 |
name=Extra Packages xxxxx | description="Extra Packages xxxxx" |
baseurl=http://mirrors.aliyun.com/epel/7/$basearch | baseurl="http://mirrors.aliyun.com/epel/7/$basearch" |
enabled=1 | enabled=yes |
gpgcheck=0 | gpgcheck=no |
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[root@m01 ~]# ansible web -m yum_repository -a \'name=nginx description="nginx repo" baseurl="http://nginx.org/packages/centos/$releasever/$basearch/" gpgcheck=no enabled=yes\'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": true,
"repo": "nginx",
"state": "present"
[root@m01 ~]# ansible web -a \'cat /etc/yum.repos.d/nginx.repo\'
172.16.1.7 | CHANGED | rc=0 >>
[nginx]
baseurl = http://nginx.org/packages/centos/$releasever/$basearch/
enabled = 1
gpgcheck = 0
name = nginx repo
温馨提示:
nginx yum源的地址:http://nginx.org/en/linux_packages.html#RHEL
7.用户管理模块
7.1 user模块
相当于用户管理的useradd,userdel
模块选项 | 说明 |
---|---|
name |
www 用户名 |
uid |
指定uid |
group | 指定用户组,一般用于事项创建好了用户组,通过选项指定 |
shell |
指定命令解释器:默认是/bin/bash |
create_home |
是否创建家目录(yes/no) |
state | present 添加 absent 删除 |
password | 加密的密码 |
#创建www-ans用户uid 2000虚拟用户
[root@m01 ~]# ansible web -m user -a \'name=www-ans uid=2000 shell=/sbin/nologin create_home=no state=present\'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": true,
"comment": "",
"create_home": false,
"group": 2000,
"home": "/home/www-ans",
"name": "www-ans",
"shell": "/sbin/nologin",
"state": "present",
"system": false,
"uid": 2000
[root@m01 ~]# ansible web -a \'id www-ans\'
172.16.1.7 | CHANGED | rc=0 >>
uid=2000(www-ans) gid=2000(www-ans) groups=2000(www-ans)
#批量更改密码
[root@m01 ~]# ansible all -i localhost, -m debug -a "msg= \'1\' |password_hash(\'sha512\',\'mima\')"
localhost | SUCCESS =>
"msg": "$6$mima$/JbXK6m0czPNRNkpNqMoAI.5kk6XZBreAKaTpV1OFDd7YGXbUe2ySHgky2KaFnUKw7ghVY2G0zer5jhLWp3DT0"
#更新密码。密码为1
[root@m01 ~]# ansible web -m user -a "name=test password= \'1\' |password_hash(\'sha512\',\'mima\') state=present"
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"append": false,
"changed": true,
"comment": "",
"group": 2001,
"home": "/home/test",
"move_home": false,
"name": "test",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/bin/bash",
"state": "present",
"uid": 2001
补充:
关于 的解释
\'1\' |password_hash(\'sha512\',\'mima\')
表示密码 1 ,经过管道,传递给了password_hash()插件,sha512加密算法,mima是随机字符用于生成随机加密后的密码
7.2 group模块
模块选项 | 说明 |
---|---|
name | 指定用户组的名字 |
gid | 指定组的gid |
state | present 添加 absent 删除 |
8. mount 模块
实现mount命令进行挂载可以修改/etc/fstab实现永久挂载
模块选项 | 说明 |
---|---|
fstype | filesystem type 指定文件系统,xfs ,ext4, iso9660,nfs |
src | 源地址,nfs地址 |
path | 注意这里不是dest,挂载点(要把源挂载到哪里) |
state | 下表 |
mount模块的state参数可使用的值 | |
---|---|
absent |
卸载并修改fstab |
umounted | 卸载不修改/etc/fstab |
present | 仅修改/etc/fstab 不挂载 |
mounted |
挂载并修改/etc/fstab |
remounted | 重新挂载 |
# 通过ans管理在web01上挂载nfs:/data挂载到web01的/ans-upload/
#在web服务器上安装nfs
[root@m01 ~]# ansible web -m yum -a \'name=nfs-utils state=present\'
#创建挂载点
[root@m01 ~]# ansible web -m file -a \'path=/ans-upload state=directory\'
#挂载nfs
[root@m01 ~]# ansible web -m mount -a \'src=172.16.1.31:/data/ path=/ans-upload fstype=nfs state=mounted\'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": true,
"dump": "0",
"fstab": "/etc/fstab",
"fstype": "nfs",
"name": "/ans-upload",
"opts": "defaults",
"passno": "0",
"src": "172.16.1.31:/data/"
#检查
[root@m01 ~]# ansible web -a \'df -h\'
172.16.1.7 | CHANGED | rc=0 >>
Filesystem Size Used Avail Use% Mounted on
devtmpfs 475M 0 475M 0% /dev
tmpfs 487M 0 487M 0% /dev/shm
tmpfs 487M 26M 461M 6% /run
tmpfs 487M 0 487M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 2.3G 15G 14% /
/dev/sda1 1014M 138M 877M 14% /boot
tmpfs 98M 0 98M 0% /run/user/0
172.16.1.31:/data 17G 2.0G 16G 12% /ans-upload
[root@m01 ~]# ansible web -a \'grep upload /etc/fstab\'
172.16.1.7 | CHANGED | rc=0 >>
172.16.1.31:/data/ /ans-upload nfs defaults 0 0
#卸载
[root@m01 ~]# ansible web -m mount -a \'path=/ans-upload state=absent\'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": true,
"dump": "0",
"fstab": "/etc/fstab",
"name": "/ans-upload",
"opts": "defaults",
"passno": "0"
9.cron模块
用于管理系统的定时任务,替代了crontab -e
模块选项 | 说明 |
---|---|
name |
定时任务名字,一定要加上,对用注释 |
minute | 分钟 minute="*/2" |
hour | 小时 |
day | 日期 |
month | 月份 |
week | 周几 |
job | 指定命令或脚本(定向到空) |
state | present 添加定时任务(默认) absent 删除 |
# 每3分钟同步时间
[root@m01 ~]# ansible web -m cron -a \'name="3.ansible rsync time" minute="*/3" job="/sbin/ntpdate ntp1.aliyun.com &>/dev/null" state=present\'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": true,
"envs": [],
"jobs": [
"3.ansible rsync time"
]
[root@m01 ~]# ansible web -a \'crontab -l\'
172.16.1.7 | CHANGED | rc=0 >>
#1.配置时间同步
*/2 * * * * /sbin/ntpdate ntp1.aliyun.com &>/dev/null
#2.定时备份etc和定时任务
* * * * * sh /server/scripts/conf_backup.sh &>/dev/null
#Ansible: 3.ansible rsync time
*/3 * * * * /sbin/ntpdate ntp1.aliyun.com &>/dev/null
#删除定时任务
[root@m01 ~]# ansible web -m cron -a \'name="3.ansible rsync time" state=absent\'
172.16.1.7 | CHANGED =>
"ansible_facts":
"discovered_interpreter_python": "/usr/bin/python"
,
"changed": true,
"envs": [],
"jobs": []
[root@m01 ~]# ansible web -a \'crontab -l\'
172.16.1.7 | CHANGED | rc=0 >>
#1.配置时间同步
*/2 * * * * /sbin/ntpdate ntp1.aliyun.com &>/dev/null
#2.定时备份etc和定时任务
* * * * * sh /server/scripts/conf_backup.sh &>/dev/null
#清理已有的定时任务,不是ansible创建的
ansible all -a "sed -i \'/ntpdate/d\' /var/spool/cron/root"
10. debug
用于调试
模块选项 | 说明 |
---|---|
msg | 输出提示 |
六、剧本
1.概述
剧本:
playbook文件,用于长久保存并且实现批量管理,维护,部署的文件,类似于脚本存放命令和变量
剧本yaml格式,yaml格式的文件:空格,冒号
ans剧本 | ans ad-doc | |
---|---|---|
共同点 | 批量使用,使用模块 | 批量管理,使用模块 |
区别 | 重复调用 | 不是很方便,不容易重复使用 |
应用场景 | 部署服务,多个步骤的任务 | 测试模块,临时性任务 |
2.剧本书写格式:
[root@m01 /server/scripts/playbook]# cat 1.show.yml
--- #可以写可以不写
- hosts: all #角色:play 指定你要管理的主机(主机清单里面的)
tasks: #任务:tasks 具体要执行的模块
- name: 01 打开冰箱门
shell: echo 01 >>/tmp/bingxiang.log #模块: 根据你的操作流程,步骤选择模块
- name: 02 把大象放入冰箱
shell: echo 02 >>/tmp/bingxiang.log
- name: 03 关上冰箱的门
shell: echo 03 >>/tmp/bingxiang.log
#书写剧本,注意以.yml或.yaml结尾
#执行剧本:
[root@m01 /server/scripts/playbook]# cat hosts
[web]
172.16.1.7
#[nfs]
#172.16.1.31
#[backup]
#172.16.1.41
#[data:children]
#nfs
#backup
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts 1.show.yml
PLAY [all] *********************************
TASK [Gathering Facts] *********************
ok: [172.16.1.7]
TASK [01 打开冰箱门] ****************************
changed: [172.16.1.7]
TASK [02 把大象放入冰箱] **************************
changed: [172.16.1.7]
TASK [03 关上冰箱的门] ***************************
changed: [172.16.1.7]
PLAY RECAP *********************************
172.16.1.7 : ok=4 changed=3 unreachable=0 ailed=0 skipped=0 rescued=0 ignored=0
补充:
执行的时候显示奶牛
可以删除软件或修改ansible.cfg配置进行关闭
nocows=1 去掉注释即可
书写Ans playbook注意事项:
- 同一个层级的内容对齐
- 不同层级的通过2个空格对齐
- 不能使用tab键
3.剧本案例
一般步骤:
- 列出流程
- 找出每个步骤的命令
- 把上面的步骤与命令--->找出对应的ans模块
- 书写剧本
- 书写剧本前拍摄快照,边书写剧本边测试,最后测试完成,恢复快照,重新跑一次(分步测试,联合测试)
3.1 创建目录并分发文件
1. 创建目录/server/files/
2. /etc/hosts文件发送过去/server/files/
[root@m01 /server/scripts/playbook]# cat 2.fenfa.yml
---
- hosts: all
tasks:
- name: 1.创建目录
file:
path: /server/files/
state: directory
- name: 2.分发文件
copy:
src: /etc/hosts
dest: /server/files
3.2 分发软件包,安装软件包,启动服务
1.zabbix-agent软件包(下载)
2.安装软件包
3.配置(略)
4.启动开机自启动
[root@m01 /server/scripts/playbook]# cat 3.zabbix.yml
---
- hosts: all
tasks:
- name: 1.下载软件包
get_url:
url: https://mirrors.tuna.tsinghua.edu.cn/zabbix/zabbix/6.0/rhel/7/x86_64/zabbix-agent-6.0.7-1.el7.x86_64.rpm
dest: /tmp/
validate_certs: no
- name: 2.安装软件包
yum:
name: /tmp/zabbix-agent-6.0.7-1.el7.x86_64.rpm
state: present
- name: 3.配置软件包
debug:
msg: "进行配置zabbix-agent"
- name: 4.启动软件包
systemd:
name: zabbix-agent
enabled: yes
state: started
3.3 nfs 服务
nfs服务端:在backup上部署nfs服务,共享/backup-nfs目录,all_squash,匿名用户:nfsnobody
nfs客户端:web挂载 /ans-upload目录挂载nfs服务端共享的/backup-nfs(永久挂载)
服务端流程:
1. 部署nfs-utils,rpcbind
2. 修改配置文件
3. 创建共享目录并改所有者
4. 启动服务rpcbind,nfs(注意顺序)
客户端流程:
1. 安装nfs-utils
2. 挂载与永久挂载
[root@m01 /server/scripts/playbook]# cat 4.nfs-playbook.yml
- hosts: backup
tasks:
- name: 部署nfs-utils,rpcbind
yum:
name: nfs-utils,rpcbind
state: present
- name: 修改配置文件
lineinfile:
path: /etc/exports
line: "/backup-nfs 172.16.1.0/24(rw,all_squash)"
- name: 创建共享目录并改所有者
file:
path: /backup-nfs
state: directory
owner: nfsnobody
group: nfsnobody
- name: 启动服务rpcbind
systemd:
name: rpcbind
enabled: yes
state: started
- name: 启动服务nfs
systemd:
name: nfs
enabled: yes
state: started
- hosts: web
tasks:
- name: 安装nfs-utils
yum:
name: nfs-utils
state: present
- name: 挂载与永久挂载
mount:
src: 172.16.1.41:/backup-nfs
path: /ans-upload
fstype: nfs
state: mounted
七、Ansible中的变量
变量无处不在,在ans中大部分的地方都可以定义变量
常用的创建变量的地方:剧本中,类似与 `` 功能,共用的变量文件
可以定义变量的地方 | 说明 |
---|---|
在剧本文件中的定义 | 比较常用,仅限于当前的play使用 |
register变量(注册变量) | 实现脚本中反引号的功能,可以获取命令结果 |
变量文件,根据主机清单分组进行定义变量 | 如果多个剧本,使用相同的变量 |
inventory主机清单中定义变量 | 用于批量修改主机使用, |
命令行中 | 几乎不用 |
facts变量 | 一般用于获取主机基本信息:ip,主机名,系统 |
1. 剧本中使用变量
#批量创建/test/a/b/c/d/
[root@m01 /server/scripts/playbook]# cat 5.vars.yml
- hosts: all
vars:
dir: /test/a/b/c/d/
tasks:
- name: 创建目录
file:
path: " dir "
state: directory
注:vars: variable 变量的内容,变量
dir就是一个变量,变量的内容就是右边的内容
温馨提示:
使用变量的时候如果变量是某个选项的开头,则变量引用的时候需要加上双引号
file:
path: " dir " #这种要添加,变量是开头.
file:
path: /test/ dir #这种可以不加引号,变量不 是开头.
注意事项:
在剧本play中定义变量:
- 仅仅在当前play生效
- 一般用来存放路径,用户名,ip地址
- 注意引号的使用
2. 共用变量-变量文件
[root@m01 /server/scripts/playbook]# cat vars_file.yml
user: www
dir: /dest
[root@m01 /server/scripts/playbook]# cat 6.vars_file.yml
- hosts: all
vars_files: ./vars_file.yml
tasks:
- name: 测试
debug:
msg: "测试vars: user dir"
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts 6.vars_file.yml
PLAY [all] ****************************
TASK [Gathering Facts] ************************
ok: [172.16.1.7]
ok: [172.16.1.41]
TASK [测试] *****************************
ok: [172.16.1.7] =>
"msg": "测试vars: www /dest"
ok: [172.16.1.41] =>
"msg": "测试vars: www /dest"
PLAY RECAP ****************************
172.16.1.41 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
172.16.1.7 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3. 共用变量- 根据主机组使用变量
group_vars根据主机清单的分组去匹配
变量文件
主机组创建变量文件
xxxx-check.yml
group_vars/
lb/vars.yml #存放lb组的变量
web/vars.yml #存放web组的变量
data/vars.yml #存放xxx组的变量
all/vars.yml #所有主机共用的变量
未来一般使用all分组即可,把所有变量存放在一起,供剧本使用.
[root@m01 /server/scripts/playbook]# mkdir -p group_vars/all
[root@m01 /server/scripts/playbook]# cat group_vars/all/vars.yml
user: www
dir: /test
[root@m01 /server/scripts/playbook]# cat 7.ans_group_vars.yml
- hosts: all
tasks:
- name: 测试所有主机
debug:
msg: "测试所有主机: user dir "
- hosts: web
tasks:
- name: 测试web主机
debug:
msg: "测试web主机: user dir "
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts 7.ans_group_vars.yml
PLAY [all] ****************************
TASK [Gathering Facts] ************************
ok: [172.16.1.7]
ok: [172.16.1.41]
TASK [测试所有主机] *************************
ok: [172.16.1.7] =>
"msg": "测试所有主机: www /test"
ok: [172.16.1.41] =>
"msg": "测试所有主机: www /test"
PLAY [web] ****************************
TASK [Gathering Facts] ************************
ok: [172.16.1.7]
TASK [测试web主机] ************************
ok: [172.16.1.7] =>
"msg": "测试web主机: www/test"
PLAY RECAP ****************************
172.16.1.41 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
温馨提示:
group_vars应用提示:
-般使用group_vars中all分组
4. register 变量注册变量
本质上就是用来实现脚本的反引号功能
用户通过命令获取的内容都存放到register变量中
某个register变量的信息
"msg":
"changed": true,
"cmd": "date +%F",
"delta": "0:00:00.004257",
"end": "2023-02-04 15:17:24.290526",
"failed": false,
"rc": 0,
"start": "2023-02-04 15:17:24.286269",
"stderr": "",
"stderr_lines": [],
"stdout": "2023-02-04",
"stdout_lines": [
"2023-02-04"
]
[root@m01 /server/scripts/playbook]# cat 8.reg.yml
- hosts: web
tasks:
- name: get date
shell: date +%F
register: result
- name: 打印result内容
debug:
msg: " result.stdout "
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts 8.reg.yml
PLAY [web] *********************************
TASK [Gathering Facts] *********************
ok: [172.16.1.7]
TASK [get date] ****************************
changed: [172.16.1.7]
TASK [打印result内容] **************************
ok: [172.16.1.7] =>
"msg": "2023-02-04"
PLAY RECAP *********************************
172.16.1.7 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
补充:
register注册变量
变量名.stdout获取输出
json形式数据.
key: value
键: 值 变量:
内容 date +%F
stdout部分是我们想要的内容.
register变量result.
result.stdout #std standard output 标准输出
5. facts变量
- ans内置变量,ans运行剧本的时候会有一个默认的task(Gathering Facts)
- 运行剧本的时候ans会收集每个主机的基本信息,这些信息形成的变量叫做fact变量
- fatcs变量setup模块获取
#查看fact变量
[root@m01 /server/scripts/playbook]# ansible web -m setup
[root@m01 /server/scripts/playbook]# cat 9.facts.yml
- hosts: web
tasks:
- name: 测试
debug:
msg: |
系统ip是 ansible_default_ipv4.address
系统主机名是 ansible_hostname
系统是 ansible_distribution
系统版本是 ansible_distribution_version
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts 9.facts.yml
PLAY [web] *********************************
TASK [Gathering Facts] *********************
ok: [172.16.1.7]
TASK [测试] **********************************
ok: [172.16.1.7] =>
"msg": "系统ip是10.0.0.7\\n系统主机名是web01\\n系统是CentOS\\n系统版本是7.9\\n"
PLAY RECAP *********************************
172.16.1.7 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
常用fact变量
ansible_hostname #主机名
ansible_memtotal_mb #内存大小(总计) 单位mb
ansible_processor_vcpus #cpu数量
ansible_default_ipv4.address #默认的网卡ip eth0
ansible_distribution #系统发行版本名字
ansible_processor_vcpus
ansible_processor_cores
ansible_date_time.date
应用建议:
- 通过facts变量获取系统的基本信息
- 通过facts变量获取信息并进行判断
- 如果不需要可以进行关闭,加速剧本的运行( gather_facts: no)
八、流程控制
1. handlers触发器
应用场景:
一般用于分发配置文件的时候,如果文件发生变化则重启服务,如果没有变化则不重启
[root@m01 /server/scripts/playbook]# cat hosts
[web]
172.16.1.7
[nfs]
172.16.1.31
#[backup]
#172.16.1.41
[ubuntu]
10.0.0.100
#[data:children]
#nfs
#backup
#
#[rsync_client:children]
#web
#nfs
[root@m01 /server/scripts/playbook]# cat 10.handler.yml
- hosts: nfs
gather_facts: no
tasks:
- name: 分发文件
copy:
src: exports
dest: /etc/exports
backup: yes
notify:
- 重启服务
handlers:
- name: 重启服务
systemd:
name: nfs
state: reloaded
#修改文件之后执行结果
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts 10.handler.yml
PLAY [nfs] *********************************
TASK [分发文件] ********************************
changed: [172.16.1.31]
RUNNING HANDLER [重启服务] *********************
changed: [172.16.1.31]
PLAY RECAP *********************************
172.16.1.31 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
#没有修改文件结果
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts 10.handler.yml
PLAY [nfs] *********************************
TASK [分发文件] ********************************
ok: [172.16.1.31]
PLAY RECAP *********************************
172.16.1.31 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
补充:
格式:
埋雷:设置绊雷(notify: 写个名字) , handlers设置名字和模块
注意事项
- handlers放在剧本的最后,否则都会被识别为handlers
- notify的名字要和handlers的名字一样
2. when判断
用于给ans运行的task模块设置条件,满足或不满足条件在运行对应的模块(不满足条件的主机提示skip)
应用建议
when进行判断,一般facts变量或register变量一起使用
#CentOS安装sl,tree Ubuntu安装 cmatrix,lolcat
[root@m01 /server/scripts/playbook]# cat 11.when.yml
- hosts: all
tasks:
- name: CentOS安装sl,tree
yum:
name: sl,tree
state: present
when: ansible_distribution == "CentOS"
- name: Ubuntu安装 cmatrix,lolcat
apt:
name: cmatrix,lolcat
state: present
when: ansible_distribution == "Ubuntu"
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts 11.when.yml
PLAY [all] *********************
TASK [Gathering Facts] *********************
ok: [172.16.1.7]
ok: [172.16.1.31]
ok: [10.0.0.100]
TASK [CentOS安装sl,tree] *********************
skipping: [10.0.0.100]
ok: [172.16.1.7]
ok: [172.16.1.31]
TASK [Ubuntu安装 cmatrix,lolcat] *********************
skipping: [172.16.1.7]
skipping: [172.16.1.31]
ok: [10.0.0.100]
PLAY RECAP *********************
10.0.0.100 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
172.16.1.31 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
172.16.1.7 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
when中使用的符号
==等于
!=不等于
is match(web)
ansible_hostname is match("web|backup") #类似于grep,正则.
ansible_hostname is not match("web|backup") #取反,排除.
3.循环
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_loops.html
- with_* :with_item
- loop
#批量启动nfs,crond
[root@m01 /server/scripts/playbook]# cat 12.loop.yml
- hosts: web
tasks:
- name: 重启nfs,crond
systemd:
name: " item "
state: restarted
#with_items:
loop:
- nfs
- crond
#循环与多个变量
[root@m01 /server/scripts/playbook]# cat 13.loop_vars.yml
- hosts: web
gather_facts: no
tasks:
- name: add user
user:
name: " item.name "
uid: " item.uid "
shell: /bin/bash
state: present
loop:
- name: "test1",uid: 2011
- name: "test2",uid: 2012
九、剧本调试
1. 检查语法与单步执行
-C --check 模拟运行,不做出改变。一些变量可能会提示报错。因为-C没有真正运行剧本。有些变量获取不到
--syntax-check 只做语法检查,不运行
--step 单步运行,y执行这个task,n忽略这个task,c自动运行
[root@m01 /server/scripts/playbook]# cat 2.fenfa.yml
---
- hosts: web
tasks:
- name: 1.创建目录
file:
path: /server/files/
state: directory
- name: 2.分发文件
copy:
src: /etc/hosts
dest: /server/files
#-C
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts -C 2.fenfa.yml
PLAY [web] *********************
TASK [Gathering Facts] *********************************************************
ok: [172.16.1.7]
TASK [1.创建目录] *********************
ok: [172.16.1.7]
TASK [2.分发文件] *********************
ok: [172.16.1.7]
PLAY RECAP *********************
172.16.1.7 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts --syntax-check 2.fenfa.yml
playbook: 2.fenfa.yml
#--step
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts --step 2.fenfa.yml
PLAY [web] *********************
Perform task: TASK: Gathering Facts (N)o/(y)es/(c)ontinue: y
Perform task: TASK: Gathering Facts (N)o/(y)es/(c)ontinue: *********************
TASK [Gathering Facts] *********************************************************
ok: [172.16.1.7]
Perform task: TASK: 1.创建目录 (N)o/(y)es/(c)ontinue: c
Perform task: TASK: 1.创建目录 (N)o/(y)es/(c)ontinue: ******************************
TASK [1.创建目录] ******************************************************************
ok: [172.16.1.7]
TASK [2.分发文件] ******************************************************************
ok: [172.16.1.7]
PLAY RECAP *********************
172.16.1.7 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2. tag标签
tag标签类似于超市物品的分类,只不过tag标签是给ansible中的task进行分类,加上标记
运行剧本的时候运行指定的tag标签或排除某些tag
[root@m01 /server/scripts/playbook]# cat 14.tags.yml
- hosts: nfs
tasks:
- name: 01. 部署nfs-utils,rpcbind
yum:
name: nfs-utils,rpcbind
state: present
tags:
- 01.install
- name: 02. 修改配置文件
lineinfile:
path: /etc/exports
line: "/backup-nfs 172.16.1.0/24(rw,all_squash)"
create: true
tags:
- 02.conf
- name: 03. 创建共享目录并改所有者
file:
path: /backup-nfs
owner: nfsnobody
group: nfsnobody
state: directory
tags:
- 03.dir
- name: 04. 启动服务rpcbind,nfs(注意顺序)
systemd:
name: " item "
enabled: yes
state: started
loop:
- rpcbind
- nfs
tags:
- 04.start_srv
#list-tags显示剧本中所有的tags标签
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts --list-tags 14.tags.yml
playbook: 14.tags.yml
play #1 (nfs): nfs TAGS: []
TASK TAGS: [01.install, 02.conf, 03.dir, 04.start_srv]
#运行剧本的时候
#-t 运行的标签,如果多个标签通过","分割
#skip-tags 排除指定的tags,如果多个标签通过","分割
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts -t 04.start_srv 14.tags.yml
PLAY [nfs] *********************
TASK [Gathering Facts] *********************
ok: [172.16.1.31]
TASK [04. 启动服务rpcbind,nfs(注意顺序)] *********************
ok: [172.16.1.31] => (item=rpcbind)
ok: [172.16.1.31] => (item=nfs)
PLAY RECAP *********************
172.16.1.31 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3.忽略错误
运行剧本的时候,因为重复运行导致的错误提示,并发是真的错误.
比如:目录已经存在,用户已经存在.
在这种情况下,我们可以通过ignore_errors忽略错误,让剧本可以继续运行.
ignore_errors: true
true/false
yes/no
十、 Jinja2模板
应用场景:
进行分发配置文件或文件的时候,需要在文件中使用变量,需要使用jinja2文件,需要使用template分发
1.基本使用
#分发motd文件,motd文件中包含ans变量(目标文件是/etc/motd).
[root@m01 /server/scripts/playbook]# cat 15.jinja2.yml
- hosts: web
tasks:
- name: 分发motd
template:
src: motd.j2
dest: /etc/motd
backup: yes
[root@m01 /server/scripts/playbook]# cat motd.j2
welcome to oldboy elastic linux system
操作需谨慎,删根弹指间.
主机名: ansible_hostname
ip地址: ansible_default_ipv4.address
内存大小: ansible_memtotal_mb
CPU数量: ansible_processor_vcpus
核心总数: ansible_processor_cores
发行版本: ansible_distribution
[root@m01 /server/scripts/playbook]# ansible-playbook -i hosts 15.jinja2.yml
PLAY [web] *****************************************
TASK [Gathering Facts] *****************************
ok: [172.16.1.7]
TASK [分发motd] **************************************
ok: [172.16.1.7]
PLAY RECAP *****************************************
172.16.1.7 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@m01 /server/scripts/playbook]# ssh 172.16.1.7
Last login: Mon Feb 6 17:15:03 2023 from 172.16.1.61
welcome to oldboy elastic linux system
操作需谨慎,删根弹指间.
主机名: web01
ip地址: 10.0.0.7
内存大小: 972
CPU数量: 1
核心总数: 1
发行版本: CentOS
[root@web01 ~]# cat /etc/motd
welcome to oldboy elastic linux system
操作需谨慎,删根弹指间.
主机名: web01
ip地址: 10.0.0.7
内存大小: 972
CPU数量: 1
核心总数: 1
发行版本: CentOS
2.判断使用
根据主机名或ip或其他条件,生成不同的配置文件
/tmp/keepalived.conf
lb01
lb02
配置文件内容
/tmp/keepalived.conf
web01 配置文件内容
state MASTER
/tmp/keepalived.conf
backup 配置文件内容
state BACKUP
[root@m01 /server/scripts/playbook]# cat 15.jinja2-
if.yml
- hosts: all
tasks:
- name: 分发配置文件
template:
src: templates/keepalived.conf.j2
dest: /tmp/keepalived.conf
[root@m01 /server/scripts/playbook]# tree templates/
templates/
├── keepalived.conf.j2
└── motd.j2
0 directories, 2 files
[root@m01 /server/scripts/playbook]# cat
templates/keepalived.conf.j2
#this is keepalived.conf
% if ansible_hostname "web01" %
state 主节点
% elif ansible_hostname "backup" %
state 备节点
% endif %
[root@m01 /server/scripts/playbook]#
3.循环
配置文件 server.conf web服务器的/tmp/目录下
10.0.0.5
10.0.0.6
10.0.0.7
10.0.0.8
10.0.0.9
10.0.0.10
% for ip in [1,2,3,4,5,6] %
10.0.0. ip
% endfor %
% for ip in range(2,11) %
10.0.0. ip
%endfor%
% for ip in ["lidao","oldwang"] %
10.0.0. ip
%endfor%
十一、include文件包含
在我们书写剧本的时候,会涉及到多个步骤,还会涉及到服务端和客户端.
发现剧本越来越大,不容易进行分析与阅读.
把剧本拆分开,分成2个文件服务端,客户端.
这时候可以通过include_tasks的功能把多个剧本文件合并在一起,让剧本变成多个方便阅读与维护.
应用场景:
1个ansible剧本内容过多,涉及到多个play,可读性变弱,不方便测试
于是把单个大的剧本拆分成多个,小的剧本
多个小的剧本可以通过include功能合并使用
[root@m01 /server/scripts/playbook]# cat 16.deploy_nfs_server.yml
- name: 部署nfs-utils,rpcbind
yum:
name: nfs-utils,rpcbind
state: present
- name: 修改配置文件
lineinfile:
path: /etc/exports
line: "/backup-nfs 172.16.1.0/24(rw,all_squash)"
- name: 创建共享目录并改所有者
file:
path: /backup-nfs
state: directory
owner: nfsnobody
group: nfsnobody
- name: 启动服务rpcbind
systemd:
name: rpcbind
enabled: yes
state: started
- name: 启动服务nfs
systemd:
name: nfs
enabled: yes
state: started
[root@m01 /server/scripts/playbook]# cat 16.deploy_nfs_client.yml
- name: 安装nfs-utils
yum:
name: nfs-utils
state: present
- name: 挂载与永久挂载
mount:
src: 172.16.1.41:/backup-nfs
path: /ans-upload
fstype: nfs
state: mounted
[root@m01 /server/scripts/playbook]# cat 16.deploy_nfs_all.yml
- hosts: backup
tasks:
- include_tasks: 16.deploy_nfs_server.yml
- hosts: web
tasks:
- include_tasks: 16.deploy_nfs_client.yml
十二、roles
通过使用include_tasks功能,大型剧本,缩小体积,变的更加模块化
但是有新问题,handlers,变量文件,发送配置文件(j2文件)存放比较混乱
于是人们发明了一套规范,这个规范是一套剧本目录结构的要求与标准,让书写剧本的时候,把剧本的内容和需要的文件,按照目录的要求,分类别存储
这套规则,叫roles规则,roles的本质是规定了1套目录结构,用于书写剧本
roles/目录
top.yml #主剧本/入口剧本
hosts #主机清单 -i hosts
nfs-server/ #功能
files/ #files目录存放配置文件,剧本中使用的文件的目录,默认在files下面
templates/ #存放.j2文件,template
tasks/ #剧本中tasks内容存放在这个目录中
main.yml
handlers/ #存放触发器内容
main.yml
group_vars #存放变量
all
main.yml
十三、 Vault
加密指定的文件,ansible-vault 用于加密敏感信息
hosts 文件
变量文件
这两个文件一般加密
#加密文件
[root@m01 /server/scripts/playbook]# ansible-vault encrypt hosts
New Vault password:
Confirm New Vault password:
Encryption successful
[root@m01 /server/scripts/playbook]# cat hosts
$ANSIBLE_VAULT;1.以上是关于Linux-ansible的主要内容,如果未能解决你的问题,请参考以下文章