zoukankan      html  css  js  c++  java
  • Ansible教程

    1. Ansible Inventory配置及详解

    提示:本文所有示例使用Inventory文件基于以下内容:
    [java1]
    172.16.12.168
    [java2]
    172.16.12.149
    [tomcat]
    172.16.12.149
    172.16.12.168
    Inventory是Ansible管理主机信息的配置文件,相当于系统HOSTS文件的功能,默认存放在/etc/ansible/hosts。在使用时可以加-i或--inventory-file来指定读取Inventory配置文件。

    ansible - i/etc/ansible/hosts webs -m ping
    

    如果只有一个Inventory文件,可以不指定路径,默认读取/etc/ansible/hosts,生产中为了方便,可能会有多个Inventory文件,这时可以通过-i来指定使用那个文件。

    1.1 定义主机和组

    Inventory配置文件是INI文件风格,中括号中的字符为组名。同一个主机可以同时属于不同的组。同时,如果目标主机使用了非默认ssh端口,也可以在主机名称之后来表明端口。

    cat /home/yangrz/ansible/hosts
    # #开头的行表示注释,
    # 可以直接为ip地址
    192.168.30.22
    # 也可以是域名的方式,后跟冒号加端口,表示ssh连接此机器的端口
    yunv.yangrz.com:8022
    test.xiaoxiaoneng.cn
    # 中括号内的内容表示一个分组,它下边的主机都属于这个组,空行后的主机也是这个组(192.168.12.168也属于java1)。
    [java1]
    172.16.12.168
    
    192.168.12.6
    [java2]
    172.16.12.149
    setting[11:20].test.com #表示11-20之间的数字,即表示:setting11.test.com  setting12.test.com .. setting20.test.com
    web-[b:f].test.com      #表示b-f,即:web-b.test.com   web-c.test.com web-d.test.com web-e.test.com web-f.test.com
    

    1.2 定义主机变量

    工作中,通常会遇到非标准化的需求配置,比如我们会修改ssh的端口,修改web服务的端口等,这时我们可以在定义主机的时候添加变量,以便在之后的palybook中使用。

    [webserver]
    web1.test.com http_port=8090
    

    1.3 定义主机组变量

    当大量机器需要自定义相同的变量时,比如ssh端口都是8022,我们可以采用定义主机组变量的方式。定义组变量,则相当于给这个组下边所有主机都赋予这一变量。

    [dbserver]
    db1.test.com
    db2.test.com
    
    [dbserver:vars]
    ntp_server=ntp.test.com #定义主机组dbserver组中所有主机ntp_server的值为ntp.test.com
    

    1.4 定义组嵌套及组变量

    主机组中可以包含其他的组,并且可以向组中的主机指定变量,不过这些变量只能在Ansible-playbook中使用。

    [apache]
    apache1.test.com
    apache2.test.com
    
    [nginx]
    nginx1.test.com
    nginx2.test.com
    
    [webserver]
    apache
    nginx
    
    [webserver:vars]
    ntp_server=ntp.magedu.com
    

    1.5主机和群组变量:在各自文件中配置

    如果管理的主机不多,将主机和群组的变量放到inventory文件中是合理的。但随着inventory文件变得越来越大,再使用这种方式就难于管理。
    为了更溜的玩儿转变量,我们来研究一下另一种方式:
    Ansible会在名为host_vars的目录中寻找主机变量文件,在名为group_vars的目录中寻找群组变量文件。
    例:
    我在/home/yangrz/下执行playbook:/home/yangrz/nginx.yml,那么我会把nginx.test.com主机的变量存放在/home/yangrz/host_vars/nginx.test.com文件中,把webservers组的变量存放在/home/yangrz/group_vars/webservers中。这样在执行playbook的时候就会调用主机和组文件中定义的变量。

    1.6变量生效顺序说明

    变量除了可以在Inventory中定义,也可以独立于Inventory文件之外,单独存储到YAML格式的配置文件中,这些文件通常以.yml、.yaml、.json为后缀或无后缀。变量通常从如下四个文件中检索(从上到下优先级由高到低):
    1、Inventory配置文件(默认/etc/ansible/hosts)
    2、Playbook中vars定义的区域
    3、Roles中vars目录下的文件
    4、Roles同级目录group_vars和hosts_vars目录下的文件
    假如nginx01同属于webserver组和nginx组,那么其变量在以下文件中都有效:
    /etc/ansible/group_vars/webserver
    /etc/ansible/group_vars/nginx
    /etc/ansible/host_vars/nginx01
    对于变量的读取,ansbile遵循优先级顺序,因此为方便维护,大家设置变量尽量采用同一种方式。

    1.7 ansible与正则

    Asible的Patterns功能等同于正则表达式,语法使用与正则也差不多,极大方便日常的使用。
    ansible < pattern_goes_here > -m < module_name> -a < arguments>
    正则可用来匹配Inventory中设置的主机和主机组。
    (1)All(全量)匹配
    匹配所有主机,all或*号功能相同。检测所有主机是否存活:

    ansible all -m ping
    ansible * -m ping
    

    检查192.168.1.0/24网段所有机器是否存活:

    ansible 192.168.1.* -m ping
    

    (2)逻辑或(or)匹配
    如果我们希望同时对多个主机或者组进行操作,相互之间用“:”冒号来分割即可。
    web1:web2

    ansible "web1:web2" -m ping
    ansible "java2:java1" -m ping
    

    (3)逻辑非(!)匹配
    逻辑非用!感叹号表示,主要针对多重条件的匹配规则。

    #所有在webservers组但不在nginx组的主机
    webservers:!nginx
    ansible tomcat:!java1 -m ping
    

    (4)逻辑与(&)匹配
    和逻辑非一样,只不过逻辑与是判断同时存在的机器。

    #所有在webservers组和nginx组同时存在的主机
    webservers:&nginx
    ansible "tomcat:&java1" -m ping
    

    (5)多条件组合
    这种情况不常用,了解即可

    #webservers和dbservers两个组中所有主机在staging组中存在切在phoenix组中不存在的主机
    webservers:dbservers:&staging:!phoenix
    

    (6)模糊匹配
    *通配符在Ansible中表示0个或多个任意字符,主要应用于一些模糊匹配规则,在平时使用频率非常高

    #所有以test.com结尾的主机
    *.test.com
    #setting开头,.com结尾的所有主机和在webservers中的所有主机
    setting*.test.com:webservers
    ansible 172.16.* -m ping
    

    (7)域切割
    Ansible底层基于Python,因此也支持域切割。Python字符串切割:

    str = '12345678'
    print str[0:1]
    

    通过[0:1]可以获取数值1.这个功能在Ansible中也支持。

    [webservers]
    web01
    web02
    web03
    webservers[0]     # ==  web01
    webservers[-1]    # == web03
    webservers[0:1]  # == web01  web02
    webservers[1:]    # == web01 web02
    ansible tomcat[-1] -m ping
    

    (8)正则匹配
    Ansible同样支持正则匹配功能,"~"开始表示匹配正则

    ~[web|db].*.test.com
    

    检测yangrz.test.com yangrz.test.org dididi.test.com setting.test.org可以使用如下正则:

    ansible "~(yangrz|dididi|setting).test.(com|org)" -m ping
    ansible "~172.16.12.1[1-9]{2}" -m ping  
    

    正则作为运维必备技能,与ansible结合更显灵活,功能愈发强大。

    2. Ansible AD-Hoc

    2.1 使用场景

    Ad-Hoc,其实就是“临时命令”,ansible提供了两种完成任务的方式:一种是AD-Hoc临时命令,另一个中ansible-playbook,前者是用来完成一些简单或临时遇到的一些任务,Ansible-playbook则更适合于解决复杂或需固化下来的任务。
    比如临时查看各个主机的系统信息,临时更新nginx的配置文件等这些临时性的,简单的工作使用Ad-Hoc即可。

    2.2 Ad-Hoc命令介绍

    ansible < host-pattern > [option]
    可用选项:

    • -v, --verbose:输出更详细的执行过程,-vvv输出执行过程中所有信息。
    • -i PATH, --inventory=PATH:指定inventory信息,默认/etc/ansible/hosts
    • -f NUM,--forks=NUM:并发线程数,默认5个线程
    • --private-key=PARIVATE_KEY_FILE:指定密钥文件
    • -m NAME,--module-name=NAME:指定执行使用的模块
    • -a ‘ARGUMENTS’,--args='ARGUMENTS':模块参数
    • -k,--ask-pass SSH:认证密码(此处把公钥删除,测试:ansible java1 -k -m ping)
    • -K, --ask-sudo-pass sudo:用户的密码(--sudo时使用)
    • -t DIRECTORY, --tree=DIRECTORY:输出信息至DIRECTORY目录下,结果文件以远程主机命名。
    • -T SECONDS, --timeout=SECONDS:指定连接远程主机的最大超时时间,单位是秒。
    • -B NUM,--background=NUM:后台执行命令,超NUM秒后终止正在执行的任务。
    • -P NUM,--poll=NUM:定期返回后台任务进度
    • -u USERNAME,--user=USERNAME:指定远程主机以USERNAME运行命令
    • -c CONNECTION,--connection=CONNECTION:指定连接方式,可用选项paramiko(SSH)、ssh、local,local方式常用于crontab和kickstarts
    • -l SUBSET,--limit=SUBSET:指定运行主机
    • -l REGEX,--limit=REGEX:指定运行主机(正则)
      示例一:检查tomcat组所有主机是否存活
    ansible tomcat -m ping
    172.16.12.149 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    172.16.12.168 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    

    说明:172.16.12.149是命令执行的主机,SUCCESS表示命令执行成功
    ">>{}"表示详细返回结果如下。“changed”:false,表示没有对主机进行更改,“ping”:“pong”,表示执行了ping命令返回结果为pong

    示例二:返回tomcat组所有主机的hostname,并打印最详细的执行过程到标准输出

    Using /etc/ansible/ansible.cfg as config file
    Using module file /usr/lib/python2.7/site-packages/ansible/modules/core/commands/command.py
    <172.16.12.168> ESTABLISH SSH CONNECTION FOR USER: None
    <172.16.12.168> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r 172.16.12.168 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142 `" && echo ansible-tmp-1489305897.26-115031391369142="` echo $HOME/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142 `" ) && sleep 0'"'"''
    <172.16.12.168> PUT /tmp/tmpKS3MN3 TO /root/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142/command.py
    <172.16.12.168> SSH: EXEC sftp -b - -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r '[172.16.12.168]'
    <172.16.12.168> ESTABLISH SSH CONNECTION FOR USER: None
    <172.16.12.168> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r 172.16.12.168 '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142/ /root/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142/command.py && sleep 0'"'"''
    <172.16.12.168> ESTABLISH SSH CONNECTION FOR USER: None
    <172.16.12.168> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r -tt 172.16.12.168 '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142/command.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142/" > /dev/null 2>&1 && sleep 0'"'"''
    172.16.12.168 | SUCCESS | rc=0 >>
    ansible-server
    
    Using module file /usr/lib/python2.7/site-packages/ansible/modules/core/commands/command.py
    # 调用command模块
    <172.16.12.168> ESTABLISH SSH CONNECTION FOR USER: None
    <172.16.12.168> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r 172.16.12.168 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142 `" && echo ansible-tmp-1489305897.26-115031391369142="` echo $HOME/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142 `" ) && sleep 0'"'"''
    # 生成目录用于存放Ansible远程执行脚本
    <172.16.12.168> PUT /tmp/tmpKS3MN3 TO /root/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142/command.py
    # 改名临时脚本,并存至临时目录
    <172.16.12.168> SSH: EXEC sftp -b - -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r '[172.16.12.168]'
    <172.16.12.168> ESTABLISH SSH CONNECTION FOR USER: None
    <172.16.12.168> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r 172.16.12.168 '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142/ /root/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142/command.py && sleep 0'"'"''
    <172.16.12.168> ESTABLISH SSH CONNECTION FOR USER: None
    <172.16.12.168> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r -tt 172.16.12.168 '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142/command.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1489305897.26-115031391369142/" > /dev/null 2>&1 && sleep 0'"'"''
    #以python脚本方式执行命令
    172.16.12.168 | SUCCESS | rc=0 >>
    ansible-server
    #命令返回结果
    

    命令流程执行图:
    enter image description here

    示例三:列出tomcat组所有主机列表:

    ansible tomcat --list
      hosts (2):
        172.16.12.149
        172.16.12.168
    

    有时候不确定主机组中有哪些机器时,可以使用这种方式查看。
    示例四:批量查看tomcat组所有主机的磁盘容量(command模块)

    ansible tomcat -m command -a 'df -h'
    172.16.12.149 | SUCCESS | rc=0 >>
    文件系统                 容量  已用  可用 已用% 挂载点
    /dev/mapper/centos-root   18G  1.5G   17G    9% /
    devtmpfs                 479M     0  479M    0% /dev
    tmpfs                    489M     0  489M    0% /dev/shm
    tmpfs                    489M   26M  464M    6% /run
    tmpfs                    489M     0  489M    0% /sys/fs/cgroup
    /dev/sda1                497M  123M  375M   25% /boot
    tmpfs                     98M     0   98M    0% /run/user/0
    
    172.16.12.168 | SUCCESS | rc=0 >>
    文件系统                 容量  已用  可用 已用% 挂载点
    /dev/mapper/centos-root   18G  7.4G   11G   43% /
    devtmpfs                 479M     0  479M    0% /dev
    tmpfs                    489M  136K  489M    1% /dev/shm
    tmpfs                    489M   51M  439M   11% /run
    tmpfs                    489M     0  489M    0% /sys/fs/cgroup
    /dev/sda1                497M  151M  347M   31% /boot
    tmpfs                     98M     0   98M    0% /run/user/0
    s3fs                     256T     0  256T    0% /data/ntalker/minioss
    
    # rc=0表示命令返回结果,返回码为0,表示命令执行成功。
    

    示例五:批量查看远程主机内存使用情况(shell模块)

    ansible tomcat -m shell -a 'free -m'
    172.16.12.149 | SUCCESS | rc=0 >>
           total        used        free      shared  buff/cache   available
    Mem:    977         212         107          25         657         553
    Swap:   2047         0          2047
    
    172.16.12.168 | SUCCESS | rc=0 >>
    	  total        used    free      shared  buff/cache   available
    Mem:   977         409      73          22         494        342
    Swap:  2047        63      1984
    

    2.3 Ad-Hoc了解Ansible的模块使用

    Ansible的help说明工具:ansible-doc,直接按回车或输入-h显示功能用法。

    ansible-doc [option]   [module...]
    常用选项:
    --version: 显示工具版本号
    -h,--help:显示该help说明
    -M MODULE_PATH,--module-path=MODULE_PATH:指定Ansible模块的默认加载目录
    -l,--list:列出所有可用模块
    -s,--snippet:只显示playbook说明的代码段
    -v:等同于--version,显示版本号
    

    查看YUM模块用法:

    > YUM
    
      Installs, upgrade, removes, and lists packages and groups with the `yum' package manager.
    
    Options (= is mandatory):
    
    - conf_file
            The remote yum configuration file to use for the transaction.
            [Default: None]
    # 其他的模块查看方式与YUM一样,想使用时查看即可。
    

    YUM模块安装举例:
    java1安装ntp服务

    172.16.12.168 | SUCCESS => {
        "changed": true, 
        "msg": "", 
        "rc": 0, 
        "results": [
            "Loaded plugins: fastestmirror
    Loading mirror speeds from cached hostfile
     * base: mirrors.btte.net
     * epel: mirrors.aliyun.com
     * extras: mirrors.tuna.tsinghua.edu.cn
     * updates: mirrors.tuna.tsinghua.edu.cn
    Resolving Dependencies
    --> Running transaction check
    ---> Package ntp.x86_64 0:4.2.6p5-25.el7.centos.1 will be installed
    --> Processing Dependency: ntpdate = 4.2.6p5-25.el7.centos.1 for package: ntp-4.2.6p5-25.el7.centos.1.x86_64
    --> Processing Dependency: libopts.so.25()(64bit) for package: ntp-4.2.6p5-25.el7.centos.1.x86_64
    --> Running transaction check
    ---> Package autogen-libopts.x86_64 0:5.18-5.el7 will be installed
    ---> Package ntpdate.x86_64 0:4.2.6p5-25.el7.centos will be updated
    ---> Package ntpdate.x86_64 0:4.2.6p5-25.el7.centos.1 will be an update
    --> Finished Dependency Resolution
    
    Dependencies Resolved
    
    ================================================================================
     Package             Arch       Version                       Repository   Size
    ================================================================================
    Installing:
     ntp                 x86_64     4.2.6p5-25.el7.centos.1       updates     547 k
    Installing for dependencies:
     autogen-libopts     x86_64     5.18-5.el7                    base         66 k
    Updating for dependencies:
     ntpdate             x86_64     4.2.6p5-25.el7.centos.1       updates      85 k
    
    Transaction Summary
    ================================================================================
    Install  1 Package  (+1 Dependent package)
    Upgrade             ( 1 Dependent package)
    
    Total download size: 699 k
    Downloading packages:
    Delta RPMs disabled because /usr/bin/applydeltarpm not installed.
    --------------------------------------------------------------------------------
    Total                                              235 kB/s | 699 kB  00:02     
    Running transaction check
    Running transaction test
    Transaction test succeeded
    Running transaction
      Updating   : ntpdate-4.2.6p5-25.el7.centos.1.x86_64                       1/4 
      Installing : autogen-libopts-5.18-5.el7.x86_64                            2/4 
      Installing : ntp-4.2.6p5-25.el7.centos.1.x86_64                           3/4 
      Cleanup    : ntpdate-4.2.6p5-25.el7.centos.x86_64                         4/4 
      Verifying  : ntp-4.2.6p5-25.el7.centos.1.x86_64                           1/4 
      Verifying  : autogen-libopts-5.18-5.el7.x86_64                            2/4 
      Verifying  : ntpdate-4.2.6p5-25.el7.centos.1.x86_64                       3/4 
      Verifying  : ntpdate-4.2.6p5-25.el7.centos.x86_64                         4/4 
    
    Installed:
      ntp.x86_64 0:4.2.6p5-25.el7.centos.1                                          
    
    Dependency Installed:
      autogen-libopts.x86_64 0:5.18-5.el7                                           
    
    Dependency Updated:
      ntpdate.x86_64 0:4.2.6p5-25.el7.centos.1                                      
    
    Complete!
    "
        ]
    }
    

    172.16.12.168: 表示命令执行的对象(在哪台机器上执行的)
    SUCCESS:表示命令执行的状态为成功状态
    ”changed": true: 主机是否有变更,true为有,false为没有
    "msg": "":安装过程信息
    "rc": 0: 表示命令执行状态码为0.

    启动ntp服务,并设置为开机启动

    ansible java1 -m service -a 'name=ntpd state=started enabled=yes'
    

    通过--limit来指定特定主机变更

    ansible tomcat -m command -a 'service ntpd status' --limit "172.16.12.149"
    

    3. playbook

    简介
    Ansible使用YAML语法描述配置文件,Ansible的任务配置文件被称为playbook(剧本),每一个剧本(playbook)中都包含一系列的任务,这每个任务在Ansible中又被称为“戏剧”(play)。一个playbook中可以包含多个play。
    一个简单palybook范例

    ---
    # 选择主机
    - hosts: webservers
    # 变量
    vars:
            http_port: 80
            max_clients: 200
    #远端的执行权限
            remote_user: root
    task:
    #利用yum模块来操作
        - name: ensure apache is at the latest version
    yum: pkg=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
    service: name=httpd state=started
    # 这里的restart apache和上面的触发是配对的。这就是handler的作用。只有notify=restart apache的时候handler下的设置才会生效。
    handlers:
        - name: restart apache
    service: name=httpd state=restarted
    

    playbook具有如下特性:
    1、以---开始,需在行首写
    2、次行开始写playbook的具体内容,但建议写明playbook的功能。
    3、 使用#号注释。
    4、 缩进必须统一,不能将空格和tab混用
    5、 缩进的级别必须统一,同样的缩进代表同样的级别,程序判断配置的级别是通过
    缩进和换行来实现的。
    6、YAML文件内容和Linux系统大小写判断方式一直,区别大小写。
    7、 k/v值可同行写,也可换行写。同行使用:分割,换行写需要以-分割。
    8、 一个name只能包含一个task。

    Cowsay:

     ______________________
    < TASK [playbook_test] >
     ----------------------
               ^__^
               (oo)\_______
                (__)       )/
                    ||----w |
                    ||     ||
    

    如果你的系统安装了cowsay程序,ansible的输出将会变成上图所示,如果想关闭,可以通过在ansible.cfg中添加如下一行:

    [default]
    nocows = 1
    
    - hosts: all #选择要执行的主机,与ansible-doc选择主机一样
      remote_user: root   #选择执行的用户
      gather_facts: False   #不获取主机信息,提高效率
      vars:           # vars定义变量,与定义shell脚本变量一样,不同的是此处需使用{{ var name }}方式调用
      - package: httpd
      - service: httpd
      tasks:   #开始任务
      - name: Install SELinux-python    #一段注释用来描述这个play是做什么的。ansible将会在这个play运行时将这段文字打印出来。
        yum: name=libselinux-python state=latest   #通过模块来执行操作
      - name: Install Apache Httpd
        yum: name={{package}} state=latest
        when: ansible_distribution == "CentOS"   #when 判断条件,只有为true时才执行
      - name: Update Conf File
        copy: src=conf/httpd.conf dest=/etc/httpd/conf/httpd.conf 
        notify:           # notify表示当前任务执行后要执行handlers中定义的指定名称的任务,
        - restart_httpd
      - name: Start Server
        service: name={{service}} state=started
      - name: Add Several Users
        user: name={{ item.user }} state=present groups={{ item.groups }}
        with_items:   #循环,上面的item为固定写法,引用with_items中的变量
          - { name: "didi", groups: "school" }
          - { name: "laowang", groups: "home" }
      handlers:
      - name: restart_httpd  # 复制完配置文件后,重启服务
        service: name={{service}} state=restarted
    

    详解:
    play:
    playbook就是由一组playbook列表。
    每个play必须包括下边两项:

    • host:需要执行任务的主机
    • task:需要再这些主机上执行的任务
      play就可以想象成连接到host上去执行task的事物。

    name: 一段注释,用来描述这个play是做什么的。ansible将会在这个play运行时将这段文字打印出来。虽不是必须写,但建议配置它们,因为它们对我们了解每一个任务的作用有很好的帮助。
    vars:定义变量,可以再playbook中通过{{ VARS }}方式来调用。

    yum: name=nginx state=latest
    

    以上,每一个任务必须包括由模块名字组成的key,由模块的参数组成的value,上边的任务表示安装最新版本的nginx服务。
    handler:Ansible提供的条件机制之一。只有在被通知的时候才会执行。例:当修改了nginx配置文件后,notify: restart nginx 。 handler配置restart nginx,则会被激活,执行handler所配置的任务。(官方只推荐重启服务和重启服务器使用)

    4. Ansible role:playbook高逼格版

    Roles 基于一个已知的文件结构,去自动的加载某些 vars_files,tasks 以及 handlers。基于 roles 对内容进行分组,使得我们可以容易地使用。

    4.1 role的基本构成

    每个role都有一个名字,如database,与database role相关的文件都放在roles/database目录中。这个目录中包含以下文件及目录:
    roles/database/tasks/main.yml

    task

    roles/database/files/

    保存着需要拷贝到远端主机的文件

    roles/database/templates/

    保存Jinja2模板文件

    关于Jinja2模板我有话说:

    (此处欠一个jinja2的说法)

    roles/database/handlers/main.yml

    handler

    roles/database/vars/main.yml
    #执行role:database所使用的变量,不应被覆盖

    roles/database/defaults/main.yml

    默认变量,可以被覆盖

    roles/database/meta/main.yml

    role的依赖信息,从属role在此设置

    一个项目如下:

    site.yml
    webservers.yml
    fooservers.yml
    roles/
       webservers/
         files/
         templates/
         tasks/
         handlers/
         vars/
         defaults/
         meta/
    

    webservers.yml如下:

    ---
    - hosts: webservers
      roles:
         - webservers
    

    这个 playbook 为一个角色 ‘x’ 指定了如下的行为:

    • 如果 roles/x/tasks/main.yml 存在, 其中列出的 tasks 将被添加到 play 中
    • 如果 roles/x/handlers/main.yml 存在, 其中列出的 handlers 将被添加到 play 中
    • 如果 roles/x/vars/main.yml 存在, 其中列出的 variables 将被添加到 play 中
    • 如果 roles/x/meta/main.yml 存在, 其中列出的 “角色依赖” 将被添加到 roles 列表中 (1.3 and later)
    • 所有 copy tasks 可以引用 roles/x/files/ 中的文件,不需要指明文件的路径。
    • 所有 script tasks 可以引用 roles/x/files/ 中的脚本,不需要指明文件的路径。
    • 所有 template tasks 可以引用 roles/x/templates/ 中的文件,不需要指明文件的路径。
    • 所有 include tasks 可以引用 roles/x/tasks/ 中的文件,不需要指明文件的路径。

    4.2 角色依赖

    假设我们有三个role: database、web、java,三个role都需要在主机上安装NTp服务。我们可以在两个role中都指定安装NTP服务,但是这样就会产生重复配置。我们可以创建一个单独的ntp role,但是这样的话,我们必须牢记每次执行database、web、java的同时还要执行ntp role,其实我们想要的就是在执行安装role的时候,能同时把ntp role也执行了,这时,我们就用到了角色依赖。
    “角色依赖” 使你可以自动地将其他 roles 拉取到现在使用的 role 中。”角色依赖” 保存在 roles 目录下的 meta/main.yml 文件中。这个文件应包含一列 roles 和 为之指定的参数,下面是在 roles/database/meta/main.yml 文件中的示例:

    ---
    dependencies:
      - { role: ntp, ntp_server=ntp.centos.com }
      - { role: '/path/to/common/roles/ntp2' }   #可以指定绝对路径调用
     }
    
    

    4.3 创建role文件与目录

    我们可以通过ansible-galaxy来创建一套初始的roles文件与目录(都是空的,只创建了文件、目录结构方便我们编写role)。
    例:

    ansible-galaxy init -p playbook/roles web
    

    -p: 指定要创建的role目录所在。如不指定,默认创建在当前目录下。
    web:创建的role名称。
    执行上边命令,创建的文件:

    playbook/roles
    └── web
        ├── defaults
        │   └── main.yml
        ├── files
        ├── handlers
        │   └── main.yml
        ├── meta
        │   └── main.yml
        ├── README.md
        ├── tasks
        │   └── main.yml
        ├── templates
        ├── tests
        │   ├── inventory
        │   └── test.yml
        └── vars
            └── main.yml
    
  • 相关阅读:
    数据库-数据约束
    数据库-表2
    数据库-表
    MySQL入门
    记一次stm8l程序跑飞
    nRF24L01P的ShockBurst与Enhance ShockBurst
    电路板工艺中的NPTH和PTH
    nRF24L01P数据传输速率
    STM32F030-UART1_DMA使用提示
    Altium Designer 复制报错-奇怪的问题解决办法
  • 原文地址:https://www.cnblogs.com/yangruizeng/p/6569349.html
Copyright © 2011-2022 走看看