Ansible 自动化最佳实践
版本标识 |
V1 |
编制单位 |
李斌 |
编制日期 |
2022年9月23日 |
Ansible官网 |
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/ |
简介:
Ansible 作为目前使用最广的自动化工具可以替代shell,可运行在服务器、网络设备等多类设备上执行。是一种可以批量管理、批量执行、批量部署的软件。
/etc/ansible/ansible.cfg |
#ansible的主配置文件;管理ansible日志和定义模块与插件;全局模式 |
inventory= /home/libin/dep-install/inventory |
自定义清单的位置 |
第一章 架构布局
1.1主机布局:
主机名 |
IP地址 |
受管节点ansible服务器libin: |
192.168.124.132 |
受管节点client01为libin2: |
192.168.124.133 |
受管节点client02为libin3: |
192.168.124.134 |
1.2安装ansible
1.2.1 配置yum源
[root@libin yum.repos.d]# cat epel-ansible.repo [epel] name=all source for ansible baseurl=https://mirrors.aliyun.com/epel/7/x86_64/ enabled=1 gpgcheck=0
[ansible] name=all source for ansible baseurl=https://mirrors.aliyun.com/centos/7/os/x86_64/ enabled=1 gpgcheck=0
|
1.2.2 安装ansible
ansible服务器libin操作:
[root@libin ansible]# yum install epel-release -y [root@libin ansible]# yum install ansible -y [root@libin ansible]# rpm -qa | grep ansible ansible-2.9.25-1.el7.noarch |
1.3配置ansible
1.3.1使用ansible前需实现ssh免密
1、 输入命令:ssh-keygen,一直按回车,直至完成操作; 2、 命令:ssh-copy-id root@ 192.168.x.x,然后输入连接密码即可实现无密码访问,另外一台机的设置方式一样,不再赘述。 [root@libin ansible]# ssh-keygen [root@libin ansible]# ssh-copy-id [email protected] [root@libin ansible]# ssh-copy-id [email protected] [root@libin ansible]# ssh-copy-id [email protected] |
1.3.2添加ansible客户机组
vim /etc/ansible/hosts,在最后面添加如下内容:
[group1] 192.168.124.128 192.168.124.134 |
1.4 自定义ansible清单、组的格式
1.4.1 定义ansible 清单inventory
[root@libin wt]# cat /etc/ansible/ansible.cfg | grep inventory inventory = /home/libin/dep-install/inventory #inventory = /etc/ansible/hosts |
1.4.2 自定义ansible的清单路径
*用普通用户执行 需要 在主配置文件ansible.cfg定义 inventory的路径,否则默认为 root的 /etc/ansible/hosts
[root@libin ansible]# mkdir dep-install [root@libin ansible]# cd dep-install/ [root@libin ansible]# vim inventory [root@libin ansible]# cat /home/libin/dep-install/inventory [group1] 192.168.124.132 #192.168.124.133 192.168.124.134 #192.168.124.135
[dev] 192.168.124.132
[db] #192.168.124.135 |
1.4.3 定义组的格式
ansible 组名 -i inventory/hosts - -list-host
[root@libin dep-install]# ansible group1 -i inventory --list-hosts hosts (2): 192.168.124.132 192.168.124.134 [root@libin dep-install]# ansible dev -i inventory --list-hosts hosts (1): 192.168.124.132 [root@libin dep-install]# ansible db -i inventory --list-hosts |
[root@libin ansible]# cat /home/libin/dep-install/inventory [group1] 192.168.124.132 #192.168.124.133 192.168.124.134 #192.168.124.135
[dev] servera serverb serverc Serverd
[db] servera serverb 192.168.[4:7].[0:255] #定义网段 [a:c].dns.example.com #定义不同域名
[dc] serverc Serverd |
第二章、使用ansible
2.1 ansible版本
[root@libin yum.repos.d]# python -V Python 2.7.5
[root@libin wt]# ansible --version ansible 2.9.25 config file = /etc/ansible/ansible.cfg configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] |
2.2 测试ansible
2.2.1在server端执行ping命令
[root@libin ansible]# ansible group1 -m ping #-m:表示指定模块 192.168.124.132 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } 192.168.124.134 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
[root@libin ansible]# ansible -m ping hosts:192.168.124.134 192.168.124.134 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } [root@libin ansible]# ansible -m ping hosts:192.168.124.132 192.168.124.132 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } |
2.2.2 查看yaml格式
ansible-doc -l | grep 模块名 // 模块搜索 [root@libin ansible]# ansible-doc -l | grep copy vsphere_copy Copy a file to a VMware datastore [root@libin ansible]# ansible-doc -s copy #查看一个copy模块的用法 |
第三章 编写简单的ansible剧本与检查剧本基本格式
3.1 编写剧本
[root@libin dep-install]# cd /etc/ansible/ [root@libin ansible]# cat libin1.yaml --- - hosts: "all" remote_user: root tasks: - name: hostname shell: hostname
|
3.1.1 试运行与正式运行yaml剧本并打印执行信息
1.检测剧本语法是否正确
[root@libin ansible]# ansible-playbook --syntax-check libin1.yaml
playbook: libin1.yaml //返回剧本即为正确 |
2.测试运行剧本
[root@libin ansible]# ansible-playbook libin1.yaml -C PLAY [all] *********************************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************************* ok: [192.168.124.134] ok: [192.168.124.132]
TASK [hostname] **************************************************************************************************************************** skipping: [192.168.124.132] skipping: [192.168.124.134]
PLAY RECAP ********************************************************************************************************************************* 192.168.124.132 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 192.168.124.134 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
|
3.执行剧本打印执行信息
-v:表示打印执行剧本信息,显示更详细-vvvv
[root@libin ansible]# ansible-playbook libin1.yaml -vvvv changed: [192.168.124.132] => { "changed": true, "cmd": "hostname", "delta": "0:00:00.003658", "end": "2022-09-25 02:01:38.546742", "invocation": { "module_args": { "_raw_params": "hostname", "_uses_shell": true, "argv": null, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "stdin_add_newline": true, "strip_empty_ends": true, "warn": true } }, "rc": 0, "start": "2022-09-25 02:01:38.543084", "stderr": "", "stderr_lines": [], "stdout": "libin.com", "stdout_lines": [ "libin.com" ] } changed: [192.168.124.134] => { "changed": true, "cmd": "hostname", "delta": "0:00:00.004876", "end": "2022-09-25 02:01:37.818458", "invocation": { "module_args": { "_raw_params": "hostname", "_uses_shell": true, "argv": null, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "stdin_add_newline": true, "strip_empty_ends": true, "warn": true } }, "rc": 0, "start": "2022-09-25 02:01:37.813582", "stderr": "", "stderr_lines": [], "stdout": "libin3.com", "stdout_lines": [ "libin3.com" ] } META: ran handlers META: ran handlers
PLAY RECAP ********************************************************************************************************************************* 192.168.124.132 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.124.134 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 |
第四章 Asible最佳实践案例-入门版
1、编写剧本将序列号输出到ansible服务端libin.csv
说明:指定要执行的服务器,all是/etc/ansible/ansible.cfg定义的清单
[root@libin ansible]# cat libin1.yaml - hosts: "all" gather_facts: no tasks: - name: fetch shell: | dmidecode -t 1 | grep "Serial Number" | awk -F ":" '{print $2}' register: serial - name: dd shell: | echo "{{serial.stdout}},{{inventory_hostname}}" >> libin.csv delegate_to: localhost
[root@libin ansible]# ansible-playbook --syntax-check libin1.yaml playbook: libin1.yaml
[root@libin ansible]# ansible-playbook libin1.yaml -v
[root@libin ansible]# cat libin.csv VMware-56 4d 40 96 fc 5e cd 30-77 81 f8 0e 35 6c e9 48,192.168.124.134 VMware-56 4d 09 03 cb 2a d4 73-0d 34 01 0b a3 28 01 0d,192.168.124.132 |
2、解决在执行剧本时出现的WARNING问题
问题1、 [WARNING]: Unhandled error in Python interpreter discovery for host 192.168.124.134: unexpected output from Python interpreter discovery 解决方案: [root@libin ansible]# vim ansible.cfg interpreter_python = auto_legacy_silent #添加这行
问题2、 [WARNING]: sftp transfer mechanism failed on [192.168.124.134]. Use ANSIBLE_DEBUG=1 to see detailed information [WARNING]: scp transfer mechanism failed on [192.168.124.134]. Use ANSIBLE_DEBUG=1 to see detailed information 解决方案: [root@localhost ~]# vim /etc/ansible/ansible.cfg [ssh_connection] #Ansible默认使用SSH协议连接对端主机,该部署是主要是SSH连接的一些配置,但配置项较少,多数默认即可 scp_if_ssh=True #Ansible默认使用SSH协议连接对端主机,该部署是主要是SSH连接的一些配置,但配置项较少,多数默认即可 (以上解决方案来自网上,只作参考,具体还以生产环境为主) |
3、批量修改服务器的密码
[root@libin ansible]# cat libin2.yaml --- - hosts: "all" remote_user: root gather_facts: no tasks: - name: chage passwd1 user: name: 用户1 password: "{{ '密码1' | password_hash('sha512', 'helloworld') }}" update_password: always [root@libin ansible]# ansible-playbook libin2.yaml -C
changed: [192.168.124.132] changed: [192.168.124.134]
PLAY RECAP ********************************************************************************************************************************* 192.168.124.132 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.124.134 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 |
4、使用执行命令的模块(command)
说明:command 模块 命令模式 执行简单的命令(默认的模块)无法解析特殊符号
-a:表示模块中具体的命令,动作
[root@libin ansible]# ansible all -m command -a "hostname" 192.168.124.132 | CHANGED | rc=0 >> libin.com 192.168.124.134 | CHANGED | rc=0 >> libin3.com 写法2: [root@libin ansible]# ansible all -a "hostname" |
5、使用SHELL模块执行命令追加到文件并查看内容
说明:可以解析运行特殊符号
[root@libin ansible]# ansible all -m shell -a "hostname >>/tmp/hostname.txt" 192.168.124.132 | CHANGED | rc=0 >>
192.168.124.134 | CHANGED | rc=0 >>
[root@libin ansible]# ansible all -m shell -a "cat /tmp/hostname.txt" 192.168.124.132 | CHANGED | rc=0 >> libin.com 192.168.124.134 | CHANGED | rc=0 >> libin3.com |
6、批量拷贝脚本到所有服务器(copy)并执行脚本
例1、说明:shell模块执行是每台服务器下的路径脚本,没有就会执行失败
[root@libin ansible]# ansible all -m shell -a "sh /root/hostname.sh" 192.168.124.132 | CHANGED | rc=0 >> libin.com 192.168.124.134 | FAILED | rc=127 >> sh: /root/hostname.sh: 没有那个文件或目录non-zero return code |
例2、复制一个脚本到所有服务器,再执行脚本
Src:表示源,一般就是我们服务端的脚本
dest:表示目的,复制到哪去
[root@libin ansible]# ansible all -m copy -a "src=/root/hostname.sh dest=/root" 192.168.124.132 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "checksum": "4080c03edf24ad1ca3a9e83c54a363236df4432b", "dest": "/root/hostname.sh", "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/root/hostname.sh", "size": 21, "state": "file", "uid": 0 } 192.168.124.134 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "4080c03edf24ad1ca3a9e83c54a363236df4432b", "dest": "/root/hostname.sh", "gid": 0, "group": "root", "md5sum": "6c65510d520b68b9ef4d5f76552e8a98", "mode": "0644", "owner": "root", "size": 21, "src": "/root/.ansible/tmp/ansible-tmp-1664115854.66-33158-5269634189153/source", "state": "file", "uid": 0 }
[root@libin ansible]# ansible all -m shell -a "sh /root/hostname.sh" #执行脚本 192.168.124.132 | CHANGED | rc=0 >> libin.com 192.168.124.134 | CHANGED | rc=0 >> libin3.com |
7、批量拷贝脚本到所有服务器(copy)并修改脚本名及权限
说明: src:源路径服务器下脚本文件路径 dest:目的路径
[root@libin ansible]# ansible all -m copy -a "src=/root/hostname.sh dest=/tmp/ip.sh owner=libin group=root mode=700" 192.168.124.132 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "4080c03edf24ad1ca3a9e83c54a363236df4432b", "dest": "/tmp/ip.sh", "gid": 0, "group": "root", "mode": "0700", "owner": "libin", "path": "/tmp/ip.sh", "size": 21, "state": "file", "uid": 1000 } 192.168.124.134 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "checksum": "4080c03edf24ad1ca3a9e83c54a363236df4432b", "dest": "/tmp/ip.sh", "gid": 0, "group": "root", "md5sum": "6c65510d520b68b9ef4d5f76552e8a98", "mode": "0700", "owner": "libin", "size": 21, "src": "/root/.ansible/tmp/ansible-tmp-1664117855.11-35846-78262962132669/source", "state": "file", "uid": 1000 } |
8、scripts执行脚本模块的使用
说明:scripts模块相当于结合了shell+copy模块,执行脚本,先把脚本传输到受管服务器,然后执行。
[root@libin ~]# ansible all -m script -a "/root/xunjian.sh " 192.168.124.132 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.124.132 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.124.132 closed." ], "stdout": "++++++++LIBIN 系统基本运行情况检查+++++++++\r\n\r\n\u001b[32m-------------------------------------------\u001b[1m\r\n当前时间: 2022-09-25-23:15:05\r\nIP地址: 192.168.124.132\r\n运行时长: 4:44\r\n系统当前负载: Current Load: 0.01\r\n\u001b[32m-------------------------------------------\u001b[0m\r\n\r\n", "stdout_lines": [ "++++++++LIBIN 系统基本运行情况检查+++++++++", "", "\u001b[32m-------------------------------------------\u001b[1m", "当前时间: 2022-09-25-23:15:05", "IP地址: 192.168.124.132", "运行时长: 4:44", "系统当前负载: Current Load: 0.01", "\u001b[32m-------------------------------------------\u001b[0m", "" ] } 192.168.124.134 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.124.134 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.124.134 closed." ], "stdout": "wlcome to study redhat-linux\r\n++++++++LIBIN 系统基本运行情况检查+++++++++\r\n\r\n\u001b[32m-------------------------------------------\u001b[1m\r\n当前时间: 2022-09-25-23:15:04\r\nIP地址: 192.168.124.134\r\n运行时长: 4:44\r\n系统当前负载: Current Load: 0.00\r\n\u001b[32m-------------------------------------------\u001b[0m\r\n\r\n", "stdout_lines": [ "wlcome to study redhat-linux", "++++++++LIBIN 系统基本运行情况检查+++++++++", "", "\u001b[32m-------------------------------------------\u001b[1m", "当前时间: 2022-09-25-23:15:04", "IP地址: 192.168.124.134", "运行时长: 4:44", "系统当前负载: Current Load: 0.00", "\u001b[32m-------------------------------------------\u001b[0m", "" ] } |
9、将ansible执行的内容日志输出到指定文件
说明:tee 命令会输出到当前路径下,也可以指定存在的文件中
[root@libin ~]# ansible all -m script -a "/root/xunjian.sh " | tee /etc/ansible/log [root@libin ~]# cat /etc/ansible/log 192.168.124.132 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.124.132 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.124.132 closed." ], "stdout": "++++++++LIBIN 系统基本运行情况检查+++++++++\r\n\r\n\u001b[32m-------------------------------------------\u001b[1m\r\n当前时间: 2022-09-25-23:25:41\r\nIP地址: 192.168.124.132\r\n运行时长: 4:54\r\n系统当前负载: Current Load: 0.00\r\n\u001b[32m-------------------------------------------\u001b[0m\r\n\r\n", "stdout_lines": [ "++++++++LIBIN 系统基本运行情况检查+++++++++", "", "\u001b[32m-------------------------------------------\u001b[1m", "当前时间: 2022-09-25-23:25:41", "IP地址: 192.168.124.132", "运行时长: 4:54", "系统当前负载: Current Load: 0.00", "\u001b[32m-------------------------------------------\u001b[0m", "" ] } 192.168.124.134 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.124.134 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.124.134 closed." ], "stdout": "wlcome to study redhat-linux\r\n++++++++LIBIN 系统基本运行情况检查+++++++++\r\n\r\n\u001b[32m-------------------------------------------\u001b[1m\r\n当前时间: 2022-09-25-23:25:40\r\nIP地址: 192.168.124.134\r\n运行时长: 4:54\r\n系统当前负载: Current Load: 0.00\r\n\u001b[32m-------------------------------------------\u001b[0m\r\n\r\n", "stdout_lines": [ "wlcome to study redhat-linux", "++++++++LIBIN 系统基本运行情况检查+++++++++", "", "\u001b[32m-------------------------------------------\u001b[1m", "当前时间: 2022-09-25-23:25:40", "IP地址: 192.168.124.134", "运行时长: 4:54", "系统当前负载: Current Load: 0.00", "\u001b[32m-------------------------------------------\u001b[0m", "" ] } |
10、file模块的使用
例1:创建目录
path:表示创建的目录/libin/xunjian/
state:表示创建目录:state=directory
state还可以指定创建文件:state=touch
state还可以指定创建硬链接:state=hard
state还可以指定创建软链接:state=link
[root@libin ~]# ansible-doc -s copy [root@libin ~]# ansible all -m file -a "path=/libin/xunjian/ state=directory" 192.168.124.132 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/libin/xunjian/", "size": 6, "state": "directory", "uid": 0 } 192.168.124.134 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/libin/xunjian/", "size": 6, "state": "directory", "uid": 0 } [root@libin ~]# ls -ld /libin/xunjian/ drwxr-xr-x 2 root root 6 9月 25 23:33 /libin/xunjian/
[23:40:27 root@libin3 ~]# ls -ld /libin/xunjian/ drwxr-xr-x 2 root root 6 9月 25 23:33 /libin/xunjian/
[root@libin ~]# ansible all -a "tree /libin" 192.168.124.132 | CHANGED | rc=0 >> /libin └── xunjian
1 directory, 0 files 192.168.124.134 | CHANGED | rc=0 >> /libin ├── libin |
例2、创建文件
[root@libin ~]# ansible all -m file -a "path=/libin/xunjian/libin.txt state=touch" 192.168.124.132 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/libin/xunjian/libin.txt", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "size": 0, "state": "file", "uid": 0 } 192.168.124.134 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/libin/xunjian/libin.txt", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "size": 0, "state": "file", "uid": 0 } |
11、ansible中颜色的说明
绿色:成功,但没有修改 黄色:成功,进行了修改 红色:执行报错 |
12、yum模块安装cowsay
说明:
name=包名
state=present 添加
state=latest 最新的
state=absent 不存在
state=removed 已删除或
[root@libin ansible]# ansible all -m yum -a "name=cowsay state=removed" 卸载
[root@libin ~]# ansible-doc -s yum #查看yum模块 [root@libin ~]# ansible all -m yum -a "name=cowsay state=present" 安装 192.168.124.132 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "changes": { "installed": [ "cowsay" ] }, "msg": "Repository epel is listed more than once in the configuration\nRepository network_ha-clustering_Stable is listed more than once in the configuration\n", "rc": 0, "results": [ "Loaded plugins: fastestmirror, langpacks, priorities, product-id, search-\n : disabled-repos, subscription-manager\n\nThis system is not registered with an entitlement server. You can use subscription-manager to register.\n\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * extras: mirrors.aliyun.com\n * updates: mirrors.aliyun.com\nResolving Dependencies\n--> Running transaction check\n---> Package cowsay.noarch 0:3.04-4.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n cowsay noarch 3.04-4.el7 epel 42 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 42 k\nInstalled size: 77 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : cowsay-3.04-4.el7.noarch 1/1 \n Verifying : cowsay-3.04-4.el7.noarch 1/1 \n\nInstalled:\n cowsay.noarch 0:3.04-4.el7 \n\nComplete!\n" ] } 192.168.124.134 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "changes": { "installed": [ "cowsay" ] }, "msg": "Repository base is listed more than once in the configuration\nRepository updates is listed more than once in the configuration\nRepository extras is listed more than once in the configuration\nRepository centosplus is listed more than once in the configuration\nRepository network_ha-clustering_Stable is listed more than once in the configuration\nThere are unfinished transactions remaining. You might consider running yum-complete-transaction, or \"yum-complete-transaction --cleanup-only\" and \"yum history redo last\", first to finish them. If those don't work you'll have to try removing/installing packages by hand (maybe package-cleanup can help).\n", "rc": 0, "results": [ "Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos,\n : subscription-manager\n\nThis system is not registered with an entitlement server. You can use subscription-manager to register.\n\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * epel: mirrors.tuna.tsinghua.edu.cn\n * extras: mirrors.aliyun.com\n * updates: mirrors.aliyun.com\nResolving Dependencies\n--> Running transaction check\n---> Package cowsay.noarch 0:3.04-4.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n cowsay noarch 3.04-4.el7 epel 42 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 42 k\nInstalled size: 77 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : cowsay-3.04-4.el7.noarch 1/1 \n Verifying : cowsay-3.04-4.el7.noarch 1/1 \n\nInstalled:\n cowsay.noarch 0:3.04-4.el7 \n\nComplete!\n" ] } |
13、cron定时任务模块
例1、说明:每天晚上12点整 打包备份 /etc 目录到 /tmp 下面
通常的写法: #root crontab -e === vi /var/spoolcron/root #backup etc 写个注释 00 00 * * * tar zcf /tmp/etc.tar.gz /etc >/dev/null 2>&1 定时任务我们后面一般都要定向到空或追加到文件
|
例2、Aansible写法添加定时任务和删除定时任务
[root@libin ~]# ansible-doc -s cron name:注释,必须要有,以便我们后面不需要时统一删除 minute: # Minute when the job should run ( 0-59, *, */2, etc ) hour: # Hour when the job should run ( 0-23, *, */2, etc ) day: # Day of the month the job should run ( 1-31, *, */2, etc ) month: # Month of the year the job should run ( 1-12, *, */2, etc ) weekday: # Day of the week that the job should run ( 0-6 for Sunday-Saturday, *, etc ) job: # The command to execute or, if env is set, the value of environment variable. The command should not contain line breaks. Required if `state=present'. state: # Whether to ensure the job or environment variable is present or absent(状态)
格式: minute=00 hour=00 job="tar zcf /tmp/etc.tar.gz /etc >/dev/null 2>&1" state=present
=============================================================================== [root@libin ansible]# ansible all -a "crontab -l" #先查看各服务器下的定时任务,没有 192.168.124.132 | FAILED | rc=1 >> non-zero return code 192.168.124.134 | FAILED | rc=1 >> non-zero return code
注:下面我们内容用了双引号外边就用单引号,否则就会有问题,还得用\转义符号 [root@libin ansible]# ansible all -m cron -a 'name="libin" minute=00 hour=00 job="tar zcf /tmp/etc.tar.gz /etc >/dev/null 2>&1" state=present' 192.168.124.132 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "None", "libin" ] } 192.168.124.134 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "None", "libin" ] } 检查: [root@libin ansible]# ansible all -a 'crontab -l' [root@libin ansible]# ansible all -m shell -a 'crontab -l '
192.168.124.132 | CHANGED | rc=0 >> 00 00 * * * tar zcf /tmp/etc.tar.gz /etc >/dev/null 2>&1
192.168.124.134 | CHANGED | rc=0 >> #Ansible: libin 00 00 * * * tar zcf /tmp/etc.tar.gz /etc >/dev/null 2>&1
删除定时任务: [root@libin ansible]# ansible all -m cron -a 'name="libin" state=absent' 192.168.124.132 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "None" ] } 192.168.124.134 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "envs": [], "jobs": [ "None" ] } |
总结:模块总结,以上为一些ansible简单模块的写法
ad-hoc :命令批量执行命令 ping command shell copy script file cron |
第五章 Asible最佳实践案例-基础版(剧本 playbook)
5.1 剧本playbook剧本的作用
(1)部署系统
(2)初始化环境
5.2 剧本playbook剧本的初步认识
(1)play:定义的是主机的角色,也就是要去执行哪些服务器(hosts)
(2)task:定义的是具体执行的任务
(3)playbook:由一个或者多个play组成,一个play可以包含多个task任务
(4)playbook:由一个或者多个play组成,一个play可以包含多个task任务,可以使用不同模块完成一件事情。
5.2.1 Playbook组成(XXX.yaml或者XXX.yml)与编写
注:严格缩进
--- 开头可以加也可以不加 - host: all 所有服务器,管理的哪些机器 remote_user: root vars: file_name: libin tasks: 任务,包含什么模块的什么命令 - name: touch new files shell: touch /tmp/{{file_name}}
|
1、写一个简单的playbook,执行hostname主机名
简单的格式是:2空格,4空格,6空格;执行主机,任务
[root@libin ansible]# vim libin3.yaml
--- - hosts: all remote_user: root tasks: # 任务 - name: show hostname # 名字可以随意 command: hostname # 使用的模块
[root@libin ansible]# ansible-playbook --syntax-check libin3.yaml # 检测语法 [root@libin ansible]# ansible-playbook -C libin3.yaml # -C:试运行 说明:下面会出现牛的图像是因为安装了cowsay ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
________________________ < TASK [Gathering Facts] > ------------------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
ok: [192.168.124.134] ok: [192.168.124.132] ______________________ < TASK [show hostname] > ---------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
skipping: [192.168.124.132] skipping: [192.168.124.134] ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
192.168.124.132 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 192.168.124.134 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 |
2、使用playbook编写一个定时任务
写法1: [root@libin ansible]# vim libin4.yaml
--- - hosts: all tasks: - name: add cron cron: name="ilibin" minute=00 hour=00 job="tar zcf /tmp/etc.tar.gz /etc >/dev/null 2>&1" state=present
[root@libin ansible]# ansible-playbook --syntax-check libin4.yaml [root@libin ansible]# ansible-playbook -C libin4.yaml [root@libin ansible]# ansible-playbook libin4.yaml
____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
________________________ < TASK [Gathering Facts] > ------------------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
ok: [192.168.124.134] ^[[Aok: [192.168.124.132] _________________ < TASK [add cron] > ----------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
changed: [192.168.124.132] changed: [192.168.124.134] ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
192.168.124.132 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.124.134 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@libin ansible]# ansible all -m shell -a "crontab -l" #可以用shell模块检查一下 192.168.124.132 | CHANGED | rc=0 >> #Ansible: ilibin 00 00 * * * tar zcf /tmp/etc.tar.gz /etc >/dev/null 2>&1 192.168.124.134 | CHANGED | rc=0 >> #Ansible: ilibin 00 00 * * * tar zcf /tmp/etc.tar.gz /etc >/dev/null 2>&1
写法2:把等号改成冒号(格式变成了2/4/6/8) [root@libin ansible]# vim libin4.yaml
--- - hosts: all tasks: - name: add cron cron: name: name="ilibin" minute: 00 hour: 00 job: "tar zcf /tmp/etc.tar.gz /etc >/dev/null 2>&1" state: present
[root@libin ansible]# ansible-playbook --syntax-check libin4.yaml playbook: libin4.yamls [root@libin ansible]# ansible-playbook -C libin4.yaml |
3、如何在playbook剧本中使用变量var
模块vars:表示创建变量
file(变量名字1):变量内容1
dir(变量名字2):变量内容2
注:变量要用两对花括号{{}} 里面为变量名字,多变量之间用/,不用空格
[root@libin ansible]# vim libin5.yaml
--- - hosts: all vars: file: 20220928.txt dir: /root/ tasks: - name: touch file file: path={{dir}}/{{file}} state=touch [root@libin ansible]# ansible-playbook --syntax-check libin5.yaml playbook: libin5.yaml
[root@libin ansible]# ansible-playbook -C libin5.yaml -v [root@libin ansible]# ansible-playbook libin5.yaml ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
________________________ < TASK [Gathering Facts] > ------------------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
ok: [192.168.124.134] ok: [192.168.124.132] ___________________ < TASK [touch file] > ------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
changed: [192.168.124.132] changed: [192.168.124.134] ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
192.168.124.132 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.124.134 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@libin ansible]# ansible all -a "ls /root/20220928.txt" #检查一下 192.168.124.132 | CHANGED | rc=0 >> /root/20220928.txt 192.168.124.134 | CHANGED | rc=0 >> /root/20220928.txt |
4、解决ansible在执行时卡着不动或者慢的问题
[root@libin ansible]# egrep -E "gathering = " ./ansible.cfg #gathering = implicit #gathering :表示收集服务器的各种信息 修改为:gathering = explicit |
5、模块register注册变量使用
1、创建一个以IP命令为目录
通常方法: IP=`hostname -I | awk '{print $2}'` mkdir -p /back/$IP
剧本的写法:例1
[root@libin ansible]# cat libin6.yaml --- - hosts: all tasks: - name: show ip shell: hostname -I | awk '{print $1}' register: ip - name: print ip var to file shell: echo {{ip}}>/tmp/ip [root@libin ansible]# ansible-playbook --syntax-check libin6.yaml playbook: libin6.yaml
[root@libin ansible]# ansible-playbook libin6.yaml ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
________________ < TASK [show ip] > ---------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
changed: [192.168.124.132] changed: [192.168.124.134] _____________________________ < TASK [print ip var to file] > ----------------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
changed: [192.168.124.132] changed: [192.168.124.134] ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
192.168.124.132 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.124.134 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@libin ansible]# ansible all -a "cat /tmp/ip" 192.168.124.132 | CHANGED | rc=0 >> { stderr_lines: [], uchanged: True, uend: u2022-09-29 00:29:43.985422, failed: False, ustdout: u192.168.122.1, ucmd: uhostname -I | awk '{print }', urc: 0, ustart: u2022-09-29 00:29:43.979365, ustderr: u, udelta: u0:00:00.006057, stdout_lines: [u192.168.122.1], ansible_facts: {udiscovered_interpreter_python: u/usr/bin/python} } 192.168.124.134 | CHANGED | rc=0 >> {stderr_lines: [], uchanged: True, uend: u2022-09-29 00:29:43.379805, failed: False, ustdout: u192.168.122.1, ucmd: uhostname -I | awk '{print }', urc: 0, ustart: u2022-09-29 00:29:43.374174, ustderr: u, udelta: u0:00:00.005631, stdout_lines: [u192.168.122.1], ansible_facts: {udiscovered_interpreter_python: u/usr/bin/python}}
注意:register 类型的变量 ,格式;格式一般在{}花括号内;逗号,表示这一部分结束;分为好几个部分;只想要其他一个的时候为:名字+某一个部分 ip.stdout=== hostname -I | awk '{print $2}' stdout:意思是standard output 标准输出 ============================================================================== 例2:注,由于我机器网卡的原因$2出来的受管节点都是一样的ip,因此这路用eth0网卡 [root@libin ansible]# vim libin6.yaml
--- - hosts: all tasks: - name: show ip shell: ip a s eth0 | awk 'NR==3' | awk -F "[ /]" '{print $6}' register: ip - name: print ip var to file shell: echo {{ip.stdout}} >>/tmp/libin
[root@libin ansible]# ansible-playbook --syntax-check libin6.yaml
[root@libin ansible]# ansible-playbook libin6.yaml [root@libin ansible]# ansible all -a "cat /tmp/ip" [root@libin ansible]# ansible all -a "cat /tmp/libin" 192.168.124.132 | CHANGED | rc=0 >> 192.168.124.132 192.168.124.134 | CHANGED | rc=0 >> 192.168.124.134 |
6、注册模块register多个变量打包etc目录
[root@libin ansible]# vim libin7.yaml
--- - hosts: all tasks: - name: get ip shell: ip a s eth0 | awk 'NR==3' | awk -F "[ /]" '{print $6}' register: ip - name: get date shell: date +%F register: date - name: mkdir dir file: path=/backup/libin/{{ip.stdout}} state=directory - name: tar shell: tar zcf /backup/libin/{{ip.stdout}}/etc-{{date.stdout}}.tar.gz /etc
[root@libin ansible]# ansible-playbook --syntax-check libin7.yaml
[root@libin ansible]# ansible-playbook libin7.yaml ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
_______________ < TASK [get ip] > --------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
changed: [192.168.124.132] changed: [192.168.124.134] _________________ < TASK [get date] > ----------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
changed: [192.168.124.132] changed: [192.168.124.134] __________________ < TASK [mkdir dir] > ------------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
changed: [192.168.124.132] changed: [192.168.124.134] ____________ < TASK [tar] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
[WARNING]: Consider using the unarchive module rather than running 'tar'. If you need to use command because unarchive 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. changed: [192.168.124.134] changed: [192.168.124.132] ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
192.168.124.132 : ok=4 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.124.134 : ok=4 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@libin ansible]# ansible all -a "tree /backup" #检查一下 192.168.124.132 | CHANGED | rc=0 >> /backup └── libin └── 192.168.124.132 └── etc-2022-09-29.tar.gz
3 directories, 2 files 192.168.124.134 | CHANGED | rc=0 >> /backup ├── hostname └── libin └── 192.168.124.134 └── etc-2022-09-29.tar.gz |
7、使用debug调试注册变量中的信息
debug:用法显示一些变量信息
格式: debug:msg={{变量}} 显示到屏幕中的信息。
[root@libin ansible]# cp libin6.yaml libin6-dubug.yaml [root@libin ansible]# vim libin6-dubug.yaml
--- - hosts: all tasks: - name: show ip shell: ip a s eth0 | awk 'NR==3' | awk -F "[ /]" '{print $6}' register: ip - name: print ip var to file debug: msg={{ip}}
[root@libin ansible]# ansible-playbook --syntax-check libin6-dubug.yaml [root@libin ansible]# ansible-playbook libin6-dubug.yaml ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
________________ < TASK [show ip] > ---------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
changed: [192.168.124.132] changed: [192.168.124.134] _____________________________ < TASK [print ip var to file] > ----------------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
ok: [192.168.124.132] => { "msg": { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "cmd": "ip a s eth0 | awk 'NR==3' | awk -F \"[ /]\" '{print $6}'", "delta": "0:00:00.005184", "end": "2022-09-29 01:43:56.057475", "failed": false, "rc": 0, "start": "2022-09-29 01:43:56.052291", "stderr": "", "stderr_lines": [], "stdout": "192.168.124.132", "stdout_lines": [ "192.168.124.132" ] } } ok: [192.168.124.134] => { "msg": { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "cmd": "ip a s eth0 | awk 'NR==3' | awk -F \"[ /]\" '{print $6}'", "delta": "0:00:00.005546", "end": "2022-09-29 01:43:55.406799", "failed": false, "rc": 0, "start": "2022-09-29 01:43:55.401253", "stderr": "", "stderr_lines": [], "stdout": "192.168.124.134", "stdout_lines": [ "192.168.124.134" ] } } ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
192.168.124.132 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.124.134 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 |
8、使用模块debug调试普通变量
[root@libin ansible]# vim libin6-dubug.yaml
--- - hosts: all vars: file: libin.txt tasks: - name: show ip shell: ip a s eth0 | awk 'NR==3' | awk -F "[ /]" '{print $6}' register: ip - name: print ip var debug: msg={{ip}} - name: print file var debug: msg={{file}}
[root@libin ansible]# ansible-playbook libin6-dubug.yaml ____________ < PLAY [all] > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
________________ < TASK [show ip] > ---------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
changed: [192.168.124.132] changed: [192.168.124.134] _____________________ < TASK [print ip var] > --------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
ok: [192.168.124.132] => { "msg": { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "cmd": "ip a s eth0 | awk 'NR==3' | awk -F \"[ /]\" '{print $6}'", "delta": "0:00:00.004745", "end": "2022-09-29 01:54:23.270872", "failed": false, "rc": 0, "start": "2022-09-29 01:54:23.266127", "stderr": "", "stderr_lines": [], "stdout": "192.168.124.132", "stdout_lines": [ "192.168.124.132" ] } } ok: [192.168.124.134] => { "msg": { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "cmd": "ip a s eth0 | awk 'NR==3' | awk -F \"[ /]\" '{print $6}'", "delta": "0:00:00.005175", "end": "2022-09-29 01:54:22.627119", "failed": false, "rc": 0, "start": "2022-09-29 01:54:22.621944", "stderr": "", "stderr_lines": [], "stdout": "192.168.124.134", "stdout_lines": [ "192.168.124.134" ] } } _______________________ < TASK [print file var] > ----------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
ok: [192.168.124.132] => { "msg": "libin.txt" } ok: [192.168.124.134] => { "msg": "libin.txt" } ____________ < PLAY RECAP > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
192.168.124.132 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.124.134 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 |
9、ansible中循环语句的使用
例子:for循环的使用:
[root@libin ansible]# for ip in {1,,2,,3} > do > echo 172.168.124.$ip > done 172.168.124.1 172.168.124.2 172.168.124.3 |
[root@libin ansible]# cat libin8.yaml
--- - hosts: all tasks: - name: show ip shell: echo 192.168.124.{{item}} with_items: - 11 - 12 - 13 - 14 [root@libin ansible]# ansible-playbook --syntax-check libin8.yaml
playbook: libin8.yaml
[root@libin ansible]# ansible-playbook libin8.yaml
PLAY [all] *********************************************************************************************************************************
TASK [show ip] ***************************************************************************************************************************** changed: [192.168.124.132] => (item=11) changed: [192.168.124.134] => (item=11) changed: [192.168.124.132] => (item=12) changed: [192.168.124.134] => (item=12) changed: [192.168.124.132] => (item=13) changed: [192.168.124.134] => (item=13) changed: [192.168.124.132] => (item=14) changed: [192.168.124.134] => (item=14)
PLAY RECAP ********************************************************************************************************************************* 192.168.124.132 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.124.134 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
|
10、使用when、yum模块按条件安装多个软件
When:当满足这个条件时进行安装
--- - hosts: all tasks: - name: yum install cowsay http yum: name=cowsay,http state=present when: (ansible_hostname == "libin3")
|
11、如何查看ansible的内置变量
[root@libin ansible]# ansible all -m setup #查看所有受管节点的
[root@libin ansible]# ansible 192.168.124.132 -m setup #查看某一台受管节点的
|
标签:124.132,ansible,192.168,最佳,Ansible,自动化,libin,124.134,root From: https://www.cnblogs.com/libin-linux/p/16770706.html