导图社区 ansible思维导图
ansible教程,Ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
编辑于2024-03-04 22:22:28Ansible
一 概念/术语
概述
Ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
特点
部署简单,只需要在主控端部署Ansible环境,被控端无需作任何操作
默认使用SSH协议对设备进行管理
主从集中化管理
配置简单、功能强大、扩展性强
支持API及自定义模块、可以通过Python轻松扩展
通过Playbooks来定制强大的配置、状态管理
对云计算平台、大数据都有很好的支持
文档
官方文档:https://docs.ansible.com/ansible/latest/
子主题
GitHub地址:https://github.com/ansible/ansible
二 Ansible 架构
架构图
组成
核心:ansible
核心模块(Core Modules):这些都是ansible自带的模块
扩展模块(Custom Modules):如果核心模块不足以完成某种功能,可以添加扩展模块
插件(Plugins):完成模块功能的补充
剧本(Playbooks):ansible的任务配置文件,将多个任务定义在剧本中,由ansible自动执行
连接插件(Connectior Plugins):ansible基于连接插件连接到各个主机上,虽然ansible是使用ssh连接到各个主机的,但是它还支持其他的连接方法,所以需要有连接插件
主机清单(Host Inventory):定义ansible管理的主机
三 Ansible 工作原理
工作原理图
管理端支持local 、ssh、zeromq 三种方式连接被管理端,默认使用基于ssh的连接,这部分对应上面架构图中的连接模块;
可以按应用类型等方式进行Host Inventory(主机清单)分类,管理节点通过各类模块实现相应的操作,单个模块,单条命令的批量执行,我们可以称之为ad-hoc;
管理节点可以通过playbooks 实现多个task的集合实现一类功能,如web服务的安装部署、数据库服务器的批量备份等。playbooks我们可以简单的理解为,系统通过组合多条ad-hoc操作的配置文件 。
九、Ad-Hoc(点对点模式)
官方文档:https://docs.ansible.com/ansible/latest/command_guide/intro_adhoc.html
1)简介
ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令,一般测试调试时用的多,ad-hoc简而言之,就是"临时命令"。
2)常用模块
1、command 模块(默认模块)
默认模块,没有shell强大,基本上shell模块都可以支持command模块的功能。
【1】帮助
ansible-doc command # 推荐使用下面这个 ansible-doc command -s
【2】参数解释
free_form
必须参数,指定需要远程执行的命令。需要说明一点,free_form 参数与其他参数(如果想要使用一个参数,那么则需要为这个参数赋值,也就是name=value模式)并不相同。比如,当我们想要在远程主机上执行 ls 命令时,我们并不需要写成”free_form=ls” ,这样写反而是错误的,因为并没有任何参数的名字是 free_form,当我们想要在远程主机中执行 ls 命令时,直接写成 ls 即可。因为 command 模块的作用是执行命令,所以,任何一个可以在远程主机上执行的命令都可以被称为 free_form。
chdir
此参数的作用就是指定一个目录,在执行对应的命令之前,会先进入到 chdir 参数指定的目录中。
creates
看到 creates,你可能会从字面上理解这个参数,但是使用这个参数并不会帮助我们创建文件,它的作用是当指定的文件存在时,就不执行对应命令,比如,如果 /testdir/test文件存在,就不执行我们指定的命令。
removes
与 creates 参数的作用正好相反,它的作用是当指定的文件不存在时,就不执行对应命令,比如,如果 /testdir/tests 文件不存在,就不执行我们指定的命令,此参数并不会帮助我们删除文件。
【3】示例演示
# 上面命令表示在 web 主机上执行 ls 命令,因为使用的是 root 用户,所以默认情况下,ls 出的结果是 web 主机中 root 用户家目录中的文件列表。 ansible web -m command -a "ls" # chdir 参数表示执行命令之前,会先进入到指定的目录中,所以上面命令表示查看 web 主机上 /testdir 目录中的文件列表,返回显示有2个文件。 ansible web -m command -a "chdir=/testdir ls" # 下面命令表示 /testdir/testfile1 文件存在于远程主机中,则不执行对应命令。/testdir/testfile3 不存在,才执行”echo test”命令。 ansible web -m command -a "creates=/testdir/testfile1 echo test" # 下面命令表示 /testdir/testfile3 文件不存在于远程主机中,则不执行对应命令。/testdir/testfile1 存在,才执行”echo test”命令。 ansible web -m command -a "removes=/testdir/testfile1 echo test"
2、shell 模块
shell模块 [执行远程主机的shell/python等脚本]。
【1】查看帮助
ansible-doc shell -s
【2】示例演示
# -o:一行显示 # 安装httpd ansible web -m shell -a 'yum -y install httpd' -o # 查看时间 ansible web -m shell -a 'uptime' -o
3、script 模块
script模块 [在远程主机执行主控端的shell/python等脚本 ]。
【1】查看帮助
ansible-doc script -s
【2】参数解释
free_form
必须参数,指定需要执行的脚本,脚本位于 ansible 管理主机本地,并没有具体的一个参数名叫 free_form,具体解释请参考 command 模块。
chdir
此参数的作用就是指定一个远程主机中的目录,在执行对应的脚本之前,会先进入到 chdir 参数指定的目录中。
creates
使用此参数指定一个远程主机中的文件,当指定的文件存在时,就不执行对应脚本,可参考 command 模块中的解释。
removes
使用此参数指定一个远程主机中的文件,当指定的文件不存在时,就不执行对应脚本,可参考 command 模块中的解释。
【3】示例演示
# 下面命令表示 ansible 主机中的 /testdir/testscript.sh 脚本将在 web 主机中执行,执行此脚本之前,会先进入到 web 主机中的 /opt 目录 ansible web -m script -a "chdir=/opt /testdir/testscript.sh" # 下面命令表示,web主机中的 /testdir/testfile1文件已经存在,ansible 主机中的 /testdir/testscript.sh 脚本将不会在 web 主机中执行。 ansible web -m script -a "creates=/testdir/testfile1 /testdir/testscript.sh" # 下面命令表示,web 主机中的 /testdir/testfile1 文件存在,ansible 主机中的 /testdir/testscript.sh 脚本则会在 web 主机中执行。 ansible ansible-demo3 -m script -a "removes=/testdir/testfile1 /testdir/testscript.sh"
4、raw 模块
raw模块 [类似于command模块、支持管道传递]。
【1】查看帮助
ansible-doc raw -s
【2】示例演示
ansible web -m raw -a "ifconfig eth0 |sed -n 2p |awk '{print \$2}' |awk -F: '{print \$2}'"
5、copy 模块
copy 模块 从主控端复制文件到被控端。
【1】查看帮助
ansible-doc copy -s
【2】示例演示
# -a,--args:后面接参数 ansible web -m copy -a 'src=/etc/ansible/hosts dest=/tmp/hosts owner=root group=bin mode=777' # backup=yes/no:文件存在且文件内容不一样是否备份,默认不备份 ansible web -m copy -a 'src=/etc/ansible/hosts dest=/tmp/hosts owner=root group=bin mode=777 backup=yes'
6、fetch 模块
copy 模块从被控端复制文件到主控端,正好跟copy相反。
【1】查看帮助
ansible-doc fetch -s
【2】示例演示
# 跟copy支持的参数差不多,src:远端主机的目录,dest:主控端目录,其实真正存放的目录在:/tmp/192.168.182.129/tmp/up.sh,会按每台主机分组存放 # This `must' be a file, not a directory:只支持单个文件获取 ansible 192.168.182.129 -m fetch -a "src=/etc/fstab dest=/testdir/ansible/"
7、unarchive 模块(解包模块)
unarchive 模块是解包模块。
【1】查看帮助
ansible-doc unarchive -s
【2】参数解释
copy
默认为yes,当copy=yes,那么拷贝的文件是从ansible主机复制到远程主机上的,如果设置为copy=no,那么会在远程主机上寻找src源文件。
src
源路径,可以是ansible主机上的路径,也可以是远程主机上的路径,如果是远程主机上的路径,则需要设置copy=no。
dest
远程主机上的目标路径。
mode
设置解压缩后的文件权限。
【3】示例演示
ansible 192.168.182.129 -m unarchive -a 'src=/testdir/ansible/data.tar.gz dest=/tmp/tmp/'
8、archive模块(打包模块)
unarchive 模块是打包模块。
【1】查看帮助
ansible-doc archive -s
【2】示例演示
9、user 模块
【1】查看帮助
ansible-doc user -s
【2】示例演示
# 创建用户(present:默认,可以不写) ansible web -m user -a 'name=test state=present' # 删除用户(absent) ansible web -m user -a 'name=test state=absent' # 修改密码 # 步骤一、生成加密密码 echo '777777'|openssl passwd -1 -stdin # 步骤二、修改秘密 ansible web -m user -a 'name=test password="$1$Jo5FD9Jr$2QB.BuybbtR35ga4O5o8N."' # 修改shell ansible web -m user -a 'name=test shell=/sbin/noglogin append=yes'
10、group 模块
【1】查看帮助
ansible-doc group -s
【2】示例演示
# 创建 ansible 192.168.182.129 -m group -a 'name=testgroup system=yes' # 删除 ansible 192.168.182.129 -m group -a 'name=testgroup state=absent'
11、yum 模块
【1】查看帮助
ansible-doc yum -s
【2】示例演示
# 升级所有包 ansible web -m yum -a 'name="*" state=latest' # 安装apache ansible web -m yum -a 'name="httpd" state=latest'
12、service 模块
【1】查看帮助
ansible-doc service -s
【2】示例演示
ansible web -m service -a 'name=httpd state=started' ansible web -m service -a 'name=httpd state=started enabled=yes' ansible web -m service -a 'name=httpd state=stopped' ansible web -m service -a 'name=httpd state=restarted' ansible web -m service -a 'name=httpd state=started enabled=no'
13、file 模块
【1】查看帮助
ansible-doc file -s
【2】示例演示
# 创建文件 ansible web -m file -a 'path=/tmp/88.txt mode=777 state=touch' # 创建目录 ansible web -m file -a 'path=/tmp/99 mode=777 state=directory' # 删除 ansible web -m file -a 'path=/tmp/99 state=absent'
14、setup 模块
【1】查看帮助
ansible-doc setup -s
【2】示例演示
ansible web -m setup ansible web -m setup -a 'filter=ansible_all_ipv4_addresses'
15、cron 模块
【1】查看帮助
ansible-doc cron -s
【2】示例演示
# 创建定时任务 ansible 192.168.182.129 -m cron -a 'minute=* weekday=1,3,5,6,7 job="/usr/bin/wall FBI warning" name=warningcron' # 关闭定时任务 ansible 192.168.182.129 -m cron -a 'disabled=true job="/usr/bin/wall FBI warning" name=warningcron' # 删除定时任务 ansible 192.168.182.129 -m cron -a ' job="/usr/bin/wall FBI warning" name=warningcron state=absent'
16、hostname 模块
【1】查看帮助
ansible-doc hostname -s
【2】示例演示
ansible 192.168.182.129 -m hostname -a 'name=192.168.182.129'
八 Host Inventory(主机清单)
主机清单配置(默认配置文件:/etc/ansible/hosts)
1)添加被管控节点
192.168.182.110
示例:
# -m:指定模块 # -a:指定参数 ansible 192.168.182.110 -m ping ansible 192.168.182.110 -m shell -a "df -h"
示例图
2)配置主机组
# 定义webservers组 [webservers] 192.168.182.110 192.168.182.112
示例:
# -m:指定模块 # -a:指定参数 ansible webservers -m ping ansible webservers -m shell -a "df -h"
图
3)配置连接用户名和密码
[webservers] 192.168.182.130 ansible_ssh_user=root ansible_ssh_pass=123456
常用配置参数
示例:
ansible 192.168.182.130 -m ping
图
4)子分组
[web] 192.168.182.130 192.168.182.110 [mysql] 192.168.182.111 # 子分组 [nfs:children] web mysql # 对分组统一定义变量 [nfs:vars] ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22
示例:
ansible nfs -m ping # -o:一行显示 ansible nfs -m ping -o
图
5)自定义主机列表文件
cat>hostlist<<EOF [web] 192.168.182.130 192.168.182.110 [mysql] 192.168.182.111 # 子分组 [nfs:children] web mysql # 对分组统一定义变量 [nfs:vars] ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22 EOF
示例:
# -i:指定主机列表文件 ansible -i hostlist nfs -m ping
图
七 Ansible 连接被控端方式
1)ssh 密钥
# 生成秘钥 ssh-keygen # 将秘钥拷贝到被管理服务器上 ssh-copy-id -i ~/.ssh/id_rsa.pub -p 22 root@192.168.182.130
2)账号密码
1、命令行配置
# -k:交互式 ansible -uroot -k 192.168.182.130 -m ping
2、配置文件中配置
# 默认主机配置文件:/etc/ansible/hosts 192.168.182.130 ansible_ssh_user=root ansible_ssh_pass=123456 [web] 192.168.182.130 ansible_ssh_user=root ansible_ssh_pass=123456
常用的配置参数
六 主要组成
1)ansible 命令执行来源
USER,普通用户,即system administrator
USER -> ansile playbook -> ansible
CMDB,(配置管理数据库)API调用
PUBLIC / PRIVATE CLOUD API调用
2)ansible 管理方式
Ad-Hoc,即ansible命令,主要用于临时命令使用场景
Ansible-playbook,主要用于长期规划好的,大型项目的场景,需要有前提的规划 ansible-playbook(剧本)执行过程: 将已有编排好的任务集写入ansible-playbook 通过ansible-playbook命令分拆任务集至逐条ansible命令,按预定规则逐条执行
3)ansible主要操作对象
HOSTS:主机
NETWORKING:网络设备
注意事项:
执行ansible的主机一般称为主控端,中控,master或堡垒机
主控端python版本需要在2.6或以上
被控端python版本小于2.4需要安装python-simplejson
被控端如开启SELinux需要安装libselinux-python
windows不能作为主控端
五 七大命令
概述
安装完ansible后,发现ansible一共为我们提供了七个指令:ansible、ansible-doc、ansible-galaxy、ansible-lint、ansible-playbook、ansible-pull、ansible-vault。这里我们只查看usage部分,详细部分可以通过 "指令 -h" 的方式获取。
1)ansible
ansible是指令核心部分,其主要用于执行ad-hoc命令,即单条命令。默认后面需要跟主机和选项部分,默认不指定模块时,使用的是command模块。不过默认使用的模块是可以在/etc/ansible/ansible.cfg 中进行修改的#module_name = command。
ansible 192.168.182.130 -a 'date'
2)ansible-doc
该指令用于查看模块信息,常用参数有两个-l 和 -s
#列出所有已安装的模块ansible-doc -l ansible-doc -l #查看具体某模块的用法,这里如查看command模块 ansible-doc -s command
3)ansible-playbook
ansible-playbook 命令是使用最多的指令,其通过读取playbook 文件后,执行相应的动作,这个后面会做为一个重点来讲。
4)ansible-galaxy
ansible-galaxy 指令用于方便的从https://galaxy.ansible.com/ 站点下载第三方扩展模块,我们可以形象的理解其类似于centos下的yum、python下的pip或easy_install 。
ansible-galaxy install aeriscloud.docker
5)ansible-lint
ansible-lint是对playbook的语法进行检查的一个工具。用法如下:
ansible-lint playbook.yml
6)ansible-pull
该指令使用需要谈到ansible的另一种模式,pull 模式,这和我们平常经常用的push模式刚好相反,其适用于以下场景:你有数量巨大的机器需要配置,即使使用非常高的线程还是要花费很多时间;你要在一个没有网络连接的机器上运行Anisble,比如在启动之后安装。
7)ansible-vault
ansible-vault 主要应用于配置文件中含有敏感信息,又不希望他能被人看到,vault可以帮你加密/解密这个配置文件,属高级用法。
主要对于playbooks里比如涉及到配置密码或其他变量时,可以通过该指令加密,这样我们通过cat看到的会是一个密码串类的文件,编辑的时候需要输入事先设定的密码才能打开。
这种playbook文件在执行时,需要加上 --ask-vault-pass参数,同样需要输入密码后才能正常执行。
四 安装与基础配置
安装
yum install epel-release
yum -y install ansible
ansible --version
执行图
配置
1)开启记录日志
配置文件:/etc/ansible/ansible.cfg
# 去掉前面的'#'号 #log_path = /var/log/ansible.log ==> log_path = /var/log/ansible.log
2)去掉第一次连接ssh ask确认
# 第一种(推荐) vi /etc/ansible/ansible.cfg # 其实就是把#去掉 # host_key_checking = False ==> host_key_checking = False # 第二种 vi /etc/ssh/ssh_config StrictHostKeyChecking ask ==> StrictHostKeyChecking no
执行图
playbook
一 概述
playbook 与 ad-hoc 相比,是一种完全不同的运用ansible的方式,类似与saltstack的state状态文件。ad-hoc无法持久使用,playbook可以持久使用。
playbook 是由一个或多个play组成的列表,play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。
从根本上来讲,所谓的task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联合起来按事先编排的机制完成某一任务。
参考文档:https://ansible-tran.readthedocs.io/en/latest/docs/playbooks.html
Ansible 的基础介绍和环境部署
图
二 核心元素
Hosts
执行的远程主机列表
Tasks
任务集
Varniables
内置变量或自定义变量在playbook中调用
Templates
模板,即使用模板语法的文件,比如配置文件等
Handlers
和notity结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
Tags
标签,指定某条任务执行,用于选择运行playbook中的部分代码。
三 语法
playbook 语法(yaml)
playbook使用yaml语法格式,后缀可以是yaml,也可以是yml。
YAML( /ˈjæməl/ )参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822,Clark Evans在2001年5月在首次发表了这种语言,另外Ingy döt Net与OrenBen-Kiki也是这语言的共同设计者。
YAML格式是类似JSON的文件格式。YAML用于文件的配置编写,JSON多用于开发设计。
1)YAML 介绍
1、YAML 格式如下
文件的第一行应该以“---”(三个连字符)开始,表明YAML文件的开始。
在同一行中,#之后的内容表示注释,类似于shell,python和ruby。
YAML中的列表元素以“-”开头并且跟着一个空格。后面为元素内容。
同一个列表之中的元素应该保持相同的缩进,否则会被当做错误处理。
play中hosts、variables、roles、tasks等对象的表示方法都是以键值中间以“:”分隔表示,并且“:”之后要加一个空格。
2、playbooks yaml配置文件解释
Hosts:运行指定任务的目标主机 remoute_user:在远程主机上执行任务的用户; sudo_user: tasks:任务列表 tasks的具体格式: tasks: - name: TASK_NAME module: arguments notify: HANDLER_NAME handlers: - name: HANDLER_NAME module: arguments ##模块,模块参数: 格式如下: (1)action: module arguments (2) module: arguments 注意:shell和command模块后直接加命令,而不是key=value类的参数列表 handlers:任务,在特定条件下触发;接受到其他任务的通知时被触发;
3、示例
--- - hosts: web remote_user: root tasks: - name: install nginx ##安装模块,需要在被控主机里加上nginx的源 yum: name=nginx state=present - name: copy nginx.conf ##复制nginx的配置文件过去,需要在本机的/tmp目录下编辑nginx.conf copy: src=/tmp/nginx.conf dest=/etc/nginx/nginx.conf backup=yes notify: reload #当nginx.conf发生改变时,通知给相应的handlers tags: reloadnginx #打标签 - name: start nginx service #服务启动模块 service: name=nginx state=started tags: startnginx #打标签 handlers: - name: reload service: name=nginx state=restarted
2)variables 变量
variables变量有四种定义方法。如下:
1、facts:可以直接调用
ansible中有setup模块,这个模块就是通过facts组件来实现的,主要是节点本身的一个系统信息,bios信息,网络,硬盘等等信息。这里的variables也可以直接调用facts组件的facters我们可以使用setup模块来获取,然后直接放入我们的剧本之中调用即可。
ansible web -m setup
图
常用的几个参数
ansible_all_ipv4_addresses # ipv4的所有地址 ansible_all_ipv6_addresses # ipv6的所有地址 ansible_date_time # 获取到控制节点时间 ansible_default_ipv4 # 默认的ipv4地址 ansible_distribution # 系统 ansible_distribution_major_version # 系统的大版本 ansible_distribution_version # 系统的版本号 ansible_domain #系统所在的域 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 web -m setup -a 'filter=*processor*'
图
2、用户自定义变量
自定义变量有两种方式
1.通过命令行传入
ansible-playbook命令行中的 -e VARS,--extra-vars VARS,这样就可以直接把自定义的变量传入
使用playbook定义变量,实例如下:
--- - hosts: web remote_user: root tasks: - name: install {{ rpmname }} yum: name={{ rpmname }} state=present - name: copy {{ rpmname }}.conf copy: src=/tmp/{{ rpmname }}.conf dest=/etc/{{ rpmname }}/{{ rpmname }}.conf backup=yes notify: reload tags: reload{{ rpmname }} - name: start {{ rpmname }} service service: name={{ rpmname }} state=started tags: start{{ rpmname }} handlers: - name: reload service: name={{ rpmname }} state=restarted
使用:
ansible-playbook nginx.yml -e rpmname=keepalived ansible-playbook nginx.yml --extra-vars rpmname=keepalived
2.在playbook中定义变量
##在playbook中定义变量如下: vars: - var1: value1 - var2: value2
使用:
--- - hosts: web remote_user: root vars: - rpmname: keepalived tasks: - name: install {{ rpmname }} yum: name={{ rpmname }} state=present - name: copy {{ rpmname }}.conf copy: src=/tmp/{{ rpmname }}.conf dest=/etc/{{ rpmname }}/{{ rpmname }}.conf backup=yes notify: reload tags: reload{{ rpmname }} - name: start {{ rpmname }} service service: name={{ rpmname }} state=started tags: start{{ rpmname }} handlers: - name: reload service: name={{ rpmname }} state=restarted
3、通过roles传递变量
4、 Host Inventory
可以在主机清单中定义,方法如下:
#向不同的主机传递不同的变量 IP/HOSTNAME varaiable=value var2=value2 #向组中的主机传递相同的变量 [groupname:vars] variable=value
3)流程控制
1、用when 来表示的条件判断
- hosts: web remote_user: root#代表用root用户执行,默认是root,可以省略 tasks: - name: createfile copy: content="test3" dest=/opt/p1.yml when: a=='3' - name: createfile copy: content="test4" dest=/opt/p1.yml when: a=='4'
如果a"3",就将“test3”,写入到web组下被管控机的/opt/p1.yml中, 如果a"4",就将“test4”,写入到web组下被管控机的/opt/p1.yml中。
执行
# 语法校验 ansible-playbook --syntax-check p1.yml #执行 ansible-playbook -e 'a="3"' p1.yml
2、标签(只执行配置文件中的一个任务)
- hosts: web tasks: - name: installnginx yum: name=nginx - name: copyfile copy: src=/etc/nginx/nginx.conf dest=/etc/nginx/nginx.conf tags: copyfile - name: start service: name=nginx static=restarted
执行
# 语法校验 ansible-playbook --syntax-check p2.yml #执行 ansible-playbook -t copyfile p2.yml
3、循环 with_items
创建三个用户
- hosts: web tasks: - name: createruser user: name={{ item }} with_items: - shy1 - shy2 - shy3 - name: creategroup group: name={{ item }} with_items: - group1 - group2 - group3
执行
#语法校验 ansible-playbook --syntax-check p3.yml #执行 ansible-playbook p3.yml
4、循环嵌套(字典)
用户shy1的属组是group1,用户shy2的属组是group2,用户shy3的属组是group3
- hosts: web tasks: - name: creategroup group: name={{item}} with_items: - group3 - group4 - group5 - name: createuser user: name={{item.user}} group={{item.group}} with_items: - {'user': shy3,'group': group3} - {'user': shy4,'group': group4} - {'user': shy5,'group': group5}
执行
#语法校验 ansible-playbook --syntax-check p4.yml #执行 ansible-playbook p4.yml
4)模板 templates
定义
模板是一个文本文件,嵌套有脚本(使用模板编程语言编写)
Jinja2是python的一种模板语言,以Django的模板语言为原本
该模板支持:
字符串:使用单引号或双引号; 数字:整数,浮点数; 列表:[item1, item2, ...] 元组:(item1, item2, ...) 字典:{key1:value1, key2:value2, ...} 布尔型:true/false 算术运算: +, -, *, /, //, %, ** 比较操作: ==, !=, >, >=, <, <= 逻辑运算: and, or, not
通常模板都是通过引用变量来运用的
示例
1、定义模板
user nginx; #设置nginx服务的系统使用用户 worker_processes {{ ansible_processor_vcpus }}; #工作进程数 error_log /var/log/nginx/error.log warn; #nginx的错误日志 pid /var/run/nginx.pid; #nginx启动时候的pid events { worker_connections 1024; #每个进程允许的最大连接数 } http { #http请求配置,一个http可以包含多个server #定义 Content-Type include /etc/nginx/mime.types; default_type application/octet-stream; #日志格式 此处main与access_log中的main对应 #$remote_addr:客户端地址 #$remote_user:http客户端请求nginx认证的用户名,默认不开启认证模块,不会记录 #$timelocal:nginx的时间 #$request:请求method + 路由 + http协议版本 #status:http reponse 状态码 #body_bytes_sent:response body的大小 #$http_referer:referer头信息参数,表示上级页面 #$http_user_agent:user-agent头信息参数,客户端信息 #$http_x_forwarded_for:x-forwarded-for头信息参数 log_format main '$http_user_agent' '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; #访问日志,后面的main表示使用log_format中的main格式记录到access.log中 access_log /var/log/nginx/access.log main; #nginx的一大优势,高效率文件传输 sendfile on; #tcp_nopush on; #客户端与服务端的超时时间,单位秒 keepalive_timeout 65; #gzip on; server { #http服务,一个server可以配置多个location listen {{ nginxport }}; #服务监听端口 server_name localhost; #主机名、域名 #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; #页面存放目录 index index.html index.htm; #默认页面 } #error_page 404 /404.html; # 将500 502 503 504的错误页面重定向到 /50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { #匹配error_page指定的页面路径 root /usr/share/nginx/html; #页面存放的目录 } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } include /etc/nginx/conf.d/*.conf; }
2、定义yaml编排
--- - hosts: web remote_user: root vars: - rpmname: nginx - nginxport: 8088 tasks: - name: install {{ rpmname }} yum: name={{ rpmname }} state=present - name: copy {{ rpmname }}.conf copy: src=/tmp/{{ rpmname }}.conf dest=/etc/{{ rpmname }}/{{ rpmname }}.conf backup=yes notify: reload tags: reload{{ rpmname }} - name: start {{ rpmname }} service service: name={{ rpmname }} state=started tags: start{{ rpmname }} handlers: - name: reload service: name={{ rpmname }} state=restarted
使用
##使用reloadnginx标签,重新加载剧本 ansible-playbook nginx.yml -t reloadnginx
copy与template的区别
copy模块不替代参数,template模块替代参数
template的参数几乎与copy的参数完全相同
5)handlers(触发事件)
notify:触发 handlers:触发的动作
使用上场景:修改配置文件时
【示例】 正常情况时handlers是不会执行的
- hosts: web tasks: - name: installredis yum: name=redis - name: copyfile template: src=redis.conf dest=/etc/redis.conf tags: copyfile notify: restart - name: start service: name=redis state=started handlers: - name: restart service: name=redis
执行
ansible-playbook -t copyfile p6.yml
6)roles
1、roles介绍与优势
一般情况下将roles写在/etc/ansible/roles中,也可以写在其他任意位置(写在其他位置要自己手动建立一个roles文件夹)
对于以上所有方式有个缺点就是无法实现同时部署web、database、keepalived等不同服务或者不同服务器组合不同的应用就需要写多个yaml文件,很难实现灵活的调用
roles用于层次性,结构化地组织playbook。roles能够根据层次结果自动装载变量文件、tasks以及handlers等。
要使用roles只需要在playbook中使用include指令即可。
简单来讲,roles就是通过分别将变量(vars)、文件(files)、任务(tasks)、模块(modules)以及处理器(handlers)放置于单独的目录中,并且可以便捷的include它们地一种机制。
角色一般用于基于主机构建服务的场景中,但是也可以用于构建守护进程等场景中。
2、目录结构
创建目录
mkdir -pv ./{nginx,mysql,httpd}/{files,templates,vars,tasks,handlers,meta,default}
图
roles/
mysql/:mysql服务的yml文件
httpd/:apached服务的yml文件
nginx/:nginx服务的yml文件
files/:存储由copy或者script等模块调用的文件或者脚本;
tasks/:此目录中至少应该有一个名为main.yml的文件,用于定义各个task;其他文件需要由main.yml进行包含调用;
handlers/:此目录中至少应该有一个名为main.yml的文件,用于定义各个handler;其他文件需要由main.yml进行包含调用;
vars/:此目录至少应该有一个名为main,yml的文件,用于定义各个variable;其他的文件需要由main.yml进行包含调用;
templates/:存储由templates模块调用的模板文件;
meta/:此目录中至少应该有一个名为main.yml的文件,定义当前角色的特殊设定以及依赖关系,其他文件需要由main.yml进行包含调用;
default/:此目录至少应该有一个名为main.yml的文件,用于设定默认变量;
3、实战操作
【1】创建目录
mkdir -pv ./{nginx,mysql,httpd}/{files,templates,vars,tasks,handlers,meta,default}
【2】定义配置文件
先下载nginx rpm部署包
# 下载地址:http://nginx.org/packages/centos/7/x86_64/RPMS/ wget http://nginx.org/packages/centos/7/x86_64/RPMS/nginx-1.18.0-1.el7.ngx.x86_64.rpm -O nginx/files/nginx-1.18.0-1.el7.ngx.x86_64.rpm
nginx/tasks/main.yml
- name: cp copy: src=nginx-1.18.0-1.el7.ngx.x86_64.rpm dest=/tmp/nginx-1.18.0-1.el7.ngx.x86_64.rpm - name: install yum: name=/tmp/nginx-1.18.0-1.el7.ngx.x86_64.rpm state=latest - name: conf template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf tags: nginxconf notify: new conf to reload - name: start service service: name=nginx state=started enabled=true
nginx/templates/nginx.conf.j2
user nginx; #设置nginx服务的系统使用用户 worker_processes {{ ansible_processor_vcpus }}; #工作进程数 error_log /var/log/nginx/error.log warn; #nginx的错误日志 pid /var/run/nginx.pid; #nginx启动时候的pid events { worker_connections 1024; #每个进程允许的最大连接数 } http { #http请求配置,一个http可以包含多个server #定义 Content-Type include /etc/nginx/mime.types; default_type application/octet-stream; #日志格式 此处main与access_log中的main对应 #$remote_addr:客户端地址 #$remote_user:http客户端请求nginx认证的用户名,默认不开启认证模块,不会记录 #$timelocal:nginx的时间 #$request:请求method + 路由 + http协议版本 #status:http reponse 状态码 #body_bytes_sent:response body的大小 #$http_referer:referer头信息参数,表示上级页面 #$http_user_agent:user-agent头信息参数,客户端信息 #$http_x_forwarded_for:x-forwarded-for头信息参数 log_format main '$http_user_agent' '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; #访问日志,后面的main表示使用log_format中的main格式记录到access.log中 access_log /var/log/nginx/access.log main; #nginx的一大优势,高效率文件传输 sendfile on; #tcp_nopush on; #客户端与服务端的超时时间,单位秒 keepalive_timeout 65; #gzip on; server { #http服务,一个server可以配置多个location listen {{ nginxport }}; #服务监听端口 server_name localhost; #主机名、域名 #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; #页面存放目录 index index.html index.htm; #默认页面 } #error_page 404 /404.html; # 将500 502 503 504的错误页面重定向到 /50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { #匹配error_page指定的页面路径 root /usr/share/nginx/html; #页面存放的目录 } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } include /etc/nginx/conf.d/*.conf; }
nginx/vars/main.yml
nginxport: 9999
nginx/handlers/main.yml
- name: new conf to reload service: name=nginx state=restarted
定义剧本文件(roles.yml)
- hosts: web remote_user: root roles: - nginx
最后的目录结构如下:
图
执行
ansible-playbook roles.yml
执行图