ansible-playbook

  • 5.1 任务控制
    • 5.1.1 Ansible任务控制基本介绍
    • 5.1.2 条件判断(when)
    • 5.1.3 循环控制(with_items)
      • 5.1.3.1 标准loops
      • 5.1.3.2 嵌套loops
      • 5.1.3.3 散列loops
      • 5.1.3.4 文件配置loops
      • 5.1.3.5 条件判断
    • 5.1.4 Tags属性
    • 5.1.5 Handiers属性

5.1 任务控制

5.1.1 Ansible任务控制基本介绍

这里主要来介绍PlayBook中的任务控制,任务控制类似于编程语言中的if … 、for … 等逻辑控制语句。这里我们给出一个实际场景应用案例去说明在PlayBook中,任务控制如何应用。

在下面的PlayBook中,我们创建了 tomcat、www 和 mysql 三个用户。安装了Nginx 软件包、并同时更新了 Nginx 主配置文件和虚拟主机配置文件,最后让Nginx 服务处于启动状态。整个PlayBook从语法上没有任何问题,但从逻辑和写法上仍然有一些地方需要我们去注意及优化:
1、Nginx启动逻辑欠缺考虑。若Nginx的配置文件语法错误则会导致启动Nginx失败,以至于PlayBook执行失败。
2、批量创建用户,通过指令的罗列过于死板。如果再创建若干个用户,将难以收场。

5.1.2 条件判断(when)

解决第一个问题
*Nginx启动逻辑欠缺考虑。若Nginx的配置文件语法错误则会导致启动Nginx失败,以至于PlayBook执行失败 *

如果我们能够在启动之前去对Nginx的配置文件语法做正确性的校验,只有当校验通过的时候我们才去启动或者重启Nginx;否则则跳过启动Nginx的过程。这样就会避免Nginx 配置文件语法问题而导致的无法启动的风险。

Nginx 语法校验

- name: check nginx syntax   shell: /usr/sbin/nginx -t

那如何将Nginx语法检查的TASK同Nginx启动的TASK关联起来呢?

如果我们能够获得语法检查的TASK的结果,根据这个结果去判断“启动NGINX的TASK”是否执行,这将是一个很好的方案。 如何和获取到语法检查TASK的结果呢? 此时就可以使用Ansible中的注册变量。

获取Task任务结果(注册变量)

- name: check nginx syntax   shell: /usr/sbin/nginx -t   register: nginxsyntax

此时有可能还有疑问,我获取到任务结果,但是结果里面的内容是个什么样子, 我如何在后续的PlayBook中使用呢?

通过debug模块去确认返回结果的数据结构

- name: print nginx syntax result    debug: var=nginxsyntax

通过debug 模块,打印出来的返回结果。 当nginxsyntax.rc 为 0 时语法校验正确。

通过条件判断(when) 指令去使用语法校验的结果

---- name: check nginx syntax    shell: /usr/sbin/nginx -t   register: nginxsyntax   - name: print nginx syntax  debug: var=nginxsyntax - name: start nginx server  service: name=nginx state=started when: nginxsyntax.rc == 0

笔者机器网络很差,下nginx耗费需要很长时间,附上httpd的playbook,逻辑一样

