Loading... <blockquote>在本博客中,ansible是一个系列文章,我们会尽量以通俗易懂的方式总结ansible的相关知识点。 ansible系列博文直达链接:<a href="https://www.zsythink.net/archives/tag/ansible/" target="_blank" rel="noopener">ansible轻松入门系列</a> “ansible系列”中的每篇文章都建立在前文的基础之上,所以,请按照顺序阅读这些文章,否则有可能在阅读中遇到障碍。 </blockquote> 你可能会在实际使用ansible的过程中遇到一些小问题,这些小问题通常对应着实际的应用场景,你会在遇到这些小问题时搜索怎样解决,也许,你只是需要学会一些小技巧罢了,记住这些小技巧,能让我们在实际的工作中事半功倍,当然,这些都是见仁见智的,我只是将我觉得有用的进行总结,想到哪个写哪个,可能会分成几篇文章进行总结 。 <h2 id="wznav_0">小技巧:在ansible中使用python字符串的一些特性</h2> ansible基于python实现,当我们在ansible中处理字符串时,能够借助一些python的字符串特性,比如,在python中可以使用中括号(方括号)截取字符串中的一部分,在ansible中也可以利用这一特性,示例playbook如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># cat test.yml</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test71</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> a: </span><span class="enlighter-s0">"vaA12345"</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{a[2]}}"</span></div> </div> </div> </div> 如上例所示,我们定义了一个字符串变量a,如果我们想要获取a字符串的第3个字符,则可以使用”a[2]”获取,索引从0开始,执行上例playbook,debug的输出信息如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test71</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"A"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> </div> </div> 可以从输出信息中看到,我们已经获取到了a字符串的第三个字符”A” 你也可以使用a[2:5]获取到a字符串的第3到第5个字符(不包含第6个字符) 使用a[:5]获取到a字符串的第6个字符之前的所有字符(不包含第6个字符) 使用a[5:]获取到a字符串的第6个字符之后的所有字符(包含第6个字符) 其实之前文章中总结的成员运算符”in”和”not in”,也是python的字符串运算符 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">- hosts: test71</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> a: </span><span class="enlighter-s0">"vaA12345"</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"true"</span></div> </div> <div class=""> <div><span class="enlighter-text"> when: </span><span class="enlighter-s0">"'va' in a"</span></div> </div> </div> </div> 如上例所示,我们可以利用它们判断某个字符串是否包含另一个字符串 我们可以使用加号”+”连接两个字符串 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">- hosts: test71</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> a: </span><span class="enlighter-s0">"vaA12345"</span></div> </div> <div class=""> <div><span class="enlighter-text"> b: </span><span class="enlighter-s0">"vbB67890"</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{a+b}}"</span></div> </div> </div> </div> 或者使用乘号”*”连续的重复输出字符串,比如将字符串a连续输出3次 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">- hosts: test71</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> a: </span><span class="enlighter-s0">"vaA12345"</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{a*3}}"</span></div> </div> </div> </div> 上例的debug输出如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test71</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"vaA12345vaA12345vaA12345"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> </div> </div> 在python中,有很多内建的处理字符串的函数(或者称之为字符串方法),在ansible中我们也可以利用这些字符串函数,处理字符串。 比如,使用find函数查找指定字符在字符串中的位置,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">- hosts: test71</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> a: </span><span class="enlighter-s0">"vaA12345"</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{a.find('A1')}}"</span></div> </div> </div> </div> 上例表示,找出字符串’A1’处于字符串a的位置,上例的debug输出如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">debug</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************</span></div> </div> <div class=""> <div><span class="enlighter-text">ok: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test71</span><span class="enlighter-g1">]</span><span class="enlighter-text"> =</span><span class="enlighter-g1">></span> <span class="enlighter-g1">{</span></div> </div> <div class=""> <div><span class="enlighter-s0">"msg"</span><span class="enlighter-text">: </span><span class="enlighter-s0">"2"</span></div> </div> <div class=""> <div><span class="enlighter-g1">}</span></div> </div> </div> </div> 输出结果是2,也就是说,”A1″在字符串a中的位置是3,当在字符串中没有找到对应的字符时,find函数的返回值为”-1″,所以,我们也可以利用这一特性,判断字符串中是否包含指定的字符,如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">- hosts: test71</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> a: </span><span class="enlighter-s0">"vaA12345"</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"not found"</span></div> </div> <div class=""> <div><span class="enlighter-text"> when: a.</span><span class="enlighter-m3">find</span><span class="enlighter-g1">(</span><span class="enlighter-s0">'A2'</span><span class="enlighter-g1">)</span><span class="enlighter-text"> == </span><span class="enlighter-n1">-1</span></div> </div> </div> </div> 在使用find函数时,也可以指定查找范围,find函数的语法是find(string,begin,end) string是要查找的字符串,begin是起始位置,end是结束位置 比如,从字符串的第2个字符开始查找 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">- hosts: test71</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> a: </span><span class="enlighter-s0">"vaA12345"</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{a.find('A1',1)}}"</span></div> </div> </div> </div> 除了find函数,还有很多其他的字符串函数,你可以了解一下,动手试试,此处只是为了演示怎样在ansible中使用python的字符串函数,所以就不一一示例了。 <h2 id="wznav_1">小技巧:”任务委派”,让某个任务在指定的主机上执行</h2> 当我们执行一个playbook时,需要设置目标主机,也就是说,playbook中定义的task会在目标主机上执行(一些特定的模块除外,某些模块天生就只会在ansible主机上执行,即使你指定了目标主机,它也仍然会在ansible主机上执行)。 但是,在某些场景下,我们需要指定某个任务在特定的主机上执行,举个例子,playbook中设置的目标主机是A、B、C三台主机,playbook中一共有5个task,因为某些原因,其中第3个task需要在D主机上执行,而不是在A、B、C这三台目标主机上执行,这个时候,我们该怎么办呢?我们可以使用最原始的方法,将第3个task单独设置成一个play段,然后将这个play段的目标主机设置为D,示意代码如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">- hosts: A,B,C</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - task1:</span></div> </div> <div class=""> <div><span class="enlighter-text"> ...</span></div> </div> <div class=""> <div><span class="enlighter-text"> - task2:</span></div> </div> <div class=""> <div><span class="enlighter-text"> ...</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: D</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - task3:</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: A,B,C</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - task4:</span></div> </div> <div class=""> <div><span class="enlighter-text"> ...</span></div> </div> <div class=""> <div><span class="enlighter-text"> - task5:</span></div> </div> <div class=""> <div><span class="enlighter-text"> ...</span></div> </div> </div> </div> 上述playbook虽然可以满足我们的目标,但是略显笨拙,因为上例中的大部分tasks都是需要在目标主机A、B、C上执行的,只是因为某些逻辑上的原因,task3需要到特定的主机上执行,难道每次遇到这种临时需要到特定主机上执行的任务,都需要单独分出一个play段吗?这样也太麻烦了吧,有没有更好的办法呢?当然有啦,遇到这种情况,我们就可以使用ansible的”任务委托”功能,”任务委派”可以让某个任务在指定的主机上执行,使用”delegate_to”关键字即可实现”任务委托”功能,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">- hosts: test70,test71</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - file:</span></div> </div> <div class=""> <div><span class="enlighter-text"> path: </span><span class="enlighter-s0">"/tmp/ttt"</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: touch</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text"> - file:</span></div> </div> <div class=""> <div><span class="enlighter-text"> path: </span><span class="enlighter-s0">"/tmp/delegate"</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: touch</span></div> </div> <div class=""> <div><span class="enlighter-text"> delegate_to: test61</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text"> - file:</span></div> </div> <div class=""> <div><span class="enlighter-text"> path: </span><span class="enlighter-s0">"/tmp/ttt1"</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: touch</span></div> </div> </div> </div> 如上例所示,上例中一共有3个tasks,第2个task使用了”delegate_to”关键字指定了对应的主机,test61,也就是说,第2个task只会在test61主机上执行,而不会在目标主机test70和test71主机上执行,但是第1个task和第3个task仍然会在目标主机test70和test71上执行,这样,就轻松的实现了我们想要的效果,通过”delegate_to”关键字,可以指定某个任务在特定的主机上执行,这个特定的主机可以是目标主机中的某一个,也可以不是目标主机中的任何一个。执行上例playbook,输出如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0"># ansible-playbook test1.yml</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">PLAY </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70,test71</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">file</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************</span></div> </div> <div class=""> <div><span class="enlighter-text">changed: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test71</span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text">changed: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">file</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************</span></div> </div> <div class=""> <div><span class="enlighter-text">changed: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70 -</span><span class="enlighter-g1">></span> <span class="enlighter-n0">10.1</span><span class="enlighter-text">.</span><span class="enlighter-n0">1.61</span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text">changed: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test71 -</span><span class="enlighter-g1">></span> <span class="enlighter-n0">10.1</span><span class="enlighter-text">.</span><span class="enlighter-n0">1.61</span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">TASK </span><span class="enlighter-g1">[</span><span class="enlighter-text">file</span><span class="enlighter-g1">]</span> <span class="enlighter-g0">*************************</span></div> </div> <div class=""> <div><span class="enlighter-text">changed: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test70</span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text">changed: </span><span class="enlighter-g1">[</span><span class="enlighter-text">test71</span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text">PLAY RECAP </span><span class="enlighter-g0">*************************</span></div> </div> <div class=""> <div><span class="enlighter-text">test70 </span><span class="enlighter-g0">:</span><span class="enlighter-text"> ok=</span><span class="enlighter-n1">3</span><span class="enlighter-text"> changed=</span><span class="enlighter-n1">3</span><span class="enlighter-text"> unreachable=</span><span class="enlighter-n1">0</span><span class="enlighter-text"> failed=</span><span class="enlighter-n1">0</span></div> </div> <div class=""> <div><span class="enlighter-text">test71 </span><span class="enlighter-g0">:</span><span class="enlighter-text"> ok=</span><span class="enlighter-n1">3</span><span class="enlighter-text"> changed=</span><span class="enlighter-n1">3</span><span class="enlighter-text"> unreachable=</span><span class="enlighter-n1">0</span><span class="enlighter-text"> failed=</span><span class="enlighter-n1">0</span></div> </div> </div> </div> 如你所见,第二个task都委托到test61主机上执行了。 <h2 id="wznav_2">小技巧:让某个任务在ansible主机上执行,而不是在目标主机上执行</h2> 默认情况下,task都会在目标主机上执行,但是在某些场景下,我们需要让某个task在ansible主机上执行,而不是在目标主机上执行,我们该怎么做呢?聪明如你一定想到了,刚才提到的”delegate_to”关键字不是正好能解决这个问题吗?我们只需要将”delegate_to”对应的主机设置成ansible主机即可,完全正确,”delegate_to”的确可以完美的解决这个问题,不过,除了”delegate_to”,还有另外一种方法也能实现相同的效果,当我们想要让某个任务在ansible主机上执行,而不是在目标主机上执行时,可以使用”connection: local”来完成,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">- hosts: test70,test61</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - file:</span></div> </div> <div class=""> <div><span class="enlighter-text"> path: </span><span class="enlighter-s0">"/tmp/inAnsible"</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: touch</span></div> </div> <div class=""> <div><span class="enlighter-text"> connection: local</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text"> - file:</span></div> </div> <div class=""> <div><span class="enlighter-text"> path: </span><span class="enlighter-s0">"/tmp/test"</span></div> </div> <div class=""> <div><span class="enlighter-text"> state: touch</span></div> </div> </div> </div> 上例中,第一个task使用了”connection: local”,表示当前任务只在ansible主机本地执行,并不在目标主机上执行,快动手试试吧。 <h2 id="wznav_3">小技巧:”只跑一次”,设置某个task只运行一次</h2> 默认情况下,一个task会在每个目标主机上都执行一遍,也就是说,如果目标主机有5台,那么一个task就会执行5遍(每一遍在不同的目标主机上执行),在某些场景下,我们希望某个任务只运行一次,而不是有多少个目标主机就运行多少次。 我来描述一个场景,在剧本的开始,我需要下载某个软件包到ansible主机,于是我使用了get_url模块,从网站上下载了这个包,但是由于目标主机中一共有5台,所以,下载包的这个task会重复执行5次,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">- hosts: A,B,C,D,E</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - get_url:</span></div> </div> <div class=""> <div><span class="enlighter-text"> url: </span><span class="enlighter-s0">"http://nexus.zsythink.net/repository/testraw/testfile/test.tar"</span></div> </div> <div class=""> <div><span class="enlighter-text"> dest: /tmp/</span></div> </div> <div class=""> <div><span class="enlighter-text"> connection: local</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text"> - copy:</span></div> </div> <div class=""> <div><span class="enlighter-text"> src: </span><span class="enlighter-s0">"/tmp/test.tar"</span></div> </div> <div class=""> <div><span class="enlighter-text"> dest: </span><span class="enlighter-s0">"/tmp"</span></div> </div> </div> </div> 执行上例playbook,你会发现,每个任务会针对每个目标主机都执行一遍,一共执行5遍,但是对于第一个task来说,没有必要执行5遍,因为只要执行一遍,我需要的安装包就会下载到ansible主机中,之后的4遍就没必要执行了,如果执行上例playbook,你会发现,由于ansible具备幂等性,当第一个task执行一次后,之后执行的4次其实并没有什么实质性的操作,但是,当你的安装包特别大、目标主机又特别多时,这些多余的操作仍然会浪费一些时间,所以,我们完全没有必要执行之后的4遍操作,这时,我们就需要借助到”run_once”关键字了,”run_once”关键字能让对应的任务只运行一次,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">- hosts: A,B,C,D,E</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - get_url:</span></div> </div> <div class=""> <div><span class="enlighter-text"> url: </span><span class="enlighter-s0">"http://nexus.zsythink.net/repository/testraw/testfile/test.tar"</span></div> </div> <div class=""> <div><span class="enlighter-text"> dest: /tmp/</span></div> </div> <div class=""> <div><span class="enlighter-text"> connection: local</span></div> </div> <div class=""> <div><span class="enlighter-text"> run_once: </span><span class="enlighter-k1">true</span></div> </div> <div class=""> <div></div> </div> <div class=""> <div><span class="enlighter-text"> - copy:</span></div> </div> <div class=""> <div><span class="enlighter-text"> src: </span><span class="enlighter-s0">"/tmp/test.tar"</span></div> </div> <div class=""> <div><span class="enlighter-text"> dest: </span><span class="enlighter-s0">"/tmp"</span></div> </div> </div> </div> 如上例所示,我为第一个task设置了”run_once: true”,这表示,即使目标主机有5台,这个task也只会运行一次。 运行上例playbook,你会发现,当执行get_url这个任务时,只运行了一次。 当任务设置了”run_once”以后,只会在操作第一个目标主机时,运行一次。 这篇文章就先总结到这里,希望这些小技巧能够对你有所帮助~ 转载自朱双印日志https://www.zsythink.net/archives/3277 Last modification:May 29, 2024 © Allow specification reprint Like 如果觉得我的文章对你有用,请随意赞赏