
方法一:
pip install ansible
方法二:
yum -y install ansible
2. ansible 配置方法三:
git clone git://github.com/ansible/ansible.git
cd ./ansible
source ./Hacking/env-setup
ansible配置文件有多个位置:按照下面顺序查找
1、环境变量 ANSIBLE_CONfig 所指向的位置
2、当前目录下的 ansible.cfg
3、HOME目录下的配置文件 ~/.ansible.cfg
4、/etc/ansible/ansible.cfg
ansible 常见配置参数如下:
● inventory=~/ansible_hosts: 表示主机清单 inventory 文件位置
● forks = 5 : 并发连接数,默认为5
● sudo_user = root : 设置默认执行命令的用户
● remote_port = 22 : 指定被管理节点的连接端口,默认为22,。建议修复,能够更加安全
● host_key_checking = False : 设置是否安全检查ssh主机的秘钥,值为True/False。关闭后第一次连接不会提示配置实例
● timeout = 60 :设置SSH连接的超时时间,单位为秒
● log_path = /var/log/ansible.log :指定一个存储ansible日志的文件(默认不记录日志)
3.1、对主机进行分组
[]中的字符串代表组名,便于对主机进行分组管理
[group01]
192.168.0.11
192.168.1.20
foo.example.com
bar.example.com
3.2、分配变量给主机
分配变量给不同主机,在后面使用palybook中会用到
格式:主机地址 变量名=变量值 (多个变量以空格隔开)
[group02]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=999
3.3、定义组变量
组变量可以定义属于整个组的变量
[group03:vars]
ntp_server=ntp.example.com
proxy=proxy.example.com
3.4、将组作为另一个组的子成员
可以将一个组定义为另一个组的子成员,以及分配变量给整个组使用,这些变量可以给/usr/bin/ansible-playbook使用,但是不能给/usr/bin/ansible使用
[root@localhost ~]# vim /etc/ansible/hosts[atlanta]host1host2[raleigh]host2host3[southeast:children]some_server= foo.southeast.example.comhalon_system_timeout = 30self_destruct_countdown = 60escape_pods = 2[usa:children]southeastnortheastsouthwestnorthwest3.5、给每个主机选择连接类型和连接用户名
[targets]localhost ansible_connection=localother.example.com other.example.com=ssh ansible_ssh_user=testother2.example.com other2.example.com=ssh ansible_ssh_user=test23.6、设置inventory参数
通过设置inventory参数,可以控制Ansible与远程主机的交互方式
ansible_ssh_host # 如果将要连接的远程主机名与你想要设定的主机的别名不同的话,可以通过此变量来控制ansible_ssh_port # ssh的端口号,如果不是默认端口号,就通过此变量来设置ansible_ssh_user # 默认ssh的用户名ansible_pass # ssh的密码(这种方式不建议,很不安全,建议使用秘钥)ansible_sudo_pass # sudo的密码(建议使用 --ask-sudo-pass)ansible_sudo_exe # sudo的命令路径ansible_connection # 与主机连接的类型。比如:local,ssh 或者 parmaikoansible_ssh_private_key_file # ssh 使用的私钥文件,适用于有多个密钥,而你不想使用ssh代理的情况下ansible_shell_type # 目标系统的shell类型,默认情况下使用“sh”,也可以设置成"csh"或"fish"ansible_python_interpreter # 目标主机python的路径,使用情况:系统中有多个python,或者路径不是/usr/bin/python等# -------------------------以下是一个主机文件示例-----------------------some_host absible_ssh_port=2222 ansible_ssh_user=test1one_host absible_ssh_port=2222 ansible_ssh_user=test2三、上传秘钥秘钥上传前
返回的信息是false,Ping测试不成功[root@localhost ~]# ansible master -m Ping192.168.10.10 | UNREACHABLE! => { "changed": false, "msg": "Failed to connect to the host via ssh: Permission denIEd (publickey,gssAPI-keyex,gssAPI-with-mic,password).", "unreachable": true}可以加上–ask-pass来手动输入密码
这时候Ping成功了,但是这样很麻烦[root@localhost ~]# ansible master -m "Ping" --ask-passSSH password: # 输入密码192.168.10.10 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "Ping": "pong"}上传秘钥
# 生成秘钥[root@localhost ~]# ssh-keygen -t rsa……省略部分+---[RSA 2048]----+| ++=Eo ||oo..= || o.. . . || o * = . || = + * S || . * . ||. +.*.. . || =*=+= o. o || .=@=o=..o |+----[SHA256]-----+# 查看公钥文件[root@localhost ~]# ls -ltr /root/.ssh/ 总用量 12-rw-r--r--. 1 root root 396 5月 23 19:23 ID_rsa.pub-rw-------. 1 root root 1679 5月 23 19:23 ID_rsa-rw-r--r--. 1 root root 175 5月 23 19:24 kNown_hosts# 上传公钥[root@localhost ~]# ansible all -m authorized_key -a "user=root key='{{lookup('file', '/root/.ssh/ID_rsa.pub')}}' path=/root/.ssh/ID_rsa.pub manage_dir=yes" --ask-passSSH password: 192.168.10.10 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "comment": null, "exclusive": false, "follow": false, "gID": 0, "group": "root", "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDmZ3VmXIZRL2W2INKz8iZV/DBLcfyoPhciAQKJJKLNdpKDcHwsT33WgdioVunk1qgwPVi79PZZtl/4sSmo1ZJt1sQ4W37Y9a8ad4jMuQW2JhD/TWfYFKsQgisgSE9YgdTkEZv7T5/Fuqpa0RgblLnqZ0pv3Kb/OweHZIWsIEVGZ9pom+MQ3f06mngPRpQIxCDiUHdoAvCRCvk3TXMbggOhg2R8BpZLmPzbu8rR9UOEezT03+nS3gQGuhtJvz3iOBEqLgN80FtsLBm812Vbxjj97ZCu+Dc8kMhtwaOs/GZtH3IMACmAd5chj4ZJomV1EY22eWPslRuceIGOv9QovalT root@localhost", "key_options": null, "keyfile": "/root/.ssh/ID_rsa.pub", "manage_dir": true, "mode": "0600", "owner": "root", "path": "/root/.ssh/ID_rsa.pub", "size": 396, "state": "file", "uID": 0, "user": "root", "valIDate_certs": true}# 测试是否已实现免密[root@localhost ~]# ansible all -m Ping192.168.10.10 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "Ping": "pong"}四、ansible ad-hoc模式1. 查看分组主机列表[root@localhost ~]# ansible 分组名 --List-hosts ##查看分组中的主机列表[root@localhost ~]# ansible work --List-host hosts (40): 192.168.2.115 192.168.2.116 192.168.2.202 192.168.2.204 192.168.2.207……2. 生成秘钥代理[root@localhost ~]# ssh-keygen -t rsa ##生成秘钥Generating public/private rsa key pair.Enter file in which to save the key (/root/.ssh/ID_rsa): ##直接回车Enter passphrase (empty for no passphrase): ##输入密码123123Enter same passphrase again: ##再次输入密码Your IDentification has been saved in /root/.ssh/ID_rsa.Your public key has been saved in /root/.ssh/ID_rsa.pub.[root@localhost ~]# ssh-copy-ID root@192.168.10.30[root@localhost ~]# ssh-copy-ID root@192.168.10.170 //配置密钥对验证------------免交互代理--------------(设置代理可以让主机不要再输入密码)ssh-agent bash ## 开启代理功能ssh-add ## 添加秘钥给代理3. ansible 命令模板ansible-doc -l # 列出所有已安装的模块 注:按q退出ansible-doc -s yum #-s列出yum模块描述信息和 *** 作动作## -m:指定模块;-a:指定参数(如-m command:指定命令模块;-a date:命令模块参数为date,相当于在对方执行了date命令)------------------ ansible指定ip执行命令 ----------------方法1:[root@localhost ~]# ansible all -i "IP地址," -m shell -a "free -m"方法2:[root@localhost ~]# ansible ip地址 -m command -a 'date'----------------- ansible指定分组批量执行命令 -----------[root@localhost ~]# ansible 分组名 -m command -a 'date'3.1 、command模块 (执行命令,是默认模块)命令格式:ansible [主机] [-m 模块] [-a args]
ansible MysqL -m command -a 'date'ansible all -m command -a 'date' //所有hosts主机执行date命令ansible all -a 'ls /' ##如果不加-m模块,则默认运行command模块,all:表示所有的分类## 报错信息:"changed": false, ##########################################################[root@localhost ~]# ansible all -a 'ls /'192.168.10.30 | UNREACHABLE! => { "changed": false, "msg": "Failed to connect to the host via ssh: Permission denIEd (publickey,gssAPI-keyex,gssAPI-with-mic,password).", "unreachable": true}192.168.10.170 | UNREACHABLE! => { "changed": false, "msg": "Failed to connect to the host via ssh: Permission denIEd (publickey,gssAPI-keyex,gssAPI-with-mic,password).", "unreachable": true} 报错原因:ssh秘钥错误 ssh-keygen -t rsa ##生成秘钥 ssh-copy-ID root@192.168.10.30 ssh-copy-ID root@192.168.10.170 //配置密钥对验证 ssh-agent bash ##开启代理功能 ssh-add ##添加秘钥给代理########################################################################3.2、cron模块(设置计划任务)两种状态(state):present表示添加(可以省略),absent表示移除[root@localhost ~]# ansible-doc -s cron # 查看cron模块信息,帮助文档[root@localhost ~]# ansible webserver -m cron -a 'minute="*/1" job="/usr/bin/echo heihei" name="test cron job"'# 选项解释:# -m:指定模块;# -a:指定参数;minute="*/1":表示每分钟执行计划任务;# job="/bin/echo heihei":表示执行echo的动作;# 最后name表示定义的计划任务的名称(自定义)[root@localhost ~]# ansible webserver -a 'crontab -l' # 查看设置的计划任务192.168.10.30 | CHANGED | rc=0 >>#Ansible: test cron job*/1 * * * * /usr/bin/echo heihei[root@localhost ~]# crontab -l # 去192.168.10.30(即webserver)上查看计划任务#Ansible: test cron job*/1 * * * * /usr/bin/echo heihei # 可以查看到计划任务You have new mail in /var/spool/mail/root # 执行的结果生成在/var/spool/mail/root文件内[root@localhost ~]# ansible webserver -m cron -a 'name="test cron job" state=absent' //指定计划任务名称,结合state=absent参数,移除计划任务[root@localhost ~]# ansible webserver -a 'crontab -l' # 再次查看,计划任务消失了192.168.10.30 | CHANGED | rc=0 >>3.3、user模块(用户 *** 作)# user模块是请求的是useradd,userdel,usermod三个指令[root@localhost ~]# ansible-doc -s user # 查看user模块参数说明[root@localhost ~]# ansible MysqL -m user -a 'name="test01"' # 创建用户test01[root@localhost ~]# ID test01 # 到192.168.10.170(即MysqL上)查看用户是否建立uID=1001(test01) gID=1001(test01) 组=1001(test01)[root@localhost ~]# ansible MysqL -m command -a 'tail -1 /etc/passwd' # 同样可以查看到新用户test01192.168.10.170 | CHANGED | rc=0 >>test01:x:1001:1001::/home/test01:/bin/bash[root@localhost ~]# ansible MysqL -m user -a 'name="test01" state=absent' # 删除用户test01,state=absent参数用于删除3.4、group模块(用户组 *** 作)# group模块请求的是groupadd,groupdel,groupmod 三个指令。[root@localhost ~]# ansible-doc -s group # 查看group模块参数说明[root@localhost ~]# ansible MysqL -m group -a 'name=MysqL gID=306 system=yes' # 创建用户组MysqL,指定uID,system=yes代表创建的是系统组[root@localhost ~]# ansible MysqL -a 'tail -1 /etc/group' # 查看到新建的用户组192.168.10.170 | CHANGED | rc=0 >>MysqL:x:306:[root@localhost ~]# ansible MysqL -m user -a 'name=test01 uID=306 system=yes group=MysqL' # 创建test01用户,指定uID,和ground组名,添加到MysqL组[root@localhost ~]# ansible MysqL -a 'tail -1 /etc/passwd' # 查看,MysqL组中多了test01用户成员192.168.10.170 | CHANGED | rc=0 >>test01:x:306:306::/home/test01:/bin/bash[root@localhost ~]# ansible MysqL -a 'ID test01' # 查看test01用户,标明了所在组192.168.10.170 | CHANGED | rc=0 >>uID=306(test01) gID=306(MysqL) groups=306(MysqL)3.5、copy模块(复制目录或文件)[root@localhost ~]# ansible-doc -s copy # 查看copy模块参数说明[root@localhost ~]# ansible MysqL -m copy -a 'src=/etc/fstab dest=/opt/fstab.back owner=root mode=640'# 参数解释:# src:源文件(被copy的文件);# dest:目标文件;# owner:属主属性;# mode:文件权限属性[root@localhost ~]# ansible MysqL -a 'ls -l /opt' # 查看copy过去的文件,属主root,权限640192.168.10.170 | CHANGED | rc=0 >>total 4-rw-r-----. 1 root root 465 Nov 29 22:34 fstab.back[root@localhost ~]# ansible MysqL -a ' cat /opt/fstab.back' # 查看内容[root@localhost ~]# ansible MysqL -m copy -a 'content="hello heihei !" dest=/opt/fstab.back' # 将hello heihei!写入/opt/fstab.back[root@localhost ~]# ansible MysqL -a 'cat /opt/fstab.back' # 查看到写入的内容192.168.10.170 | CHANGED | rc=0 >>hello heihei !3.6、file模块(修改文件属性)1、修改文件属性, ansible all -m file -a “path=/root/test.sh owner=test group=test mode=0644”
2、生成链接文件:ansible all -m file -a “src=/root/test.sh dest=/root/testlink.sh owner=root group=root state=link”
3、创建空文件:ansible all -m file -a “path=/root/testtouch.sh state=touch mode=0644”
4、创建空目录: ansible all -m file -a “path=/root/testdirectory state=directory mode=0644”
5、删除目录或文件,强制执行:ansible all -m file -a “path=/root/testdirectory state=absent force=yes”
[root@localhost ~]# ansible-doc -s file # 查看file模块参数说明[root@localhost ~]# ansible MysqL -m user -a ' name=MysqL system=yes'[root@localhost ~]# ansible MysqL -m group -a ' name=MysqL system=yes'[root@localhost ~]# ansible MysqL -m file -a 'owner=MysqL group=MysqL mode=644 path=/opt/fstab.back' # 修改文件属主、属组、权限[root@localhost ~]# ansible MysqL -m file -a ' src=/opt/fstab.back path=/opt/fstab.link state=link' # 给原文件/opt/fstab.back建立软连接,利用state=link参数[root@localhost ~]# ansible MysqL -m file -a "path=/opt/fstab.back state=absent" # 删除一个文件或目录[root@localhost ~]# ansible MysqL -m file -a "path=/opt/test state=touch" # 创建一个空文件[root@localhost ltp]# ansible 192.168.2.100 -m file -a "name=/abc state=directory" # 创建一个目录3.7、Ping模块(测试被管理主机是否在线)[root@localhost ~]# ansible all -m Ping ## Ping所有分类192.168.10.30 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "Ping": "pong" ## "pong" 表示能Ping通}192.168.10.170 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "Ping": "pong"}3.8、yum模块[root@localhost ~]# ansible-doc -s yum # 查看模块帮助文档[root@localhost ~]# ansible webserver -m yum -a 'name="httpd"' //yum安装httpd服务 [root@localhost ~]# rpm -q httpd ##到192.168.10.20上查看,安装成功了httpd-2.4.6-97.el7.centos.x86_64 [root@localhost ~]# ansible webserver -m yum -a 'name=httpd state=absent' //卸载httpd[root@localhost ~]# rpm -q httpd ##再到192.168.10.20上查看,被卸载了package httpd is not installed3.9、service模块(用于启动服务)[root@localhost ~]# ansible-doc -s service[root@localhost ~]# ansible webserver -m yum -a 'name="httpd"' [root@localhost ~]# ansible webserver -a 'systemctl status httpd' // 查看web服务器httpd运行状态192.168.10.30 | Failed | rc=3 >>● httpd.service - The Apache http Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; Disabled; vendor preset: Disabled) Active: inactive (dead) Docs: man:httpd(8) man:apachectl(8)non-zero return code[root@localhost ~]# ansible webserver -m service -a 'enabled=true name=httpd state=started' //启动httpd服务,并且开机自启[root@localhost ~]# ansible webserver -a 'systemctl status httpd' //查看是否开启,成功开启了 192.168.10.30 | CHANGED | rc=0 >>● httpd.service - The Apache http Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: Disabled) Active: active (running) since Sun 2020-11-29 23:30:11 CST; 8s ago Docs: man:httpd(8) man:apachectl(8)3.10、shell模块(执行shell命令)[root@localhost ~]# ansible-doc -s shell[root@localhost ~]# ansible webserver -m user -a 'name=jack' ##创建一个用户[root@localhost ~]# ansible webserver -m shell -a 'echo abc123 | passwd --stdin jack' ##使用无交互模式给用户设置密码192.168.10.30 | CHANGED | rc=0 >>Changing password for user jack.passwd: all authentication tokens updated successfully. ##免密设置成功3.11、script模块(本地先写脚本,利用ansible在控制主机上执行)ansible-doc -s script[root@localhost ~]# vim /opt/test.sh ##写一个脚本#!/bin/bashecho "hello ansible from script"> /opt/script.txt[root@localhost ~]# chmod +x test.sh ##给执行权限[root@localhost ~]# ansible MysqL -m script -a '/opt/test.sh' ##指定script模块和脚本位置,执行脚本[root@localhost ~]# cat /opt/script.txt ##到192.168.10.170上查看,脚本是否执行成功hello ansible from script3.12、setup模块 ( 获取主机信息 )ansible-doc -s setupansible MysqL -m setup //获取MysqL组主机的facts信息(包含ip信息、版本信息等等)五、Ansible playbooks 模式ansible-playbook剧本,可以更加灵活的配置部署不同的主机1. 查看ansible-playbook的帮助文档[root@localhost ~]# ansible-playbook -husage: ansible-playbook [-h] [--version] [-v] [-k] [--private-key PRIVATE_KEY_file] [-u REMOTE_USER] [-c CONNECTION] [-T TIMEOUT] [--ssh-common-args SSH_COMMON_ARGS] [--sftp-extra-args SFTP_EXTRA_ARGS] [--scp-extra-args SCP_EXTRA_ARGS] [--ssh-extra-args SSH_EXTRA_ARGS] [--force-handlers] [--flush-cache] [-b] [--become-method BECOME_METHOD] [--become-user BECOME_USER] [-K] [-t Tags] [--skip-Tags SKIP_Tags] [-C] [--Syntax-check] [-D] [-i INVENTORY] [--List-hosts] [-l SUBSET] [-e EXTRA_VARS] [--vault-ID VAulT_IDS] [--ask-vault-pass | --vault-password-file VAulT_PASSWORD_fileS] [-f FORKS] [-M MODulE_PATH] [--List-tasks] [--List-Tags] [--step] [--start-at-task START_AT_TASK] playbook [playbook ...]……2. 讲解playbook的yamlplaybook是根据yaml语法格式的文件进行编写的对于ansible来说,每一个yaml文件都是从一个列表开始,列表中的每一项都是一个键值对,通常被称为一个"哈希"或"字典"。所有的yaml文件开始行都应该是"—",这是yaml格式的一部分,表明一个文件的开始。列表中的所有成员都开始于相同的缩进级别了,并且使用一个"-“作为开头(一个横杠”-“和一个空格” ")YAML支持的数据结构:
1.对象:键值对的集合,又称为映射(mapPing)/哈希(hashes)/字例如:name: Example Developer 键 值2.数组:一组按次序排列的值,又称为序列(sequence)/列表(List)例如:- Apple - Orange3.纯量:单个的、不可再分的值例如: number: 12.30sure: trueyaml示例:
---# 一个美味的水果列表- Apple- Oranage- Strawebrry- Mango一个字典是由一个简单的 键: 值 的形式组成(注意:这个":"冒号后面必须是一个空格)
---# 一个职工的记录name: Example Developerjob: Developerskill: Elite字典也可以使用缩进形式来表示(这种格式在ansible中不经常使用)
---# 一个职工记录{name: Example Developer, job: Developer, skill: Elite}可以通过下面格式指定一个布尔值
---create_key: yesneed_agent: nokNows_oop: Truelikes_emacs: TRUEuses_cvs: False示例:将上面的示例整合到一个yaml中
---# 一个职工记录name: Example Developerjob: Developerskill: Eliteemployed: Truefoods: - Apple - Orange - StrawBerry - Mango# 相当于{foods:[Apple, Orange, StrawBerry, Mango]}languages: ruby: Elite python: Elite dotnet: Lame# 相当于{languages:{ruby: Elite, python: Elite, dotnet: Lame}}3. 尝试编写playbook.yamlplaybooks本身由以下各部分组成
(1) Tasks:任务,即调用模块完成的某 *** 作,执行了tasks,相当于执行了事务,一旦有一条失败,则进行回滚 ;(2) Variables:变量(3) Templates:模板(4) Handlers:处理器,当某条件满足时,触发执行的 *** 作;(5) Roles:角色。示例1:
[root@localhost ~]# cat /etc/ansible/hosts |grep -Ev "^$|^#" [work]masternode[master]192.168.10.10[node]192.168.10.20[root@localhost ~]# vim MyPlaybook.yaml- shosts: master remote_user: root task: - name: read sys time shell: echo "$(date +'%Y-%m-%d %T')" > time.txt- hosts: slave remote_user: root task: - name: List file shell: ls -ltr > List.txt执行结果:
[root@localhost ~]# ansible-playbook MyPlaybook.yaml --ask-passSSH password: PLAY [master] ********************************************************************************************************TASK [Gathering Facts] ***********************************************************************************************ok: [192.168.10.10]TASK [read sys time] *************************************************************************************************changed: [192.168.10.10]PLAY [node] **********************************************************************************************************TASK [Gathering Facts] ***********************************************************************************************ok: [192.168.10.20]TASK [List file] *****************************************************************************************************changed: [192.168.10.20]PLAY RECAP ***********************************************************************************************************192.168.10.10 : ok=2 changed=1 unreachable=0 Failed=0 skipped=0 rescued=0 ignored=0 192.168.10.20 : ok=2 changed=1 unreachable=0 Failed=0 skipped=0 rescued=0 ignored=0 # 查看执行后生成的文件[root@localhost ~]# ansible all -m shell -a "ls -ltr |tail -1"192.168.10.10 | CHANGED | rc=0 >>-rw-r--r-- 1 root root 20 5月 23 21:14 time.txt192.168.10.20 | CHANGED | rc=0 >>-rw-r--r-- 1 root root 1051 5月 23 21:14 List.txt-f :可以指定并发进程数
例如:ansible-playbook MyPlaybook.yaml --ask-pass -f 3 # 表示由3个并发进程来执行
示例2
下面是一个playbook的示例:
# 查看模板内容,模板中用{{变量名}}来调用playbook.yaml中的变量值,如下[root@localhost temp]# vim httpd-temp.confListen {{http_port}}MaxClIEnts {{max_clIEnts}}[root@localhost temp]# vim httpPlaybook.yaml- hosts: node # 定义的主机组,即应用的主机,前面的(- hosts:)不能更改,指明在/etc/ansible/hsots中声明的组 vars: # 定义变量 http_port: 80 max_clIEnts: 200 user: root # 在远程执行时建议使用remote_user远程用户 tasks: # 执行的任务 - name: ensure apache is at the latest version # 指定任务名称,会在执行任务时显示出来的内容(自定义),有利于定位错误发生位置 yum: pkg=httpd state=latest # yum是模块,pkg指定检测软件包,state=latest是否为最新的 - name: write the apache config file template: src=httpd-temp.conf dest=/etc/httpd/conf/httpd.conf # 定义配置文件模板 notify: # 调用下面自定义的restart apache(restart apache在handlers中定义了具体内容) - restart apache - name: ensure apache is running service: name=httpd state=started handlers: # 处理器,当某条件满足时,触发执行的 *** 作,和notify结合使用,被notify调用; - name: restart apache service: name=httpd state=restarted执行结果:
[root@localhost temp]# ansible-playbook httpPlaybook.yaml PLAY [node] **********************************************************************************************************TASK [Gathering Facts] ***********************************************************************************************ok: [192.168.10.20]TASK [ensure apache is at the latest version] ************************************************************************ok: [192.168.10.20]TASK [write the apache config file] **********************************************************************************ok: [192.168.10.20]TASK [ensure apache is running] **************************************************************************************changed: [192.168.10.20]PLAY RECAP ***********************************************************************************************************192.168.10.20 : ok=4 changed=1 unreachable=0 Failed=0 skipped=0 rescued=0 ignored=0 [root@localhost temp]# ansible node -m shell -a "systemctl status httpd"192.168.10.20 | CHANGED | rc=0 >>● httpd.service - The Apache http Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; Disabled; vendor preset: Disabled) Active: active (running) since 日 2021-05-23 21:30:07 CST; 21s ago Docs: man:httpd(8) man:apachectl(8) Main PID: 7544 (httpd) Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec" Memory: 3.3M CGroup: /system.slice/httpd.service ├─7544 /usr/sbin/httpd -DFOREGROUND ├─7545 /usr/sbin/httpd -DFOREGROUND ├─7546 /usr/sbin/httpd -DFOREGROUND ├─7547 /usr/sbin/httpd -DFOREGROUND ├─7548 /usr/sbin/httpd -DFOREGROUND └─7549 /usr/sbin/httpd -DFOREGROUND5月 23 21:30:07 node01 systemd[1]: Starting The Apache http Server...5月 23 21:30:07 node01 httpd[7544]: AH00558: httpd: Could not reliably determine the server's fully qualifIEd domain name, using fe80::20c:29ff:fe47:c5d7. Set the 'Servername' directive globally to suppress this message5月 23 21:30:07 node01 systemd[1]: Started The Apache http Server.4. ansible-playbook相关命令执行一个playbook
语法:ansible-playbook [yaml文件名]
例如: ansible-playbook Ping.yml
参数:-k(-ask-pass):用来交互输入ssh密码
-K(-ask-become-pass):用来交互输入sudo密码(提权)…
-u:指定用户
补充命令:
5. hosts和users介绍
# 检查yaml文件的语法
ansible-playbook Nginx.yaml --Syntax-check
# 检查tasks任务
ansible-playbook Nginx. yaml --List-task
# 检查生效的主机
ansible-playbook Nginx. yaml --List-hosts
# 指定playbook中的task执行,检查效果
ansible-playbook Nginx.yaml --start-at-task=‘copy Nginx.conf’
# 指定执行playbook的并行线程数
ansible-playbook Nginx.yaml -f 线程数
- hosts: webserver # 指定主机组,可以是一个或多个组。 remote_user: root # 指定远程主机执行的用户名,注意,用户一定要有执行权限还可以为每个任务定义远程执行用户:
- hosts: MysqL remote_user: root tasks: -name: test connection Ping: remote_user: MysqL # 指定远程主机执行tasks的运行用远程指定的用户执行playbook时: ansible-playbook Ping. yml -k
指定远程主机sudo切换用户:
-hosts: MysqL remote_user: root become: yes ## 2.6版本以后的参数,之前是sudo,意思相同 become_user: MysqL ## 指定sudo用户为MysqL,之后执行任务的用户就变为MysqL了执行playbook时 : ansible-playbook Ping. yml -K
6. tasks列表和action
1、Play的主体部分是task列表,task列表中的各任务按次序逐个在hosts中指定的主机上执行
在hosts中扌在运行playbook时(从上到下执行),如果一个host执行task失败,整个tasks都将回滚,请求修正playbook中的错误Task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量,模2、每一个task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很好的辨别出是属于那一部分的任务
3、定义一个task,常见的格式:”module: options”是"模块对应参数"的形式,例如: yum: name=htttpd
4、ansible的自带模块中,command模块和shel1模块无需使用key=value格式
示例:
- hosts: 192.168.10.20 remote_user: root tasks: - name: disable selinux command: '/sbin/setenforce o' - name: make sure apache is running service: name=httpd state=startedplaybook中只要执行命令的返回值不为0,就会报错,tasks停止
要想报错不停止执行tasks,修改如下 ignore_errors: True
- hosts: webserver remote_user: root tasks: - name: disable selinux command: '/sbin/setenforce 0' ignore_errors: True #忽略错误,强制返回成功,继续执行,true这个布尔值不区分大小写的 - name: make sure apache is running service: name=httpd state=started以下是另外一个示例,可以读一读
- hosts: webserver remote_user: root tasks: - name: create Nginx group group: name=Nginx system=yes gID=208 - name: create Nginx user user: name=Nginx uID=208 group=Nginx system=yes- hosts: MysqL remote_user: root tasks: - name: copy file to MysqL copy : src=/etc/inittab dest=/opt/inittab.back7. Handlers介绍Handlers也是一些task的列表,和一般的task并没有什么区别。是由通知者进行的notify,如果没有被notify,则Handlers不会执行,假如不管有多少个通知者进行了notify,等到play中的所有task执行完成之后,只有当一个task中的动作action执行了,这个task中的notify才会生效,才会通知执行handler中的action示例1
- hosts: webserver remote_user: root tasks: - name: install httpd package yum: name=httpd state=latest - name: install configuration file for httpd copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf notify: - restart httpd - name: start httpd service service: enabled=true name=httpd state=started handlers: - name: restart httpd service: name=httpd state=restarted示例2:测试notify所在task执行失败,是否会继续执行notify
[root@localhost temp]# vim testvarPlaybook.yaml - hosts: node remote_user: root vars: # 定义变量 - path: /root/ - filename: test.txt tasks: - name: delete file file: path=/root/test.txt state=absent ignore_errors: True notify: - modify file handlers: - name: modify file shell: echo "123" >{{path}}{{filename}}若目标及其的root目录下不存在test.txt文件,"delete file"的任务无法执行成功。发现notify不会调用handler# 目标及其没有test.txt文件[root@localhost temp]# ansible node -m shell -a "cat test.txt"192.168.10.20 | Failed | rc=1 >>cat: test.txt: 没有那个文件或目录non-zero return code# 执行playbook[root@localhost temp]# ansible-playbook testvarPlaybook.yaml PLAY [node] **********************************************************************************************************TASK [Gathering Facts] ***********************************************************************************************ok: [192.168.10.20]TASK [delete file] ***************************************************************************************************ok: [192.168.10.20]PLAY RECAP ***********************************************************************************************************192.168.10.20 : ok=2 changed=0 unreachable=0 Failed=0 skipped=0 rescued=0 ignored=0 # 再次查看,依旧没有test.txt文件[root@localhost temp]# ansible node -m shell -a "cat test.txt"192.168.10.20 | Failed | rc=1 >>cat: test.txt: 没有那个文件或目录non-zero return code若目标机器的root目录下存在test.txt文件,"delete file"的任务能成功执行。发现notify调用的handler也执行了,修改了test.txt中内容# 首先在目标机器上创建test.txt文件[root@localhost temp]# ansible node -m file -a "path=/root/test.txt state=touch"192.168.10.20 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/root/test.txt", "gID": 0, "group": "root", "mode": "0644", "owner": "root", "size": 0, "state": "file", "uID": 0}# 查看文件内容为空[root@localhost temp]# ansible node -m shell -a "cat test.txt"192.168.10.20 | CHANGED | rc=0 >># 执行playbook[root@localhost temp]# ansible-playbook testvarPlaybook.yaml PLAY [node] **********************************************************************************************************TASK [Gathering Facts] ***********************************************************************************************ok: [192.168.10.20]TASK [delete file] ***************************************************************************************************changed: [192.168.10.20]RUNNING HANDLER [modify file] ****************************************************************************************changed: [192.168.10.20]PLAY RECAP ***********************************************************************************************************192.168.10.20 : ok=3 changed=2 unreachable=0 Failed=0 skipped=0 rescued=0 ignored=0 # 查看test.txt文件,handler的action被调用执行[root@localhost temp]# ansible node -m shell -a "cat test.txt"192.168.10.20 | CHANGED | rc=0 >>1238.playbook引入变量playbook使用变量的方法:
1、在yml文件中使用vars来设置变量
2、在/etc/ansible/hosts文件中主机名后面声明变量(如:变量username=lisi)
3、在执行ansible-playbook时,后面加上 -e 变量名=值 的方式给变量赋值;如 ansible-playbook test.yml -e “service=httpd”
示例1
- hosts: webserver remote_user: root vars: - package: httpd - service: httpd tasks: - name: install httpd package yum: name={{package}} state=latest - name: install configuration file for httpd copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf notify: - restart httpd - name: start httpd service service: enabled=true name={{service}} state=started handlers: - name: restart httpd service: name={{service}} state=restarted9. 引用ansible的固定变量示例
[root@localhost temp]# vi test.yml- hosts: node remote_user: root tasks: - name: copy filel # {{ansible_all_ipv4_addresses}}是引用ip的固定变量 copy: content="{{ansible_all_ipv4_addresses}}," dest=/opt/ipList.txt执行结果
[root@localhost temp]# ansible-playbook test.yaml PLAY [node] **********************************************************************************************************TASK [Gathering Facts] ***********************************************************************************************ok: [192.168.10.20]TASK [copy filel] ****************************************************************************************************changed: [192.168.10.20]PLAY RECAP ***********************************************************************************************************192.168.10.20 : ok=2 changed=1 unreachable=0 Failed=0 skipped=0 rescued=0 ignored=0 [root@localhost temp]# ansible node -m shell -a "cat /opt/ipList.txt"192.168.10.20 | CHANGED | rc=0 >>([u'192.168.122.1', u'192.168.10.20'],)# 查看目标机器ip,确实有192.168.122.1 和 192.168.10.20两个ip[root@localhost temp]# ansible node -m shell -a "ip a"192.168.10.20 | CHANGED | rc=0 >>……2: ens33: <broADCAST,MulTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:47:c5:d7 brd ff:ff:ff:ff:ff:ff inet 192.168.10.20/24 brd 192.168.10.255 scope global ens33……3: virbr0: <NO-CARRIER,broADCAST,MulTICAST,UP> mtu 1500 qdisc noqueue state DOWN qlen 1000 link/ether 52:54:00:13:da:e3 brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0……10. 条件测试,条件判断如果需要根据变量facts (setup)或此前任务的执行结果来作为某task执行依据,可以在task后添加when子句,即可使用条件测试: when子句支持jinjia2表达式或10.1、单条件判断
[root@localhost temp]# vim test.yaml - hosts: node remote_user: root tasks: - name: "look os" shell: echo {{ansible_distribution}} >os.txt when: ansible_distribution == "CentOS"执行结果
[root@localhost temp]# ansible-playbook test.yaml PLAY [node] **********************************************************************************************************TASK [Gathering Facts] ***********************************************************************************************ok: [192.168.10.20]TASK [look os] *******************************************************************************************************changed: [192.168.10.20]PLAY RECAP ***********************************************************************************************************192.168.10.20 : ok=2 changed=1 unreachable=0 Failed=0 skipped=0 rescued=0 ignored=0 # 查看os.txt文件[root@localhost temp]# ansible node -m shell -a "cat os.txt"192.168.10.20 | CHANGED | rc=0 >>CentOS10.2、多条件判断[root@localhost temp]# cat test.yaml - hosts: node remote_user: root tasks: - name: "look os" shell: echo "{{ansible_distribution}}.{{ansible_distribution_major_version}}" >os.txt when: - ansible_distribution == "CentOS" - ansible_distribution_major_version == "7"执行结果
[root@localhost temp]# ansible-playbook test.yaml PLAY [node] **********************************************************************************************************TASK [Gathering Facts] ***********************************************************************************************ok: [192.168.10.20]TASK [look os] *******************************************************************************************************changed: [192.168.10.20]PLAY RECAP ***********************************************************************************************************192.168.10.20 : ok=2 changed=1 unreachable=0 Failed=0 skipped=0 rescued=0 ignored=0 [root@localhost temp]# ansible node -m shell -a "cat os.txt"192.168.10.20 | CHANGED | rc=0 >>CentOS.710.3、组条件判断[root@localhost temp]# cat test.yaml - hosts: node remote_user: root tasks: - name: "look os" shell: echo "{{ansible_distribution}}.{{ansible_distribution_major_version}}" >os.txt when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "7") or (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6")## 满足系统为centos且为6版本,或者系统文centos且是6版本,则执行命令执行结果
[root@localhost temp]# ansible-playbook test.yaml PLAY [node] **********************************************************************************************************TASK [Gathering Facts] ***********************************************************************************************ok: [192.168.10.20]TASK [look os] *******************************************************************************************************changed: [192.168.10.20]PLAY RECAP ***********************************************************************************************************192.168.10.20 : ok=2 changed=1 unreachable=0 Failed=0 skipped=0 rescued=0 ignored=0 [root@localhost temp]# ansible node -m shell -a "cat os.txt"192.168.10.20 | CHANGED | rc=0 >>CentOS.710.4、自定义变量进行条件测试[root@localhost temp]# vi test.yaml - hosts: node remote_user: root vars: msg: 'hellow world' exist: True flag: None tasks: - name: "existed file" shell: rm -rf os.txt when: - exist == False - name: 'look file' shell: echo "{{msg}}" >os.txt when: flag == "None"执行结果
[root@localhost temp]# ansible-playbook test.yaml PLAY [node] **********************************************************************************************************TASK [Gathering Facts] ***********************************************************************************************ok: [192.168.10.20]TASK [existed file] **************************************************************************************************skipPing: [192.168.10.20]TASK [look file] *****************************************************************************************************changed: [192.168.10.20]PLAY RECAP ***********************************************************************************************************192.168.10.20 : ok=2 changed=1 unreachable=0 Failed=0 skipped=1 rescued=0 ignored=0 [root@localhost temp]# ansible node -m shell -a "cat os.txt"192.168.10.20 | CHANGED | rc=0 >>hellow world11、迭代当有需要重复性执行的任务时,可以使用迭代机制。迭代器,类似于for循环,依次执行11.1、直接调用item迭代器[root@localhost temp]# vim test.yaml - hosts: node remote_user: root vars: path: /ltp/ msg: "hellow world" tasks: - name: "Save Msg" shell: echo {{msg}} > {{path}}{{item}} # 固定变量item,值为下面with_items:下的参数,遍历执行 with_items: # 定义了item的值 - first.txt - second.txt - third.txt register: shell_result # registe用于储存执行结果,调试阶段使用,利用下面的deBUG返回结果 - deBUG: var=shell_result.stdout verbosity=0 执行结果
# 查看文件内容[root@localhost temp]# ansible node -m shell -a "cat /ltp/first.txt"192.168.10.20 | CHANGED | rc=0 >>I am the first[root@localhost temp]# ansible node -m shell -a "cat /ltp/second.txt"192.168.10.20 | CHANGED | rc=0 >>I am the second[root@localhost temp]# ansible node -m shell -a "cat /ltp/third.txt"192.168.10.20 | CHANGED | rc=0 >>I am the third# 执行playbook[root@localhost temp]# ansible-playbook test.yaml PLAY [node] **********************************************************************************************************TASK [Gathering Facts] ***********************************************************************************************ok: [192.168.10.20]TASK [Save Msg] ******************************************************************************************************changed: [192.168.10.20] => (item=first.txt)changed: [192.168.10.20] => (item=second.txt)changed: [192.168.10.20] => (item=third.txt)TASK [deBUG] *********************************************************************************************************ok: [192.168.10.20] => { "shell_result.stdout": "VARIABLE IS NOT defineD!"}PLAY RECAP ***********************************************************************************************************192.168.10.20 : ok=3 changed=1 unreachable=0 Failed=0 skipped=0 rescued=0 ignored=0 # 再次查看文件内容,全部被改变了[root@localhost temp]# ansible node -m shell -a "cat /ltp/first.txt"192.168.10.20 | CHANGED | rc=0 >>hellow world[root@localhost temp]# ansible node -m shell -a "cat /ltp/second.txt"192.168.10.20 | CHANGED | rc=0 >>hellow world[root@localhost temp]# ansible node -m shell -a "cat /ltp/third.txt"192.168.10.20 | CHANGED | rc=0 >>hellow world11.2、自定义迭代器也可以自己定义迭代器属性
[root@localhost temp]# vim item.yaml- hosts: node remote_user: root tasks: - name: "Add users" # with_items:下每一行就是item的一个值,item.name指其值得name字段的值,如test1 user: name={{item.name}} state=present groups={{item.groups}} with_items: - {name: 'test1',groups: 'wheel'} - {name: 'test2',groups: 'root'}# 执行效果就是创建两个用户,并且分别指定了属主和属组12、给task打标签(Tags)Tags模块:在一个playbook中,我们一般会定义很多个task,如果我们只想执行其中的一个或者某一些 *** 作时,可以在tasks *** 作语句下面添加Tags标签,指定执行。
示例:
[root@localhost temp]# vim host.yaml- hosts: webserver remote_user: root tasks: - name: touch file file: path=/opt/host01 state=touch - name: copy hosts file copy : src=/etc/hosts dest=/opt/hosts Tags: - abc - name: touch file file: path=/opt/host02 state=touch执行命令:ansible-playbook hosts.yml --Tags="abc" # 加上"–Tags=标签" ,就只执行打上标签的这段 *** 作语句ansible-playbook hosts.yml # 若不加上"–Tags=标签" ,那么将会执行全部的task事实上,不光可以为单个或多个task指定同一个Tags。playbook还提供了一个特殊的Tags标签(always),被打上always标签的任务,无论是否指定标签执行是有没有指定它,它都会执行。
示例
[root@localhost temp]# wim host.yaml- hosts: MysqL remote_user: root tasks: - name: copy hosts file copy: src=/etc/hosts dest=/opt/hosts Tags: - only - name: touch file file: path=/opt/host1 state=touch Tags: - always执行命令
ansible-playbook host.yaml --Tags="only" # 指定执行带有only标签的命令,结果发现带有always标签的也会跟着执行
以上是内存溢出为你收集整理的python -- 自动化运维工具ansible(大全)全部内容,希望文章能够帮你解决python -- 自动化运维工具ansible(大全)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)