目录
- Ansible
- 1、自动化运维平台介绍
- 1.1、运维自动化平台的优势
- 2、常见的运维自动化工具
- 3、Ansible简介
- 3.1、ansible的特性
- 3.2、优点
- 3.3、基本架构:
- 3.4、Ansible Tower介绍
- 3.4.1Ansible Tower能够做什么
- 3.5、ansible命令执行的过程
- 3.6、安装目录(yum默认安装目录)
- 3.7、配置文件介绍
- 3.7.1、ansible主机清单
- 4、ansible自动化运维平台部署
- 4.1部署前准备
- 5、ansible命令用法
- 5.1查看所有支持的模块
- 6、playbook剧本
- 6.1、playbook基础操作
- 6.1.1、tasks列表
- 6.1.2、变量的定义
- 6.2、Playbook角色和Include语句
- 6.2.1、角色:
- 6.2.2、include
- 6.1、playbook基础操作
- 1、自动化运维平台介绍
注:本随笔纯属个人笔记,如果错误请见谅,以及评论给出意见谢谢Ansible1、自动化运维平台介绍
运维自动化平台是由管理机器[s]和业务机器[c]组成的C/s
管理机器:任务定制及发布任务
业务机器:接收任务并执行任务
1.1、运维自动化平台的优势
- 一次性任务定制:任务一次性发布给所有机器
- 节省任务执行时间:任务主机并发完成任务,节省部署时间
- 错误率低:避免重复,保证一次任务定制准确即可
2、常见的运维自动化工具
Puppet
基于Ruby开发,有产品线已经在用,优点是历史悠久,比较成熟,可远程可本地,功能强劲,批量执行需要写专门的配置文件,费力费时,而却有客户端在,和授权系统结合比较麻烦
Saltstack
saltstack和ansible都是python开发的,而且功能上来讲,两者也极为相似,不同的地方是salt – stack是有客户端的,并且execution模块还用OMQ实现了pub-sub,命令和执行结果因此可以高效并传输,不过第一个sub阶段(将querystring下发到所有机器,然后收集机器响应的阶段)太依赖与客户端返回了,如果客户端未能及时返回或响应为响应的话,playbook执行阶段可能会直接漏掉这部分机器而没有任务提示,这对于运维来说是不可接收的
Ansible
Ansible在特性上并不抢眼,配置管理方面(playbook)也比不过puppet,批量执行方面也只是多线程,不像saltstack那么高大上,不过ansible不会悄悄的丢机器,而且依赖ssh,与登录授权管理系统天然继承,简单既有效。
3、Ansible简介
Ansible是一个部署一群远程主机的工具,远程的主机可以是远程虚拟机或物理机,也可以是本地主机,实现了批量系统配置、批量程序部署、批量运行命令等功能,ansible是基于模块工作的,本身没有批量部署能力,真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架,主要包括:
- 连接插件connection plugings:负责和被监控端实现通信;ansible管理端和客户端基于ssh协议通信
- host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;提供主机管理列表,定义管理谁
- 各种模块核心模块、command模块、自定义模块;提供了日常模块
- 借助于插件完成记录日志邮件等功能;根据需求后续添加模块,邮件、日志模块
- playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务,一次发布多条指令给客户端
3.1、ansible的特性
- 不需要在被控住主机上安装任务客户端
- 无服务端,使用时直接运行命令即可
- 基于模块工作,可使用任意语言开发模块
- 使用yaml语言定制剧本playbook
- 基于SSH工作
- 可实现多记指挥
3.2、优点
- 轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可
- 批量执行可以写成脚本,而且不用分发到远程就可以执行
- 使用python编写,维护更简单
- 支持sudo
3.3、基本架构:
- 控制节点:控制节点是指运行Ansible命令的主机,他可以是物理机或者虚拟机,在控制节点上安装和配置Ansible,并用于编辑和执行Ansible Playbook
- 模块:模块是Ansible的核心组件之一,他们执行实际的任务,Ansible提供了丰富的内置模块,用于管理各种系统资源和服务,例如文件操作、软件包管理、用户管理等,通过调用不同的模块,可以实现特定目标的配置和部署
- 插件:插件是Ansible的扩展组件,用于增强和自定义Ansible的功能,Ansible支持多种插件类型,包括连接插件、变量插件、回潮插件等,可以方便地扩展Ansible的能力
- 发现:Ansible支持对目标主机的发现和动态加入,通过发现功能,可以自动识别新加入的主机,并将其纳入到管理范围
- 渐进式推进:Ansible使用渐进式推推送的方式进行配置和部署,这就意味着Ansible会按照定义的顺序执行任务,确保系统达到期望的状态
Ansible管理员节点和远程主机节点通过ssh协议进行通信,所以ansible配置的时候只需要保证从Ansible管理节点通过SSH能够连接到被管理的远程的远程节点即可,但是SSH必须配置为公钥认证登录方式,而非密码认证
在管理员节点安装ansible,编写脚本,在管理节点执行命令或者脚本时,通过SSH连接被管理主机,被管理的远程节点不需要进行特殊安装软件
ansible可以同时管理redhat系统的linux,Debian系统的linux,以及Windows主机,管理节点只是在执行脚本时与远程主机连接,没有特别的同步机制,所以断电等异常一般不会影响ansible
工作原理: 1、用户登录管理机器:通过ansible剧本或者单行命令针对业务机器组或者单个机器部署任务 2、管理机器读取用户的部署任务:根据自己hosts文件中定义的业务机器组查找对应的机器地址(ip或者域名) 3、管理机下发任务:管理机通过ssh免密连接业务机器,下发任务给业务机器 4、业务机器执行任务 5、业务机器将执行结果发送给ansible管理机器 反馈字体颜色 绿色 未发生变化 黄色 更改生效 红色 执行错误
3.4、Ansible Tower介绍
Ansible Tower一款针对企业用户的收费软件
每一台被ansible远程管理的主机,都需要配置基于key的ssh连接,个人用户管理几台虚拟机和远程主机不会有什么问题,但是对于企业级用户,则满足不了业务和安全上的需求
- 首先,每增加一台主机,都需要收工配置一下ssh连接,企业级的pc主机成百上千,每个管理员都需要在自己电脑上配置所有的ssh连接,无疑工作量巨大
- 还有在安全方面如果管理员能够拿到ssh key,或者拷贝给别人,对于生产环境来说无疑是最大的安全隐患
3.4.1Ansible Tower能够做什么
Ansible Tower是针对企业级用户的,中心化ansible管理节点,他向管理员提供Web页面接口,来运行ansible脚本playbook
- 管理员在ansible tower上使用和分享主机的ssh key,但是不能查看和拷贝key文件
- 登录ansible tower的所有管理员可以共享playbook脚本,较少重复工作
- 此外ansible还可以收集和展示所有主机的palybook的执行状况,便于统计和分析主机的状态
3.5、ansible命令执行的过程
- 加载自己的配置文件,默认/etc/ansible/ansible.cfg
- 查找对应的主机配置文件,找到要执行的主机或者组
- 加载自己对应的模块文件,如command
- 通过ansible将模块或命令生成对应的临时py文件(python文件),并将该文件传输至远程服务器
- 对应执行用户的家目录的.ansible/tmp/xxx/xxx.py文件
- 给文件+x权限
- 执行并返回结果
- 删除临时py文件,sleep 0 退出
3.6、安装目录(yum默认安装目录)
- 配置文件目录:/etc/ansible
- 执行文件目录:/usr/bin
- Lib库依赖目录:/usr/lib/pythonx.x/site-packages/ansible
- Help文档目录:/usr/share/doc/ansible-x.x.x/
- Man文档目录:/usr/share/man/man1/
3.7、配置文件介绍
ansible的配置文件为/etc/ansible/ansible.cfg;ansible有许多参数
常见参数
inventory = /etc/ansible/hosts #这个参数表示资源清单inventory文件的位置library = /usr/share/ansible #指向存放ansible模块的目录,支持多个目录方式,只要用冒号隔开就行forks = 5 #并发连接数,默认是5sudo_user = root #设置默认执行命令的用户remote_port = 22 #指定连接被管理节点的管理端口,默认为22端口,建议修改,能更加安全host_key_checking = False #设置是否检查ssh主机的密钥,值为True/False,关闭后第一次连接不会提示配置实例timeout = 60 #设置ssh连接的超时时间,单位为秒log_path = /var/log/ansible.log #指定一个储存ansible日志的文件(默认不会记录日志)
3.7.1、ansible主机清单
在配置文件中我们提到的资源清单,这个清单就是我们的主机清单,里面保存的是ansible需要连接管理的主机列表,定义方式:
vim /etc/ansible/hosts1. 直接指明知己地址或主机名 # green.example.com# # blue.example.com# #192.168.100.1 #192.168.100.22. 定义一个主机名[组名]把地址或者主机名加进去 [mysql_test] 192.168.100.100 www.dev.com
4、ansible自动化运维平台部署4.1部署前准备
- 部署机器准备
- 计算机域名解析
- 关闭防火墙、selinux
- 时间同步
- 软件版获得
- ssh免密登陆
约定事项:
所有服务器全部采用静态ip
主机名称 IP地址 manage01 192.168.98.200/24 node1 192.168.98.201/24 node2 192.168.98.202/24 node3 192.168.98.203/24 主机名及主机名互相绑定
[root@manage01 ~]# cat /etc/hosts127.0.0.1 localhost::1 localhost 192.168.98.200manage01192.168.98.201node1192.168.98.202node2192.168.98.203node3
关闭防火墙,selinux
[root@manage01 ~]# systemctl disable firewalld[root@manage01 ~]# sed -i -r '/SELINUX=/c\SELINUX=disabled' /etc/selinux/config[root@manage01 ~]# reboot其他机器同理
采用时间服务器,时间同步
1、修改配置文件,配置时间服务器为阿里云的时间服务器[root@manage01 ~]# egrep "^server" /etc/chrony.conf server ntp1.aliyun.comserver ntp2.aliyun.comserver ntp3.aliyun.comserver ntp4.aliyun.com#注释# pool 2.centos.pool.ntp.org iburst2、重启服务chronyd[root@manage01 ~]# systemctl restart chronyd.service 3、查看源信息#chronyc chrony的命令行客户端[root@manage01 ~]# chronyc sources -v210 Number of sources = 2 .-- Source mode '^' = server, '=' = peer, '#' = local clock. / .- Source state '*' = current synced, '+' = combined , '-' = not combined,| / '?' = unreachable, 'x' = time may be in error, '~' = time too variable.|| .- xxxx [ yyyy ] +/- zzzz|| Reachability register (octal) -. | xxxx = adjusted offset,|| Log2(Polling interval) --. | | yyyy = measured offset,|| \ | | zzzz = estimated error.|| | | \MS Name/IP address Stratum Poll Reach LastRx Last sample ===============================================================================^? 120.25.115.20 2 6 1 3 +663us[ +663us] +/- 23ms^? 203.107.6.88 2 6 1 2 -1326us[-1326us] +/- 17ms
确认和配置yum源(需要epel源)
[root@manage01 ~]# yum -y install epel-*
ssh远程连接
管理端和被管理端连接时基于ssh的,所以有两种连接方式
基于ssh口令
基于ssh证书
如果想不需要运维人员干预,被管理端必须允许管理端证书免密登录
#管理端manage01生成ssh公私钥[root@manage01 ~]# ssh-keygen Generating public/private rsa key pair.Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter 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.The key fingerprint is:SHA256:aufJno2QjPK/V63/PVW13h5oWlKu0jk7HesXYTho0gM root@manage01The key's randomart image is:+---[RSA 2048]----+| || E .|| o . . o|| . = + +.|| S o.+ = +|| o o ...* +o|| . . * ....O o.+|| o . =.*.B o +.|| ..o+B oo*oo o|+----[SHA256]-----+#将公钥传给node1[root@manage01 ~]# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.98.201/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub"The authenticity of host '192.168.98.201 (192.168.98.201)' can't be established.ECDSA key fingerprint is SHA256:u+yOQz+E+eF7Oixdz/vClLXlAEu/7K8jy783gzk20dQ.ECDSA key fingerprint is MD5:c0:80:1b:ae:93:32:c2:66:f5:da:2f:1c:26:1e:7e:f8.Are you sure you want to continue connecting (yes/no)? yes/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keysroot@192.168.98.201's password: Number of key(s) added: 1Now try logging into the machine, with: "ssh 'root@192.168.98.201'"and check to make sure that only the key(s) you wanted were added.#将公钥传给node2[root@manage01 ~]# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.98.202/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub"The authenticity of host '192.168.98.202 (192.168.98.202)' can't be established.ECDSA key fingerprint is SHA256:X4JeiiFuwV0cja81veAyGCosriEfZm/zv34cfYkuxmU.ECDSA key fingerprint is MD5:7d:17:0f:80:d5:2b:30:ec:2c:62:f9:79:6b:fb:5f:bc.Are you sure you want to continue connecting (yes/no)? yes/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keysroot@192.168.98.202's password: Number of key(s) added: 1Now try logging into the machine, with: "ssh 'root@192.168.98.202'"and check to make sure that only the key(s) you wanted were added.#将公钥传给node3[root@manage01 ~]# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.98.203/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub"The authenticity of host '192.168.98.203 (192.168.98.203)' can't be established.ECDSA key fingerprint is SHA256:PtpsYBjaXkE+o3j8QYU5Ju8uPgcW2lVW8wsx4X1PV/c.ECDSA key fingerprint is MD5:50:a1:63:a0:ef:e7:61:26:11:25:ae:06:ec:93:cb:18.Are you sure you want to continue connecting (yes/no)? yes/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keysroot@192.168.98.203's password: Number of key(s) added: 1Now try logging into the machine, with: "ssh 'root@192.168.98.203'"and check to make sure that only the key(s) you wanted were added.小窍门免交互创建公私钥[root@manage01 ansible]# ssh-keygen -f /root/.ssh/id_rsa -N "" -f 指定密钥存放路径-N "" 新密码设置问空-P "" 老密码是什么如何可以非交互式传公钥呢[root@manage01 ansible]# yum -y install sshpass[root@manage01 ansible]# sshpass -p111111 ssh-copy-id -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa.pub root@192.168.98.202 StrictHostKeyChecking 严厉的主机监测=no 就不会问你yes|no了 sshpass 非交互式传密码测试证书是否生效[root@manage01 ~]# for i in `seq 201 203`;do> ssh root@192.168.98.$i "hostname"> donenode1node2node3看到返回客户端的计算机名称
ansible管理部署
管理端安装ansible
安装方式yum
[root@manage01 ~]# yum -y install ansible[root@manage01 ~]# ansible --versionansible 2.8.5 config file = /etc/ansible/ansible.cfg configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python3.6/site-packages/ansible executable location = /usr/bin/ansible python version = 3.6.8 (default, May 21 2019, 23:51:36) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]
源码安装
1、官网下载地址:https://releases.ansible.com/ansible[root@manage01 ~]# wget https://releases.ansible.com/ansible/ansible-2.9.3.tar.gz2、安装ansible[root@manage01 ~]# tar xf ansible-2.9.3.tar.gz [root@manage01 ~]# mv ansible-2.9.3 /opt/ansible[root@manage01 ~]# cd /opt/ansible-2.9.3#python软件包安装--1、安装依赖[root@manage01 ansible-2.9.0rc3]# pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/[root@manage01 ansible]# ln -s /usr/bin/pip3 /usr/bin/pip#python软件包安装--2、安装软件[root@manage01 ansible-2.9.0rc3]# pip install --user ansible -i https://pypi.tuna.tsinghua.edu.cn/simple/#安装后设置[root@manage01 ~]# ln -s /usr/bin/python3 /usr/bin/python[root@manage01 ~]# ln -s /opt/ansible/bin/* /usr/bin/[root@manage01 ~]# cp /opt/ansible/examples/ansible.cfg /etc/ansible/[root@manage01 ~]# cp /opt/ansible/examples/hosts /etc/ansible/
常见的问题
[root@manage01 ansible-2.9.0rc3]# ./bin/ansible -m ping 192.168.98.201 [WARNING]: No inventory was parsed, only implicit localhost is available [WARNING]: provided hosts list is empty, only localhost is available. Note thatthe implicit localhost does not match 'all' [WARNING]: Could not match supplied host pattern, ignoring: 192.168.98.201 触发原因 执行ansible的时候回去读取客户端文件hosts,如果没有把客户端加入到hosts文件,就说明无法ansible无法管理。 解决方案 [root@manage01 ansible]# mkdir /etc/ansible [root@manage01 ansible]# cp examples/hosts /etc/ansible/ #将需要管理的客户端IP地址写入hosts文件,可以分组或者直接写 [root@manage01 ~]# cat /etc/ansible/hosts 192.168.98.[201:203] 分组 [group1]192.168.98.[201:203]
ansible管理服务器部署
管理端ansible目录:/etc/ansible[root@manage01 ansible]# tree .├── ansible.cfg #ansible配置文件,不需要配置├── hosts#主机列表└── roles #角色列表1 directory, 2 files
部署主机列表,定义被监控主机
[root@manage01 ansible]# egrep -v "(^#|^$)" /etc/ansible/hosts [group1]#名字可以随便起 后面跟上业务机器的IP地址或者域名192.168.98.201192.168.98.202192.168.98.203
关于业务机器分组
分组中使用范围[nginx]组名apache[1:10].aaa.com表示apache1.aaa.com到apache10.aaa.com这10台机器nginx[a:z].aaa.com表示nginxa.aaa.com到nginxz.aaa.com共26台机器10.1.1.[11:15]表示10.1.1.11到10.1.1.15这5台机器如果业务机器的SSH端口不是2210.1.1.13:2222表示10.1.1.13这台,但ssh端口为2222指定业务机器别名,未做免密登陆的机器可以通过下面的机器设置账号密码nginx1 ansible_ssh_host=10.1.1.13 ansible_ssh_port=2222 ansible_ssh_user=root ansible_ssh_pass="123456"ansible_ssh_host 指定业务机器的IP或域名ansible_ssh_port 指定业务机器的ssh端口ansible_ssh_user 指定业务机器的ssh用户名ansible_ssh_pass 指定业务机器的ssh用户名密码利用机器别名分组nginx1 ansible_ssh_host=10.1.1.13 ansible_ssh_port=2222 ansible_ssh_user=root ansible_ssh_pass="123456"nginx2 ansible_ssh_host=10.1.1.12[nginx]nginx1 #写服务器别名nginx2[root@manage01 ansible]# egrep -v "(^#|^$)" /etc/ansible/hosts #别名定义web1 ansible_ssh_host=192.168.98.203 ansible_ssh_port=12121#分组[group1]192.168.98.201#未做免密登陆机器192.168.98.202:12121 ansible_ssh_user=sko ansible_ssh_pass='123'#别名机器web1 ansible_ssh_user=sko ansible_ssh_pass='123'
测试管理机和业务机器的联通性
我们可以使用ansible通过调用ping模块来测试分组机器或某个机器-m 指定使用的模块 group1 业务机器分组#测试单个机器#测试主机列表中的机器#测试单个机器方法[root@manage01 ~]# ansible -m ping 192.168.98.201#测试主机列表中的机器方法[root@manage01 ~]# ansible -m ping group1
ansible管理哪些主机?什么是hostinventory(主机清单)
Host Inventory是配置文件,用来告诉Ansible需要管理哪些主机,并且把这些主机根据按需分类
可以根据用途分类:数据库节点,服务节点等;根据地点分类:中部,西部机房
Host Inventory配置文件
默认的文件是:/etc/ansible/hosts(上面介绍配置文件的时候有介绍)
192.168.1.50aserver.example.orgbserver.example.org分组的:mail.example.com[webservers]foo.example.combar.example.com[dbservers]one.example.comtwo.example.comthree.example.com
5、ansible命令用法
ansible 主机 -m 模块名称 -a ‘模块参数’
基本格式:ansible 操作的主机或组名 -m 模块名 -a ‘参数1=值1 参数2=值2’
5.1查看所有支持的模块
# ansible-doc -la10_server Manage A10 Networks AX/SoftAX...a10_server_axapi3 Manage A10 Networks AX/SoftAX...a10_service_group Manage A10 Networks AX/SoftAX...a10_virtual_server Manage A10 Networks AX/SoftAX...aci_aaa_user Manage AAA users (aaa:User).......如果要查看ping模块的用法,使用下面命令(其它模块以此类推)# ansible-doc ping
常见的模块
hostname模块
hostname模块用于修改主机名(不能修改/etc/hosts文件)
ansible -m hostname -a ‘name=host1’ 192.168.98.203
file模块
file模块用于对文件或者文件夹相关的操作,主要用来设置文件、链接、目录的属性,或者移除文件、链接、目录,很多其他的模块也会包含这种作用,例如copy,assemble和template
文件创建
ansible -m file group1 -a “path=/tmp/host1 state = touch”
参数 说明 path 文件绝对路径 state 操作(touch文件新建、absent删除、link软连接、hard硬链接、directory目录创建) owner 设置所有者 group 设置所属的组 mode 权限 0000 recurse 递归 yes or no 文件的删除
ansible -m file 192.168.98.201 -a “path=/tmp/host1 state=absent”
文件权限
修改node2主机文件/tmp/host1 所有者sko,所有组nobody 权限600
ansible -m file 192.168.98.202 -a “path=/tmp/host1 owner=sko group=nobody mode=0600”
创建链接文件[软连接、硬链接]
软连接
ansible -m file 192.168.98.202 -a “src = /tmp/host1 path=/tmp/host1 state=link”
硬链接
ansible -m file 192.168.98.202 -a “src=/tmp/host1 path=/tmp/host1 state=hard”
创建目录:
ansible -m file group1 -a ‘path=/tmp/host1 state=firectory’
修改目录及子文件权限
所有者设置为sko
权限为2775
ansible -m file group1 -a “path=/tmp/host1 owner=sko mode=2775 recurse=yes”
删除一个目录【包括子文件全部删除】
ansible -m file group1 -a “path=/tmp/host1 state=absent”
copy模块
参数 说明 src 文件源路径 dest 目标路径 content 往目标文件输入内容 force 强制 yes or no backup 是否备份有冲突的源文件[文件名相同,内容不同] yes or no checksum 拷贝完整性校验,使用sha1sum生成校验码 owner 目标文件所有者 group 目标文件所属组 mode 目标文件权限 拷贝manage01主机/root/readme文件到group1组的主机
ansible -m copy group1 -a 'src=/root/reame dest=/opt'
fetch模块
fetch模块和copy模块类似,用于吧远程的机器拷贝到本地
ansible -m fetch group1 -a ‘src=/opt/readme dest=opt’
user模块
user模块用于管理用户账号和属性
常用参数 说明 name=”” 指定用户名 password=”” 指定密码,必须是密文 state= absent|present 删除|创建 system= yes|no 是否为系统用户 shell=”” 指定登陆shell generate_ssh_key= yes|no 是否创建秘钥对 uid= 指定用户的uid append= yes|no 用户是否追加到其他组 group= 用户属组 groups= 将现有用户加入到某个组,空值就会把该用户从所有所属组中删除 create_home= yes|no 是否建立家目录 remove= yes|no 删除家目录 group模块
group模块用于管理用户组和用户属性
参数 说明 name= 组名 state= persent|absent 创建|删除 system= yes|no 是否为系统组 gid gid cron模块
cron模块用户管理周期性的任务
参数 说明 name 计划任务的名称 user 执行计划任务的用户 job 计划任务命令 minute 执行计划任务的分 默认为* hour 执行计划任务的时 默认为* day 执行计划任务的日 默认为* month 执行计划任务的月 默认为* week 执行计划任务的周 默认为* state=absent 删除计划任务 每天14:20执行echo ‘haha’> /tmp/test
ansible -m cron group1 -a ‘name=”cron test” user=root job=”echo haha >/tmp/test minute=20 hour=14 “
yum_repository模块
用于配置yum仓库
参数 说明 name 仓库名 name.repo 源的名称 [name] description 描述 baseurl 包下载路径 gpgcheck= 1 or 0 包gpg验证 enabled = yes|no 是否开启本源 state= absent 删除源 添加一个/etc/yum.repos.d/dvd.repo 配置文件
ansible -m yum_respository group1 -a “name=dvd description=BaseOS baseurl=file:///mnt/BaseOS gpgcheck=0 enabled=yes””
yum模块
用来实现软件包的安装与卸载
参数 说明 name 需要安装软件包的名称 list= installed, updates, available and repos 列出已安装 需要更新 可获得的 和 yum源 state= absent removed installed present latest 删除、删除、安装确认、安装确认、安装最新版本 ansible -m yum group1 -a “list=repos”
service模块
用于控制服务的启动关闭,开机自启等
参数 说明 name 服务名称 state reloaded, restarted, started, stopped 服务管理 enabled yes|no 开启是否启动 ansible -m service 192.168.98.202 -a ‘name=vsftpd state=started enabled=on’
script模块
用于在远程主机上执行本地脚本
ansible -m script group -a ‘/root/ansible_test.sh’
command模块和shell模块
这个和shell模块都是用来执行linux命令的,shell和command模块差不多但是shell模块可以执行正则
ansible -m shell 192.168.98.201 -a ‘echo “hello world” > /tmp/test’
setup模块
setup用来收集远程的基本信息(系统类型,ip,cup,内存等等)
ansible -m setup 192.168.98.201
使用filter过滤输出
ansible -m setup 192.168.98.201 -a “filter=’ansible_processor'”
stat模块
类似于linux的stat命令,获取文件的状态信息的
ansible -m stat 192.168.98.201 -a “path=/etc/fstab”
template模块
这个模块用于根据模板文件和变量生成目标文件
常见用法示例:
1.创建模板文件:
首先,在ansible项目中创建一个模板文件,可以使用jinjia2模板语言编写,例如,创建一个名为
template.j2
的模板文件Hello, {{ name }}!Today is {{ date }}.
在playbook中使用tamplate模块
- hosts: all vars: name: "Alice" date: "2023-07-28" tasks: - name: Generate file from template template: src: template.j2 dest: /path/to/destination/file
6、playbook剧本
Playbooks是ansible的配置,部署,编排语言,他们可以被描述为一个需要希望远程主机执行命令的方案,或者一组IT程序运行时的命令集合
playbook可以完全使用shell脚本代替,但是一般情况下都写的yaml文件
playbook是一种简单的配置管理系统与多机器部署系统的基础,与现有的其他系统有不同之处,且非常适合于复杂应用的部署,palybook可以用于声明配置,更请打的地方在于在playbook中可以编排有序的执行过程,甚至于做到在多组机器之间来回有序的执行特别指定的步骤,并且可以同步或异步的发起任务
playbook的格式是yaml,语法做到最小化,意在避免playbooks成为一种编程语言或是脚本,但是它并不是一个配置或过程模型
playbook由一个或多个plays组成,他的内容是一个以plays为元素的列表
在play之中,一组机器被映射为定义好的角色,在ansible中,play的内容被称为tasks,即任务,在基本层次的应用中,一个任务是一个对ansible模块的调用
6.1、playbook基础操作
hosts行的内容是一个或多个组或主机的patterns,以逗号为分隔符
remote_user就是用户名
----hosts:webservers remote_user:root
参数remote_user以前写作user,在ansible1.4之后才改为了remoteuser,主要为了不跟user模块混淆(user模块用于在远程系统上创建用户)
可以在每一个task中定义自己的远程用户
---- hosts: webservers remote_user: root tasks: - name: test connection ping: remote_user: yourname
tasks中的remote_user参数在1.4版本之后添加
tasks
是Ansible Playbook文件中的关键字,用于定义要在目标主机上执行的任务列表。也支持从sudo执行命令
---- host: webservers remote_user: yourname sudo: yes
也可以在一个task中使用sudo执行命令,而不是在整个play中使用sudo
---- hosts: webservers remote_user: yourname tasks: - service: name=nginx state=started #任务名称 sudo: yes
也可以登录只有sudo到不同的用户身份而不是root
---- hosts: webserver remote_user: yourname sudo: yes sudo_user: postgres
6.1.1、tasks列表
每一个play包含了一个task列表(任务列表),一个task在其所对应的所有主机上(通过host pattern匹配的所有主机)执行完毕之后,下一个task才会执行,有一点需要明白的是,在一个play之中,所有hosts会获取相同的任务指令,这是play的一个目的所在,也就是将一组选出的hosts映射到task
在运行playbook时,从上到下执行,如果一个host执行task失败,这个host将会从整个playbook的rotation中移除,如果发生执行失败的情况,修改完playbook的错误,然后再次执行即可(执行过的成功任务会跳过)
每一个task的目标在于执行一个moudle,通常是带有特定的参数来执行,在参数中可以使用变量
modules具有‘幂等’性,意思是如果你再一次地执行moudle(比如遇到远端系统被意外改动,需要恢复原状),moudle只会执行必要的改动,只会改变需要改变的地方.所以重复多次执行 playbook 也很安全.
每个task必须有一个名称,这样在运行playbook时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个task的,如果没有定义名称,‘action’的值将会用作输出信息中标记特定的task
如果要声明一个task,大概格式为:module: options
tasks: - name: disable selinux command: /sbin/setenforce 0
在使用command模块或shell模块时,我们需要关心返回码信息,如果有一条命令,他的成功执行的返回码是不是0
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand || /bin/true
或
tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand ignore_errors: True
6.1.2、变量的定义
在playbook中可以使用变量,假设在‘vars’哪里定义了一个变量,‘vhost’,可以这样使用它
在命令行中可以使用-e选项来定义变量,或者在文件中使用‘vars’关键字来定义变量
- name: 示例 Playbook hosts: all vars: #定义的变量 jdk_version: "1.8" tomcat_version: "9.0.56" tasks: - name: #安装 Java apt: name: openjdk-8-jdk state: present update_cache: yes - name: #安装 Tomcat yum: name: centos-release-scl state: present when: "'{{ jdk_version }}' != '{{ item.key }}'" - name: #安装 Tomcat yum: name: #centos-release-scl-rh state: present when: "'{{ jdk_version }}' == '{{ item.key }}'" - name: #配置 Tomcat template: src: tomcat.conf.j2 dest: /opt/tomcat/conf/tomcat.conf vars: tomcat_version: "{{ tomcat_version }}"
外部变量
可以通过命令行参数、库函数或者外部文件来提供变量
ansible-playbook playbook.yaml - 'my_var=hello'- name: Using external variable debug: var: "{{ my_var }}"
引用另一个文件中的变量
创建一个独立的变量文件比如(vars.yaml),并定义变量,例如:
# vars.ymlmy_var: 'hello,world!'
在playbook中使用vars_files 关键字加载变量文件,例如
- hosts: all vars_files: - vars.yml tasks: - name: Print variable debug: var: my_var
剧本的运行:
ansible-playbook 剧本名字
-i
:指定 Ansible 的主机清单文件。-u
:指定要在远程主机上运行的用户。--private-key=
:指定要用于 SSH 连接的私钥文件。-e
:指定额外的变量,可以在 Playbook 中使用。--tags=
:只运行具有指定标记的任务。
6.2、Playbook角色和Include语句
我们刚开始学习运用playbook时,可能会把playbook写成一个很大的文件,到后来可能你希望这些文件是可以方便去重用的,所以需要重新去组织这些文件
基本上,使用include语句引用task文件的方法,可允许你将一个配置策略分解到更小的文件中,使用include语句引用tasks是将tasks从其他文件拉取过来,因为handlers也是tasks,所以你可以使用include语句去引用handlers文件,handlers 文件来自 ‘handlers:’ section。
Playbook同样可以是会用include引用
Roles 的概念来自于这样的想法:通过 include 包含文件并将它们组合在一起,组织成一个简洁、可重用的抽象对象。这种方式可使你将注意力更多地放在大局上,只有在需要时才去深入了解细节。
角色和include介绍:
角色:
- 目的:角色提供一种组织和重用代码的方式,以模块化和可维护的方式构建playbook,角色是将相关任务、处理程序和变量组织成一个独立的单元,以便在多个playbook中重复使用
- 主要用途:
- 将相关的任务、处理程序和变量几种到一个可重用的实体中,提高代码的可读性、可维护性和可重用性
- 增加playbook的模块化程度,使其易于理解、管理和扩展
- 使用场景:
- 当需要在多个playbook中重复使用相同的任务集、处理程序和变量时。
- 当希望将大型的playbook拆分成为更小、可重用的组件时
include语句:
- 目的:include语句运行您引用和重用其他文件的任务、变量和处理程序,他允许将playbook和任务文件拆分为多个更小的单元,以提高可读性和复用性
- 主要用途:
- 将复杂的playbook拆分为多个文件,使其易于理解和维护
- 在多个playbook之间共享和重用代码片段
- 使用场景:
- 当一个playbook变得过于庞大和复杂,需要将其分割问多个文件以提高可读性和可维护性时
- 当希望多个playbook之间共享相同的任务或playbook代码时
结论:角色适用于将相关任务、处理程序和变量组织成独立的、可重复用的单元,而include语句适用于将playbook和代码分割为多个文件提高可读性和复用性
6.2.1、角色:
角色提供一种将相关任务、处理和变量组织成一个可重负和独立的单元的方法,他们允许您以模块化的方式组织playbook,并促进代码的可维护性和可重用性
角色通常的目录结构:
roles/├── myrole/ │ ├── tasks/│ │ ├── main.yml│ ├── handlers/│ │ ├── main.yml│ ├── files/│ │ ├── myfile.txt│ ├── templates/│ │ ├── mytemplate.j2│ ├── vars/│ │ ├── main.yml│ ├── defaults/│ │ ├── main.yml│ ├── meta/│ │ ├── main.yml│ └── README.md
每个目录的作用如下:
tasks/
:包含角色任务的主要文件。这些任务在执行角色时会被执行。handlers/
:包含角色处理程序的主要文件。这些处理程序在角色任务完成后执行。files/
:包含角色使用的任何文件。这些文件可以在角色任务中使用。templates/
:包含角色使用的任何模板文件。这些模板可以在角色任务中使用。vars/
:包含角色使用的任何变量文件。这些变量可以在角色任务中使用。defaults/
:包含角色默认变量的主要文件。这些变量可以在其他文件中覆盖。meta/
:包含角色元数据的主要文件。这些元数据描述了角色的依赖关系和其他信息。README.md
:包含角色的文档和说明。
使用:
创建角色目录结构
使用ansible提供的命令行工具
ansible-galaxy
来创建角色目录结构比如:要创建一个名为
myrole
的新角色ansible-galaxy init myrole
这将在当前目录下创建一个名为
myrole
的目录,并在其中创建一些默认文件和目录编写角色任务
在
myrole/tasks/main.yml
文件中,可以编写角色的任务,这些任务将在应用角色时自动执行,例如,以下是一个简单的角色任务---- name: Install Apache yum: name: httpd state: latest become: true
这个任务将使用Yum包管理安装最新版本的的apache web服务器
编写角色处理程序
在
myrole/handlers/main.yml
文件中,可以编写角色的处理程序,这些处理程序将在任务完成后自动执行---- name: Restart Apache service: name: httpd state: restarted become: true
这个处理程序将重启Apache服务
编写角色元数据
在
myrole/meta/main.yml
文件中,你可以编写角色的元数据,这些元数据描述了角色的依赖关系和其他信息---dependencies: - role: common
这个元数据表名,
myrole
角色依赖于另一个名为common
的角色使用角色
在使用角色时,可以在playbook文件中声明角色,并指定角色的变量和其他参数,这个按例是使用
myrole
角色的playbook---- name: Apply myrole hosts: web_servers roles: - myrole
这个playbook将在名为
web_servers
的主机上应用myrole
角色,并执行其中定义的任务和处理程序playbook角色是ansible中一种非常有用的功能,可以帮助我们更好的组织和管理ansible playbook,提高代码的可维护性和重用性
角色的运行方式和单独的playbook的运行方式是一样的
首先编写一个playbook,在其中引用要运行的角色,例如:创建名为
myplaybook.yaml
的playbook文件---- hosts: servers tasks: - name: Run myrole include_role: name: myrole
然后再运行这个playbook即可
6.2.2、include
1、Include任务
可以使用includ_tasks指令将一个或多个任务包含到playbook中,以下playbook包含了一个名为task.yml的任务文件
---- name: Include tasks hosts: all tasks: - include_tasks: tasks.yml
在tasks.yml文件中,可以包含一个或多个任务
---- name: Install packages apt: name: "{{ item }}" state: present with_items: - nginx - mysql - php- name: Configure nginx template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf
2、Include 剧本
可以使用include_playbook指令将其他playbook文件包含到当前playbook中,以下playbook包含了一个名为common.yaml的playbook文件
---- name: Include common playbook hosts: all tasks: - include_playbook: common.yml
在common.yml文件中,可以包含一组任务和其他playbook文件
---- name: install common packages apt: name: "{{ item }}" state: present with_items: - curl - wget - vim- include_tasks: tasks.yml
3、Include 变量
可以使用include_vars指令将其他变量文件包含到playbook中,以下playbook包含了一个名为vars.yml的变量文件
---- name: Include variables hosts: all tasks: - include_vars: vars.yml - debug: var: my_var
在vars.yml文件中,可以定义一组变量:
my_var: "hello,world"
4、include 文件
可以使用include指令将其他文件包含到playbook中,例如,以下playbook包含了一个名为script.sh的脚本文件
---- name: Include script hosts: all tasks: - name: Run script include: script.sh
在script.sh文件中,可以编写任意的shell脚本代码
总之,include指令可以帮助你重用代码和组织playbook文件结构,可以包含其他任务、playbook、变量文件和任意文件