1. 程式人生 > >Ansible簡介與實驗

Ansible簡介與實驗

del 取消 必須 多級 gid () png 中文 iat

一、簡介

ansible是新出現的自動化運維工具,基於Python開發,集合了眾多運維工具(puppet、cfengine、chef、func、fabric)的優點,實現了批量系統配置、批量程序部署、批量運行命令等功能。

ansible是基於模塊工作的,本身沒有批量部署的能力。真正具有批量部署的是ansible所運行的模塊,ansible只是提供一種框架。

主要特點:
  • 模塊化,調用特定的模塊,完成特定的任務,基於Python語言實現,易於擴展;

  • 部署簡單,agentless,無需客戶端安裝軟件,服務端通過連接插件connection plugins和被監控端實現通信;

  • playbook:可以讓節點調用角色模板一次性運行多個任務快速部署基礎環境。

  • ansible所執行的操作主要是定義管理者所期望的對象狀態,多次執行命令的結果具有冪等性

    冪等性原本是數學上的概念,即使公式:f(x)=f(f(x)) 能夠成立的數學性質。用在編程領域,則意為對同一個系統,使用同樣的條件,一次請求和重復的多次請求對系統資源的影響是一致的

ansible架構圖

技術分享圖片

二、常用模塊介紹

ansible-doc 命令用於獲取ansible相關幫助頁面,-l是查看可用模塊,-s可顯示指定模塊說明。

ansible的命令行執行格式如下:

