自动化运维之ANIBLE

  

Ansible介绍:

  ansible是一款基于python开发的自动化运维工具,用它可以实现批量部署,批量系统配置,批量运行命令等。但ansible本身没有批量部署的能力,它相当于一个框架,而在该框架由许许多多的模块完成批量任务。而且使用它无需安装代理(agent),因为他是基于ssh协议来远程通讯,目前已被红帽收购。

  官网:https://www.ansible.com/

Ansible特性:

  模块化:调用特定的模块完成特定的任务,而且也支持自定义模块(预留API)

  部署简单,基于python和SSH(默认已安装),无需代理(即不需要再被控端安装代理程序)

  安全:基于openssh

  有些模块具有幂等性(一个任务执行1遍和执行n遍效果一样),不因重复执行带来意外情况。

  支持playbook编排任务(yaml格式,支持丰富的数据结构(jinjia2))

  较强大的多层解决方案(role)

Ansible组成:

  inventory:ansible管理的主机清单(默认/etc/ansbile/hosts)

  modules:ansible执行命令的功能模块,多数为内置的核心模块,也可自定义

  plugins:模块功能的补充,如变量插件,过滤插件,循环插件等

  API:提供第三方程序调用的应用程序编程接口

Ansible的注意事项:

  执行ansible的主机一般称为管理端,主控端,中控,master等

  主控端python版本需要在2.6(或以上)

  被控端python版本小于2.4,需要安装python——simplejson

  windows不能作为主控端

Ansible安装:

  安装方式很多,如官网下载源码包。

  这里以centos8为例安装ansible(如果没有epel源,需要配置epel源)

  [root@localhost ~]# yum | dnf  install -y ansible

  如果时ubuntu系统:使用命令:apt -y install ansible

1.查看版本:

  rel系列:[root@localhost ~]# yum info ansible  或 [root@localhost ~]#  yum --version

  debian系列:apt show ansible

2.Ansible相关配置文件(提示:使用rpm -ql ansible命令即可查看生成所得的文件)

  /etc/ansible/ansible.cfg    主配置文件,主要是配置ansible的工作特性(如:加载的主机清单文件路径,加载模块文件的路径,是否需要记录日志,并行运行的主机数[forks]等)

  /etc/ansible/hosts:主机清单(该清单主要存放被管理的主机的ip地址,而且如果数量过多还可以分组配置管理)

  /etc/ansible/roles:存放角色的目录

2.1.1 /etc/ansible/ansible.cfg 文件一般修改的位置。(按需求修改,也可不该)

 #inventory   = /etc/ansible/hosts(可以改为自己定义的目录,如/data/ansible/hosts,注意:一定记得复制/etc/ansible/hosts/下的hosts文件至自己定义的目录下)

 #forks     = 5  (可以自定义数字,建议范围在10之内)

 #host_key_checking = False(检擦对应服务器的host_key,建议取消注释)

 #log_path=/var/log/ansible.log(日志文件,可自定义文件路径,建议取消注释)

 #module_name = command  (默认模块,建议修改为shell模块)

2.1.2 /etc/ansible/hosts (主机清单文件格式)

  inventory文件遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组
中。此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明

  例如:  

      [webservs]

      10.0.0.110  ansible_connection=local(指定本地连接,无需ssh配置)

      10.0.0.11[3:8]    表范围10.0.0.113-10.0.0.118

      10.0.0.112  ansible_connection=ssh  ansible_port=22 ansible_user=ldl ansible_password=123456

  

3. Ansible相关工具:

3.1  ansible-doc,显示模块的帮助信息,功能相当于man。

  格式:ansible-doc [OPTIONS] [MODULES]

  选项:

    -l ,--list: 列出可用模块

    -s,--snippet 显示指定模块的playbook片段 

  如:ansible-doc  -l 

    ansible-doc  ping

    ansible -s ping

3.2  ansible,此工具通过ssh协议,实现对远程主机的配置管理、应用部署、任务执行等功能

  3.2.1  格式:ansible <HOST_PATTERN> [-m MODULE_NAME] [- a args]

  选项:

    --version  显示版本

    -m module:指定模块,默认为command

    -v | -vv | -vvv:显示详细过程

    --list-hosts:显示主机列表

    -C,--check:检查,并不执行,相当于dry run

    -T,--TIMEOUT=TIMEOUT:执行命令的超时时间,默认为10s

    -k,--ask_pass  :提示输入ssh连接密码

    -u,--user=remote_user:远程执行命令的用户

    

   3.2.2  HOST_PATTERN:

    all:表示所有inventory中的所有主机(即定义在主机清单里的所有主机)

      例如:ansible all -m shell -a "wall hello,everyone"

    *:通配符

      例如:ansible “*” -m ping

         ansible 10.0.0.* -m ping

     或关系:用“:”连接,相当于取并集

      例如:ansible "dbsrv:websrv" -m ping

         ansible "10.0.0.111:172.16.0.100" -m ping

     与关系:用”:&“ 连接,相当于取交集

      例如:ansible "dbsrv:&websrv" -m ping

     非关系:用':!' 连接,相当于取反,而且使用时一定得注意patter必须使用单引号

      例如:ansible 'websrv:!dbsrv'  -m  ping    

       三种关系组合:

         例如: ansible 'websrv:!dbsrv:&appsrv'  -m  ping  

     正则表达式:注意,使用得是基本正则表达式,有些符号需要转义

        例如:ansible "~(web|db).*\.com"

          ansible ‘kube*:etcd:!10.0.0.112’ -a "wall hello word!"

  3.2.3  ansible命令执行过程

    a.加载机子得配置文件,默认为/etc/ansible/ansible.cfg

    b.加载自己对应模块文件,如:command,shell,copy...

    c.通过ansible将模块或命令生成对应得临时py文件,并将该临时py文件传输至被控端的对应执行用户的家目录下,

      且是隐藏文件。一般格式:$HOME/.ansible/tmp/ansible-tmp-随机数字/xxx.PY

    d.给该临时py文件执行权限

    e.执行后返回结果至控制端

    f.删除临时py文件,退出

  

  3.2.4 ansible 的执行状态。该状态是在控制端显示的。而且该执行状态的定义是在/etc/ansible/ansible.cfg文件中

    查看/etc/ansible/ansible.cfg文件中对执行状态的定义:

      grep -A 14 '\[colors\]' /etc/ansible/ansible.cfg

    一般常见的:

      绿色:执行成功,但不需要做改变操作

      黄色:执行成功,且对目标主机已做更改

      红色:执行失败,报错!

3.3  ansibel-console,此工具交互式执行命令,支持tab。是在ansible 2.0版本之后新加的

  3.3.1 提示符格式:

    执行用户@当前操作的主机组 (当前组的主机数量)[f:并发数]$

  

  3.3.2 常用子命令:

设置并发数:forks n   例如:forks 5

    切换组:cd 主机组  例如:cd web

    列出当前组的主机列表:list

    列出所有内置命令:?或help

3.4 ansible-vault,此工具可以用于加密解密yml文件。

  格式:ansible-valut [ create | descrypt | edit | encrypt |rekey |view ]  FILE.yml

    例如:ansible-valut  encrypt  install_http.yml              #加密

       ansible-vault decrypt install_http.yml                 #解密

       ansible-vault view  install_http.yml                     #查看

       ansible-vault edit  install_http.yml                      #编辑加密文件

       ansible-vault rekey  install_http.yml                  #修改口令

       ansible-vault create  install_http.yml                 # 创建新文件

4.ansible常用模块

  提示:使用:ansible-doc [-s] 模块名,即可查看模块的帮助信息

  4.1 ping模块,测试被控主机连通性,如果能通则返回“pong”

    例如:ansible dbsrv -m ping   #测试dbsrv组的主机是否能连通

  4.2 command模块,在远程主机上执行命令,此模块为默认模块,故可忽略-m选项

    注意:此模块不支持使用变量(变量引用),管道,重定向,命令连接符特殊符号等,如果要是有,可以是有shell模块

    注意:此模块不具有幂等性(当命令运行一次后,后续该命令无论运行多少次,结果都不会发送变法)。

    常用子选项:

      chdir:在执行命令之前,切换至指定目录。

        如:ansible dbsrv [-m command] -a "chdir=/etc/  cat issue"

      cmd:执行的具体命令。

        如:ansible dbsrv [-m command] -a "wall ''hello,word!"

      creates:判断,如果指定的文件存在,则后面的命令将不会执行

        如:ansible dbsrv [-m command] -a "chdir=/etc/  creates=/data/f1.txt cat issue"

      removes:与creats相反,如果指定的文件存在,则执行后面的命令。

        如:ansible dbsrv [-m command ] -a "removes=/etc/fatab wall 'hello everyone!'"

  4.3  shell模块,相当于command模块的升级版,支持各种符号。

    注意:此模块不具有幂等性。

    常用子选项:chdir,cmd,creates,removes等。

    范例:

      ansible dbsrv -m shell -a "echo $HOSTNAME"

      ansible dbsrv -m shell -a "hostname >/tmp/hostname.txt"

      ansible dbsrv -m shell -a "echo centos | passwd --stdin ldl"

      

      注意:向如下这种复杂的命令,有时shell模块执行也会报错,建议写到脚本中执行。

        ansible dbsrv -m shell -a "cat /tmp/test.md | awk -F'|' '{print $1,$2}' &> /tmp/example.txt"

  4.4 script模块,在被控端上运行控制端上的脚本,且该脚本无需执行权限。

    注意:此模块不具有幂等性。

    常用子选项:chdir,cmd,creates,removes等。

    范例:ansible dbsrv -m script -a "/data/install.httpd.sh"

  

  4.5  copy模块,把控制端上的文件复制到被控端上。

    不具有幂等性。

    常用子选项:

      backup=yes | no  :如果目标存在,默认是覆盖,如果加上次选项,则先备份。

      mode:设置复制到远程主机上后文件的权限

      owner:设置复制到远程主机上后文件的从属关系(属主属组关系)

        如:ansible dbsrv -m copy -a "src=/root/t.txt   dest=/tmp/test.sh   backup=yes" 

      src:要复制到远程服务器的文件的路径,可以是相对的,也可以是绝对的。

        如果src给定的是目录,则复制该目录下的所有内容至目标主机上。

          ansible dbsrv -m copy -a "src=/data/test/   dest=/data/"

        如果src给定的是目录,且目录没有以/结尾,则复制目录下的所有内容包括目录本身。

      dest:必选项,文件要复制到的远程主机上的路径,绝对路径。

        如果src是一个目录,则dest也必须是一个目录

        如果dest是一个不存在的路径,或则src是一个目录且以/j结尾,则创建

          范例:  ansible websrvs -m copy -a "src=/etc dest=/backup"  #注意src后面没有/,复制目录下的内容包括目录本身

               ansible websrvs -m copy -a "src=/etc/  dest=/backup"       #注意src后面有/,复制目录下的内容不包括目录本身           

      content:在指定复制过程中指定内容,并复制到目标主机上的某文件中

        ansible websrvs -m copy -a "content='test line1\ntest line2'  dest=/tmp/test.txt"

  

  4.6 fetch模块,从远程主机上提取文件至控制端,与copy相反,但不支持目录。

    不具有幂等性。

    常用子选项:

      src:必选项,指定远程主机上的文件的位置。

      dest:系选项,在控制端指定文件保存的位置。

      注意:该抓取过来的文件,会在控制端指定的目录下创建一个目录结构,该目录结构的一级目录是被控制端的ip或主机名,二级目录是被控端文件的源目录。

      ansible dbsrv -m fetch -a "src=/root/t1.sh   dest=/opt"

  

  4.7 file模块,设置远程主机上的文件的属性,创建软连接。

    常用子选项:

      owner,group,mode,recurse[递归]

      path:必选项,指定被管理的文件位置

      state:对文件执行的操作,absent[删除],touch[创建文件],directory[创建目录],link[创建链接]

      src,dest:只有创建链接时才会用到。表示对目标主机上的那个文件创建链接至那个位置

    范例:

        ansible dbsrv -m file -a "path=/data/test.sh state=touch"

        ansible dbsrv -m file -a "path=/data/test.sh state=absent"

        ansible dbsrv -m file -a "path=/data/test.sh owner=ldl mode=600"

        ansible dbsrv -m file -a "path=/data/mysql  state=directory" owner=mysql group=mysql"   #创建目录

        ansible dbsrv -m file -a "src=/data/file1 path=/data/file1-link state=link"     #创建软连接

        ansible dbsrv -m file -a "path=/data/mysql  state=directory" owner=mysql group=mysql recurse=yes"          #递归修改目录属性

  4.8 unarchive模块,解包。

    且有两中用法

      a. 将控制端的上压缩包传到运城主机后解压至特定目录,copy=yes,默认

      b. 将远程主机上的某个包解压到指定目录下,设置copy=no

    常用子选项:

      copy=yes|no

      remote_src=yes|no 功能根copy相似,yes表示在远程主机上

      src:源路径,可以是ansible主机上的路径,也可以是远程主机(被管理端或者第三方主机)上的路径,如果

          是远程主机上的路径,则需要设置copy=no

      dest:远程主机上的目标路径

      mode:设置解压缩后的文件权限

     范例:

      ansible all -m unarchive -a 'src=/data/foo.gz dest=/data owner=ldl group=ldl'

      ansible all -m unarchive -a 'src=/data/foo.gz dest=/opt copy=no'

      ansible websrvs -m unarchive -a 'src=https://releases.ansible.com/ansible/ansible-2.1.6.0-0.1.rc1.tar.gz  dest=/data/  owner=mysql remote_src=yes' (将网上的包下载并解压到目标主机上)

  

  4.9 archive模块,打包压缩远程主机上的文件

   常用子选项:

      path,owner,mode,group,dest

      format,指明压缩类型

    范例:ansible dbsrv -m archive -a "path=/var/log/ dest=/data/log.tar.bz2  format=bz2 mode=600"

  

  4.10 hostname模块,管理远程主机上的主机名

    常用子选项:name

    范例:ansible dbsrv -m hostname -a "name=dbsrv.ldl.org"  

  

  4.11  cron模块,在远程主机上做计划任务。  

      常用子选项:

        时间:hour,minute,weekday,mouth,day

        name:计划任务的名称

        job:计划任务具体,可以是脚本

        disabled =yes| on:计划任务的禁用与启用

        state=absent :删除计划任务

      范例:

         ansible websrvs  -m cron -a "minute=*/5 job='/usr/sbin/ntpdate ntp.aliyun.com

