Linux之Ansible入门用法(实验解析)

实验前提: 三台CentOS7和一台CentOS6,其中一台CentOS7当作Ansible堡垒机,其余三台主机当作被控主机。四台主机均为最小化安装,全部配置好了yum源,包括本地和EPEL源,禁用了防火墙和SELINUX。每个主机上面都增加了一块桥接网卡可供安装EPEL源资源。分别设置各个主机的主机名为ansible,node1-centos7,node2-centos7,node3-centos,使用Ansible管理,最好基于SSH KEY验证,这样就不用输入各个主机的密码了。

1,更改各个主机名称

#hostnamectl set-hostname ansible-centos7

其余两台Centos7按下图更改类似,更改完毕后,重新登入生效

#hostname node3-centos6
#vim /etc/hosts 在第一行最后增加node3-centos6

# vim /etc/sysconfig/network

添加如下

HOSTNAME=node3-centos6.localdomain

2,配置基于SSH KEY验证

ssh-keygen 生成密钥对-实验用处,故没有对私钥加密,生产环境看需要

[root@ansible-centos7 ~]  # ssh-copy-id 172.16.36.132 **

同样拷贝到另外两台被控主机,即可直接SSH IPADDR

3,配置堡垒机/主控机

yum源配置就位,外网卡连接就位,开始安装ansible

#yum install ansible        没任何意外安装成功
#vim /etc/ansible/ansible.cfg

找到下面的一行,将 #号删除,此项是为了SSH远程主机IP时,检查对应服务器的host_key,不输入YES。,建议取消注释

**找到下面的一行,将 #号删除,更改command为shell。此项为Ansible不加-m MODULE时默认调用模块。 **

ansible.cfg中对返回的消息不同颜色的释义

如果想要使用ansible的话,需要将被控主机IP放入到hosts目录中,如下图,参照内部说明即可定义。同一个主机IP可以同时属于不同组

测试Ansible ping模块-返回正常,表明堡垒机配置成功。

**Ansible一共有2080个模块,学无止境。 **

**先收工回去休息^.^,Ansible批量关机 **

4,Ansible部分用法

**1, # ansible websrv -m ping -v|-vv|-vvv 显示详细或更详细过程 **

2, # ansible |172.16.36.12|websrv|appsrv|all -m ping
hostpattern可以使用通配符,别名,ip地址。前提在/etc/ansible/hosts中有定义

3, # ansible ‘websrv:!appsrv’|'websrv:&appsrv' -m ping hostpattern也可以使用逻辑与&,逻辑非!,以及正则表达式(需要以~开头),来取得hosts中的IP

**4, # ansible-doc -s shell 查看shell这个模块的说明 **

5, # ansible websrv -a ‘echo $HOSTNAME’ 查看被控主机时,变量引用需要在单引号中,双引号无效(显示本机主机名),双引号中可以写命令(如果命令中还有需要使用引号的选项,则使用单引号)

**6, # ansible websrv -a 'sed -i "s@SELINUX=disabled@SELINUX=permissvie@" /etc/selinux/config' 批量修改selinux配置文件 **

5,Ansible常用模块

command,shell,script,copy,fetch,file,unarchive,hostname,cron,yum,service,user,group,setup **1,script
脚本模块 直接在被控主机执行本机脚本 **

# vim hello.sh
hostname > /data/hostname.log
# ansible websrv -m script -a '/root/hello.sh'

2,copy
拷贝模块 将本机文件复制到被控主机上,可指定相应内容

# ansible websrv -m copy -a 'src=/root/hello.sh dest=/data/ owner=martin group=bin mode=600'

写内容并在被控主机生成文档

# ansible websrv -m copy -a 'content="hello\nlinux" dest=/data/my.txt' 

源文件覆盖被控主机文件,提前备份主机文件

# ansible websrv -m copy -a 'src=/root/hello.sh dest=/data/my.txt backup=yes  

3,fetch 抓取模块 被控端主机文件抓取到本地机,目前支支持文件抓取,需要抓取目录内所有数据的话,先打包 抓取过来同时保持目录结构

# ansible websrv -m fetch -a 'src=/data/my.txt dest=/root/' 

4,file 文件模块 设置文件属性 创建软硬链接 state=touch(空文件)|directory(目录)|link(软链接)|hard(硬链接)|absent(删除,不支持通配符*)

# ansible websrv -m file -a 'path=/data/root owner=martin mode=000'

创建软链接

