codecamp

Ansible 如何操作

相信大家手边都有可以练习 Ansible 的环境了,这次冻仁就来谈谈怎么操作 Ansible!

automate_with_ansible_basic-16.jpg

一般来说,我们可以用 Ad-Hoc command 和 Playbook 两种方式来操作 Ansible。

automate_with_ansible_basic-17.jpg

前者是透过一次次简短的指令来操作 Ansible,而后者则是先把任务写好,然后再一次执行。两者的关系就好比我们在 Linux Shell 里打指令和先写个 Shell Script 再执行一样。

Ad-Hoc Commands 是什么?

Ad hoc 这个单字是来自拉丁文常用短语中的一个短语,通常用来形容为一个特定的问题或任务而专门设定的解决方案 1Ad-Hoc Commands 可以翻译为简短地指令,在这里冻仁会用指令操作模式来形容它,以常见的 ping 和 echo 操作为例。

  • ping.

    $ ansible all -m ping
    server1 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    
  • echo.

    $ ansible all -m command -a "echo Hello World"
    server1 | SUCCESS | rc=0 >>
    Hello World
    

从以上的例子中可以看到 Ad-Hoc commands 一次只能处理一件事情,这即是它与 Playbooks 最大的差异。

详情请参考官方的 Introduction To Ad-Hoc Commands | Ansible Documentation 文件。

Playbooks 是什么?

Playbook 就字面上的意思为剧本。我们可以通过事先写好的剧本 (Playbooks) 来让各个 Managed Node 进行指定的动作 (Plays) 和任务 (Tasks)。 2

简而言之,Playbooks 是 Ansible 的脚本 (Script),而且还是个比传统 Shell Script 还强大数百倍的脚本!如果今天只能记住一件事,请记住 Ansible 最好用、最厉害的就是它的 Playbook!

automate_with_ansible_basic-18.jpg图片来源:http://goo.gl/GKJvXn

在一份 Playbook 中,可以有多个 Play、多个 Task 和多个 Module。

  • Play:通常为某个特定的目的,例如:
    • Setup a official website with Drupal (借由 Drupal 建置官网)
    • Restart the API service (重开 API 服务)
  • Task:是要实行 Play 这个目地所需做的每个步骤,例如:
    • Install the Nginx (安裝 Nginx)
    • Kill the djnago process (强制停止 django 的行程)
  • Module:Ansible 所提供的各种操作方法,例如:
    • apt: name=vim state=present (使用 apt 套件安装 vim)
    • command: /sbin/shutdown -r now (使用 shutdown 的指令重新开机)

automate_with_ansible_basic-19.gif

详情请参考官方的 Playbooks | Ansible Documentation 文件。

Hello World Playbook

  • 来写一下我们的第一个 playbook!请建立一个 hello_world.yml 的档案,并将 --- 开始的内容都写进去。

    $ vi hello_world.yml
    ---
    
    - name: say 'hello world'
      hosts: all
      tasks:
    
        - name: echo 'hello world'
          command: echo 'hello world'
          register: result
    
        - name: print stdout
          debug:
            msg: ""
    
  • 执行 playbook:在这个范例中,我们执行了 1 个 Play、3 个 Task 和 2 个 Module。

    $ ansible-playbook hello_world.yml
    
    PLAY [say 'hello world'] *******************************************************
    
    TASK [setup] *******************************************************************
    ok: [server1]
    
    TASK [echo 'hello world'] ******************************************************
    changed: [server1]
    
    TASK [print stdout] ************************************************************
    ok: [server1] => {
        "msg": "hello world"
    }
    
    PLAY RECAP *********************************************************************
    server1                    : ok=3    changed=1    unreachable=0    failed=0
    

没有 Ansible 时,我们是怎么操作的?

冻仁在此附上 Linux Shell 3 上的传统作法,来比对两者的操作。

Shell (command line, cli, console)

  • ping.

    $ ping -c 1 8.8.8.8
    PING 8.8.8.8 (8.8.8.8): 56 data bytes
    64 bytes from 8.8.8.8: icmp_seq=0 ttl=44 time=10.022 ms
    
    --- 8.8.8.8 ping statistics ---
    1 packets transmitted, 1 packets received, 0.0% packet loss
    round-trip min/avg/max/stddev = 10.022/10.022/10.022/0.000 ms
    
  • echo.

    $ echo Hello World
    Hello World
    

Shell Script

  • 建立 hello_world.sh 档案。

    #!/bin/bash
    echo 'Hello World'
    
  • 执行。

    $ bash hello_world.sh
    Hello World
    

后话

大家或许会问,会写 script 就够用了,为什么还要会写 playbook 呢?冻仁在此列了几个理由给大家参考:

  1. 若有现成的 script,我们可以用 shell module 来执行它,这部份虽不冲突,但使用 shell module 会造成每次跑 playbook 都会重复执行,不像其它 module 执行过就不会再执行了。
  2. 用 Ansible 的 module 可以把很多杂乱的指令给标准化,例如不同的 Linux 发行版本在安装套件时需代各种不同的参数。
  3. 在现有的 cloud native 的架构下,传统的 Shell Script 已不符使用,一般而言 Shell Script 只能对一台机器 (instance) 进行操作。

相信大家都知道要怎么操作 Ansible 了,好好享受 Ansible 带给我们的乐趣吧!

相关连结

1. 详情请参考维基百科上的 Ad hoc 解释。 ↩
2. 关于组态管理工具的隐喻,可参考 William Yeh 前辈所撰写的电脑界的隐喻:组态管理 | 软件架构・絮语一文。 ↩
3. Linux Shell,是我们一般在 GNU/Linux 上操作的模式,而常见的 Shell 有 Bash, Zsh ... 等,在 Windows 上则有命令提示字元 (CMD),但它对使用者而言没有 Shell 友善。 ↩


Ansible 用 Docker 练习 Ansible
Ansible 用 Jupyter 操控 Ansible (localhost)
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }