Ansible快速入門

背景:node

在實際生產環境中,當我門手工管理十來臺服務器時,工做仍是輕輕鬆鬆的;可是若是公司有上百服務器或者上千臺服務器呢,不可能每一臺都手工配置管理。因此ansible自動化運維工具的出現就很好的解決這問題,讓我門從刀耕火種時代進入自動化運維時代。linux


Ansible簡介:nginx

Ansible是一種agentless(基於ssh),可實現批量配置、命令執行和控制,基於Python實現的自動化運維工具。git

 其特性有:github

  ①模塊化:經過調用相關模塊,完成指定任務,且支持任何語言編寫的自定義模塊web

  ②playbook:劇本,可根據須要一次執行完劇本中的全部任務或某些任務redis

  安裝方式:shell

 yum安裝,在epel源中npm

         extras(注意ansible用的是這個extras倉庫,也是僅次於os(base)倉庫經常使用),    yum info ansible  能夠查到vim

    這裏直接使用yum安裝

    yum -y install ansible  

程序配置文件:

/usr/bin/ansible:命令行工具

     /usr/bin/ansible-doc                 幫助文檔

  /usr/bin/ansible-playbook         劇本執行工具

  /etc/ansible/ansible.cfg             主配置文件

  /etc/ansible/hosts                     管理的主機清單

  /etc/ansible/roles                      角色存放處

/usr/share/ansible_plugins/             插件目錄


ansible命令通用格式:ansible <host-pattern> [options] [-m module_name] [-a args]

      命令的使用:  Usage: ansible <host-pattern> [options]

         經常使用選項:

                -m      MOD_NAME   指明調用的模塊

                -a       MOD_ARGS    安裝模塊須要執行的參數 ,這兩個是最經常使用的。

                -f                               指明被管理的主機,默認是5個

基本配置:

1.SSH基於密鑰方式登錄

此次配置以三臺CentOS 7 主機,一臺CentOS 6 主機進行

  其中A主機爲管理端主機(centos6):192.168.38.119

      B主機:192.168.38.120

      C主機:192.168.38.121

      D主機:192.168.38.122

   在A主機上建立密鑰對,實現對其餘三臺主機實現無密碼訪問,執行:

     ssh-keygen -t rsa -P  ''   或者直接執行 ssh-keygen 也能夠

     複製密鑰到其餘的3臺主機

     for i in 119 120 121 ;do ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.38.$i;done

     鏈接測試,發現能夠執行命令了。說明沒問題

     ssh 192.168.38.121 'ifconfig'

2.配置A管理主機的清單

     進入配置文件  

vim /etc/ansible/ansible.cfg


 43 ## db-[99:101]-node.example.com
 44  [websrvs]            #配置第一個websrvs服務器
 45 192.168.38.120
 46 192.168.38.121
 47
 48 [dbsrvs]               #配置第二個dbsrvs服務器
 49 192.168.38.121
 50 192.168.38.122             


簡單測試查看配置是否生效,結果發現沒問題


ansible all -m command -a "w"       
 192.168.38.122 | SUCCESS | rc=0 >>
 19:21:20 up  8:53,  3 users,  load average: 0.05, 0.03, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.38.1     19:17    4:18   0.03s  0.03s -bash
root     pts/1    node1            19:21    0.00s  0.18s  0.01s w

 192.168.38.121 | SUCCESS | rc=0 >>
 19:21:20 up  8:54,  3 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.38.1     19:16    4:23   0.02s  0.02s -bash
root     pts/1    node1            19:21    0.00s  0.18s  0.01s w

192.168.38.120 | SUCCESS | rc=0 >>
 19:21:20 up  8:53,  3 users,  load average: 0.04, 0.03, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.38.1     19:16    4:24   0.04s  0.04s -bash
root     pts/1    node1            19:21    0.00s  0.17s  0.01s w


ansible經常使用模塊:

    獲取模塊列表:

        命令 ansible-doc  -l