# ansible websrv -m file -a 'src=/data/hello.sh path=/data/hello.sh.link state=link'

创建硬链接

# ansible websrv -m file -a 'src=/data/hello.sh path=/data/hello.sh.hardlink state=hard' 

5,unarchive 解压模块 解压文件到被控主机 如果copy不指定no,默认copy为yes相当于把本机打包文件拷贝到被控主机上,再解压。

# ansible websrv -m unarchive -a 'src=/root/root.tar dest=/data/'

当copy=no时,src指定网上的压缩包

# ansible websrv -m unrchive -a ‘src=https://example.com/example.zip dest=/usr/local/bin copy=no’

6,hostname
主机名模块
更改主机名 如果要定义不同主机不同主机名,需要用到变量,此方式修改,直接修改主机名的配置文件centos6:/etc/sysconfig/networks,centos7:/etc/hostname,永久生效。

# ansible 172.16.36.142 -m hostname -a 'name=test.localdomain'

7,cron
计划任务 支持时间:minute,hour,day,month,weekday 每5分钟执行一次向堡垒机同步时间。

# ansible 172.16.36.112 -m cron -a 'name=synctime minute=*/5 job="ntpdate 172.16.36.122 &> /dev/null"'

# ansible all -m cron -a 'name=synctime minute=*/5 job="ntpdate 172.16.36.122 &> /dev/null" disabled=true'

删除名字为synctime的任务项

# ansible all -m cron -a 'name=synctime state=absent'

8,yum
安装模块
安装服务等

# ansible appsrv -m yum -a 'name=httpd state=present'   安装
# ansible appsrv -m yum -a 'name=httpd state=absent'    卸载

9,service
服务模块 对服务状态做出控制

# ansible appsrv -m service -a 'name=httpd state=started|stoppted|reloaded|restarted' 服务管理
# ansible appsrv -m service -a 'name=httpd enabled=yes'  开机是否自启动

10,user 用户模块 创建用户使用 创建mysql为系统用户,指定家目录,但不创建家目录

# ansible appsrv -m user -a 'name=mysql system=yes shell=/sbin/nologin home=/usr/local/mysql create_home=no'

删除mysql用户

# ansible appsrv -m user -a 'name=mysql state=absent'

删除mysql用户,如果家目录存在的话,删除之

# ansible appsrv -m user -a 'name=mysql remove=true state=absent'

11,group 组模块 创建组使用 创建mysql组

# ansible appsrv -m user -a 'name=mysql system=yes'

删除mysql组

#  ansible appsrv -m user -a 'name=mysql state=absent'

12,setup 主机信息模块

# ansible appsrv -m setup -a 'filter="*hostname*"'

6,Ansible系列命令

1,ansible-galaxy

连接 https://galaxy.ansible.com 下载相应的roles 安装galaxy geerlingguy.redis 开发者姓名.角色

# ansible-galaxy install geerlingguy.redis 

删除galaxy

# ansible-galaxy remove geerlingguy.redis

2,ansible-playbook

执行脚本前检查有无错误,可使用ansible-playbook -C xxx.yml

1,编写一个yml文件

严格区分空格,对其方式,第一次写头大

# vim wall_helo.yml

执行yml文件

# ansible-playbook wall_helo.yml
2,编写一个安装httpd的yml文件
# vim install_httpd.yml

执行脚本

# ansible-playbook install_httpd.yml

配置文件端口已被修改为8000 执行结果:

3,编写一个yum文件,用于创建mysql用户
# vim create_mysql.yml               

执行结果:

4,存储yml文件目录结构,方便存储。

针对上述install_httpd.yml,改进如下

5,handlers和notify结合使用出发条件

针对上述install_httpd.yml,改进如下

6,tags的应用

针对上述install_httpd.yml,改进如下 指定tags定义的内容,只执行此tags内的列表内容,可多个tags同时执行,用逗号分隔。 tags定义的内容可以相同,同时执行相同tags内的列表内容。

# ansible-playbook -t config install_httpd.yml

7,变量引用
ansible_hostname
ansible_nodename
ansible_fqdn    
ansible_memtotal_mb
ansible_processor_vcpus

**1,使用setup模块内部变量 **

# vim create_file.yml

执行结果:

2,定义普通变量

# vim /etc/ansible/hosts 如下图针对不同IP增加port变量

# vim create_file.yml
# 创建文件名时加上{{port}},调用上面/etc/ansible/hosts里port变量里的值。

查看结果

