Ansible--playbook介紹

playbook能夠理解成劇本,即一份文件能夠存放多個ansible任務。後續的操做所有按照playbook中定義的動做執行java

playbook使用YAML格式
nginx

YAML有本身的書寫格式,操做時必定要嚴格按照此格式執行,後面會詳細介紹其格式web


playbook示例:redis

首先編輯yaml格式的文件,而此文件中統必定義要執行的操做:
vim  test.yaml     
- hosts: webservers   #指定操做的遠程主機 
  remote_user: root   #以root身份執行如下tasks
  tasks: 
  - name: install nginx               #任務的名稱,即在執行時顯示的標題名稱
    yum: name=nginx state=latest      #調用yum模塊,與單獨使用yum模塊時的用法是同樣的
  - name: start nginx 
    service: name=nginx enabled=true state=started  #service模塊

- hosts: dbservers     #另外一組遠程主機
  remote_user: root
  tasks: 
  - name: install redis 
    yum: name=redis state=latest 
  - name: install conf file
    copy: src=/root/redis.conf dest=/app/ owner=redis group=root mode=0644
  - name: start redis 
    service: name=redis state=started
#以上注意hosts與name前要有短橫線打頭,這是yaml的格式要求
#並且tasks和其後面的具體任務要錯開,即不能頂格配置name、service等

ansible-playbook  --list-hosts test.yaml
#主機檢查
ansible-playbook  --list-tasks test.yaml
#任務檢查
ansible-playbook  --syntax-check test.yaml
#語法檢查

存在兩個問題
vim

1)只想執行test.yaml中的某一個任務怎麼作tomcat

2)配置文件修改了,服務怎麼重啓,要知道service模塊的配置中state已經配置爲started了,不會再添加state爲restartedbash

上述兩個問題都須要執行任務可是隻能將全部任務從新執行一遍,效率不高app


問題1)的解決方案:給任務加標籤less

vim test.yaml
 tasks: 
  - name: install redis 
    yum: name=redis state=latest 
  - name: install conf file
    copy: src=/root/redis.conf dest=/app/ owner=redis group=root mode=0644
    tags: install    #加此標籤,執行時指定此標籤則只執行此任務,未加標籤的任務不執行
  - name: start redis 
    service: name=redis state=started
    tags: start
#並且能夠指定多個標籤,多個任務也可使用同一個標籤,當調一個標籤時能夠執行多個任務
ansible-playbook  --list-tags test.yaml 
#查看哪些hosts打了標籤
ansible-playbook  -t install,start test.yaml
#指定標籤執行

問題2)的解決方案:webapp

條件式觸發任務,在配置文件被修改時會觸發handlers機制

vim test.yaml
- hosts: dbservers
  remote_user: root
  tasks: 
  - name: install redis 
    yum: name=redis state=latest 
  - name: install conf file
    copy: src=/root/redis.conf dest=/etc/ owner=redis group=root mode=0644
    tags: install 
    notify: restart redis service   #條件通知,當此任務即要複製的文件被修改了notify就會通知handlers執行觸發任務
  - name: start redis 
    service: name=redis state=started
    tags: start
  handlers:    #條件觸發器,只有知足特定條件纔會執行後續任務
  - name: restart redis service 
    service: name=redis state=restarted
#handlers依然調用service模塊重啓,這樣只有配置文件修改纔會觸發handlers,纔會執行此處的service。
#正常配置文件未改變的狀況下不會觸發此任務
ansible-playbook  -t install  test.yaml  
#將redis.conf的bind端口修改後,測試便可

還有一個問題須要注意,即如何根據實際狀況調整參數

如redis.conf配置文件中有maxmemory字段,表示用於redis的內存容量,若是想將此容量調整爲當前主機的內存容量的一半該怎麼作。

要知道多個遠程主機的內存容量不必定是同樣的,有的是4G有的是16G如何根據主機自身的內存容量來配置呢?解決方案以下:

這個就用到了變量variables

facts變量:
ansible dbservers -m setup |  less
用戶自定義變量:
    a、在playbook中定義變量,以下: 
    vim tree.yml  
- hosts: webservers
  remote_user: root
  vars:   #定義變量,其格式是 變量名+冒號+值
  - pkgname: tree
  tasks:
  - name: install {{ pkgname }} pkg   #調用變量使用花括號
    yum: name={{ pkgname }} state=latest   #在執行任務時就能夠調用變量
而後測試便可
ansible-playbook  -C tree.yml  

     b、在ansible-playbook命令中指定變量,其優先級高於playbook中定義的,以下:
     接着上述步驟a進行操做
     ansible-playbook -e "pkgname=memcached" -C tree.yml 
     #在命令行中使用-e指定變量的鍵值,tree.yml只是本次測試使用
     
    c、經過roles傳遞的變量,後續介紹
    
    d、host inventory主機列表中定義的變量:
    vim /etc/ansible/hosts 
    [webservers]
    192.168.1.106 pkgname=redis
    192.168.1.107 pkgname=redis
    #在定義主機列表時定義
    若是同一組內主機變量所有相同,即向一個組傳遞相同變量,還可使用下述方法定義:
    [webservers:var]
    pkgname=redis