command模塊:在遠程(目標)主機運行命令;

       查看對應的模塊-a有哪些參數可用

       命令 ansible-doc -s command

   相關選項

              creates:一個文件名,當該文件存在,則該命令不執行

           removes:一個文件名,當該文件不存在,則該選項不執行

             free_form:要執行的linux指令

      chdir:在執行指令以前,先切換到該目錄

             executable:切換shell來執行指令,該執行路徑必須是一個絕對路徑

    特別注意:  要求 執行操做每一個命令必須是冪等的,就是執行屢次不會有危害的後果,獲得效果是同樣的,例如執行ifconfig命令。

    若是不冪等就加上條件creates參數讓它冪等

示例1:

    ansible 192.168.38.120 -m command -a "mkdir mydir chdir=/tmp"

    [WARNING]: Consider using file module with state=directory rather than running mkdir

                 192.168.38.120 | SUCCESS | rc=0 >>


    ansible 192.168.38.120 -m command -a "mkdir mydir chdir=/tmp creates=mydir"

    192.168.38.120 | SUCCESS | rc=0 >>

    skipped, since mydir exists

    在120機器上查看就發現目錄/tmp/mydir 已經建立

示例2:添加用戶並賦予密碼,可使用shell,用command會報錯。

    ansible websrvs -m command -a "useradd user1"

    ansible websrvs -m shell  -a "echo magedu |passwd --stdin user1"


結論:command模塊不支持管道命令(|);shell支持,想用管道就用shell


shell模塊:在遠程主機在shell進程下運行命令,支持shell特性,如管道等;

    相關選項:

            chdir=:執行命令前切換工做目錄至指定的位置; creates=/PATH/TO/SOMEFILE_OR_DIR:若是此處給定的文件或目錄存在,則  不執行命令;

            removes=/PATH/TO/SOMEFILE_OR_DIR:若是此處給定的文件或目錄不存在,則不執行命令;

      意爲:令此處給定的文件或目錄存在時方執行命令;

            executable=/PATH/TO/SHELL:指定運行命令使用的shell解釋器;

示例3:

    ansible all -m shell -a "echo "test" | passwd --stdin test1"


group模塊:管理用戶組模塊

    相關選項:

   name:組名稱

   gid:指定GID

   state:present/absent   建立/刪除

   system:yes/no  系統組

示例4:建立組名name=haproxy ;system若是不給表示no 就是普通用戶

    ansible websrvs -m group -a "name=haproxy system=yes state=present"

    刪除組:ansible websrvs -m group -a "name=haproxy system=yes state=absent"

    在node2查看:[root@node2 ~]# tail /etc/group


user模塊:管理用戶模塊

    相關選項:

   因爲user模塊的選項衆多,這裏只介紹一些經常使用的選項:

   name:用戶名

   password:爲用戶設置登錄密碼,此密碼是明文密碼加密後的密碼

   update_password:always/on_create

     always:只有當密碼不相同時纔會更新密碼(默認)

     on_create:只爲新用戶設置密碼

   shell:用戶的shell設定

   groups:用戶組設定

   home:指定用戶的家目錄

   state:present/absent

   append:yes/no

      yes:增量添加group

      no:全量變動group,只設置groups指定的group組(默認)

   remove:配合state=absent使用,刪除用戶的家目錄->remove=yes

   expires:設置用戶的過時時間,值是一個時間戳

示例5:建立用戶tom 加入組是groups=haproxy  ,注意必須先有組,不然報錯

    先建立組:ansible websrvs -m group -a "name=haproxy system=yes state=present"

    ansible websrvs -m user -a "name=tom groups=haproxy state=present uid=3000 shell=/bin/tsch generate_ssh_key=true"


copy模塊:複製本地文件至遠程主機上  

    相關選項:

            backup:在覆蓋以前,將源文件備份,備份文件包含時間信息。有兩個選項: yes|no

            content:用於替代「src」,能夠直接設定指定文件的值

            dest:必選項。要將源文件複製到的遠程主機的絕對路徑,若是源文件是一個目錄,那麼該路徑也必須是個目錄

            directory_mode:遞歸設定目錄的權限,默認爲系統默認權限

            force:若是目標主機包含該文件,但內容不一樣,若是設置爲yes,則強制覆蓋,若是爲no,則只有當目標主機的目標位置不存在該文件時,才複製。默認爲yes

            others:全部的file模塊裏的選項均可以在這裏使用

            src:被複制到遠程主機的本地文件,能夠是絕對路徑,也能夠是相對路徑。若是路徑是一個目錄,它將遞歸複製。在這種狀況下,若是路徑使用「/」來結尾,則只複製目錄裏的                內容,若是沒有使用「/」來結尾,則包含目錄在內的整個內容所有複製,相似於rsync。


