CHAPTER 5 Ansible playbook(二)
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(二)相关推荐
- ansible笔记(11):初识ansible playbook(二)
ansible笔记(11):初识ansible playbook(二)有前文作为基础,如下示例是非常容易理解的:--- - hosts: test211remote_user: roottasks:- ...
- Python+Django+Ansible Playbook自动化运维项目实战(二)
Python+Django+Ansible Playbook自动化运维项目实战 一.资产管理,自动化发现.扫描 1.服务端资产探测.扫描发现 1)资产管理的资产: 2)抽象与约定: 2.探测协议和模块 ...
- Ansible playbook
1.什么是playbook playbook :定义一个文本文件,以yml为后缀结尾,那playbook组成如下. play:定义的是主机的角色 task: 定义的是具体执行的任务 总结:playbo ...
- Ansible 学习总结(2)—— Ansible playbook 入门详解
一.Ansible playbook 简单概述 playbook 是 ansible 用于配置,部署,和管理被控节点的剧本.通过 playbook 的详细描述,执行其中的一系列 tasks ,可以让远 ...
- DevOps—持续部署Ansible(二)
目录 介绍 安装 默认配置文件结构 Ansible服务配置 Inventory 介绍 Inventory 参数 Inventory配置案例 Ansible常用模块 Ansible执行方式 执行ad-h ...
- Ansible playbook
一.Ansible playbook 简介和使用场景 1.简介 playbook 是 ansible 用于配置,部署,和管理被控节点的剧本. 通过 playbook 的详细描述,执行其中的一系列 ta ...
- ansible———playbook剧本
ansible--playbook剧本 文章目录 ansible--playbook剧本 一.主机清单 二.Yaml文件 三.playbook剧本 四.Handlers介绍 五.条件测试 一.主机清单 ...
- ansible(二)—— inventory
2019独角兽企业重金招聘Python工程师标准>>> <h2 style="font-size: 24px; -webkit-print-color-adjust: ...
- ansible——playbook剧本的讲解与应用
目录 一.playbook 概述 1.1 playbook 介绍 1.2 Ansible playbook 使用场景 1.3 yaml基本语法规则 1.4 yaml支持的数据结构 1.3 示 ...
最新文章
- stm32l0的停止模式怎么唤醒_探索者 STM32F407 开发板资料连载第二十二章 待机唤醒实验
- 不为人知的动网7.1 SQL版注入漏洞
- CMU贺斌教授团队提出:冥想可以增强对脑机接口的控制
- To-do List
- 一文读懂除法溢出-使用汇编重定向0号中端(除法错误中断,比如,执行div指令产生的除法溢出)
- 删除两个字符串中的特定字符使其相等,统计删除的字符的ASCII和
- kafka高可用集群原理
- javaScript第六天(1)
- Npm install failed with “cannot run in wd”
- 使用Docker Compose管理多个容器
- linux chmod 755 ,750,777
- 杰奇小说2.3独家定制版淡绿唯美模板自动采集关关采集器带WAP
- c语言输入任意两个数求乘积,C语言程式 从键盘输入两个小数,输出它们的和及乘积...
- 深信服SSL远程接入与深信服行为审计同步登陆用户信息
- 论文Robust Range Estimation with a Monocular Camera for Vision-Based FCW System解读
- python xpath定位 麦客表单
- HTML绘制小房子,简笔画教程怎么画小房子
- 证券业数据大集中及其风险控制分析
- 用python一键生成你的微信好友头像墙
- 牛客网暑期ACM多校训练营(第二场)G.transform (二分+思维)