模板與變量引用:一般須要在模板中調用變量

template模塊:jinja2語法格式,相似於copy模塊

vim redis.yml  
- hosts: webservers
  remote_user: root
  tasks:
  - name: install redis maxmem
    template: src=/root/redis.conf dest=/tmp/ owner=redis mode=666 
#在此任務中咱們使用template模塊,其提供模板功能,用法相似於copy
vim redis.conf 
maxmemory {{ ansible_memtotal_mb /2 }}mb
#ansible_memtotal_mb是ansible內置變量,能夠參與多種運算
#在控制端,定義ansible內置變量並進行除法運算,即取本本機內存空間的一半
#這樣即便遠程多臺主機的內存大小不一致,此變量仍會取內存大小的一半並將取出的最終結果定義在此配置文件中傳給遠程主機
ansible-playbook  redis.yml   
#template支持嵌套腳本的文本文件這是與copy模塊的主要區別
#此示例能夠上述提到的根據具體主機分別設置參數的問題。關鍵就是使用template模塊並使用正確的變量

條件測試:

when語句,只有知足when條件纔會執行任務

cat dfile.yml  
- hosts: webservers
  remote_user: root
  tasks:
  - name: copy file
    copy: src=/root/diff1.txt dest=/app/
    when: ansible_default_ipv4['address'] == '172.18.251.244'  #只有知足此條件纔可以執行此任務
    #此條件說明當地址爲127.18.251.244時執行copy模塊的操做,ansible_default_ipv4是ansible的內置變量,中括號[]表示調用變量的子鍵
    #
  - name: copy file2
    copy: src=/root/diff2.txt dest=/app/
    when: ansible_default_ipv4['address'] == '192.168.1.107'
    #
ansible-playbook  --syntax-check dfile.yml 
#檢查語法
ansible-playbook  dfile.yml

循環:迭代

須要重複執行任務,如在遠程主機上安裝多個程序包

cat tomcat.yml  
- hosts: dbservers
  remote_user: root
  vars:
  - jdk_version: 1.8.0   #定義變量
  tasks:
  - name: install  pkgs
    yum: name={{ item }} state=latest   #變量的調用方法是{{ }},而item是變量,其內容就是with_items中的
    with_items: 
    - nginx
    - java-{{ jdk_version }}-openjdk   #此處使用變量調用上文的內容
    - tomcat 
    - tomcat-webapps
    - tomcat-docs-webapp
    - tomcat-admin-webapps
    #以上是在一個任務中要安裝的軟件包
    擴展:以上是在一個任務中安裝多個軟件包,若是是建立多個用戶、組也是相似的方法
    總結:迭代循環配合變量,迭代的關鍵字段是with_items,變量的調用使用{{ }}
    
ansible-playbook  tomcat.yml   #執行操做

下面思考一個問題:

若是使用循環方式安裝多個軟件包,而每一個軟件包的版本號基本是不同的,那如何動態的在安裝軟件包時添加版本號,而不是事先寫好在yaml文件中?

解決上述問題須要調用字典

cat tomcat.yml  
- hosts: dbservers
  remote_user: root
  tasks:
  - name: install  pkgs
    yum: name={{ item.name }}-{{ item.version }} state=latest   #item是使用循環的固定變量,此處item變量調用字典內容
    with_items:    #此處即所謂的字典,定義好軟件包名稱和版本號
    - { name: 'nginx', version: 1.10.2 }
    - { name: 'tomcat',version: 7.0.69 } 
#在一個任務中使用字典安裝軟件
ansible-playbook  -C tomcat.yml

再來看下面這個例子:循環加字典的使用
在控制端修改了兩份文件:tomcat-users.xml和 server.xml
如今要是先的是將此二份文件經過copy模塊複製到遠程主機
cat tomcat.yml 
- hosts: dbservers
  remote_user: root
  tasks:
  - name: install config file 
    copy: src={{ item.file }} dest={{ item.conf }}
    with_items:
    - { file: '/root/server.xml',conf: '/etc/tomcat/server.xml' }
    - { file: '/root/tomcat-users.xml',conf: '/etc/tomcat/tomcat-users.xml' }
#在字典中咱們定義file和conf
ansible-playbook  tomcat.yml
#完成上述步驟,就能夠到遠程主機上查看指定路徑的文件是否已經修改過

roles  角色:

vim /etc/ansible/ansible.cfg 
roles_path    = /etc/ansible/roles   #roles的路徑