示例6:把test.txt文件複製到全部主機

    ansible all -m copy -a "src=test.txt dest=/tmp/ owner=daemon group=nobody mode=664"

    在 node2主機查看;ll /tmp 就能夠看到 -rw-rw-r--  1 daemon nobody   16 Nov 18 11:47 test.txt


file模塊:設置文件屬性

    相關選項:

          force:須要在兩種狀況下強制建立軟連接,一種是源文件不存在,但以後會創建的狀況下;另外一種是目標軟連接已存在,須要先取消以前的軟鏈,而後建立新的軟鏈,有兩個選                  項:yes|no

   group:定義文件/目錄的屬組

   mode:定義文件/目錄的權限

   owner:定義文件/目錄的屬主

   path:必選項,定義文件/目錄的路徑

   recurse:遞歸設置文件的屬性,只對目錄有效

   src:被連接的源文件路徑,只應用於state=link的狀況

   dest:被連接到的路徑,只應用於state=link的狀況

   state:

         directory:若是目錄不存在,就建立目錄

          file:即便文件不存在,也不會被建立

          link:建立軟連接

          hard:建立硬連接

          touch:若是文件不存在,則會建立一個新的文件,若是文件或目錄已存在,則更新其最後修改時間

         absent:刪除目錄、文件或者取消連接文件

    注意:state屬性的可用值

            file,directory,link,hard(硬連接),touch(建立空文件),absent(刪除)

示例6:

    ansible all -m file -a "path=/tmp/hidir state=directory"

    ansible all -m file -a "path=/tmp/hidir state=directory owner=nobody mode=770"

    刪除:ansible all -m file -a "path=/tmp/hidir state=absent"  


get_url模塊: Downloads files from HTTP, HTTPS, or FTP to node

    從網頁上下載連接url到主機指明的地方

    相關選項:

            *url=

            *dest=

              sha256sum=

              owner, group, mode

示例7:把這網頁https://redis.io/download 的url下載到全部的主機目錄是tmp下

    ansible all -m get_url -a "url=https://redis.io/download dest=/tmp"


git模塊:Deploy software (or files) from git checkouts

        能夠克隆特別好用的工具,直接拖到本地

    相關選項:

          clone=

           repo=

           dest=

           version=

示例7:直接把源碼克隆到本地,注意的先安裝git

    git clone https://github.com/happyfish100/fastdfs.git

    ansible websrvs -m git  -a "repo= https://github.com/happyfish100/fastdfs.git dest=/tmp/fastdfs"


cron模塊:計劃任務的實現

    相關選項:

   minute=/hour=/day=/month=/weekday= 某個值不寫,默認就是*

   name:必選項,任務描述信息

   job:執行的任務,要加引號

   state:present(建立)/absent(刪除)

示例8:建立計劃任務,同步時間

    建立:ansible all -m cron -a "name='timesync' job='/usr/sbin/ntpdate 172.18.0.1 &> /dev/null' minute='*/5'"

    刪除: ansible all -m cron -a "name='timesync' job='/usr/sbin/ntpdate 172.18.0.1 &> /dev/null' minute='*/5' state=absent"

    ansible all -m cron -a "name='timesync' job='/usr/sbin/ntpdate 172.18.0.1 &> /dev/null' minute='*/5' state='present' disabled='false/(true)'"


