ansible 环境配置
配置centos7.4的源 及安装
只需要 epel-release
yum install -y epel-release
安装ansible
yum install -y ansible
验证安装结果( 查看ansible版本)
ansible --version
关闭selinux firewall
配置域名并创建组
配置文件:
(1)ansible应用程序的主配置文件:/etc/ansible/ansible.cfg
(2) Host Inventory定义管控主机:/etc/ansible/hosts
ansible.cfg配置文件可以存在于多个地方。读取配置文件的顺序依次是当前命令执行目录,其次是用户家目录下的.ansible.cfg,最后是/etc/ansible/ansible.cfg,先找到哪个就用哪个。
#vim /etc/hosts //配置域名
#vim /etc/ansible/hosts //创建添加组
添加变量
#vim /etc/ansible/ansible.cfg //无需使用密码远程
#ansible 组 --list -hosts //查看
#ansible web -m ping
#ssh web1
不同路径下分组
#cp -r /etc/ansible /opt
#vim /etc/ansible/ansible.cfg //指定路径
inventory = /opt/ansible/hosts
#vim /opt/ansible/hosts //添加创建组
#ansible aa --list-hosts
使用交互式密码分组
#vim /etc/ansible/hosts //删除变量
#ansible all -m command -a 'hostname' -k
#ansible all -m command -a 'id' -k //查看
使用脚本,脚本输出的必须是json格式(ansible方可识别)
创建密钥实现批量无密码配置
#rm -rf ~/.ssh/*
#cd /root/.ssh
#ssh-keygen //创建密钥
#ls
#ansible all -m authorized_key -a "user=root exclusive=true manage_dir=true key='$(< /root/.ssh/id_rsa.pub)'" -k -v //批量传送密钥
#ssh web1 //测试
ansible 系列命令
一 ansible 命令 :用于执行临时性的工作
二 ansible-doc :说明模块的手册 相当于shell的man
ansible-doc -l 列出所有的模块
ansible-doc [模块名] 查看帮助
ansible-doc modulename 查看modulename帮助 文档
三 ansible-console:类似于shell一样的交互式工具,
四 ansible-galaxy
五 ansible-playbook ansible的脚本
六 ansible-vault 配置文件加密
加密:ansible-vault encrypt a.yml
解密:ansible-vault decrypt a.yml
七 ansible-pull 与push工作模式相反 数量巨大的机器需要管理时
ansible 命令格式
ansible
host-pattern 主机定义的分组
]# vim /etc/ansible/hosts
#inventory file例子,添加主机名hostname或者ip地址
#未分组的主机,添加在最前面
122.19.45.201
hostname1
122.19.45.[1:10] #[1:10]表示所有1~10之间的数字,表示一组ip地址45.1、45.2、...
#分组管理的主机
[test0] #组名
122.28.13.100
122.19.61.68:5030 #如果主机ssh端口不是22,可在地址后加:指定
[targets1]
localhost ansible_connection=local
122.28.13.10 ansible_connection=ssh ansible_ssh_user=user #指定连接类型和连接用户名
[targets2] #可配置主机变量
host1 http_port=80
host2 http_port=80 var2=xxx var3=xxx
[targets2:var] #添加关键字var,配置组变量,对属于该组的所有主机都适用
var4=xxx
var5=xxx
[targets3:children] #添加关键字children,把组作为其他组的子成员
targets1
targets2
主机列表的正则匹配
ansible支持主机列表的正则匹配
全量: all/*
逻辑或: :
逻辑非: !
逻辑与: &
切片: []
正则匹配: 以~开头
ansible all -m ping #所有默认inventory文件中的机器
ansible '*' -m ping #同上
ansible '121.28.13.*' -m ping #所有122.28.13.X机器
ansible 'web1:web2' -m ping #所有属于组web1或属于web2的机器
ansible 'web1:!web2' -m ping #属于组web1,但不属于web2的机器
ansible 'web1&web2' -m ping #属于组web1又属于web2的机器
ansible webserver[0] -m ping #属于组webserver的第1台机器
ansible webserver[0:5] -m ping #属于组webserver的第1到4台机器
ansible '~(beta|web)\.example\.(com|org)' -m ping
Ansible选项:
-M 指定模块路径
-m 使用模块,默认 command 模块
-a or --args 模块参数
-i inventory 文件路径,戒可执行脚本
-k 使用交互式登陆密码,而不是使用秘钥
-e 定义变量
-v 详细信息,-vvvv 开启 debug 模式
-K 提示输入sudo密码,与sudo一起使用
-o 一个主机的执行结果在一行显示
-s -u指定用户的时候,使用sudo获得root权限
-t 将输入放到制定的目录下,命名为每一个主机的名称
-T 超时时长
-B 在后台运行命令,在制定NUM秒后kill该任务
-P 每隔NUM秒,poll一个后台任务 和-B一起使用
-u 指定移动端的执行用户
-U sudo到SUDO_USERNAME,代替root用户
-c 指定建立连接的类型,一般有ssh,localhost FILES
-f 并发进程数量 默认是5
常用模块
ping模块
ansible all -m ping
检测机器是否可登录,ping模块不需要传送参数
command模块 #未指定模块 默认为command 未启动shell
comand模块的参数非key=value格式,直接给出要执行的命令
可以执行任意命令,但不接受管道命令和重定向符号,如果想使用这些,则需要使用Shell模块。
shell | raw 模块
shell调用/bin/sh进行执行命令
raw 没有chdir creates removes 参数
shell 模块,用法其本和command一样,不过的是其是通过/bin/sh进行执行,所以shell 模块可以执行任何命令,就像在本机执行一样
script 模块
# cat a.sh
#!/bin/bash
if ! $(id lisi > /dev/null) ;then
useradd -g 100 zhangsan
echo 123456| passwd --stdin zhangsan
chage -d 0 zhangsan
# ansible all -m script -a 'a.sh'
script模块,其是将管理端的shell 在被管理主机上执行,其原理是先将shell 复制到远程主机,再在远程主机上执行,原理类似于raw模块
分发配置文件
copy模块
src:要复制到进程主机的文件在本地的地址,可以是
绝对路径,也可以是相对路径。如果路径是一个目录,
它将递归复制。在这种情况下,如果路径使用"/"来结
尾,则只复制目录里的内容,如果没有使用"/"来结尾,
则包含目彔在内的整个内容全部复制,类似于rsync
dest:必选项。进程主机的绝对路径,如果源文件是
一个目录,那么该路径也必须是个目录
复制文件
ansible all -m copy -a 'src=/root/alog dest=/root/a.log'
复制目录
ansible all -m copy -a 'src=urdir dest=/root/'
适合短小的目录与文件的分发
lineinfile 模块
类似于sed的一种行编辑替换模块
path=路径/文件 目的文件
regexp=正则 匹配
line=修改后的该行
# ansible all -m lineinfile -a 'path="/etc/sysconfig/network-scripts/ifcfg-eth0" regexp="^BOOTPROTO=" line="BOOTPROTO=static"'
replace 模块
path=路径/文件 目的文件 修改哪个文件
regexp=正则 匹配 修改哪个地方
replace=替换后的字符 修改成什么样子
#ansible all -m replace -a 'path="/etc/sysconfig/network-scripts/ifcfg-eth0" regexp="^(BOOTPROTO=).*" replace="\1none"'
#ansible all -m replace -a 'path="/etc/selinux/config" regexp="^(SELINUX=).*" replace="\1disabled"'
修改配置文件 相同的用copy 不同的 用linefile|replace
yum 模块
使用yum包管理器来管理软件包
config_file:yum的配置文件
disable_gpg_check:关闭gpg_check
disablerepo:不启用某个源
enablerepo:启用某个源
name:要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路径
state:状态(present,absent,latest) #不写状态默认是安装
删除软件包
ansible all -m yum -a 'name="lrzsz" state=absent'
删除多个软件包
ansible all -m yum -a 'name="lrzsz,lftp" state=absent'
安装软件包
ansible all -m yum -a 'name="lrzsz"'
安装多个软件包
ansible all -m yum -a 'name="lrzsz,lftp"'
file模块
用来设置文件、文件夹或快链的属性,或者删除文件、快链、文件夹。
创建一个文件夹,如果目标不存在
ansible webservers -m file -a "path=/tmp/tdir state=directory mode=0755"
get_url模块
从服务器上下载一个文件到远程主机指定的目录
ansible webservers -m get_url -a "url='http://baidu.com dest=/tmp/ba.html"
service模块
name:必选项,服务名称
enabled:是否开机启动 yes|no
sleep:如果执行了restarted,在则stop和start之间
沉睡几秒钟
state:对当前服务执行启动,停止、重启、重新加载
等操作(started,stopped,restarted,reloaded)
ansible all -m service -a 'name="sshd" enabled="yes" state="started"'
在web1 web2 上安装apache
并且设置开机启动 启动服务 并且把端口改称8080
修改默认主页为hello world
# vim auto_apache.sh
#!/bin/bash
ansible all -m yum -a 'name="httpd"'
ansible all -m lineinfile -a 'path="/etc/httpd/conf/httpd.conf" regexp="^Listen" line="Listen 8080"'
ansible all -m service -a 'name="httpd" enabled="yes" state="started"'
echo hello world > /root/test.html
ansible all -m copy -a 'src=/root/test.html dest=/var/www/html/index.html'
setup模块
用于获取主机信息
filter 可以过滤到我们需要的信息
ansible t1 -m setup -a 'filter=ansible_distribution'
user模块
-a 'name= state={present(创建)|absent(删除)} force=(是否强制操作删除家目录) system= uid= shell= home='
[root@localhost ~]# ansible all -m user -a 'name=ansible state=present'
user:用户管理模块
常用参数:
name= #指定用户名(必须指定)
state=present/absent #添加/删除用户
system=yse/no #是否创建为系统用户
uid= #指定用户uid
shell= #指定用户shell环境
home= #指定用户家目录
group= #指定用户组
groups= #指定用户组附加组,以”,“分隔
例:
ansible web -m user -a 'name=HR state=present system=yes uid=100 groups=root,ntp shell=/bin/csh home=/home/HR_home'
ansible web -m user -a 'name=HR state=absent' #删除用户
批量创建用户和密码时可以使用该命令
ansible host -m shell -a ‘useradd username’
ansible host -m shell -a ‘echo password | passwd username --stdin’
cron模块
计划任务管理模块
name #任务计划的描述信息(必须指定)
minute #分(0-59 ,* ,*/2)
hour #时(0-23 ,* ,*/2)
day #日(1-31 ,* ,*/2)
month #月(1-12 ,* ,*/2)
weekday #周(0-6 ,*)
job=path #执行的命令的绝对路径
backup=yes/no #是否先备份再创建新的任务计划
user #以哪个用户新建任务计划,默认 root
state=present/absent #创建删除计划任务
例:
ansible web -m cron -a 'name=A user=root job="/bin/date &>/dev/null" weekday="*/1" state=present'
-a 'name= state= minute= hour= day= month= weekday= job='
[root@localhost ~]# ansible all -m cron -a 'name=Time state=present minute="*/5" job="/usr/sbin/ntpdate 172.168.0.1 &> /dev/null'' '
synchronize模块
目的:将主控方/root/a目录推送到指定节点的/tmp目录下
命令:ansible all -m synchronize -a 'src=/root/a dest=/tmp/ compress=yes'
delete=yes 使两边的内容一样(即以推送方为主)
--exclude=.git 忽略同步.git结尾的文件
由于模块,默认都是推送push。因此,如果你在使用拉取pull功能的时候,可以参考如下来实现
mode=pull 更改推送模式为拉取模式
ansible Playbook
json 数据格式 轻量级数据交换格式 JavaScript 对象表示法
yaml 数据格式
jinja2 数据格式
playbook 由YAML语言编写 遵循YAML标准
由---开始 ansible的命令流
检测所有主机是否连通 \
# vim ping.yml #创建playbook
---
- hosts: all
remote_user: root
tasks:
- ping:
]# ansible-playbook ping.yml -f 5 #运行playbook
-f 并发进程数量 默认是5
tasks 在对应的所有主机上执行的命令 上一个命令执行完毕后 才会执行下一个命令
实验案例
给所有主机添加plj用户
默认密码为123456
要求第一次登陆修改密码
# vim useradd.yml
---
- hosts: all
remote_user: root
tasks:
- name: create user plj
user: name=plj groups=users
- shell: echo 123456 | passwd --stdin plj
- shell: chage -d 0 plj
选项 -name 给命令做一个简短的注释
playbook 语法进阶
定义变量以及过滤器的使用
# vim useradd.yml
---
- hosts: all
remote_user: root
vars:
username: lx
tasks:
- user: name={{username}} groups=users password={{'123456'|password_hash('sha512')}}
- shell: chage -d 0 {{username}}
ansible-playbook对错误的处理 上一个命令的返回值如果不为0 则中止执行
忽略当前产生的错误
第一种方式:
shell: /usr/bin/somecommand || /bin/true
第二种方式:
- name: run some command
shell: /usr/bin/somecommand
ignore_errors: true
handlers 用于当关注的资源发生变化时采取一定的操作
# vim setup_apache.yml
---
- hosts: test
vars:
http_port: 80
servername: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: name=httpd state=latest
- name: write the apache config file
template: src=/srv/httpd.j2 dest=/etc/httpd.conf
notify:
- restart apache
- name: ensure apache is running (and enable it at boot)
service: name=httpd state=started enabled=yes
handlers:
- name: restart apache
service: name=httpd state=restarted
模板文件
]# sed -n '/^\(Listen\|ServerName\)/p' /srv/httpd.j2
Listen {{http_port}}
ServerName {{servername}}
when 当满足特定条件时 触发操作
register 变量注册 保存某个命令的执行结果
写一个playbook 要求查看web服务器的负载情况 当系统负载大于0.7的时后 停止apache服务
uptime | awk '{printf("%.2f\n",$(NF-2))}' 输出系统负载
# vim load.yml
---
- hosts: all
remote_user: root
tasks:
- shell: uptime | awk '{printf("%.2f\n",$(NF-2))}'
register: result
- service: name=httpd state=stopped
when: result.stdout|float > 0.7
使用
# awk 'BEGIN{while(1){}}'& 提高系统负载
# watch -n 1 'uptime ;netstat -anptu | grep 80' 同时查看uptime以及apache的运行状态
with_items playbook的标准循环
# vim useradd_item.yml
---
- hosts: all
remote_user: root
tasks:
- user:
name: "{{item.name}}"
group: "{{item.group}}"
with_items:
- {name: 'nb', group: 'users'}
- {name: 'dd', group: 'root'}
with_nested 嵌套循环
tag 标签
ansible调试方法
检测语法
ansible-playbook --syntax-check playbook.yaml
测试运行
ansible-playbook -C playbook.yaml
显示收到影响到主机 --list-hosts
显示工作的 task --list-tasks
显示将要运行的 tag --list-tags
debug模块 运行时输出更详细的信息 帮助排错
---
- hosts: 192.168.1.16
remote_user: root
tasks:
- shell: uptime |awk '{printf("%f\n",$(NF-2))}'
register: result
- shell: touch /tmp/isreboot
when: result.stdout|float > 0.5
- name: Show debug info
debug: var=result