&>/dev/null' name=Synctime"   (定义计划任务)

        ansible websrvs  -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1

&>/dev/null' name=Synctime disabled=yes"  (禁用计划任务)

        ansible websrvs -m cron -a "name='backup mysql' state=absent" (删除计划任务)

  4.12 yum和apt模块,安装软件包

      常用子选项:

        name:软件包名称,如果有多个,用逗号隔开

        state=absent | present 卸载或安装,默认是安装

      范例:ansible dbsrv -m yum -a "name=httpd "

           ansible dbsrv -m yum -a "name=httpd,wget,vim,lrzsz "

         ansible dbsrv -m yum -a "name=httpd,wget,vim,lrzsz  state=absent"

  

  4.13 service模块,管理远程主机上的服务。

    常用子选项:

      name,enabled,state[started| stopped | restarted | reloaded ]

    范例:

      ansible all -m service -a 'name=httpd state=started enabled=yes'

      ansible all -m service -a 'name=httpd state=restarted '

  

  4.14 user模块:管理远程主机上的用户

    常用子选项:name,comment,uid,home,group,shell,system,remove(删除用户时是否删除用户的家目录),create_home(创建用户时是否创建用户的家目录)

    范例:ansible dbsrv -m user -a "name=appache uid=80 comment='appache user' home=/data/apache group=ldl"

        ansible dbsrv -m user -a "name=nginx uid=88 comment='nginx user' group=nginx system=no shell=/sbin/nologin create_home=no"

      ansible all -m user -a 'name=apache state=absent remove=yes'

  4.15 group模块,管理远程主机上的用户组信息

    常用子选项:gid,name,system,state

    范例:ansible dbsrv -m group -a "name=apache system=yes gid=80"

      ansible dbsrc -m group -a "name=apache state=absent"

  4.16  Lininfile 模块,替换远程主机上的某文件中的某字段。单行替换

    ansible在使用sed进行替换时,经常会遇到需要转义的问题,而且ansible子啊遇到特殊符号进行替换时,存在问题,如无正常进行替换。ansible提供了两个模块,lineinfile和replace。

    常用子选项:

      regexp:使用正则表达式匹配对应的行,当替换文本时,如果有多行都被匹配到,则只会有最后面被匹配到的那行文本才会被替换;当删除文本时,如果有多行文本都能被匹配,则,这些被匹配到的行都会被删除。

      path,state

      line:指定替换成的字段

    范例:

      ansible dbsrv -m lineinfile -a "path=/etc/httpd/conf/http.conf regexp='^Listen'  line='Listen 80' "

      ansible dbsrv -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX='  line='SELINUX=disaabled'"

      ansible dbsrv -m lineinfile -a "path=/eetc/fstab state=absent regexp='^#' "

  4.17 replace 模块,基于正则进行匹配和替换,多好替换

      常用子选项:

        regexp:使用正则表达式匹配对应的行,当替换文本时,如果有多行都被匹配到,则只会

          替换所有被匹配到的内容;当删除文本时,如果有多行文本都能被匹配,则,这些被匹配到的行都会被删除。

        path,state

        replace:替换成的字段,可以使用后向引用

      范例:

        ansible all -m replace -a "path=/etc/fstab regexp='^(UUID.*)' replace='#\1'"  (在匹配到的行的行首添加#号)

  4.18 setup模块,手机远程主机的系统信息,这些facts信息可以直接以变量的形式引用,如果远程主机较多的话会影响执行速度,如果不要收集远程主机的facts信息可将其禁止(gather_facts:no)

    常用子选项:

      filter:相当于定义变量存取远程主机的信息。

    范例:

     ansible all -m setup

     ansible all -m setup -a "filter=ansible_nodename"

     ansible all -m setup -a "filter=ansible_hostname"

     ansible all -m setup -a "filter=ansible_domain"

     ansible all -m setup -a "filter=ansible_memtotal_mb"

     ansible all -m setup -a "filter=ansible_memory_mb"

       ansible all -m setup -a "filter=ansible_memfree_mb"

       ansible all -m setup -a "filter=ansible_os_family"                   #去操作系统版本

       ansible all -m setup -a "filter=ansible_distribution_major_version"

       ansible all -m setup -a "filter=ansible_distribution_version"

       ansible all -m setup -a "filter=ansible_processor_vcpus"               #cpu核数

       ansible all -m setup -a "filter=ansible_all_ipv4_addresses"              #取ip地址

       ansible all -m setup -a "filter=ansible_architecture"

       ansible all -m setup -a "filter=ansible_uptime_seconds"

     ansible all -m setup -a "filter=ansible_processor*"

 

5.playbook介绍:

  palybook 剧本时有一个或多个play组成的列表

  paly的主要功能在于将预定义的一组主机,装扮成实现通过ansible中的task定义好的角色。

  task实际是调用ansible的一个modules,将多个play组织在一个playbook中可以让他们联合起来按事先编排的机制执行预定义的动作

  playbook是用yaml语言编写的

5.1 yaml语言

  是一个目前流行的(写配置文件),人易读的书写语言。可以基于流来处理,便于扩展和交互

  5.1.1 语法简介:

    在文件第一行,用三个连续的”-“ 符号表开始,有时候用三个”.“ 表示文件的结尾

    次行的开始正常写playbook的内容,一般建议写明该playbook的功能

    使用#注释代码

    缩进必须统一,不能空格和tab混用

    所进的级别必须一致,同样的缩进表示同样的级别

    YAML文件内容是区别大小写,k/v的值更是大小写敏感

    key后面冒号需要加一个空格 

    value可以是一个字符串,也可以是一个列表

    YAML文件的扩展名通常为yml或yaml

  

  5.2.2 yaml支持的数据类型:

    标量:单个的,不可再分的值

    对象:键值对的集合,又称字典,映射,哈希

    属组:一组按次序排列的值,又称序列或列表

  5.2.2.1  标量(scalar)

    key对应的value

    格式1:name: value

    格式2:name:

          value

    标量是最基本的,不可再分的值。

  

  5.2.2.2  字典(Dictionary)

    字典有多个k/v构成,k与v之间用:分割,而且:后面有一个空格。或写在一行 {}

    格式1:aaccount:  { name: ldl, age:20}

    格式2:account:

          name: ldl

          age:  20

  5.2.2.3 列表(list)

    列表有多个元素组成,每个元素放在不同行,且元素前均使用- 打头,并且- 后面有一个空格。或写在一行 []

    格式1:course:

          - linux

          - python

          -go

     格式2:[ linux, python, go ]    

5.3 palybook核心组件

  一个playbook中由列表组成,其中所用到的常见组类型如下:

    Hosts:执行的远程主机列表

    Tasks:任务集,由多个task的元素组成的列表实现,每个tasks是一个字典,一个完整的代码块功能最少需要

      元素包括name和task,一个name只能包括一个task

    variables:内置变量或自定义变量在playbook中调用

    templates 模板,可替换模板文件中的变量并实现一些简单拿的逻辑的文件

    handlers和notify结合使用,由特定的条件触发的操作,满足条件则执行,否则不执行

    tags标签,指定某任务执行,用于选择运行playbook中的部分代码,ansible具有幂等性,因此会自动跳过没有变化的

      部分,即便如此,有些代码为测试其确实没有发生变化的时间依然非常的长。此时如果确信没有发送变化,就可以通过tags跳过这些代码片段

  5.3.1  hosts组件

    playbook中的每一个play的目的都是为了让特定的主机以某指定的用户身份执行任务。hosts用于指定要执行的任务的主机,

      必须事先定义在清单中。

      例如:- hosts: websrv:appssrv

  5.3.2 remote_user 组件

    可用于hosts和task中,也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务。

      例如: 

    

  5.3.3 task列表和action组件

    play的主体部分是task list,task list中有一个或多个task,各个task按次序逐个在hosts中指定的主机上执行,即在所有主机上完成第一个task

      后,在开始第二个task。

    task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行有些具有幂等性。这就意味着,多次执行是安全的,结果一致

    每个task都应该尤其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤,如果未提供name,则action的结果将用于输出。

    task两种格式:

      action: module arguments

      module:  arguments

      注意:shell和command模块后跟命令,而非K=V

例如:

 

  5.3.4 handlers和notify

    handlers本质时task list,类似于mysql中的触发器触发的行为,其中的task与前诉的task并没有本质上的不同

    主要用于关注的资源发生变化时,才会采取一定的操作,而notify对应的action可用在每个play的最后被触发,这

    样可避免多次有改变发生时每次执行特定的操作,仅在所有的变化发生完成之后一次性的执行特定操作。在notify中

    列出的操作成为handlers,即notify中调用handler中定义的操作

   范例:

 

  5.3.5 playbook命令

    格式:ansible-playbook <filename.yml> ... [options]

    选项:

      --syntax-check:语法检查,相当于bash -n

      -C,--check:只检测可能发生的改变,但不真正执行操作。相当于dry run

      --list-hosts:列出运行任务的主机

      --list-tags:列出tag

      --limit  主机列表:只针对主机列表中的特定主机执行

      -v,-vv-,vvv:显示过程  

  5.3.6 playbook中使用tags组件

    在playbook文件中,可以利用tags组件,为特定task指定标签,当在执行playbook时,可以只执行特定

    tags的task,而非整个playbook

  范例:

   

[root@localhost ~]# ansible-playbook -t show test.yml

  5.3.7 playbook中使用变量

    变量:仅能有字母,数字和下划线组成,且只能以字母开头。

    变量定义:

      k=v

      如:port=80

    变量调用:

      通过{{ variable_name}}调用变量,有时变量前后需要空格

    变量来源:

      a. ansible的setup facts远程主机的所有变量都可以直接调用

      b. 通过命令行指定变量,优先级最高

        如:ansible-playbook -e varname=value test.yml

      c. 在playbook文件中定义

        如:

          vars:

           -  var1: value1

           -  var2: value2

           -  var3: value3

      d. 在独立的变量YAML文件中定义

        - hosts: all

          vars_file: 

            -  vars.yml

      e. 在/etc/ansible/hosts 中定义

        主机(普通)变量:主机组中主机单独定义,优先级高于公共变量

        组(公共)变量:针对主机组中所有主机定义统一变量

      f. 在role中定义

5.4.1  使用setup模块中的变量

  本模块自动在playbook中调用,不要使用ansible命令调用

  范例:ansible websrv -m setup -a "filter=ansible_default_ipv4"

     ansible websrv -m setup -a "filter=ansible_nodename" 

 

   

5.4.2 在playbook命令行中定义变量

  

  

 5.4.3 在playbook文件中定义变量

  

5.4.4 使用变量文件

  可以使用一个独立的playbook文件中定义变量,在另一个playbook文件中引用文件中的变量,而且使用变量文件定义的变量

  优先级比playbook中定义的变量高。

  

   

5.4.5 主机清单文件中定义变量

    5.4.5.1 主机变量

      在inventory 主机清单文件在为指定的主机定义变量以便于在playbook中使用

      如:

        [websrv]

        10.0.0.112  port=80 maxrequestsperchild=808

        10.0.0.119  prot=8080 maxrequestperchild=9090

     

     5.4.5.2 组(公共)变量

       在inventory主机清单文件中赋予给指定组内所有主机上的在playbook中可用的变量,如果组内定义的

       变量与主机变量同名,则使用主机变量

        如:

          [websrv]

          10.0.0.112 hname=www1 domain=ldl.org

          10.0.0.118 hname=www2 

          [websrv:vars]

          mark="-"

          domain=playbook.org

5.4.6  register 注册变量

  在playbook中可以是使用register将捕获命令的输出保存在临时变量中,然后使用debug模块进行显示输出。

  

   

  

 

5.5 template模板:

  模板是一个文本文件,可作为生成文件的模板,并且模板文件中可以嵌套jinja语法

jinja2语言:

  官网:http://jinja.pocoo.org/

  字面量,如字符串:使用单引号或双引号;数字:整数,浮点数

  列表:[item1,item2,...]

  元组:(item1,item2)

  字典:{key1: value1, key2: value2...}

  布尔型:true/false

  算术运算:+,-,*,/,//[整除],%,**[次方]

  比较操作符:==,!=,>,<,<=,>=

  逻辑运算:and or not

  流表达式:for,if,when

template功能:可以根据和参考模块文件,动态生成类似的配置文件。

  注意:template文件必须妇女防御templates目录下,且命令为.j2j结尾

  yml/yml文件需要和template目录平级。目录结构如下  

    ./
    ├── temnginx.yml
    └── templates
    └── nginx.conf.j2

 范例1:利用template同步nginx配置文件

  

 范例2:算术运算

  

 范例三:template中使用流程控制for和if

  

   

 5.6  playbook使用when

  when语句,可以实现条件测试,如果需要根据变量,facts或此前任务的执行结果来作为某task执行与

  否的前提时要用到条件测试,通过在task后添加when自居即可使用条件测试。

  范例:判断操作系统版本

5.7 playbook使用迭代with_items

  迭代:当有需要重复执行的任务时,可使用迭代机制。

  对迭代项引用,固定内置变量名为“item”

  要在task中使用with_items给定要迭代的元素列表

  列表元素格式:

    字符串

    字典

  范例1 :

5.7.1 迭代嵌套子变量

  在迭代中,还可以嵌套子变量,关联多个变量在一起使用

  范例:

5.8 管理节点过多导致超时问题解决方法

  默认情况下,ansible将尝试并行管理playbook中所有机器,对于滚动更新用例,可以使用serial关键

  定义ansible一次应管理多少主机,还可以将serial关键字指定为百分比,表示每次并行执行的主机数

  占总数的比例

范例1:

 范例2

   

6. roles 角色

  角色时ansible自1.2版本引入的新特性,用于层次化,结构化的组织playbook。roles能够根据层次型结构自动装载变量文件

  task以及handlers等。要使用roles只需在playbook中使用include指令即可。简单来讲,roles就是通过将变量,文件,任务,模板及处理器

  放置于单独的目录中,并可以便捷的include它们的一种机制。

  

  roles: 多个角色的集合目录,可以将多个roles,分别放至roles目录下的独立目录中。

    如:      

      roles/
        mysql/
        nginx/
        tomcat/
        redis/

   默认roles存放路径:   

    /root/.ansible/roles
    /usr/share/ansible/roles
    /etc/ansible/roles

  roles目录结构:

    playbook.yml

      roles/

        project/

        files/

        vars/

        templaate/  

        handlers/

        default/

        meta/

6.1 roles个目录作用:

      roles/project/ : 项目名称,有一下子目录

        files/:存放有copy或script模块等调用的文件

        templates/:template模块查找所需要模板文件的目录

        tasks/:定义task,roles的基本元素,至少应该包含一个名为main.yml的文件;其他的文件需要在此文件

          中通过include进行包含

        handlers/:至少应该包含一个main.yml的文件,此目录下的其他的文件需要在次文件通过include进行包含

        vars:定义变量,至少应该包含一个名为main.yml的文件,此目录下的其他的变量需要在次文件通过include进行包含

        meta/:定义当前角色的特殊设定及依赖关系,至少应该包含一个名为main.yml的文件;其他的文件需要在此文件

          中通过include进行包含

        default/:设定默认变量时使用此目录中的main.yml文件,比vars的优先级低

6.1.2  创建role的步骤:      

    1 创建以roles命名的目录
    2 在roles目录中分别创建以各角色名称命名的目录,如mysql等
    3 在每个角色命名的目录中分别创建files、handlers、tasks、templates和vars等目录;用不到的目
      录可以创建为空目录,也可以不创建
    4 在每个角色相关的子目录中创建相应的文件,如 tasks/main.yml,templates/nginx.conf.j2
    5 在playbook文件中,调用需要的角色

  

  范例:roles的i结构目录 

      nginx-role.yml
        roles/
        └── nginx
            ├── files
            │  └── main.yml
            ├── tasks
            │         ├── groupadd.yml
            │         ├── install.yml
            │         ├── main.yml
            │         ├── restart.yml
            │         └── useradd.yml
            └── vars
                └── main.yml

6.1.3 playbook调用角色方法:

  范例1:  

    ---

    - hosts: websrvs
      remote_user: root
         roles:
         -  mysql
         -  memcached
      -  nginx

  范例二: (键role用于指定角色名称,后续的k/v用于传递变量给角色)

    ---
    - hosts: all
      remote_user: root
       roles:
       - mysql
             - { role: nginx, username: nginx }

  范例三:(还可基于条件测试实现角色调用)   

    ---
    - hosts: all
       remote_user: root
     roles:
       - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' }

6.1.4 roles中使用tags  

  [root@ansible ~]#vi app-role.yml
    ---
    - hosts: appsrvs
       remote_user: root
     roles:
        - { role: nginx ,tags: [ 'nginx', 'web' ] ,when:
        ansible_distribution_major_version == "6" }
        - { role: httpd ,tags: [ 'httpd', 'web' ] }
        - { role: mysql ,tags: [ 'mysql', 'db' ] }
        - { role: mariadb ,tags: [ 'mariadb', 'db' ]


      

  

 

     

    

  

    

 

      

      

 

    

        

         

          

   

    

  

    

        

        

      

    

      

    

 

    

  

    

  

      

  

一如IT深似海,从此妹子是路人; 只要学不死,就往死里学;
原文地址:https://www.cnblogs.com/ldlx/p/14456373.html