yum模塊:Manages packages with the `yum' package manager

    相關選項:

        name=:程序包名稱,能夠帶版本號;

        state=  安裝狀態

        present, latest, installed (安裝)

        absent, removed (卸載)

示例9:yum 安裝nginx  狀態是最新的state=latest

      ansible websrvs -m yum -a "name=nginx state=latest"

      查看安裝完成的命令:ansible websrvs -a 「rpm -q nginx」


service模塊:管理服務   注意這服務很重要

    相關選項:

   name:服務名稱

   state:started/stopped/restarted

   enabled:true(開機啓動)/false(關閉)

   runlevel:運行級別  

示例10:啓動nginx服務  

    ansible websrvs -m service -a "name=nginx enabled=true state=started"


其它的包管理工具:apt(debian), zypper(suse), dnf(fedora), rpm, dpkg,mpm,pip ...

    注意: pip 、npm、yum 都是用來實現安裝管理功能的組件


Playbook:YAML格式,任務(task)

    playbook是由一個或多個「play」組成的列表,可讓它們聯同起來按事先編排的機制執行;所謂task無非是調用ansible的一個module,而在模塊參數中可使用變量;模塊執行是冪      等的,這意味着屢次執行是安全的,由於其結果均一致;

      核心元素:hosts,tasks,variables,templates,handlers和roles(包含以上四個元素於一體的角色集合)


    基本數據結構:

           標量、數組、關聯數組

           維基百科 :https://zh.wikipedia.org/wiki/YAML

   Playbook的核心元素:

           Hosts:主機

           Tasks:任務列表

           Variables  #變量

           Templates:包含了模板語法的文本文件;模板

           Handlers:由特定條件觸發的任務;  處理器

            Roles

       

    playbook的基礎組件:

           Hosts:運行指定任務的目標主機;

           remoute_user: 在遠程主機上執行任務的用戶;

           sudo_user:

           tasks:任務列表

            模塊,模塊參數;

定義任務的2種格式:

                   (1) action: module arguments

                   (2) module: arguments  模塊、參數

注意:shell和command模塊後面直接跟命令,而非key=value類的參數列表;

                   (1) 某任務的狀態在運行後爲changed時,可經過「notify」通知給相應的handlers;

                   (2) 任務能夠經過"tags「打標籤,然後可在ansible-playbook命令上使用-t指定進行調用;


例子11: 作個計劃任務,安裝nginx、redis

        vim nginx.yaml  

            - hosts: websrvs

              remote_user: root   #遠程主機能夠是能夠普通用戶用sudo 運行

             tasks:

            - name: install nginx package

               yum: name=nginx state=latest

           - name: start nginx service  

            service: name=nginx enabled=true state=started #啓動服務的命令

           - hosts:dbsrvs

            remote_user: root

        tasks:

          - name: install redis package

             yum: name=redis state=latest

          - name: install conf file  

            copy: src=/root/redis.cnf dest=/etc/redis.conf owner=redis group=root mode=644

            tags: instconf

          - name: start redis service

            service: name=redis state=started

查看:有兩處主機

    ansible-playbook --list-hosts nginx.yaml      

        playbook: nginx.yaml

          play #1 (websrvs): websrvs    TAGS: []

          pattern: [u'websrvs']

           hosts (2):

            192.168.38.120

            192.168.38.121


        play #2 (dbsrvs): dbsrvs      TAGS: []

            pattern: [u'dbsrvs']

            hosts (2):

                192.168.38.121

                192.168.38.122

    

列出任務:

        ansible-playbook --list-tasks  nginx.yaml

                playbook: nginx.yaml

                  play #1 (websrvs): websrvs    TAGS: []

                    tasks:

                    install nginx package     TAGS: []

                    start nginx service       TAGS: []


                play #2 (dbsrvs): dbsrvs      TAGS: []

                    tasks:

                        install redis package     TAGS: []

                                     install conf file TAGS: []

                            start redis service       TAGS: []


    語法檢查:ansible-playbook --syntax-check nginx.yaml

    測試有沒有報錯(試運行): ansible-playbook -C nginx.yaml

    沒問題就運行:ansible-playbook nginx.yaml


運行playbook的方式:

        查看幫助:ansible-playbook -h

            (1) 測試

                  ansible-playbook  --check

                       只檢測可能會發生的改變,但不真正執行操做;

                   ansible-playbook  --list-hosts

                       列出運行任務的主機;

                   ansible-playbook  --list-tasks

                       列出要運行的任務列表

                   ansible-playbook --syntax-check

                       語法檢查

               (2) 運行:ansible-playbook

相關文章
相關標籤/搜索