ansible <host-pattern> [-f forks] (host分批) -m module_name -a args

  • command:執行命令無須為key=value格式,而是直接給出要執行的命令即可。

    註意,command為默認調用模塊可以不使用-m指定。

    • 示例1:

      [root@ansible-manager ~]# ansible directors -a "ifconfig"192.168.7.151 | SUCCESS | rc=0 >>ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.7.151 netmask 255.255.255.0 broadcast 192.168.7.255 .........

    • 示例2:chdir選項可指定命令運行的目錄

      [root@ansible-manager ~]# ansible directors -a "chdir=/var ls"192.168.7.151 | SUCCESS | rc=0 >>

      ..........

    • 示例3:command模塊並不能理解執行 花括號命令行展開,管道符傳遞等特殊命令形式

      [root@ansible-manager ~]# ansible directors -a "ifconfig |grep ens33"192.168.7.152 | FAILED | rc=255 >>SIOCSIFADDR: No such device

      ..........

    • 示例4: 上例的問題可用shell模塊解決

      [root@ansible-manager ~]# ansible directors -m shell -a "ifconfig |grep ens33" 192.168.7.151 | SUCCESS | rc=0 >>ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500

      .........

  • user -a ‘name= state={present|absent} system= uid=‘

    • 示例:

      [root@ansible-manager ~]# ansible directors -m user -a "name=wind state=present password=abc321"192.168.7.152 | SUCCESS => { "changed": true, "comment": "", #用戶的描述信息 "createhome": true, "group": 1000, "home": "/home/wind", "name": "wind", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": false, #非系統用戶 "uid": 1000}

      到客戶機上驗證結果:

      [root@client2 ~]# id winduid=1000(wind) gid=1000(wind) groups=1000(wind)

  • cron -a ‘name= minute= hour= day= month= weekday= job= user= state=‘

    • 示例:

      [root@ansible-manager ~]# ansible all -m cron -a "name=ntptime minute=*/3 job=‘/usr/sbin/ntpdate 192.168.7.138 &>/dev/null ‘"192.168.7.152 | SUCCESS => { "changed": true, "envs": [], "jobs": [ "ntptime" ]}

      註意:

      1. 默認的state就是present,刪除的時候可以僅指定name和state=absent.

      2. job=‘character string‘ job的內容必須加單引號,否則報錯.

      3. 任務計劃能否成功創建並不受客戶機是否有相關命令影響,沒有安裝ntpdate命令也可以成功創建.

  • copy -a ‘dest= src= mode= owner= group=‘

    • 示例: src參數不帶絕對路徑的話默認是復制當前目錄下的指定文件,支持相對路徑。

      • [root@ansible-manager ~]# ansible directors -m copy -a "src=repo.tar dest=/root"

        192.168.7.151 | SUCCESS => {

      • [root@ansible-manager ~]# ansible directors -m copy -a "src=../home/wind/1.txt dest=/root/2.txt"192.168.7.151 | SUCCESS => {

    • 註意:如果src以“/”結尾則僅復制目錄中的內容,不以此結尾就是復制目錄及其中內容src不是必選項因為可以用content直接生成目標文件的內容(可生成空文件)。

  • yum -a ‘name= state={present|latest|absent}‘

    • 示例:

      ansible directors -m yum -a "name=ntpdate"

      192.168.7.151 | SUCCESS => {

      ? "changed": true,

  • fetch 從遠程主機取回文件到本地,

    • 示例:

      [root@ansible-manager ~]# ansible 192.168.7.151 -m fetch -a "src=/root/2.txt dest=remotefile"

      命令運行後在本地直接生成了remotefile目錄,而且將遠程主機上的絕對路徑也復制到了本地指定目錄的遠程主機名目錄之下。即./remotefile/REMOTE_HOST/REMOTE_PATH

    • 如果不需要此種多級目錄結構,可使用flat選項,其幫助文件說明如下:

      flat: # If dest ends with ‘/‘, it will use the basename of the source file, similar to the copy module. Obviously this is only handy if the filenames are unique.

      • ansible 192.168.7.152 -m fetch -a "src=/root/2.txt src=/root/3.txt flat=yes dest=test/"

        [root@ansible-manager ~]# ls test/2.txt 3.txt

      使用此選項並不會生成多級目錄,但是顯然這個選項不適合從多主機上拉取文件的情況。

      會造成多主機重復寫入同一文件。

      如果在多個遠程主機的拉取文件時使用了flat選項,執行命令後,則會輪流覆蓋寫入拉回本地的文件,執行結果多個主機依次變為黃色changed。

      原因是,依照hosts文件中定義的主機上下順序,依次對比遠程主機文件與ansiblemanager本地文件的校驗值,如果發生改變則覆蓋,執行結果黃色;校驗值同的主機顯示為綠色狀態未變更。

      此種執行方式僅為興趣探究,實際中並無意義,從多個主機取回文件必然是不希望互相覆蓋的。

    • 註意:

      • src必須指向遠程主機上的文件,不可以是目錄。可以指定多個src

      • 使用flat=yes選項時,適合拉取單臺主機文件的情況,降低目錄復雜性。

  • file -a ‘path= mode= owner= group= state={directory|link|present|absent} src=‘

    • 示例:

      [root@ansible-manager ~]# ansible directors -m file -a "path=/root/a.txt src=/root/2.txt state=link"192.168.7.152 | SUCCESS => { "changed": true, "dest": "/root/a.txt", "gid": 0, "group": "root", "mode": "0777", "owner": "root", "size": 11, "src": "/root/2.txt", "state": "link", "uid": 0}

    • state選項說明:

      If ‘directory‘, all immediate subdirectories will be created if they do not exist, since 1.7 they will be created with the supplied permissions.

      ? If ‘file‘, the file will NOT be created if it does not exist, see the [copy] or [template] module if you want that behavior.

      If ‘link‘, the symbolic link will be created or changed. Use ‘hard‘ for hardlinks.

      If ‘absent‘, directories will be recursively deleted, and files or symlinks will be unlinked. Note that ‘absent‘ will not cause ‘file‘ to fail if the ‘path‘ does not exist as the state did not change.

      If ‘touch‘ (new in 1.4), an empty file will be created if the ‘path‘ does not exist, while an existing file or directory will receive updated file access and modification times (similar to the way ‘touch‘ works from the command line).

      • 如果是directionary,1.7版本後, path指定的目錄都將依據提供的權限設置遞歸創建。

      • 如果是file,path指定的文件如果原來不存在, 那麽也不會被創建。如果需要新建一個文件請使用copy或template模塊,或者使用touch參數(創建空文件)。

      • 如果是link,符號鏈接將被創建或更改。使用hard選項創建 hardlinks(也就是說默認軟連接)。

      • 如果是absent, 目錄將被遞歸地刪除, 文件或符號鏈接將被取消鏈接。請註意, path不存在時不會導致file執行失敗,因為命令會返回狀態未改變的結果。

      • 如果是touch, (1.4新增參數), 如果path不存在, 則會創建一個空文件, 而如果path是現有或目錄時將更新文件access和modifycation時間 (類似命令行下執行touch命令)。

  • ping 沒有參數,僅測試是否可以ping通

    • 示例:

      [root@ansible-manager ~]# ansible directors -m ping 192.168.7.151 | SUCCESS => { "changed": false, "ping": "pong"}192.168.7.152 | UNREACHABLE! => { "changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 192.168.7.152 port 22: Connection timed out\r\n", "unreachable": true}

  • service -a ‘name= state={started|stopped|restarted} enabled=‘

    • 示例:

      [root@ansible-manager ~]# ansible directors -m service -a "name=httpd state=restarted"192.168.7.151 | SUCCESS => {

      .......會顯示很長的詳細狀態信息

三、playbook

Playbooks 是 Ansible的配置,部署,編排語言。是一種希望遠程主機執行所需命令的方案,或者一組IT程序運行的命令集合.

(一)Playbook的核心元素:
  • tasks: 任務

    任務列表

  • variables: 變量

    ansible有內置變量與自定義變量,變量定義可以在命令行,主機清單,角色目錄下的變量目錄等多處進行。

  • templates: 模板

    主要用於服務的配置文件的參數傳遞至被控主機

  • handlers: 觸發調用任務

    適用於如配置文件變更時觸發重啟/重載等任務。需要tasks任務列表中使用notify調用。

  • roles: 角色

    通過對以上元素的整合,達成一整套的服務自動配置的目的。有固定的目錄組織形式,各元素分別定義。在playbook中通過對host安排角色進行調用。

具體的每個元素不再詳述,可以參考ansible中文手冊,下面以實例來演示。

(二)使用roles部署keepalived一主一備實例
  1. 創建目錄

    [root@ansible-manager ansible]# mkdir -p roles/keepalived/{tasks,handlers,meta,templates,vars,files}

    [root@ansible-manager ansible]# tree roles/

    roles/

    └── keepalived

    ├── files

    ├── handlers

    ├── meta

    ├── tasks

    ├── templates

    └── vars

    7 directories, 0 files

    tasks?錄:存放task列表。若role要?效,此?錄必須要有?個主task?件main.yml,在main.yml中可以使?include包含同?錄(即tasks)中的其他?件。handlers?錄:存放handlers的?錄,若要?效,則?件必須名為main.yml?件。files?錄:在task中執?copy或script模塊時,如果使?的是相對路徑,則會到此?錄中尋找對應的?件。templates?錄:在task中執?template模塊時,如果使?的是相對路徑,則會到此?錄中尋找對應的模塊?件。vars?錄:定義專屬於該role的變量,如果要有var?件,則必須為main.yml?件。defaults?錄:定義??默認變量,??默認變量的優先級最低,會被任意其他層次的同名變量覆蓋。如果要有var?件,則必須為main.yml?件。meta?錄:?於定義??依賴(dependencies),如果要有??依賴關系,則?件必須為main.yml。

    以上引自博客園——駿馬金龍的ansible教程。

  2. 各目錄具體配置

    • tasks

      • main.yml

        - name: yum install keepalived
        yum: name=keepalived state=present
        when: ansible_distribution_major_version == ‘7‘ #無實際意義的條件判斷僅測試下when語句
        - name: copy script
        copy: src=notify.sh dest=/etc/keepalived
        - name: copy conf
        template: src=keepalived.conf.j2 dest=/etc/keepalived/keepalived.conf
        notify: restart keepalived
        - name: start keepalived
        systemd: name=keepalived state=started
        - name: show vip
        shell: /usr/sbin/ip addr show |grep {{ vip }}
    • handlers

      • main.yml

        - name: restart keepalived
        systemd: name=keepalived state=restarted
    • templates

      • keepalived.conf.j2

        ! Configuration File for keepalived
        ?
        global_defs {
        notification_email {
        root@localhost
        }
        notification_email_from keepalived@localhost
        smtp_server 127.0.0.1
        smtp_connect_timeout 30
        router_id {{ ansible_hostname }} #引用內置變量
        vrrp_mcast_group1 224.0.0.33
        vrrp_skip_check_adv_addr
        vrrp_strict
        vrrp_garp_interval 0
        vrrp_gna_interval 0
        }
        ?
        vrrp_instance vip1 {
        state {{ keepalived_state }} #主機清單定義變量
        interface {{ ansible_default_ipv4.interface }} #引用內置變量的子參數需以VAR.XX的形式
        virtual_router_id 51
        priority {{ pri }} #主機清單定義變量
        advert_int 1
        authentication {
        auth_type PASS
        auth_pass 1111
        }
        virtual_ipaddress {
        {{ vip }} #自定義變量
        }
        notify_master "/etc/keepalived/notify.sh master"
        notify_backup "/etc/keepalived/notify.sh backup"
        notify_fault "/etc/keepalived/notify.sh fault"
        }
    • files

      • notify.sh

        #!/bin/bash
        #僅通知本機root用戶做測試
        contact=‘root@localhost‘
        ?
        notify() {
        local mailsubject="$(hostname) to be $1, vip floating"
        local mailbody="$(date +‘%F %T‘): vrrp transition, $(hostname) changed to be $1"
        echo "$mailbody" | mail -s "$mailsubject" $contact
        }
        ?
        case $1 in
        master)
        notify master
        ;;
        backup)
        notify backup
        ;;
        fault)
        notify fault
        ;;
        *)
        echo "Usage: $(basename $0) {master|backup|fault}"
        exit 1
        ;;
        esac
    • vars

      • main.yml

        vip: 192.168.7.120 #必須是字典形式
    • roles所在目錄定義hosts以及playbook

      • hosts

        [directors]
        192.168.7.151 keepalived_state=MASTER pri=99
        192.168.7.152 keepalived_state=SLAVE pri=90
      • keepalived.yml

        - hosts: directors
        roles:
        - keepalived

Ansible簡介與實驗