[root@dbc-server-554 ansible]# cat playbook_httpd.yml
---
- name: httpd controlhosts: allgather_facts: notasks:- name: yum httpd webserveryum: name=httpd state=present- name: update httpd main configcopy: src=httpd.conf dest=/etc/httpd/httpd.conf- name: check httpd syntaxshell: /usr/sbin/httpdregister: httpd_syntax- name: print httpd syntaxdebug: var=httpd_syntax- name: stop httpd serversystemd: name=httpd state=stopped- name: start httpd serversystemd: name=httpd state=startedwhen: httpd_syntax.rc == 0
...
[root@dbc-server-554 ansible]# ansible-playbook -i hosts playbook_httpd.ymlPLAY [httpd control] *******************************************************************************************TASK [yum httpd webserver] *************************************************************************************
ok: [192.168.71.183]TASK [update httpd main config] ********************************************************************************
changed: [192.168.71.183]TASK [check httpd syntax] **************************************************************************************
changed: [192.168.71.183]TASK [print httpd syntax] **************************************************************************************
ok: [192.168.71.183] => {"httpd_syntax": {"changed": true,"cmd": "/usr/sbin/httpd","delta": "0:00:00.036550","end": "2023-01-04 11:33:22.319418","failed": false,"rc": 0,"start": "2023-01-04 11:33:22.282868","stderr": "","stderr_lines": [],"stdout": "httpd (pid 30108) already running","stdout_lines": ["httpd (pid 30108) already running"]}
}TASK [stop httpd server] ***************************************************************************************
changed: [192.168.71.183]TASK [start httpd server] **************************************************************************************
changed: [192.168.71.183]PLAY RECAP *****************************************************************************************************
192.168.71.183             : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

(注册变量,when注册变量结果)
以上的逻辑,只要语法检查通过都会去执行 “start nginx server"这个TASK。当反复执行这个PlayBook 的,除了第一次外,其他"start nginx server” 的TASK是没有必要的执行的。能否避免这样的问题呢?我们在判断"start nginx server" 这个TASK任务是否启动的条件基础上再加一个条件。只有当语法校验正确等于0、且Nginx 服务没有启动的时候再去启动服务。

另外when支持如下运算符:

==
!=
> >=
< <=
is defined
is not defined
true
false
支持逻辑运算符:and or

5.1.3 循环控制(with_items)

解决第二个问题
*批量创建用户,通过指令的罗列过于死板。如果再创建若干个用户,将难以收场。 *
如果在创建用户时,抛开PlayBook的实现不说, 单纯的使用shell去批量的创建一些用户。通常会怎么写呢?

#! /bin/bash
createuser="tomcat mysql www"
for i in `echo $createuser`
do  useradd $i
done

那么如果PlayBook中也存在这样的循环控制,我们也可以像写shell一样简单的去完成多用户创建工作。 在PlayBook中使用with_items去实现循环控制,且循环时的中间变量(上面shell循环中的$i 变量)只能是关键字item,而不能随意自定义

在上面的基础上,改进的PlayBook
在这里使用定义了剧本变量createuser(一个列表),然后通过with_items循环遍历变量这个变量来达到创建用户的目的。

[root@dbc-server-554 ansible]# cat playbook_user.yml
---
- name: user adddhosts: allgather_facts: novars:createuser:- tomcat- www- mysqltasks:- name: create useruser: name={{item}} state=presentwith_items: "{{createuser}}"- name: get passwdshell: tail -3 /etc/passwdregister: passwd- name: show passwddebug: var=passwd
[root@dbc-server-554 ansible]# ansible-playbook -i hosts playbook_user.ymlPLAY [user addd] ***********************************************************************************************TASK [create user] *********************************************************************************************
ok: [192.168.71.183] => (item=tomcat)
ok: [192.168.71.183] => (item=www)
ok: [192.168.71.183] => (item=mysql)TASK [get passwd] **********************************************************************************************
changed: [192.168.71.183]TASK [show passwd] *********************************************************************************************
ok: [192.168.71.183] => {"passwd": {"changed": true,"cmd": "tail -3 /etc/passwd","delta": "0:00:00.004885","end": "2023-01-04 12:23:32.082390","failed": false,"rc": 0,"start": "2023-01-04 12:23:32.077505","stderr": "","stderr_lines": [],"stdout": "test:x:1009:1010::/home/test:/bin/bash\ntomcat:x:1010:1011::/home/tomcat:/bin/bash\nwww:x:1011:1012::/home/www:/bin/bash","stdout_lines": ["test:x:1009:1010::/home/test:/bin/bash","tomcat:x:1010:1011::/home/tomcat:/bin/bash","www:x:1011:1012::/home/www:/bin/bash"]}
}PLAY RECAP *****************************************************************************************************
192.168.71.183             : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

注意: with_items: “{{createuser}}”,必须加双引号
解决了以上问题,整个PlayBook已经有了很大的改进。但我们在生产环境中验证时发现还是不够灵活。

5.1.3.1 标准loops

[root@dbc-server-554 ansible]# cat loop.yml
---
- name: loop itemhosts: allgather_facts: novars:some_list:- a- b- cnum_list:- 1- 2- 3- 4- 5tasks:- name: show alpdebug:var: "{{item}}"loop: "{{some_list}}"- name: show digthdebug:var: "{{item}}"loop: "{{num_list}}"when: item > 3
[root@dbc-server-554 ansible]# ansible-playbook -i hosts loop.ymlPLAY [loop item] ***********************************************************************************************TASK [show alp] ************************************************************************************************
ok: [192.168.71.183] => (item=a) => {"a": "VARIABLE IS NOT DEFINED!","ansible_loop_var": "item","item": "a"
}
ok: [192.168.71.183] => (item=b) => {"ansible_loop_var": "item","b": "VARIABLE IS NOT DEFINED!","item": "b"
}
ok: [192.168.71.183] => (item=c) => {"ansible_loop_var": "item","c": "VARIABLE IS NOT DEFINED!","item": "c"
}TASK [show digth] **********************************************************************************************
skipping: [192.168.71.183] => (item=1)
skipping: [192.168.71.183] => (item=2)
skipping: [192.168.71.183] => (item=3)
ok: [192.168.71.183] => (item=4) => {"4": "VARIABLE IS NOT DEFINED!","ansible_loop_var": "item","item": 4
}
ok: [192.168.71.183] => (item=5) => {"5": "VARIABLE IS NOT DEFINED!","ansible_loop_var": "item","item": 5
}PLAY RECAP *****************************************************************************************************
192.168.71.183             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

5.1.3.2 嵌套loops

[root@dbc-server-554 ansible]# cat loop2.yml
---
- hosts: allgather_facts: notasks:- name: debug loopsdebug: msg="name->{{ item[0] }} value->{{ item[1] }}"with_nested:- ['A']- ['a','b','b'][root@dbc-server-554 ansible]# ansible-playbook -i hosts loop2.ymlPLAY [all] *****************************************************************************************************TASK [debug loops] *********************************************************************************************
ok: [192.168.71.183] => (item=[u'A', u'a']) => {"msg": "name->A value->a"
}
ok: [192.168.71.183] => (item=[u'A', u'b']) => {"msg": "name->A value->b"
}
ok: [192.168.71.183] => (item=[u'A', u'b']) => {"msg": "name->A value->b"
}PLAY RECAP *****************************************************************************************************
192.168.71.183             : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

5.1.3.3 散列loops

标准loop支持的是数组,类似于python中的列表。
嵌套loop其实使用是[{},{}]这种列表套字典的形式,
而散列loop可以直接支持字典形式,只是变相要遵循yaml格式。

---
- hosts: allgather_facts: Faslevars:user:kebi:name: zhangrongkaiaddr: luotianmaoxian: name: songlixingaddr: xiaochangtasks:- name: debug loopsdebug: msg="name--->{{ item.key }} value--->{{ item.value.name }} addr---{{ item.value.addr }}"with_dict: "{{ user }}"

5.1.3.4 文件配置loops

在某些时候,我们需要针对某一类型的文件进行一些操作,这个时候就可以使用fileglob这个参数。
通过这个fileglob就能匹配到相应的文件,然后就可以进行相应的操作。
定义:file_loop.yaml