3,定义公共组变量

# vim /etc/ansible/hosts 如下图针对某个组内增加martin变量

# vim create_file.yml
# 创建文件名时加上{{martin}},调用上面/etc/ansible/hosts里martin变量里的值。

4,定义公共组变量和普通变量,其中有一个IP没定义port变量

# vim /etc/ansible/hosts

结论:变量优先级:普通变量优先级大于公共变量

5,命令行变量直接定义-e

# ansible-playbook -e port=9527 create_file.yml

结论:命令行变量优先级大于普通变量优先级大于公共变量

6,直接在yml脚本内定义变量

# vim create_file.yml

结论:yml文件内变量优先级大于普通变量优先级大于公共变量

7,变量单独定义在另一个yml文件中

# vim vars.yml

# vim create_file.yml

结论:单独yml定义变量优先级在执行的yml脚本内变量之上

8,命令行定义变量,yml脚本内定义变量,同时定义普通变量和公共变量

# ansible-playbook -e port=9999 create_file.yml

**结论: 命令行定义变量优先级最高 外部yml定义变量优先级第二 yml内定义变量优先级第三 普通变量优先级第四 公共变量优先级第五 **

8,模板template

根据模板内容动态生成对应的配置文件,模板文件必须存放在templates目录下,且后缀为.j2,此目录和yml文件存放目录平级。

模板应用之一:httpd

# vim templates/httpd.conf.j2 找到Listen这行,将端口改为9999
修改上面的install_httpd.yml

执行结果:通过template功能拷贝文件到被控主机端覆盖文件

模板应用之二:nginx

# vim install_nginx.yml

跑一下yml脚本,安装成功后,可以看下nginx线程数, 但由于使用最小安装,pstree竟然都没有,自己安装下》。》

# ansible appsrv -a 'yum install psmisc -y'

查看一下进程树,ngnix的线程数和cpu内核数量有关,但可后期人为更改,需要用到template,

把配置文件先拷贝到templates文件夹内

# cp /etc/nginx/nginx.conf templates/nginx.conf.j2

使用setup模块找到cpu对应的变量,进而去修改nginx.conf里的线程数量,改变启动后的线程数

# vim nginx.conf.j2

更改如下,将线程数改为cpu内核数量+2个。

# vim install_nginx.yml

修改如下 ,然后跑一遍

结果:线程数增加

模板应用之三:when的使用 根据被控主机系统不同应用不同模板时,就需要使用到when 还是拿httpd服务实验,websrv里有一台主机是centos6,另一台是centos7。事先在templates文件夹里放入两个不同版本的httpd.conf.j2。为了加以区分,6的端口号改为90,7的端口号改为4444

**yml文件内容 **

**跑一遍yml文件 结果: **

迭代:with_items的使用 使用方法之一:创建不同名称文件

# cp create_file.yml create_file2.yml
# vim create_file2.yml

跑一遍yml脚本 结果:迭代生成多个文件。

使用方法之二:创建用户和与之对应的组(with_items和字典{})

执行结果:创建用户成功,组相对应

模板应用之四:for if 使用test.conf.j2模板,动态生成多个不同内容的配置文件

# vim test.conf.j2

定义默认端口,如果yml文件里没给出端口号,会使用模板默认端口,if用法,如果定义了,就使用定义的,没定义就置为空。

再写一个yml脚本:

执行结果:

3,ansible-vault

管理加密解密yml文件

ansible-vault [create|decrypt|edit|encrypt|rekey|view]
ansible-vault encrypt hello.yml 加密
ansible-vault decrypt hello.yml 解密
ansible-vault view hello.yml 查看
ansible-vault edit hello.yml 编辑加密文件
ansible-vault rekey hello.yml 修改口令
ansible-vault create new.yml 创建新文件

4,ansible-console

交互式执行ansible命令

Ansible-console:2.0+新增,可交互执行命令,支持tab
root@test (2)[f:10] $
执行用户@当前操作的主机组 (当前组的主机数量)[f:并发数]$
设置并发数: forks n 例如: forks 10
切换组: cd 主机组 例如: cd web
列出当前组主机列表: list
列出所有的内置命令: ?或help
示例:
root@all (2)[f:5]$ list
root@all (2)[f:5]$ cd appsrvs
root@appsrvs (2)[f:5]$ list
root@appsrvs (2)[f:5]$ yum name=httpd state=present
root@appsrvs (2)[f:5]$ service name=httpd state=started