本文共 38207 字,大约阅读时间需要 127 分钟。
Ansible 是近年越来越火的一款运维自动化工具,是基于python语言开发的。底层基于ssh。其主要功能是帮忙运维实现 IT 工作的自动化、降低人为操作失误,提升运维工作效率常用于软件批量部署自动化、批量配置自动化、批量管理自动化、持续集成等。
saltstackpuppet
1.host inventory 主机清单
定义客户机 ---需要去控制的客户机,可以对客户机进行分组:如web组、db组、redis组、flask组、django组等
2.playbook 剧本,配置文档
写明了ansible需要哪些客户机做哪些事情
3.module 模块
每个模块实现相应的功能 安装软件、复制文件、服务管理(启动、停止、重启)、执行linux命令等
4.plugins 插件
依附于ansible的一个小软件,实现某个小功能。
Ansible 系统由控制主机对被管节点的操作方式可分为两类,即adhoc和playbook:
ad-hoc模式(点对点模式)
使用单个模块,支持批量执行单条命令。ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令就相当于bash中的一句话shell。
playbook模式(剧本模式)
是Ansible主要管理方式,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能,如Web服务的安装部署、数据库服务器的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件。
语法检测:
--syntax-check -C效果一样[root@ansible playbooks]# ansible-playbook --syntax-check redis.yaml [root@ansible playbooks]# ansible-playbook -C redis_v1.yaml
copy:从本机到远程,实现文件的分发,推送
参数说明:src= 源文件路径dest= 目标路径 注意src= 路径后面带/ 表示带里面的所有内容复制到目标目录下,不带/是目录递归复制过去content= 自行填充的文件内容owner 属主group 属组mode权限
fetch:从远程主机拉取文件到本机
[root@ansible ~]# ansible all -m fetch -a "src=/tmp/hi.txt dest=/tmp"
command:裸执行linux命令,不能识别管道
shell:执行linux命令,可以识别管道
service:配置相关服务
ansible webdaozhu -m service -a "name=nignx state=stopped enabled=true"state的几种状态:reloaded --优雅的重启restarted ---重启started --启动stopped --停止enabled =true 设置开机启动
yum:—安装卸载软件
常用参数说明:enablerepo,disablerepo表示启用与禁用某repo库name 安装包名state (present' orinstalled', latest')表示安装, (absent' or `removed') 表示删除eg:通过安装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"
script模块 = shell +copy
把本地的脚本传到远端执行;前提是到远端可以执行ansible all -m script -a "/root/test.sh"
cron —设置计划任务
minutehourday monthweekdayeg: ansible all -m cron -a "minute=0 hour=8-18 month=5 weekday=1-5 job='bash /root/iptables.sh' name=runiptables2"删除计划任务ansible all -m cron -a "name=update_time state=absent"
file --文件相关操作
设置文件属性(创建文件)常用参数:path目标路径state directory为目录,link为软件链接group 目录属组owner 属主等等,其他参数通过ansible-doc -s file 获取示例:创建目录[root@ansible ~]# ansible all -m file -a "path=/var/tmp/hello.dir state=directory"创建软件链接ansible all -m file -a "src=/tmp/hi.txt path=/var/tmp/hi.link state=link"
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"
安装在哪: ansible安装在linux里的管理节点上,被管理的机器不需要安装,但被管理的节点需要有ssh 服务,centos7/8 默认有安装openssh 可以提供ssh服务如何安装: yum install ansible -yansible可以管理windows机器,但默认需要安装一些软件
在xshell 里 ---点工具---新建用户密钥生成向导---选择ecdsa类型的密钥--密钥长度默认---自定义密钥名称---密钥栏设为空(免密登录)---保存公钥文件到桌面----将公钥文件传到linux里,并将其放到/etc/.ssh/authorized_keys文件里(cat id_ecdsa_256_sc.pub >> authorized_keys)
实验环境:
3台虚拟机(centos7为例)主机名:ansible ip:192.168.0.211主机名:node1-web ip :192.168.0.172 主机名:node2-db ip :1921.68.0.173
实验步骤:
1,更改主机名#临时修改主机名[root@localhost ~]# hostname ansible[root@localhost ~]# su - root上一次登录:六 10月 17 15:22:31 CST 2020从 192.168.0.28pts/1 上#永久修改主机名[root@ansible ~]# vim /etc/hostname[root@ansible ~]# cat /etc/hostnameansible
#临时修改主机名[root@server ~]# hostname node1-web[root@server ~]# su - root上一次登录:六 10月 17 15:00:05 CST 2020从 192.168.0.28pts/0 上#永久修改主机名[root@node1-web ~]# vim /etc/hostname[root@node1-web ~]# cat /etc/hostnamenode1-web
#临时修改主机名[root@client ~]# hostname node2-db[root@client ~]# su - root上一次登录:六 10月 17 15:00:58 CST 2020从 192.168.0.28pts/0 上#永久修改主机名[root@node2-db ~]# vim /etc/hostname[root@node2-db ~]# cat /etc/hostnamenode2-db
2,先建立免密通道
[root@ansible ~]# ps aux|grep sshdroot 7048 0.0 0.4 112756 4312 ? Ss 15:04 0:00 /usr/sbin/sshd -Droot 7760 0.0 0.5 158760 5580 ? Ss 15:22 0:00 sshd: root@pts/1root 17654 0.0 0.0 112724 988 pts/1 S+ 18:26 0:00 grep --color=auto sshd[root@ansible ~]# cd /etc/ssh[root@ansible ssh]# lsmoduli ssh_host_ecdsa_key ssh_host_ed25519_key.pubssh_config ssh_host_ecdsa_key.pub ssh_host_rsa_keysshd_config ssh_host_ed25519_key ssh_host_rsa_key.pub
在ansible主机上生成ecdsa类型的密钥
[root@ansible ssh]# ssh-keygen -t ecdsaGenerating public/private ecdsa key pair.Enter file in which to save the key (/root/.ssh/id_ecdsa): Created directory '/root/.ssh'.Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_ecdsa.Your public key has been saved in /root/.ssh/id_ecdsa.pub.The key fingerprint is:SHA256:fH71sWdKHCMtVk3GPoSwK8UcpfCSc6vIIASI8LEZAXE root@ansibleThe key's randomart image is:+---[ECDSA 256]---+|B+E. . oo...o||oo.= * +. =.|| +. + O o..|| . . = oo ..|| . . S..o+ =..|| . o .oo. = +o|| o .. . o.+|| . . o.|| . |+----[SHA256]-----+[root@ansible ssh]# cd /root/.ssh/[root@ansible .ssh]# ll总用量 8-rw-------. 1 root root 227 10月 17 18:31 id_ecdsa --私钥-rw-r--r--. 1 root root 174 10月 17 18:31 id_ecdsa.pub --公钥
将公钥上传到被控制的服务器node1-web和node2-db上
#上传密钥至node1-web[root@ansible .ssh]# ssh-copy-id -p22 -i id_ecdsa.pub root@192.168.0.172/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "id_ecdsa.pub"The authenticity of host '192.168.0.172 (192.168.0.172)' can't be established.ECDSA key fingerprint is SHA256:RAFPf4IJfMT3AiTfKGqSw7oXSV6ij02Un3NfA0IIozY.ECDSA key fingerprint is MD5:af:a3:30:a0:52:3b:a8:e6:df:e4:94:68:ca:bc:e9:42.Are you sure you want to continue connecting (yes/no)? yes/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keysroot@192.168.0.172's password: Number of key(s) added: 1Now try logging into the machine, with: "ssh -p '22' 'root@192.168.0.172'"and check to make sure that only the key(s) you wanted were added.#上传密钥至node2-db[root@ansible .ssh]# ssh-copy-id -p22 -i id_ecdsa.pub root@192.168.0.173/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "id_ecdsa.pub"The authenticity of host '192.168.0.173 (192.168.0.173)' can't be established.ECDSA key fingerprint is SHA256:RAFPf4IJfMT3AiTfKGqSw7oXSV6ij02Un3NfA0IIozY.ECDSA key fingerprint is MD5:af:a3:30:a0:52:3b:a8:e6:df:e4:94:68:ca:bc:e9:42.Are you sure you want to continue connecting (yes/no)? yes/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keysroot@192.168.0.173's password: Number of key(s) added: 1Now try logging into the machine, with: "ssh -p '22' 'root@192.168.0.173'"and check to make sure that only the key(s) you wanted were added.
在ansible主机上验证一下是否可以免密登录
[root@node1-web .ssh]# ssh 'root@192.168.0.173'Last login: Sat Oct 17 18:49:43 2020 from 192.168.0.172[root@node2-db ~]# [root@node1-web .ssh]# ssh 'root@192.168.0.172'Last login: Sat Oct 17 18:55:24 2020 from node1-web[root@node1-web ~]#
查看主机清单–hosts文件
[root@ansible ~]# cd /etc/ansible[root@ansible ansible]# lsansible.cfg hosts roles[root@ansible ansible]# vim hosts[root@ansible ansible]# cat hosts# This is the default ansible 'hosts' file.## It should live in /etc/ansible/hosts## - Comments begin with the '#' character# - Blank lines are ignored# - Groups of hosts are delimited by [header] elements# - You can enter hostnames or ip addresses# - A hostname/ip can be a member of multiple groups# Ex 1: Ungrouped hosts, specify before any group headers.## green.example.com## blue.example.com## 192.168.100.1## 192.168.100.10# Ex 2: A collection of hosts belonging to the 'webservers' group[web]192.168.0.172[db]192.168.0.173## [webservers]## alpha.example.org## beta.example.org## 192.168.1.100## 192.168.1.110
ansible 的简单使用
在ansible主机上使用某个模块,去所有主机上执行命令[root@ansible ansible]# ansible all -m shell -a "ip add"192.168.0.172 | 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 forever2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:91:4f:94 brd ff:ff:ff:ff:ff:ff inet 192.168.0.172/24 brd 192.168.0.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe91:4f94/64 scope link valid_lft forever preferred_lft forever192.168.0.173 | 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 forever2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:3f:f2:d9 brd ff:ff:ff:ff:ff:ff inet 192.168.0.173/24 brd 192.168.0.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe3f:f2d9/64 scope link valid_lft forever preferred_lft forever
warning:新建文件夹用file模块比shell更好
[root@ansible ansible]# ansible all -m shell -a "mkdir /sc/lele -p"[WARNING]: Consider using the file module with state=directory rather thanrunning 'mkdir'. If you need to use command because file is insufficient youcan add 'warn: false' to this command task or set 'command_warnings=False' inansible.cfg to get rid of this message.192.168.0.172 | CHANGED | rc=0 >>192.168.0.173 | CHANGED | rc=0 >>
指定主机组进行操作
[root@ansible ansible]# ansible db -m shell -a "mkdir /sc/lele/db -p"[WARNING]: Consider using the file module with state=directory rather thanrunning 'mkdir'. If you need to use command because file is insufficient youcan add 'warn: false' to this command task or set 'command_warnings=False' inansible.cfg to get rid of this message.192.168.0.173 | CHANGED | rc=0 >>[root@ansible ansible]# ansible web -m shell -a "mkdir /sc/lele/web -p"[WARNING]: Consider using the file module with state=directory rather thanrunning 'mkdir'. If you need to use command because file is insufficient youcan add 'warn: false' to this command task or set 'command_warnings=False' inansible.cfg to get rid of this message.192.168.0.172 | CHANGED | rc=0 >>
ansible的常用命令
ansible-doc 查看某个模块的用法,相当于help,man,按q退出
[root@ansible ansible]# ansible-doc shell> SHELL (/usr/lib/python2.7/site-packages/ansible/modules/c The `shell' module takes the command name followed by of space-delimited arguments. Either a free form comma `cmd' parameter is required, see the examples. It is a exactly like the [command] module but runs the command a shell (`/bin/sh') on the remote node. For Windows ta use the [win_shell] module instead. * This module is maintained by The Ansible Core Team * note: This module has a corresponding action plugin.OPTIONS (= is mandatory):- chdir Change into this directory before running the command. [Default: (null)] type: path version_added: 0.6- cmd The command to run followed by optional arguments. [Default: (null)] type: str- creates A filename, when it already exists, this step will *no run. [Default: (null)] type: path- executable:
查看ansible有哪些模块,可以去官网查看具体内容
[root@ansible ansible]# ansible-doc -lfortios_router_community_list azure_rm_devtestlab_info ecs_taskdefinition avi_alertscriptconfig tower_receive netapp_e_iscsi_target azure_rm_acs fortios_log_syslogd2_filter junos_rpc na_elementsw_vlan pn_ospf pn_snmp_vacm cp_mgmt_service_sctp onyx_ospf icx_command cs_snapshot_policy nxos_install_os cnos_static_route win_eventlog vmware_category vmware_host_feature_info avi_cluster na_ontap_user ...... :
常用模块:
copy shell 执行shell命令 script 跑脚本 fetch 从远程主机拉取模块到本地 cron 创建计划任务:
[root@ansible ansible]# mkdir /lianxi[root@ansible ansible]# cd /lianxi[root@ansible lianxi]# ls[root@ansible lianxi]# vim feng.sh[root@ansible lianxi]# cat feng.sh#!/bin/bashtouch /root/feng{ 1..10}.txt
在所有主机上新建用户
[root@ansible lianxi]# ansible all -m user -a "name=sczwx" 192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/sczwx", "name": "sczwx", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1001}192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/sczwx", "name": "sczwx", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1001}
将ansible主机上的文件传送到各个主机上,并规定该文件的权限,属主和属组
[root@ansible lianxi]# ansible all -m copy -a "src=/lianxi/feng.sh dest=/root mode=777 owner=sczwx group=sczwx"192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "22ae77faaa8e67b7d9b087fa7ffe6336cd6d46e3", "dest": "/root/feng.sh", "gid": 1001, "group": "sczwx", "md5sum": "a8142c12949d65cce2ed3add4e943d3a", "mode": "0777", "owner": "sczwx", "secontext": "system_u:object_r:admin_home_t:s0", "size": 41, "src": "/root/.ansible/tmp/ansible-tmp-1602987387.13-18854-27236434212338/source", "state": "file", "uid": 1001}192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "22ae77faaa8e67b7d9b087fa7ffe6336cd6d46e3", "dest": "/root/feng.sh", "gid": 1001, "group": "sczwx", "md5sum": "a8142c12949d65cce2ed3add4e943d3a", "mode": "0777", "owner": "sczwx", "secontext": "system_u:object_r:admin_home_t:s0", "size": 41, "src": "/root/.ansible/tmp/ansible-tmp-1602987387.13-18855-2677683065084/source", "state": "file", "uid": 1001}[root@ansible lianxi]#
将远程主机上的文件拉取到本地
[root@ansible lianxi]# ansible all -m fetch -a "src=/etc/passwd dest=/lianxi"192.168.0.173 | CHANGED => { "changed": true, "checksum": "489f53603354949cde551f0805c37c7479e46b38", "dest": "/lianxi/192.168.0.173/etc/passwd", "md5sum": "8ef55b8ac28514959588d15a36534579", "remote_checksum": "489f53603354949cde551f0805c37c7479e46b38", "remote_md5sum": null}192.168.0.172 | CHANGED => { "changed": true, "checksum": "09134eb68efd7842beef48cee20514073cb0c51f", "dest": "/lianxi/192.168.0.172/etc/passwd", "md5sum": "5fa4efa58243dfe1b7c66939dbe5f1c1", "remote_checksum": "09134eb68efd7842beef48cee20514073cb0c51f", "remote_md5sum": null}[root@ansible lianxi]# tree.├── 192.168.0.172│ └── etc│ └── passwd├── 192.168.0.173│ └── etc│ └── passwd└── feng.sh4 directories, 3 files
command和shell模块的区别
command和shell都可以执行linux命令,但command模块不能识别管道符号,即只能执行单一命令,不能识别组合命令,裸执行file 模块 新建文件/文件夹
— state:touch 空文件 | directory 目录 |link 软链接文件| hard 硬链接 | absent 删除文件和文件夹#新建文件夹 [root@ansible lianxi]# ansible all -m file -a "path=/gus state=directory" 192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/gus", "secontext": "unconfined_u:object_r:default_t:s0", "size": 6, "state": "directory", "uid": 0}192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/gus", "secontext": "unconfined_u:object_r:default_t:s0", "size": 6, "state": "directory", "uid": 0}#新建文件[root@ansible lianxi]# ansible all -m file -a "path=/gus/lele.txt state=touch" 192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/gus/lele.txt", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:default_t:s0", "size": 0, "state": "file", "uid": 0}192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/gus/lele.txt", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:default_t:s0", "size": 0, "state": "file", "uid": 0}#新建链接文件[root@ansible lianxi]# ansible all -m file -a "path=/gus/lele.txt state=touch" 192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/gus/lele.txt", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:default_t:s0", "size": 0, "state": "file", "uid": 0}192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/gus/lele.txt", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:default_t:s0", "size": 0, "state": "file", "uid": 0}[root@ansible lianxi]# ansible all -m file -a "src=/gus/lele.txt path=/gus/yanle state=link" 192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/gus/yanle", "gid": 0, "group": "root", "mode": "0777", "owner": "root", "secontext": "unconfined_u:object_r:default_t:s0", "size": 13, "src": "/gus/lele.txt", "state": "link", "uid": 0}192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/gus/yanle", "gid": 0, "group": "root", "mode": "0777", "owner": "root", "secontext": "unconfined_u:object_r:default_t:s0", "size": 13, "src": "/gus/lele.txt", "state": "link", "uid": 0}#删除文件[root@ansible lianxi]# ansible all -m file -a "path=/gus/lele.txt state=absent" 192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "path": "/gus/lele.txt", "state": "absent"}192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "path": "/gus/lele.txt", "state": "absent"}
计划任务模块 cron
五个时间段 从左到右 分别为 minute (0-59) hour(0-23) day of month(1-31) month(1-12) day of week(0-6)[root@ansible lianxi]# ansible all -m cron -a "minute=*/3 job='date >>/gushuai/date.txt' name=gus_date"192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "gus_date" ]}192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "gus_date" ]}#查看一下[root@node2-db ~]# crontab -l#Ansible: gus_date*/3 * * * * date >>/gushuai/date.txt[root@node1-web ~]# crontab -l#Ansible: gus_date*/3 * * * * date >>/gushuai/date.txt您在 /var/spool/mail/root 中有邮件
由于名字一样,所以会把原来的替换掉
[root@ansible lianxi]# ansible all -m cron -a "minute=*/30 hour=1 day=15 month=10 job='bash /gus/gu.sh' name=gus_date"192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "gus_date" ]}192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "gus_date" ]}[root@node1-web ~]# crontab -l#Ansible: gus_date*/30 1 15 10 * bash /gus/gu.sh[root@node2-db ~]# crontab -l#Ansible: gus_date*/30 1 15 10 * bash /gus/gu.sh
删除计划任务
[root@ansible lianxi]# ansible all -m cron -a "name=gus_date state=absent"192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": []}192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": []}
小练习:在ansible 机器上写好脚本;把脚本推到node服务器上;创建计划任务
[root@ansible lianxi]# cat backup_log.sh #!/bin/bash#年-月-日形式显示ctime=$(date +%F%H%M%S)mkdir -p /backuptar czf /backup/${ctime}-log.tar.gz /var/log[root@ansible lianxi]# ansible all -m copy -a "src=/lianxi/backup_log.sh dest=/gus"192.168.0.173 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "checksum": "8f60eabd3608114ebdeb0668eaf3ada43be7cb67", "dest": "/gus/backup_log.sh", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "path": "/gus/backup_log.sh", "secontext": "system_u:object_r:default_t:s0", "size": 120, "state": "file", "uid": 0}192.168.0.172 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "checksum": "8f60eabd3608114ebdeb0668eaf3ada43be7cb67", "dest": "/gus/backup_log.sh", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "path": "/gus/backup_log.sh", "secontext": "system_u:object_r:default_t:s0", "size": 120, "state": "file", "uid": 0}[root@ansible lianxi]#
[root@ansible lianxi]# ansible all -m cron -a "minute=30 hour=2 job='bash /gus/backup_log.sh' name=backup_cron"192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "backup_cron" ]}192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "backup_cron" ]}[root@node2-db gus]# crontab -l#Ansible: backup_cron30 2 * * * bash /gus/backup_log.sh
yum 模块 ----安装软件
常用参数
name :安装的软件包名 state :present installed lastest 表示安装 absent/removed 表示删除[root@ansible lianxi]# ansible all -m yum -a "name=tree state=installed"192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "changes": { "installed": [ "tree" ] }, "msg": "", "rc": 0, "results": [ "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirrors.tuna.tsinghua.edu.cn\n * extras: mirrors.tuna.tsinghua.edu.cn\n * updates: mirrors.tuna.tsinghua.edu.cn\nResolving Dependencies\n--> Running transaction check\n---> Package tree.x86_64 0:1.6.0-10.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n tree x86_64 1.6.0-10.el7 base 46 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 46 k\nInstalled size: 87 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : tree-1.6.0-10.el7.x86_64 1/1 \n Verifying : tree-1.6.0-10.el7.x86_64 1/1 \n\nInstalled:\n tree.x86_64 0:1.6.0-10.el7 \n\nComplete!\n" ]}192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "changes": { "installed": [ "tree" ] }, "msg": "", "rc": 0, "results": [ "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirrors.163.com\n * epel: d2lzkl7pfhq30w.cloudfront.net\n * extras: mirrors.tuna.tsinghua.edu.cn\n * updates: mirrors.163.com\nResolving Dependencies\n--> Running transaction check\n---> Package tree.x86_64 0:1.6.0-10.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n tree x86_64 1.6.0-10.el7 base 46 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 46 k\nInstalled size: 87 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : tree-1.6.0-10.el7.x86_64 1/1 \n Verifying : tree-1.6.0-10.el7.x86_64 1/1 \n\nInstalled:\n tree.x86_64 0:1.6.0-10.el7 \n\nComplete!\n" ]}[root@node2-db gus]# tree.├── backup_log.sh└── yanle -> /gus/lele.txt0 directories, 2 files[root@node2-db gus]#
多进程删除软件
-f n --启动n个进程去执行[root@ansible lianxi]# ansible all -f 2 -m yum -a "name=tree state=removed"192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "changes": { "removed": [ "tree" ] }, "msg": "", "rc": 0, "results": [ "已加载插件:fastestmirror\n正在解决依赖关系\n--> 正在检查事务\n---> 软件包 tree.x86_64.0.1.6.0-10.el7 将被 删除\n--> 解决依赖关系完成\n\n依赖关系解决\n\n================================================================================\n Package 架构 版本 源 大小\n================================================================================\n正在删除:\n tree x86_64 1.6.0-10.el7 @base 87 k\n\n事务概要\n================================================================================\n移除 1 软件包\n\n安装大小:87 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n 正在删除 : tree-1.6.0-10.el7.x86_64 1/1 \n 验证中 : tree-1.6.0-10.el7.x86_64 1/1 \n\n删除:\n tree.x86_64 0:1.6.0-10.el7 \n\n完毕!\n" ]}192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "changes": { "removed": [ "tree" ] }, "msg": "", "rc": 0, "results": [ "已加载插件:fastestmirror\n正在解决依赖关系\n--> 正在检查事务\n---> 软件包 tree.x86_64.0.1.6.0-10.el7 将被 删除\n--> 解决依赖关系完成\n\n依赖关系解决\n\n================================================================================\n Package 架构 版本 源 大小\n================================================================================\n正在删除:\n tree x86_64 1.6.0-10.el7 @base 87 k\n\n事务概要\n================================================================================\n移除 1 软件包\n\n安装大小:87 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n 正在删除 : tree-1.6.0-10.el7.x86_64 1/1 \n 验证中 : tree-1.6.0-10.el7.x86_64 1/1 \n\n删除:\n tree.x86_64 0:1.6.0-10.el7 \n\n完毕!\n" ]}
service 模块
服务管理模块 常用参数 name 服务名 state 服务的状态 enabled 是否开机启动 true|false runlevel 启动级别安装ftp
[root@ansible lianxi]# ansible all -f 2 -m yum -a "name=vsftpd state=installed"192.168.0.173 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "changes": { "installed": [ "vsftpd" ] }, "msg": "", "rc": 0, "results": [ "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirrors.tuna.tsinghua.edu.cn\n * extras: mirrors.tuna.tsinghua.edu.cn\n * updates: mirrors.tuna.tsinghua.edu.cn\nResolving Dependencies\n--> Running transaction check\n---> Package vsftpd.x86_64 0:3.0.2-27.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n vsftpd x86_64 3.0.2-27.el7 base 172 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 172 k\nInstalled size: 353 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : vsftpd-3.0.2-27.el7.x86_64 1/1 \n Verifying : vsftpd-3.0.2-27.el7.x86_64 1/1 \n\nInstalled:\n vsftpd.x86_64 0:3.0.2-27.el7 \n\nComplete!\n" ]}192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "changes": { "installed": [ "vsftpd" ] }, "msg": "", "rc": 0, "results": [ "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirrors.163.com\n * epel: d2lzkl7pfhq30w.cloudfront.net\n * extras: mirrors.tuna.tsinghua.edu.cn\n * updates: mirrors.163.com\nResolving Dependencies\n--> Running transaction check\n---> Package vsftpd.x86_64 0:3.0.2-27.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n vsftpd x86_64 3.0.2-27.el7 base 172 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 172 k\nInstalled size: 353 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : vsftpd-3.0.2-27.el7.x86_64 1/1 \n Verifying : vsftpd-3.0.2-27.el7.x86_64 1/1 \n\nInstalled:\n vsftpd.x86_64 0:3.0.2-27.el7 \n\nComplete!\n" ]}[root@ansible lianxi]#
起服务
[root@ansible lianxi]# ansible all -m service -a "name=vsftpd state=started enabled=true"192.168.0.172 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "enabled": true, "name": "vsftpd", "state": "started", "status": { "ActiveEnterTimestampMonotonic": "0", "ActiveExitTimestampMonotonic": "0", "ActiveState": "inactive", "After": "systemd-journald.socket basic.target system.slice network.target", "AllowIsolate": "no", "AmbientCapabilities": "0", "AssertResult": "no", "AssertTimestampMonotonic": "0", "Before": "shutdown.target", "BlockIOAccounting": "no", "BlockIOWeight": "18446744073709551615", "CPUAccounting": "no", "CPUQuotaPerSecUSec": "infinity", "CPUSchedulingPolicy": "0", "CPUSchedulingPriority": "0", "CPUSchedulingResetOnFork": "no", "CPUShares": "18446744073709551615", "CanIsolate": "no", "CanReload": "no", "CanStart": "yes", "CanStop": "yes", "CapabilityBoundingSet": "18446744073709551615", ......
script模块
把本地的脚本传到远端执行,前提是到远端可以执行;=copy+shell[root@ansible lianxi]# ansible all -m script -a "/lianxi/backup_log.sh"192.168.0.172 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.0.172 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.0.172 closed." ], "stdout": "tar: 从成员名中删除开头的“/”\r\n", "stdout_lines": [ "tar: 从成员名中删除开头的“/”" ]}192.168.0.173 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.0.173 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.0.173 closed." ], "stdout": "tar: 从成员名中删除开头的“/”\r\n", "stdout_lines": [ "tar: 从成员名中删除开头的“/”" ]}[root@node2-db backup]# ls2020-10-18131404-log.tar.gz
playbook是ansible的配置,部署,和编排的语言,playbook相当于一个指导手册
playbook 是基于YAML 语言格式配置的
playbook的核心元素
hosts playbook 配置文件作用的主机 tasks 任务列表 variables : 变量 templates 包含模板语法的文本文件 handlers 由特定条件触发的任务,异常捕获 roles 用于层次性,结构化的组织playbook, roles能够根据层次型结构自动装载变量文件,tasks以及handlers等playbook运行方式
ansible-playbook --check 只检测可能会发生的改变,但不真执行操作 ansible-playbook --list-hosts 列出运行任务的主机 ansible-playbook --syntax-check playbook.yaml 语法检测 ansible-playbook -t TAGS_NAME playbook.yaml 只执行TAGS_NAME任务实操
[root@ansible lianxi]# vim first_redis.yaml[root@ansible lianxi]# cat first_redis.yaml- hosts: all remote_user: root tasks: - name: install redis yum: name=redis state=installed - name: start redis service: name=redis state=started - name: install tree yum: name=tree state=installed#语法检测[root@ansible lianxi]# ansible-playbook --syntax-check first_redis.yamlplaybook: first_redis.yaml[root@ansible lianxi]# #查看playbook会在哪些机器上执行[root@ansible lianxi]# ansible-playbook --list-hosts first_redis.yamlplaybook: first_redis.yaml play #1 (all): all TAGS: [] pattern: [u'all'] hosts (2): 192.168.0.172 192.168.0.173
执行playbook
[root@ansible lianxi]# ansible-playbook first_redis.yamlPLAY [all] *********************************************************************TASK [Gathering Facts] *********************************************************ok: [192.168.0.172]ok: [192.168.0.173]TASK [install redis] ***********************************************************fatal: [192.168.0.173]: FAILED! => { "changed": false, "msg": "No package matching 'redis' found available, installed or updated", "rc": 126, "results": ["No package matching 'redis' found available, installed or updated"]}changed: [192.168.0.172]TASK [start redis] *************************************************************changed: [192.168.0.172]TASK [install tree] ************************************************************changed: [192.168.0.172]PLAY RECAP *********************************************************************192.168.0.172 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.0.173 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
可以看到,有一台机器上执行失败了,原因是因为该机器上未安装epel 源
[root@node2-db backup]# yum install redis已加载插件:fastestmirrorLoading mirror speeds from cached hostfile * base: mirrors.tuna.tsinghua.edu.cn * extras: mirrors.tuna.tsinghua.edu.cn * updates: mirrors.tuna.tsinghua.edu.cn没有可用软件包 redis。错误:无须任何处理
vars 变量的定义和使用
vars: scredis:/lianxi/redis.conf ----定义变量 tasks: … copy:src={ {scredis}} dest=/etc/redis.conf owner=redis —引用变量notify:restart redis ----通知,异常捕获,相当于python里的raise,常与handler连用,handler : 处理异常
template 模板
和copy模板差不多,都可以实现将文件从管理节点上传到服务器节点,但是template 模块可以在模板文件里使用变量,因为template背后有jinjia2语法的支持,变量可以用自定义变量也可以用内置变量
yaml文件:template:src={
{scredis}} dest=/etc/redis.conf 模板文件:Redis.conf --bind { {ansible_facts[“ansible_all_ipv4_addresses”] [0] }}roles --角色
https://www.cnblogs.com/yanjieli/p/10980057.html