---
- hosts: alltasks:- name: debug loopsdebug: msg="filename--->{{ item }}"with_fileglob:- /tmp/*.py

5.1.3.5 条件判断

有时候,我们需要执行一个操作,这个操作可能失败,我们希望5秒之后再去尝试执行,
这样的操作重复5次,如果还不行就退出。


[root@dbc-server-554 ansible]# ansible-playbook -i hosts loop3.yamlPLAY [all] *****************************************************************************************************TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.71.183]TASK [debug loops] *********************************************************************************************
FAILED - RETRYING: debug loops (5 retries left).
FAILED - RETRYING: debug loops (4 retries left).
FAILED - RETRYING: debug loops (3 retries left).
FAILED - RETRYING: debug loops (2 retries left).
FAILED - RETRYING: debug loops (1 retries left).
fatal: [192.168.71.183]: FAILED! => {"attempts": 5, "changed": true, "cmd": "cat /etc/hostname", "delta": "0:00:00.065739", "end": "2023-01-05 06:49:21.348004", "rc": 0, "start": "2023-01-05 06:49:21.282265", "stderr": "", "stderr_lines": [], "stdout": "k8s-node-02", "stdout_lines": ["k8s-node-02"]}PLAY RECAP *****************************************************************************************************
192.168.71.183             : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0[root@dbc-server-554 ansible]# cat loop3.yaml
---
- hosts: alltasks:- name: debug loopsshell: cat /etc/hostnameregister: hostuntil: host.stdout.startswith("centos")retries: 5delay: 5

解释说明:

  • name: debug loops #任务名称,非必需
  • shell: cat /etc/hostname #操作
  • register: host #操作的结果赋值给host
  • until: host.stdout.startswith(“centos”) #直到…成立
  • retries: 5 #重复5次
  • delay: 5 #每个5秒重复一次

考虑这样一个情况
若更新了Nginx的配置文件后,我们需要通过PlayBook将新的配置发布到生产服务器上,然后再重新加载我们的Nginx服务。但以现在的PlayBook来说,每次更改Nginx配置文件后虽然可以通过它发布到生产,但整个PlayBook都要执行一次,这样无形中扩大了变更范围和变更风险。(想挑选某些执行,某些跳过)

下面的Tags 属性就可以解决这个问题。

5.1.4 Tags属性

我们可以通过Play中的tags 属性,去解决目前PlayBook变更而导致的扩大变更范围和变更风险的问题。

在改进的PlayBook中,针对文件发布TASK 任务 “update nginx main config” 和"add virtualhost config"新增了属性 tags ,属性值为updateconfig。另外我们新增"reload nginx server" TASK任务。当配置文件更新后,去reload Nginx 服务。这样对配置文件更新的操作将很完美。

那重新加载需要依赖于Nginx服务是已经启动状态。所以,还需要进一步通过判断Nngix的pid 文件存在,才证明Nginx服务本身是启动中,启动中才可以reload Nginx服务。

判断一个文件是否存在使用stat模块,观察结果会发现nginxrunning.stat.exists的值是true就表示启动状态,是false就是关闭状态。接下来下来就可以依据这个结果,来决定是否重新加载Nginx服务。

---
- name: task control playbook example   hosts: webservers   gather_facts: no    wars:   createuser: - tomcat    - www   - mysql tasks:  - name: create user user: name={{ item }} state=present   with_items: "{{ createuser }}"    - name: yum nginx webserver yum: name=nginx state=present - name: update nginx main config    copy: src=nginx.conf dest=/etc/nginx/ tags: update    - name: add virtualhost config  copy: src=virtualhost.conf dest=/etc/nginx/conf.d/    tags: update    - name: check nginx syntax  shell: /usr/sbin/nginx -t   register: nginxsyntax   tags: update    - name: check nginx running stat: path=/var/lock/subsys/nginx  register: nginxrunning  tags: update    - name: print nginx syntax  debug: var=nginxsyntax - name: start nginx server  service: name=nginx state=started when: nginxsyntax.rc == 0 and nginxrunning.stat.exists == false

指定tags去执行Playbook
// 执行时一定要指定tags,这样再执行的过程中只会执行task 任务上打上tag 标记为 updateconfig 的任务

]# ansible-playbook site.yml -t update

httpd示例:

[root@dbc-server-554 ansible]# cat playbook_httpd.yml
---
- name: httpd controlhosts: allgather_facts: notasks:- name: yum httpd webserveryum: name=httpd state=present- name: update httpd main configcopy: src=httpd.conf dest=/etc/httpd/httpd.conftags: update- name: check httpd syntaxshell: /usr/sbin/httpdregister: httpd_syntaxtags: update- name: print httpd syntaxdebug: var=httpd_syntaxtags: update- name: stop httpd serversystemd: name=httpd state=stoppedtags: update- name: start httpd serversystemd: name=httpd state=startedwhen: httpd_syntax.rc == 0tags: update
...
[root@dbc-server-554 ansible]# ansible-playbook -i hosts playbook_httpd.yml -t updatePLAY [httpd control] *******************************************************************************************TASK [update httpd main config] ********************************************************************************
ok: [192.168.71.183]TASK [check httpd syntax] **************************************************************************************
changed: [192.168.71.183]TASK [print httpd syntax] **************************************************************************************
ok: [192.168.71.183] => {"httpd_syntax": {"changed": true,"cmd": "/usr/sbin/httpd","delta": "0:00:00.040005","end": "2023-01-05 04:53:48.992756","failed": false,"rc": 0,"start": "2023-01-05 04:53:48.952751","stderr": "","stderr_lines": [],"stdout": "httpd (pid 77189) already running","stdout_lines": ["httpd (pid 77189) already running"]}
}TASK [stop httpd server] ***************************************************************************************
changed: [192.168.71.183]TASK [start httpd server] **************************************************************************************
changed: [192.168.71.183]PLAY RECAP *****************************************************************************************************
192.168.71.183             : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

但反复执行此PlayBook依然存在问题。当我的配置文件没有发生变化时,每次依然都会去触发TASK “reload nginx server”。如何能做到只有配置文件发生变化的时候才去触发TASK “reload nginx server”,这样的处理才是最完美的实现。此时可以使用handlers 属性。

5.1.5 Handiers属性

观察当前的Playbook,不难发现,当配置文件没有发生变化时,每次依然都会去触发TASK"reload nginx server"。 如何能做到只有配置文件发生变化的时候才去触发TASK"reload nginxserver",这样的处理才是最完美的实现。此时可以使用handlers属性。

task:    - name: update nginx config notify: reload nginx server
handlers:   - name: reload nginx server service: name=nginx state=reloadwhen:- nginxsyntax.rc == 0- nginxrunning.stat.exists == true

在改进的PlayBook中,我们针对文件发布TASK 任务 “update nginx main config” 和 “add virtualhost config” 增加了新属性 notify, 值为 “reload nginx server”。它的意思是说,针对这两个文件发布的TASK,设置一个通知机制,当Ansible 认为文件的内容发生了变化(文件MD5发生变化了),它就会发送一个通知信号 handlers 中的任务。

具体发送到handlers中的哪个任务,由notify 的值"reload nginx server"决定。通知发出后handlers 会根据发送的通知,在handlers中相关的任务中寻找名称为"reload nginx server" 的任务。当发现存在这样名字的TASK,就会执行它。若没有找到,则什么也不做。若我们要实现这样的机制,千万要注意notify属性设置的值,一定要确保能和handlers中的TASK 名称对应上。

#修改httpd.conf后,第一次执行
[root@dbc-server-554 ansible]# ansible-playbook -i hosts playbook_httpd.ymlPLAY [httpd control] *******************************************************************************************TASK [yum httpd webserver] *************************************************************************************
ok: [192.168.71.183]TASK [update httpd main config] ********************************************************************************
changed: [192.168.71.183]TASK [check httpd syntax] **************************************************************************************
changed: [192.168.71.183]TASK [check httpd running] *************************************************************************************
changed: [192.168.71.183]TASK [print httpd syntax] **************************************************************************************
ok: [192.168.71.183] => {"httpd_syntax": {"changed": true,"cmd": "/usr/sbin/httpd","delta": "0:00:00.036497","end": "2023-01-05 06:27:02.222614","failed": false,"rc": 0,"start": "2023-01-05 06:27:02.186117","stderr": "","stderr_lines": [],"stdout": "httpd (pid 54722) already running","stdout_lines": ["httpd (pid 54722) already running"]}
}TASK [stop httpd server] ***************************************************************************************
changed: [192.168.71.183]TASK [start httpd server] **************************************************************************************
changed: [192.168.71.183]RUNNING HANDLER [get httpd server status] **********************************************************************
ok: [192.168.71.183] => {"msg": {"changed": true,"cmd": "ps -ef|grep httpd","delta": "0:00:00.074944","end": "2023-01-05 06:27:02.564682","failed": false,"rc": 0,"start": "2023-01-05 06:27:02.489738","stderr": "","stderr_lines": [],"stdout": "root      54722      1  0 06:22 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND\napache    54727  54722  0 06:22 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND\napache    54728  54722  0 06:22 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND\napache    54729  54722  0 06:22 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND\napache    54730  54722  0 06:22 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND\nroot      56416  56415  0 06:27 pts/1    00:00:00 /bin/sh -c ps -ef|grep httpd\nroot      56418  56416  0 06:27 pts/1    00:00:00 grep httpd","stdout_lines": ["root      54722      1  0 06:22 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND","apache    54727  54722  0 06:22 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND","apache    54728  54722  0 06:22 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND","apache    54729  54722  0 06:22 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND","apache    54730  54722  0 06:22 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND","root      56416  56415  0 06:27 pts/1    00:00:00 /bin/sh -c ps -ef|grep httpd","root      56418  56416  0 06:27 pts/1    00:00:00 grep httpd"]}
}PLAY RECAP *****************************************************************************************************
192.168.71.183             : ok=8    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
#第一次执行后,未做任何更改,第二次执行
[root@dbc-server-554 ansible]# ansible-playbook -i hosts playbook_httpd.ymlPLAY [httpd control] *******************************************************************************************TASK [yum httpd webserver] *************************************************************************************
ok: [192.168.71.183]TASK [update httpd main config] ********************************************************************************
ok: [192.168.71.183]TASK [check httpd syntax] **************************************************************************************
changed: [192.168.71.183]TASK [check httpd running] *************************************************************************************
changed: [192.168.71.183]TASK [print httpd syntax] **************************************************************************************
ok: [192.168.71.183] => {"httpd_syntax": {"changed": true,"cmd": "/usr/sbin/httpd","delta": "0:00:00.036841","end": "2023-01-05 06:27:27.106098","failed": false,"rc": 0,"start": "2023-01-05 06:27:27.069257","stderr": "","stderr_lines": [],"stdout": "httpd (pid 56562) already running","stdout_lines": ["httpd (pid 56562) already running"]}
}TASK [stop httpd server] ***************************************************************************************
changed: [192.168.71.183]TASK [start httpd server] **************************************************************************************
changed: [192.168.71.183]PLAY RECAP *****************************************************************************************************
192.168.71.183             : ok=7    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

特点:

1.handlers是ansible提供的条件机制之一,handlers和tasks很类似,但是只在被tasks通知的时候才会触发执行;
2.handlers只会在任务执行完成后执行。即使被通知了很多次,也只会执行一次。
3.当一个tasks中有多个notify,只会执行最后一个。

上一章:CHAPTER 4 Ansible playbook(一)
下一章:CHAPTER 6 Ansible playbook(三)

CHAPTER 5 Ansible playbook(二)相关推荐

  1. ansible笔记(11):初识ansible playbook(二)

    ansible笔记(11):初识ansible playbook(二)有前文作为基础,如下示例是非常容易理解的:--- - hosts: test211remote_user: roottasks:- ...

  2. Python+Django+Ansible Playbook自动化运维项目实战(二)

    Python+Django+Ansible Playbook自动化运维项目实战 一.资产管理,自动化发现.扫描 1.服务端资产探测.扫描发现 1)资产管理的资产: 2)抽象与约定: 2.探测协议和模块 ...

  3. Ansible playbook

    1.什么是playbook playbook :定义一个文本文件,以yml为后缀结尾,那playbook组成如下. play:定义的是主机的角色 task: 定义的是具体执行的任务 总结:playbo ...

  4. Ansible 学习总结(2)—— Ansible playbook 入门详解

    一.Ansible playbook 简单概述 playbook 是 ansible 用于配置,部署,和管理被控节点的剧本.通过 playbook 的详细描述,执行其中的一系列 tasks ,可以让远 ...

  5. DevOps—持续部署Ansible(二)

    目录 介绍 安装 默认配置文件结构 Ansible服务配置 Inventory 介绍 Inventory 参数 Inventory配置案例 Ansible常用模块 Ansible执行方式 执行ad-h ...

  6. Ansible playbook

    一.Ansible playbook 简介和使用场景 1.简介 playbook 是 ansible 用于配置,部署,和管理被控节点的剧本. 通过 playbook 的详细描述,执行其中的一系列 ta ...

  7. ansible———playbook剧本

    ansible--playbook剧本 文章目录 ansible--playbook剧本 一.主机清单 二.Yaml文件 三.playbook剧本 四.Handlers介绍 五.条件测试 一.主机清单 ...

  8. ansible(二)—— inventory

    2019独角兽企业重金招聘Python工程师标准>>> <h2 style="font-size: 24px; -webkit-print-color-adjust: ...

  9. ansible——playbook剧本的讲解与应用

    目录 一.playbook  概述 1.1  playbook  介绍 1.2  Ansible playbook 使用场景 1.3 yaml基本语法规则 1.4 yaml支持的数据结构 1.3  示 ...

最新文章

  1. stm32l0的停止模式怎么唤醒_探索者 STM32F407 开发板资料连载第二十二章 待机唤醒实验
  2. 不为人知的动网7.1 SQL版注入漏洞
  3. CMU贺斌教授团队提出:冥想可以增强对脑机接口的控制
  4. To-do List
  5. 一文读懂除法溢出-使用汇编重定向0号中端(除法错误中断,比如,执行div指令产生的除法溢出)
  6. 删除两个字符串中的特定字符使其相等,统计删除的字符的ASCII和
  7. kafka高可用集群原理
  8. javaScript第六天(1)
  9. Npm install failed with “cannot run in wd”
  10. 使用Docker Compose管理多个容器
  11. linux chmod 755 ,750,777
  12. 杰奇小说2.3独家定制版淡绿唯美模板自动采集关关采集器带WAP
  13. c语言输入任意两个数求乘积,C语言程式 从键盘输入两个小数,输出它们的和及乘积...
  14. 深信服SSL远程接入与深信服行为审计同步登陆用户信息
  15. 论文Robust Range Estimation with a Monocular Camera for Vision-Based FCW System解读
  16. python xpath定位 麦客表单
  17. HTML绘制小房子,简笔画教程怎么画小房子
  18. 证券业数据大集中及其风险控制分析
  19. 用python一键生成你的微信好友头像墙
  20. 牛客网暑期ACM多校训练营(第二场)G.transform (二分+思维)

热门文章

  1. vue+swiper仿抖音视频滑动
  2. 宽带拨号错误代码处理
  3. 美护品牌inFace获中国品牌经济峰会2021年度最具价值投资项目
  4. Windows Vista系统垃圾清理批处理
  5. 中国的亲戚关系您理顺了吗
  6. 应用出海,如何使用苹果 CallKit 提升网络通话体验
  7. 将ntfs分区转换为ext4分区
  8. Cesium中级教程8 - Introduction to Particle Systems 粒子系统入门
  9. 手机电池充电时间计算方法
  10. 二级生物实验室防护设计基本要求