ansible.cfg配置文件说明
ansible_ssh_port=22 #远程主机登陆端口
ansible_ssh_user=root #远程主机登陆用户名
ansible_ssh_pass=******* #远程主机登陆用户名的密码
ansible_ssh_private_key_file=/etc/ansible/hosts #指定管理主机群列表文件
host_key_checking=False #跳过第一次连接检测询问是否登陆的提示(YES/NO)
hostfile = /etc/ansible/hosts #指定文件
常用命令
列出当前的核心模块 ansible-doc -l
查看此模块用法 ansible-doc -s 模块名
启动并发线程数,减少压力 ansible 组名 -f
测试通信 ansible all -m ping
在组里的机器去创建用户 ansible 组名 –m user –a 'name=名字'
给组里的所有机器安装这个软件 ansible 组名 –m yum –a 'name=安装包名字 state=present'
卸载组里所有机器的这个安装包 ansible 组名 –m yum –a 'name=安装包名字 state=absent'
重启组里所有机器的这个安装包 ansible 组名 –m service –a 'name=服务名字 state=restarted'
拷贝当前文件到组里的机器 ansible 组名 –m copy –a 'src=/root/psu.py dest=/tmp'
拷贝当前文件到组里的机器的任意一台 ansible 组里机器的ip –m copy –a 'src=/root/psu.py dest=/tmp'
直接执行命令 ansible 组名 –m command -a 'ls -ltr'
检测剧本是否有语法错误 ansible-playbook --syntax-check 文件名.yml
检查生效的主机 ansible-playbook a.yml --list-hosts
检查tasks任务 ansible-playbook a.yml --list-task
指定从某个task开始运行 ansible-playbook a.yml --start-at-task=‘Copy Nginx.conf’
模拟执行剧本 ansible-playbook -C 文件名.yml
playbook格式
原文链接:playbook文件详解
https://blog.51cto.com/13689359/2333338
https://www.jianshu.com/p/171578692c94 详细
注意:一定要对齐格式,不允许用TAB
- playbook书写规则
playbook语法有如下特性:
1.以 — (三个减号)开始,必须顶行写;
2.次行开始写Playbook的内容,但是一般要求写明该playbook的功能;
3.严格缩进,并且不能用Tab键缩进;
4.缩进级别必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的;
5.K/V的值可同行写,也可换行写。同行使用 :分隔,换行写需要以 - 分隔;
- 举例
---
- hosts: site #主机
remote_user: root #远程主机用户
vars: #定义变量
- file: ziyuan.sh # 变量名:变量
tasks: #任务
- name: file to dest #任务名
copy: src=/etc/ansible/script/{{file}} dest=/usr/local/src/{{file}} mode=755
- name: run #任务名
shell: /bin/bash /usr/local/src/{{file}}
playbook常用参数
gather_facts
1.这个参数是用来收集客户端主机信息的。例:主机名、内核版本、网卡接口、IP 地址、操作系统版本、环境变量、CPU 核数、可用内存、可用磁盘 等等……。
2.如果gather_facts: no或false,在playbook中setup参数是收集不到以上信息的,只有在gather_facts:yes 或者是true,才能收集到
ignore_erros
在有些情况下,一些必须运行的命令或脚本会报一些错误,而这些错误并不一定真的说明有问题,但是经常会给接下来要运行的任务造成困扰,甚至直接导致playbook运行中断。
这时候,我们可以在相关任务中添加ignore_errors: true来屏蔽当前任务的报错信息。ansible也将视该任务运行成功,不再报错,这样就不会对接下来要运行的任务造成额外困扰。但是要注意的是,我们不应过度依赖ignore_errors,因为它会隐藏所有的报错信息,而应该把精力集中在寻找报错的原因上面,这样才能从根本上解决问题
strategy
Strategies 控制task的执行方式, 在2.0中增加了"free" Strategies, 可以允许每个host尽快的执行完一个play. 默认是Strategies是linear, 表示任何host必须等待所有的host完成一个task后才能开始执行下一个task
Strategies 还有一个debug模式, debug模式在2.1中才能使用.
ansible变量
cat test.sh
#!/bin/bash
echo $1
引用anisble内部的变量
ansible 192.168.3.51 -m script -a ‘test.sh {{inventory_hostname}}’
ansible localhost -m shell -a “echo {{inventory_hostname}}”
引用自定义变量
ansible 192.168.3.51 -m script -a ‘test.sh {{test}}’ -e ‘test=“12”’
ansible localhost -m shell -a “echo {{say_hi}}” -e ‘say_hi=“hello world”’
引用playbook文件中的变量
ansible localhost -m shell -a “echo {{say_hi}}” -e @test.yaml
cat test.yaml
---
say_hi: hello world
setup模块
执行命令 : ansible all -m setup|more #获取所有hosts中所有绑定过的主机信息
ansible localhost -m setup|more #获取本地主机的系统参数
1.参数
ansible_all_ipv4_addresses # 所有的ipv4地址
ansible_all_ipv6_addresses # 所有的ipv6的地址
ansible_bios_version # 主板bios的版本
ansible_architecture # 架构信息
ansible_date_time # 系统的时间
ansible_default_ipv4 # IPv4默认地址
address #ip地址
alias #网卡名称
broadcast #广播地址
gateway # 网关
macaddress #mac地址
netmask #子网掩码
network #网段
ansible_distribution #系统的版本
ansible_distribution_file_variety # 系统的基于对象
ansible_distribution_major_version # 系统的主版本 7或6
ansible_distribution_version #系统的版本
ansible_domain #系统的域
ansible_dns #系统的dns
ansible_env #系统的环境变量
ansible_hostname #系统的主机名
ansible_fqdn #系统的完整主机名
ansible_machine #系统的架构
ansible_memory_mb #系统的内存信息
ansible_os_family #系统的家族
ansible_pkg_mgr #系统的包管理工具
ansible_processor_cores #cpu的核数
ansible_processor_count #每颗cpu上的颗数
ansible_processor_vcpus #cpu的总核数=cpu的颗数*每颗cpu上的核数
ansible_python #系统的python版本
可以通过ansible 10.0.0.132 -m setup -a "filter=‘*关键字*‘" 类似的命令进行搜索.
补充 : grep "^\(.*\):.*\1$" /etc/passwd \1表示前边分组中的信息,前后一致
grep -E "^(.*):.*\1$" /etc/passwd -E表示扩展匹配
2.playbook使用
例1:获取主机信息
---
- name: facts
hosts: test
gather_facts: true ###默认是开启的
remote_user: root
tasks:
- debug: var=ansible_distribution ###更多参数请看setup模块
例2: setup和when使用
---
- name: facts
hosts: test
gather_facts: true ###默认是开启的
remote_user: root
tasks:
- debug:
msg: "红帽系统"
when: ansible_distribution == "RedHat" ###当是ansible_distribution值是RedHat就输出红帽系统
copy模块
1.选项解释
backup : 在覆盖之前源文件备份,备份文件包含时间信息,有两个选项 yes | no
content :用于替代"src" ,可以直接指定文件的值
dest:必选项,要将文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么路径必须是个目录
directory_mode:递归的设置目录的权限,默认为系统默认权限
force:如果目标主机包含该文件,但内容不同,如果设置成yes,则强制覆盖,如果no,则只有当目标主机的目标位置不存在该文件时,才复制,默认yesothers:所有的file模块里的必选项都可以在这里使用
src:要复制到远程的主机文件在本地的地址,可以是绝对路径,也可以是相对路径,如果路径是一个目录,将递归复制,在这种情况下,如果路径使用/结尾,则复制路径里的内容,如果没有/ 则复制包含目录在内的整个内容全部复制,类似于rsync
flat:当flat 为 yes 时,有两种情况: 见例2
1.dest 是以"/" 结尾,那么文件直接保存在 dest 的目录下
2.dest 不是以 “/” 结尾,则dest 被看做文件,相当于文件会重命名再保存
2.基本使用
copy文件或者目录
ansible -i ansiblepy.py test22 -m copy -a "src=/root/ansibletest dest=/root/"
如果想在在目录下创建文件并写入内容,那么dest 参数对应的值必须是一个文件,而不能是一个路径。
ansible -i ansiblepy.py test22 -m copy -a 'content="aaa\nbbb\n" dest=/testdir/testfile1'
##force
将 ansible 主机中 /testdir/copytest 文件复制到远程主机的 /testdir 目录中时,如果远程主机中已经存在 /testdir/copytest 文件,并且文件内容与 ansible 主机中的 copytest 文件的内容不一致,则不执行拷贝操作,远程主机中的
/testdir/copytest 文件内容不会被改变。
ansible -i ansiblepy.py test22 -m copy -a 'src=/root/testdir/ttt dest=/root/testdir/ force=no'
##backup
将 ansible 主机中 /testdir/copytest 文件复制到远程主机的 /testdir 目录中时,如果远程主机中已经存在 /testdir/copytest 文件,并且文件内容与 ansible 主机中的 /testdir/copytest 文件的内容不一致,会执行拷贝操作,但是
在执行拷贝操作之前,会将远程主机中的原文件重命名,以作备份,然后再进行拷贝操作
ansible -i ansiblepy.py test22 -m copy -a 'src=/root/testdir/ttt dest=/root/testdir/ backup=yes'
##owner属主
拷贝文件时,指定文件的属主,需要注意,远程主机上必须存在对应的用户。
ansible -i ansiblepy.py test11 -m copy -a 'src=/root/testdir/ttt dest=/root/ owner=root'
##mode权限
拷贝文件时,指定文件的权限。
ansible -i ansiblepy.py test22 -m copy -a 'src=/root/testdir/ttt dest=/root/ owner=root backup=yes mode=777'
3.在playbook使用
例1:传文件
---
- name: scan
host: test
gather_facts: true ##允许收集客户端信息,默认开启
remote_user: root
vars:
host_ip: "{{inventory_hostname}}"
tasks:
- copy:
src=/opt/Ubuntu/vmware-file/redhat.txt dest=/usr/local/src/ force=yes
src=/opt/Ubuntu/vmware-file/ubuntu.txt dest=/usr/local/src/ force=yes mode=755
例2:flat参数使用
保存到本地时,直接使用远程的文件名,不需要remote_host 创建新的目录
cat fetched.yml
hosts: centos7
remote_user: root
tasks:
name : fetched file from centos7 into local
fetch:
src: /tmp/fstab_from_centos6
dest: /tmp/
flat: yes
增加 flat 参数,当flat 为 yes 时,有两种情况:
(1)dest 是以"/" 结尾,怎文件直接保存在 dest 的目录下,所以现在的结果是:
fstab_from_centos6 保存在本地主机的 /tmp/fstab_from_centos6
(2) dest 不是以 “/” 结尾,则dest 被看做文件,相当于 fstab_from_centos6 会重命名再保存。例如:
cat fetched.yml
hosts: centos7
remote_user: root
tasks:
name : fetched file from centos7 into local
fetch:
src: /tmp/fstab_from_centos6
dest: /tmp/centos
flat: yes
fstab_from_centos6 被保存为 /tmp/cnetos
复制本地(或远程)文件 到远程主机
handlers和notify模块
1.解释
在需要被监控的任务(tasks)中定义一个notify,只有当这个任务被执行时,才会触发notify对应的handlers去执行相应操作
注意:
handlers只有在其所在的任务被执行时,才会被运行;
handlers只会在Play的末尾运行一次;如果想在一个Playbook的中间运行handlers,则需要使用meta模块来实现,例如:- meta: flush_handlers。
如果一个Play在运行到调用handlers的语句之前失败了,那么这个handlers将不会被执行。我们可以使用mega模块的–force-handlers选项来强制执行handlers,即使在handlers所在Play中途运行失败也能执行。
2.playbook使用
例1:监控某一个任务是否运行成功
---
- name: scan
host: test
gather_facts: true ##收集客户端信息的
remote_user: root
vars:
host_ip: "{{inventory_hostname}}"
tasks:
- copy:
src=/opt/Ubuntu/vmware-file/redhat.txt dest=/usr/local/src/ force=yes
src=/opt/Ubuntu/vmware-file/ubuntu.txt dest=/usr/local/src/ force=yes mode=755
when: ansible_distribution == "RedHat" ###当收集到系统是红帽就运行cpoy
notify: echo ###监控当前copy这个任务,如果允许成功,就允许handlers内的任务
handlers:
- name: echo
debug:
msg: "脚本已运行"
例2:notify执行多个监控任务
见目录:不同的系统传不同的文件(批量传多个文件)
tags模块
标签的不同写法
语法一:
tags:
- testtag
- t1
语法二:
tags: tag1,t1
语法三:
tags: ['tagtest','t2']
查看playbook中的所有标签
ansible-playbook --list-tags testhttpd.yml
执行指定任务
如果在playbook中有多条任务,现在只想执行某个任务,可以在任务中定义tags,在执行操作时指定-t即可单独执行此任务.
示例 :
---
- hosts: web
tasks:
- name: install
yum: name=redis
- name: copyfile
copy: dest=/etc/redis.conf src=/etc/redis.conf
tags: copyfile #在copyfile任务中定义tags(后边名字什么的无所谓)
- name: start
service: name=redis state=started
ansible-playbook -t copyfile p2.yml #操作时通过-t指定copyfile单独执行
---
- hosts: test70
remote_user: root
tasks:
- name: task1
file:
path: /testdir/t1
state: touch
tags: t1
- name: task2
file: path=/testdir/t2
state=touch
tags: t2
- name: task3
file: path=/testdir/t3
state=touch
tags: t3
ansible-playbook --tags=t2 touch.yml #操作时通过-t指定t2单独执行
跳过指定任务
---
- hosts: test70
remote_user: root
tasks:
- name: task1
file:
path: /testdir/t1
state: touch
tags: t1
- name: task2
file: path=/testdir/t2
state=touch
tags: t2
- name: task3
file: path=/testdir/t3
state=touch
tags: t3
ansible-playbook --skip-tags='t2' testtag.yml ###加上--skip-tags表示跳过t2
一个标签执行多个任务
---
- hosts: test70
remote_user: root
tasks:
- name: install httpd package
tags: httpd,package
yum:
name=httpd
state=latest
- name: start up httpd service
tags: httpd,service
service:
name: httpd
state: started
每个任务都有多个标签,而且上例中两个任务都有一个共同的标签,就是httpd标签,所以,当我们执行:
'ansible-playbook --tags=httpd testhttpd.yml',上述两个任务都会执行
同时执行多个标签
---
- hosts: test70
remote_user: root
tags: httpd ###将标签写在开始表示整个文档都会继承这一个标签,不管是否指定自己的标签都可以继承和使用这个标签
tasks:
- name: install httpd package
tags: ['package']
yum:
name=httpd
state=latest
- name: start up httpd service
tags:
- service
service:
name: httpd
state: started
ansible-playbook --tags package,service testhttpd.yml 执行多个任务标签
特殊标签
always
never(2.5版本中新加入的特殊tag)
tagged
untagged
all当我们把任务的tags的值指定为always时,那么这个任务就总是会被执行,除非你使用’–skip-tags’选项明确指定不执行对应的任务,这样说可能不容易理解,不如看个小示例,示例如下
---
- hosts: test70
remote_user: root
tasks:
- name: task1
file:
path: /testdir/t1
state: touch
tags:
- t1
- name: task2
file: path=/testdir/t2
state=touch
tags: ['t2']
- name: task3
file: path=/testdir/t3
state=touch
tags: t3,always
上例中,task3的标签有两个,t3和always,那么我们来执行一下这个playbook,假设,我只想运行上述playbook中标签为t1的任务
在执行上述playbook时,我只指定了’t1’,正常情况下应该只执行’t1’对应的任务,也就是应该只执行task1,但是实际上执行了task1和task3,这是因为task3的标签的值包含always关键字,所以即使task3对应的标签没有被调用,task3也会执行,这就是always的作用。
如果你不想执行标签中包含always的任务,你可以使用’–skip-tags’选项明确指定跳过它们,仍然以上例的playbook为例,假设我们就是不想执行task3,我们可以执行如下命令
ansible-playbook --skip-tags always testtag.yml
但是需要注意,如果上述play中有多个任务都有always标签,那么上述命令将会跳过所有包含always标签的任务,如果上例中的
play中的多个任务都有always标签,则可以使用如下命令只跳过task3,其他带有always标签的任务不会跳过,前提是task3有除了
always以外的自定义标签。
ansible-playbook --skip-tags t3 testtag.yml
在2.5版本的ansible中,引入了新的特殊标签 'never',从字面上理解,never的作用应该与always正好相反,由于我当前使用的
ansible版本为2.4(还没有引入never标签),所以当指定任务的标签为never时,貌似被ansible当做了自定义标签,所以如果你
安装了2.5版本的ansible,可以尝试一下never标签的作用,由于还没有实际使用过2.5版本,所以此处暂时不进行示例。
剩余的三个特殊标签分别为 tagged、untagged、all
这三个特殊标签并非像always一样,always作为标签值存在,而这三个特殊标签则是在调用标签时使用,示例如下
ansible-playbook --tags tagged testtag.yml
上述命令表示只执行有标签的任务,没有任何标签的任务不会被执行。
ansible-playbook --skip-tags tagged testtag.yml
上述命令表示跳过包含标签的任务,即使对应的任务包含always标签,也会被跳过。
ansible-playbook --tags untagged testtag.yml
上述命令表示只执行没有标签的任务,但是如果某些任务包含always标签,那么这些任务也会被执行。
ansible-playbook --skip-tags untagged testtag.yml
when模块判断
1.解释
就和if判断语句一样,当when后的判断条件成立,就和之前当前任务
2.playbook使用
例1:与或判断
---
- hosts: load-node,img
remote_user: root
tasks:
- name: "touch flag file"
command: "touch /tmp/this_is_{{ ansible_distribution }}_system"
when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == '6') or
(ansible_distribution == "Debian" and ansible_distribution_major_version == '7')
例2:自定义变量判断
---
- hosts: agentd
remote_user: root
vars:
host_ip: "{{inventory_hostname}}" ' ###中括号里的是ansible的内部变量
tasks:
- name: zabbix-agent dir exist or not exist ##判断zabbix安装目录在不在
shell: ls -ld /usr/local/zabbix-agent | wc -l
register: dir_num ##声明变量
ignore_erros: True
##因为ls目录,目录不存在的情况,会报错,意思是报错也会继续执行下边的任务
- debug: var=dir_num
- name: send zabbix-4.0.4.tar.gz to agent ###发送zabbix包
copy: src=/etc/ansible/tar/zabbix_4.0.4.tar.gz dst=/usr/local/src/
##dir_num.stdout 表示输出结果如果等于零,等于零就是没有zabbix_agent目录,就执行,发送tar包
when: dir_num.stdout == "0"
ansible 实例
统计硬件信息
ansible hosts信息
[site]
192.168.101.[96:118]
[site:vars]
ansible_ssh_user='root'
ansible_ssh_pass=''
[mall]
192.168.101.[64:85]
[mall:vars]
ansible_ssh_user='root'
ansible_ssh_pass=''
方法一: ansible mall -m script -a ‘/etc/ansible/script/ziyuan.sh’
ansible mall:site -m script -a ‘/etc/ansible/script/ziyuan.sh’ 也可以
方法二: ansible-playbook [任务名] 文件名.yaml
系统名字,IP,cpu总数,内存总大小脚本
脚本
#!/bin/bash
hostname=$(hostname) && echo KaTeX parse error: Expected 'EOF', got '&' at position 10: hostname &̲& IP=(ifconfig eth0 | grep Mask | awk -F’:’ ‘{print $2}’ | awk ‘{print $1}’) && echo KaTeX parse error: Expected 'EOF', got '&' at position 4: IP &̲& CPU=(lscpu | grep “^CPU(s)” | awk ‘{print $2}’) && echo KaTeX parse error: Expected 'EOF', got '&' at position 5: CPU &̲& Mem=(cat /proc/meminfo | grep “^MemTotal” | awk ‘{print $2}’) && echo $(expr $Mem / 1024 / 1000)
playbook
---
- hosts: site #主机
remote_user: root #远程主机用户
vars: #定义变量
- file: ziyuan.sh # 变量名:变量
tasks: #任务
- name: file to dest #任务名
copy: src=/etc/ansible/script/{{file}} dest=/usr/local/src/{{file}} mode=755
- name: run #任务名
shell: /bin/bash /usr/local/src/{{file}}
过滤出信息
sed -rn 's/("stdout": ")(.*)(",)/\2/gp' test.txt > mall.txt
sed -rn 's/(.*)(\\r\\n)(.*)(\\r\\n)(.*)(\\r\\n)(.*)(\\r\\n)/\1 \3 \5 \7/gp' mall.txt
想要排序找U盘里的脚本
批量修改密码
修改密码脚本
#!/bin/bash
echo "tRM8I4_>uvwCJXqA" | passwd --stdin root
ansible hosts信息
[site]
192.168.101.[96:118]
[site:vars]
ansible_ssh_user='root'
ansible_ssh_pass=''
[mall]
192.168.101.[64:85]
[mall:vars]
ansible_ssh_user='root'
ansible_ssh_pass=''
方法一:
ansible mall -m script -a ‘/etc/ansible/script/passwd.sh’
ansible mall:site -m script -a ‘/etc/ansible/script/passwd.sh’ 也可以
方法二:
ansible-playbook [任务名] 文件名.yaml
playbook
---
- hosts: site
remote_user: root
vars:
- file: password.sh
tasks:
- name: file to dest
copy: src=/etc/ansible/script/{{file}} dest=/usr/local/src/{{file}} mode=755
- name: run
shell: /bin/bash /usr/local/src/{{file}}
批量修改主机名
添加主机hosts
[DLR]
192.168.101.154 host_name=DLRAPP_Web03
192.168.101.155 host_name=DLRAPP_Nginx01
192.168.101.156 host_name=DLRAPP_Nginx02
192.168.101.157 host_name=DLRAPP_DB01
192.168.101.158 host_name=DLRAPP_DB02
192.168.101.159 host_name=DLRAPP_DB03
192.168.101.160 host_name=DLRAPP_BI01
192.168.101.161 host_name=DLRAPP_BI02
192.168.101.162 host_name=DLRAPP_BI03
192.168.101.163 host_name=DLRAPP_Test01
[DLR:vars]
ansible_ssh_user='root'
ansible_ssh_pass='MKPEUi7rDb81OBKg'
ansile-playbook
---
- hosts: DLR
user: root
gather_facts: true
tasks:
- name: hostname
hostname: 'name={{ host_name }}' #定义上边的红色字体为变量
- name:
shell: sed -ri "s/(HOSTNAME=)(.*)/\1{{ host_name }}/g" /etc/sysconfig/network
- name:
shell: "hostname {{ host_name }}"
批量安装PHP扩展模块
脚本
vim install.sh
#!/bin/bash
value=$(php -m | grep mongo)
if [ -z $value ]
then
cd /usr/local/src/
wget http://pecl.php.net/get/mongo-1.6.16.tgz && tar -zxf mongo-1.6.16.tgz && cd /usr/local/src/mongo-1.6.16
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config && make && make install
echo "extension=mongo.so" >> /usr/local/php/etc/php.ini
pkill php-fpm
sleep 10
/usr/local/php/sbin/php-fpm
else
echo "已经安装mongo模块"
fi
方法一:
ansible mall -m script -a ‘/etc/ansible/script/install.sh’
ansible mall:site -m script -a ‘/etc/ansible/script/install.sh’ 也可以
方法二:
ansible-playbook [任务名] 文件名.yaml
批量传文件
方法一:
ansible mall -m script -a ‘/etc/ansible/script/install.sh’
ansible mall:site -m script -a ‘/etc/ansible/script/install.sh’ 也可以
方法二:
ansible-playbook [任务名] 文件名.yaml
远程复制或者本地上传,加上force=yes,则会覆盖掉原来的文件,加上backup=yes,在覆盖的时候会把原来的文件做一个备份: ansible all -m copy -a “src=/root/test.txt dest=/root force=yes backup=yes”
ansible webserver -m copy -a “src=/usr/local/tomcat8/webapps/ROOT/scripts/shell-sh/test.sh dest=/usr/local/tomcat8/shell-sh/”
不同的系统传不同的文件(批量传多个文件)
对比过滤出的文件和文件内容,并将不同部分输出
两个文件:vmfile1 vmfile2
vmfile1内容是:过滤主机上原装的VMware文件 redhat.txt是红帽上的VMware文件 ubuntu.txt是Ubuntu上的VMware文件
vmfile2内容是:过滤主机上其他以VMware命名的文件
目标:将vmfile2中比vmfile1中不同的过滤出来(批量的)
---
- name: Ascan
hosts: AIP
strategy: free
gather_facts: true
remote_user: root
vars:
host_ip: "{{inventory_hostname}}"
tasks:
#当时Ubuntu系统客户端时删除这ubuntu.txt and scan.sh文件
- name: delete agent ubuntu.txt and scan.sh
file: path=/usr/local/src/{{ item }} state=absent
when: ansible_distribution == "Ubuntu"
with_items:
- ubuntu.txt
- scan.sh
#当时RedHat系统客户端时删除这redhat.txt and scan.sh文件
- name: delete agent redhat.txt and scan.sh
file: path=/usr/local/src/{{ item }} state=absent
when: ansible_distribution == "RedHat"
with_items:
- redhat.txt
- scan.sh
#删除之后发送新的文件
- name: send ubuntu.txt to agent
copy: src=/opt/Ubuntu/vmware-file/ubuntu.txt dest=/usr/local/src/ force=yes
when: ansible_distribution == "Ubuntu"
notify:
- scansh
- run
- name: send redhat.txt to agent
copy: src=/opt/Ubuntu/vmware-file/redhat.txt dest=/usr/local/src/ force=yes
notify:
- scansh
- run
handlers:
- name: scansh
copy: src=/opt/Ubuntu/vmware-file/scan.sh dest=/usr/local/src/ mode=755 force=yes
- name: run
shell:
nohup bash /usr/local/src/scan.sh > /usr/local/src/scan.log &
scan.sh脚本
#!/bin/bash
#比较多余的VMware文件
##正常VMware文件
#判断是Redhat系统还是Ubuntu系统
version=`cat /proc/version | grep -i "red hat"`
if [[ $version =~ "Red Hat" ]]
then
vmfile1=`cat /usr/local/src/redhat.txt`
else
vmfile2=`cat /usr/local/src/ubuntu.txt`
fi
###过滤出来的VMware文件
vmfile2=`find / -name '*vmware*' | sort -r`
##声明diff_list变量为数组型
declare -a diff_list
t=0
flag=0
for file1 in ${vmfile2[@]}
do
#echo "$file1 is vmfile2"
for file2 in ${vmfile1[@]}
do
#echo "$file2 is vmfile2"
if [[ "${file}" == “${file2}” ]]
then
flag=1
#跳出当前for循环,执行下边if
break
fi
#如果flag=0,就把file1给diff_list数组
if [[ $flag -eq 0 ]]
then
#如果$file1中有包含以下字符串的就不输出
if [[ $file1 == *vmware-vmis* || $file1 == *-sp ]]
then
echo "" 2>&1 > /dev/null
else
diff_list[t]=$file1
echo ${diff_list[t]}
t=$((t+1))
fi
else
flag=0
fi
done
批量分发公钥
配置文件格式
密码不一样时:
[组名]
192.168.101.154 ansible_ssh_user='root' ansible_ssh_pass='111111'
192.168.101.155 ansible_ssh_user='root' ansible_ssh_pass='222222'
192.168.101.156 ansible_ssh_user='root' ansible_ssh_pass='333333'
192.168.101.157 ansible_ssh_user='root' ansible_ssh_pass='444444'
192.168.101.166 ansible_ssh_user='root' ansible_ssh_pass='555555'
192.168.101.172 ansible_ssh_user='root' ansible_ssh_pass='666666'
密码一样时:
[组名]
192.168.101.154
192.168.101.155
192.168.101.156
192.168.101.157
192.168.101.166
192.168.101.172
[组名:vars]
ansible_ssh_user='root'
ansible_ssh_pass='MKPEUi7rDb81OBKg'
方法一:
ansible 组名 -m blockinfile -a 'dest=/root/.ssh/authorized_keys block="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDJg3gXcUtKnGADy+sgvI+ExEOp2T+hlyiDE7L4MdREn8sDSGnvTS4t7/J2CzECLuoYYAmYAxvcyS3eutMnXGR54tnM4hm0/MFhNvYm/9xzzET82ZfEadShnLHZrgtNcn0SfEEUigk0x7snOupcQDB71Voi4JG0UVr+0iKpv0agLcEi5T+Nt9bXqeaW38T0LzW4FUc1JNLLSXIP2kV+K/9lGs+nNBVzDDy+xrJ5TKy+gyx/t/rrijrJ88U3DFs+auovQa8xcMiZ6N4ZVPEige1AWqkSkwaoy1urYHcm4bxd0eoEqF24a6rJUO3EqpsxfZPEf2DXVEj0W9H0J4+70PUUP8oRCcqLW364w+TzkVrE0vEEIBe646LiRqKh8A49PaiaygkQqsT/LBairZUKTs/EOY9WvUYXcbxVfO05vsjVTYvgMZtfah8hFVLnEAapdCsW6BvcNK6errew7o9oxjikKCszWr/8N0euC+J4/04P8E6m6VKcEw66OqfR4zYGYlM= 110356@100302001796"'
方法二:
authorized_keys.yml
---
- name: ssh-copy
blockinfile: path=/root/.ssh/authorized_keys block="{{ lookup('file', 'public_key') }}"
[root@master1 ansible]# cat roles/init/files/public_key
#测试1
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvRBWaTcJwmbhfluPnHoGZBf/HNnVx5lwmPnkKx8F7HxeMxuUd6Ju38ReGdY0l0qtiDlTQ6eNuZjakfuca1lw==
#测试2
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2tVQjRc3Zrkkj6Vh4Vja4iV0fDq0WIUtN+L8PwA5u+ugwQ4U1kTn4P5olepq4oN/SstmuLn9BR6/PvCTjn1Y
方法三:
[root@master1 ansible]# vim roles/init/tasks/ssh.yaml
- hosts: caoguo
remote_user: root
tasks:
- name: copy ssh key
authorized_key:
user: root
key: "{{ lookup('file', '/root/.ssh/id_rsa.pub') }}"
方法四:
[root@localhost ansible]# vim roles/init/tasks/ssh.yaml
- hosts: caoguo
remote_user: root
tasks:
- name: mkdir /root/.ssh
command: mkdir -p /root/.ssh
- name: copy ssh key
copy: src=/root/.ssh/id_rsa.pub dest=/root/.ssh owner=root group=root mode=0644
blockinfile模块
将内容写入到目标服务器文件中
dest后是目标服务器上的文件,必须存在 block后是公钥
文件中会多出两行
BEGIN ANSIBLE MANGED BLOCK
中间是block的内容
END ANSIBLE MANGED BLOCK
ansible 组名 -m blockinfile -a 'dest=/root/.ssh/文件名 block="内容"'
批量源码安装zabbix-agentd
playbook
---
- hosts: agentd
remote_user: root
vars:
host_ip: "{{inventory_hostname}}" ' ###中括号里的是ansible的内部变量
tasks:
- name: PS
shell: ps -ef | grep zabbix | grep -v grep | wc -l ##判断zabbix进程在不在
register: zabbix_num ##声明变量
- debug: var=zabbix_num ##调试
- name: zabbix-agent dir exist or not exist ##判断zabbix安装目录在不在
shell: ls -ld /usr/local/zabbix-agent | wc -l
register: dir_num ##声明结果
ignore_erros: True ##因为ls目录不存在会报错,所以需要,意思是报错也要执行
- debug: var=dir_num
- name: zabbix_agentd script exist or not exist ###判断zabbix_agentd脚本存在不存在
shell: ls -l /usr/local/src/zabbix_agentd | wc -l ###查zabbix_agnetd脚本
register: script_num ##声明变量
ignore_errors: True ##因为ls脚本不存在会报错,所以需要,意思是报错也要执行
- debug: var=script_num
- name: send zabbix-4.0.4.tar.gz to agent ###发送zabbix包
copy: src=/etc/ansible/tar/zabbix_4.0.4.tar.gz dst=/usr/local/src/
when: dir_num.stdout == "0" ##dir_num.stdout 表示输出结果如果等于零,等于零就是没有zabbix_agent目录,就执行,发送tar包
- name: send zabbix_agentd start or stop script ###发送zabbix_agentd启停程序
copy: src=/etc/ansible/roles/init/tasks/zabbix_agentd dest=/usr/local/src/
when: script_num.stuout == "0" ##script_num.stdout 表示输出结果如果等于零,等于零就是没有zabbix_agend,就执行,发送zabbix_agnetd
- name: install zabbix_agentd
script: /etc/ansible/roles/init/tasks/install-zabbix.sh {{host_ip}} > /usr/local/src/zabbix.log ###执行安装脚本,安装日志在zabbix.log
install-zabbix.sh
#!/bin/bash
srcdir=/usr/local/zabbix_agent
installdir=/usr/local/zabbix-agent
zabbix=zabbix-4.0.4
tar=zabbix-4.0.4.tar.gz
###grep zabbix pid 过滤zabbix进程
num=`ps -ef | grep zabbix_agentd | grep -v grep | wc -l` ###过滤zabbix进程数
pid=`ps -ef | grep zabbix_agentd | grep -v grep | awk '{print $2}'` ###过滤zabbix进程号
usernum=`awk -F':' '{print $1}' /etc/passwd | grep -w "zabbix" | wc -l` ###过滤是否存在zabbix用户
date=`date +%F`
zabbix_server=192.168.3.51 ###zabbixserverIP
###stop zabbix-agentd 停zabbix_agentd服务
if [ $num -ne 0 ]
then
kill -9 $pid
fi
###依赖包 install
[ -d $installdir ] || yum -y install gcc gcc-c++ make pcre pcre-devel
###install zabbix_agentd 安装zabbix_agnetd端
cd $srcdir
[ -d $installdir ] || tar -zxf $tar && cd $zabbix && ./configure --prefix=$installdir --enable-agent && make && make install
###mkdir logdir and backup zabbix_agentd.conf 创建日志目录以及备份配置文件
cd $installdir
[ -d logs ] || mkdir logs
cd etc/
[ -f zabbix_agentd.conf-$date ] || cp zabbix_agentd.conf zabbix_agnetd.conf-$date
###config zabbix_agentd 修改配置文件
cat << eof > zabbix_agentd.conf
PidFile=$installdir/logs/zabbix_agentd.pid
LogFile=$installdir/logs/zabbix_agentd.log
ListenPort=10050
Server=$zabbix_server
ServerActive=$zabbix_sever:10051
Hostname=$1
Include=$installdir/etc/zabbix_agentd.conf.d/*.conf
UnsafeUserParameters=1
eof
###user add zabbix and dir auth 创建用户以及目录权限
if [ $usrnum -eq 0 ]
then
useradd -M -s /sbin/nologin zabbix
fi
chown -R zabbix:zabbix $installdir
###service join boot 服务加入开机自启
\cp -f $srcdir/zabbix_agentd /etc/init.d/
if [ -f /etc/init.d/zabbix_agentd ]
then
service=`chkconfig --list` | grep zabbix_agentd | wc -l`
cd /etc/init.d/
sed -ri "s|(BASEDIR=)(.*)|\1$installdir|g" /etc/init.d/zabbix_agentd
sed -i "s|PIDFILE=.*|PIDFILE=$installdir\/logs\/zabbix_agentd.pid|g" /etc/init.d/zabbix_agentd
chmod +x /etc/init.d/zabbix_agentd
[ $service -eq 1 ] && chkconfig --del zabbix_agentd
chkconfig --add zabbix_agentd
chkconfig zabbix_agentd on
chkconfig --list | grep zabbix_agentd
fi
###start zabbix 启动zabbix
$installdir/sbin/zabbix_agentd && echo "zabbix service running"
报错
提示ssh主机需要输入yes
Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host’s fingerprint to your known_hosts file to manage this host.
解决:
vi /etc/ansible/ansible.cfg
#uncomment this to disable SSH key host checking
host_key_checking = False