/etc/ansible/roles/nginx/   
#其中nginx就是一個角色,在nginx目錄下應該具備特定的目錄層級結構,如:handlers  tasks  templates  vars
cat /etc/ansible/roles/nginx/tasks/main.yml    #tasks是nginx角色的一個任務模塊,main.yml是固定格式不能改變
- name: install nginx pkg
  yum: name=nginx state=latest
- name: start nginx service 
  service: name=nginx state=started enabled=true
  #此任務模塊完成兩個動做,安裝nginx和啓動nginx
  
而後配置playbook文件
cat websrv.yml 
- hosts: webservers
  remote_user: root
  roles:   #不須要像之前那樣配置tasks之類的,而是直接指定角色
  - nginx 
  #對webservers的主機以root身份調用nginx角色,而nginx橘色定義了兩個task任務

ansible-playbook  -C websrv.yml 
#測試

總結:建立角色nginx,配置playbook文件,而此文件只需調用角色便可,具體操做已經在角色的模塊中定義好了

示例:
基於模板生成nginx配置文件
第一步定義nginx內的變量                    #定義變量,將被templates模板調用
cat /etc/ansible/roles/nginx/vars/main.yml 
nginx_server_port: 8888
nginx_server_name: www.abc.com
nginx_doc_root: /webdata
第二步配置nginx下的模板文件                #定義模板文件,調用vars變量,此模板將用於生成nginx服務的配置文件
cat /etc/ansible/roles/nginx/templates/web-conf.j2 
server {
        listen {{ nginx_server_port }};
        server_name {{ nginx_server_name }};

        location  / {
                root {{ nginx_doc_root }};
        }
}
第三步定義nginx下的任務文件                #定義多項任務,安裝nginx、配置文件、建立文件、開啓服務
cat /etc/ansible/roles/nginx/tasks/main.yml  
- name: install nginx pkg
  yum: name=nginx state=latest
- name: install conf file
  template: src=web-conf.j2 dest=/etc/nginx/conf.d/web.conf
- name: create datadir
  file: path={{ nginx_doc_root }} state=directory    #此目錄即nginx模板文件中將使用的
- name: start nginx service 
  service: name=nginx state=started enabled=true
第四步配置playbook文件                #定義webservers組中主機以root身份調用nginx角色,而nginx角色能作什麼上述三個步驟已定義
cat /root/websrv.yml 
- hosts: webservers
  remote_user: root
  roles:
  - nginx
第五步測試i
ansible-playbook   websrv.yml 
#執行完上述操做,在遠程webservers主機的/etc/nginx/conf.d/web.conf文件中就會有nginx模板下web-conf.j2文件的內容
#

接着以上述實驗爲基礎,再繼續延伸

定義handlers模塊

進入nginx角色目錄下
cat handlers/main.yml 
- name: restart nginx service
  service: name=nginx state=restarted
而後咱們修改vars下的文件內容,如將端口修改
cat vars/main.yml 
nginx_server_port: 8888   #變量改變,templates文件就會變化,templates文件變化就會觸發notify執行handlers的動做
接着在tasks下修改觸發條件
cat tasks/main.yml 
- name: install conf file
  template: src=web-conf.j2 dest=/etc/nginx/conf.d/web.conf
  notify: restart nginx service   #此處notify定義的與handlers中的name對應
最後playbook文件內容不變
ansible-playbook  websrv.yml 

試想一下,若是每次修改配置文件,都要所有執行一遍playbook操做太麻煩並且也沒必要要
因此咱們可使用tags標籤,指定標籤的任務纔會執行,如:
vim tasks/main.yml 
 name: install conf file
  template: src=web-conf.j2 dest=/etc/nginx/conf.d/web.conf
  notify: restart nginx service
  tags: changed   #指定標籤,這樣修改配置文件後咱們只要對特定標籤進行操做便可
- name: create datadir
  file: path={{ nginx_doc_root }} state=directory 
  tags: changed   #此處使用與配置文件相同標籤,由於配置文件若是修改了目錄此處也要跟着修改
  #完成上述操做,咱們能夠修改配置文件,而後ansible下發配置便可
  ansible-playbook -t changed -C websrv.yml
  #測試

以上測試使用到模板文件、變量文件、觸發器、任務管理模塊 ,下面來使用靜態文件複製nginx的配置文件
 
靜態文件:
  編輯在角色下的files文件,做爲靜態文件
  vim files/nginx.conf    #隨便修改寫內容,如日誌格式,只要能看到效果便可
  cat  tasks/main.yml    #修改tasks配置文件
- name: install config file2
  copy: src=nginx.conf dest=/etc/nginx/nginx.conf    #複製靜態文件
  notify: restart nginx service    #啓動觸發,一旦此文件被修改就會執行handlers操做
  tags: changed    #一樣的此任務也加入同一標籤中
  而後執行便可
  ansible-playbook -t changed  websrv.yml


結束

相關文章
相關標籤/搜索