Ansbile - Playbook 使用

目錄

  1. Ansible - 安裝介紹
  2. Ansible -常用模塊介紹
  3. Ansbile - Playbook 使用
  4. Ansible - Roles 使用示例

參考

  1. bilibili馬哥視頻
  2. 運維派教程

介紹

Playbook中,使用task來定義一個子任務,並在任務中指定需要使用的模塊,以及觸發條件等信息。最終一個PlaybookYml文件中可由多個task組成,按照任務順序對指定主機進行自動化運維


YAML語言

教程

https://www.runoob.com/w3cnote/yaml-intro.html


核心元素

  • Hosts 執行的遠程主機列表
  • remote_user:指定執行任務時在遠程主機上所用的用戶
  • Tasks 任務集
  • Variables 內置變量或自定義變量在playbook中調用
  • Templates 模板,可替換模板文件中的變量並實現一些簡單邏輯的文件
  • Handlers 和 notify 結合使用,由特定條件觸發的操作,滿足條件方纔執行,否則不執行
  • tags 標籤 指定某條任務執行,用於選擇運行playbook中的部分代碼。ansible具有冪等性,因此會自動跳過沒有變化的部分,即便如此,有些代碼爲測試其確實沒有發生變化的時間依然會非常地長。此時,如果確信其沒有變化,就可以通過tags跳過此些代碼片斷

注:hosts用於指定要執行指定任務的主機,須事先定義在主機清單中


playbook命令

格式

ansible-playbook <filename.yml> ... [options]

常見選項

-C --check          #只檢測可能會發生的改變,但不真正執行操作
--list-hosts        #列出運行任務的主機
--list-tags         #列出tag
--list-tasks        #列出task
--limit 主機列表      #只針對主機列表中的主機執行
-v -vv  -vvv        #顯示過程

playbook初步

開啓遠程主機mysql的遠程訪問權限

[root@localhost playbook]# cat config-mysql.yml 
---
  - hosts: csmp
    gather_facts: no
    tasks:
    - name: Open mysql remote access permissions
      replace: path=/etc/my.cnf.d/server.cnf regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
    - name: restart mysql
      service: name=mysql state=restarted

執行

[root@localhost playbook]# ansible-playbook config-mysql.yml -vv


handlers和notify

作用

只有當關注的資源發生變化時,纔會採取一定的操作。在notify中列出的操作成爲handler

示例

改寫上面的例子,只有當配置文件修改的時候才重啓mysql服務

---
  - hosts: csmp
    gather_facts: no
    tasks:
    - name: Open mysql remote access permissions
      replace: path=/etc/my.cnf.d/server.cnf regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
      notify: restart mysql

    handlers:
    - name: restart mysql
      service: name=mysql state=restarted


tags組件

作用

playbook中,可以利用tags組件,爲特定task指定標籤,當在執行playbook時,可以只執行特定tagstasks,而非整個playbook文件

示例

---
  - hosts: csmp
    gather_facts: no
    tasks:
    - name: Open mysql remote access permissions
      replace: path=/etc/my.cnf.d/server.cnf regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
      tags: replace
    - name: restart mysql
      service: name=mysql state=restarted
      tags: effective

此時就可只通過tags執行其中某一個task

[root@localhost playbook]# ansible-playbook config-mysql.yml --list-tags

playbook: config-mysql.yml

  play #1 (csmp): csmp	TAGS: []
      TASK TAGS: [effective, replace]
      
#  -t TAGS, --tags TAGS  only run plays and tasks tagged with these values
[root@localhost playbook]# ansible-playbook -t effective config-mysql.yml

ansible中使用變量

定義

僅能由字母、數字和下劃線組成,且只能以字母開頭

variable=value

調用

通過{ { variable_name }} 調用變量,且變量名前後建議加空格,有時用“{ { variable_name }}”才生效


使用setup模塊中變量

要求在playbook中使用,不要用ansible命令調用

---
#var.yml
- hosts: all
  remote_user: root
  gather_facts: yes

  tasks:
    - name: create log file
      file: name=/data/{
   
               {
   
                ansible_nodename }}.log state=touch owner=wang mode=600

ansible-playbook  var.yml

在playbook命令行中定義變量

通過-e參數使用

  -e EXTRA_VARS, --extra-vars EXTRA_VARS
                        set additional variables as key=value or YAML/JSON, if
                        filename prepend with @

示例:

---
  - hosts: "{
   
                { server }}"
    gather_facts: no
    tasks:
     - name: Open mysql remote access permissions
       replace: path=/etc/my.cnf.d/server.cnf regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
       notify: restart mysql

    handlers:
     - name: restart mysql
       service: name=mysql state=restarted

在執行時通過-e指定server變量。

[root@localhost playbook]# ansible-playbook config-mysql.yml -e server=10.47.119.156

在playbook文件中定義變量

vars中定義變量,在後續直接使用

---
  - hosts: "{
   
                 { server }}"
    gather_facts: no
    vars:
     - path: /etc/my.cnf.d/server.cnf
    tasks:
     - name: Open mysql remote access permissions
       replace: path={
   
                 {
   
                  path }} regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
       notify: restart mysql

    handlers:
     - name: restart mysql
       service: name=mysql state=restarted


使用變量文件

可以在一個獨立的playbook文件中定義變量,在另一個playbook文件中引用變量文件中的變量,比playbook中定義的變量優先級高

# 定義變量文件
[root@localhost playbook]# cat config-mysql-var.yml 
---
server_conf_path: /etc/my.cnf.d/server.cnf

# playbook文件中引入使用
[root@localhost playbook]# cat config-mysql.yml 
---
  - hosts: "{
   
                  { server }}"
    gather_facts: no
    vars_files:
     - config-mysql-var.yml
    tasks:
     - name: Open mysql remote access permissions
       replace: path={
   
                  {
   
                   server_conf_path }} regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
       notify: restart mysql

    handlers:
     - name: restart mysql
       service: name=mysql state=restarted


主機清單文件中定義變量

  • 主機(普通)變量

inventory主機清單文件中爲指定得主機定義變量,以便在playbook中使用

[root@localhost playbook]# cat /etc/ansible/hosts 
[server]
10.47.119.156 server_conf_path=/etc/my.cnf.d/server.cnf
10.47.119.157 server_conf_path=/etc/my.cnf.d/server1.cnf


  • 組(公共)變量

在inventory 主機清單文件中賦予給指定組內所有主機上的在playbook中可用的變量,如果和主機變是同名,優先級低於主機變量

[root@localhost playbook]# cat /etc/ansible/hosts 
[server]
10.47.119.156 
10.47.119.157 

[server:vars]
server_conf_path=/etc/my.cnf.d/server.cnf

使用時直接使用變量即可

---
  - hosts: "{
   
                    { server }}"
    gather_facts: no
    tasks:
     - name: Open mysql remote access permissions
       replace: path={
   
                    {
   
                     server_conf_path }} regexp='^(bind-address=127.0.0.1)' replace='#\1' backup=true
       notify: restart mysql

    handlers:
     - name: restart mysql
       service: name=mysql state=restarted



template模板

jinja2語言

官網

https://jinja.palletsprojects.com/en/2.11.x/


template

功能

可以根據和參考模塊文件,動態生成相類似的配置文件

要求

template文件必須存放於templates目錄下,且命名爲 .j2 結尾
yaml/yml文件需和templates目錄平級,目錄結構如下示例:

.
├── config.yml
└── templates
	└── nginx.conf.j2

示例

# tree
.
├── config-nginx.yml
└── templates
    └── nginx.conf.j2

設置nginx進程數與ansible_processor_vcpus+1相等

# cat templates/nginx.conf.j2 

...
worker_processes {
  
                       { ansible_processor_vcpus+1 }};
...

playbook內容

# cat config-nginx.yml 
---
 - hosts: vm
   tasks: 
   - name: template config to remote hosts
     template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
     notify: restart nginx

   handlers:
   - name: restart nginx
     service: name=nginx state=restarted


使用setup模塊發現ansible_processor_vcpus值爲4,所以模板文件中對應nginx子進程數應爲5

# ansible vm -m setup -a 'filter=ansible_processor_vcpus'          
10.91.156.205 | SUCCESS => {
   
                          
    "ansible_facts": {
   
                          
        "ansible_processor_vcpus": 4, 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}

統計nginx子進程數目

# ansible vm -m 'shell' -a "ps aux | grep 'nginx: worker process' "
10.91.156.205 | CHANGED | rc=0 >>
nginx    24585  0.0  0.0 105956  3444 ?        S    15:05   0:00 nginx: worker process
nginx    24586  0.0  0.0 105956  3444 ?        S    15:05   0:00 nginx: worker process
nginx    24587  0.0  0.0 105956  3444 ?        S    15:05   0:00 nginx: worker process
nginx    24588  0.0  0.0 105956  3444 ?        S    15:05   0:00 nginx: worker process
nginx    24589  0.0  0.0 105956  3448 ?        S    15:05   0:00 nginx: worker process
...

流程控制

template中可使用流程控制 for 循環和 if 條件判斷,實現動態生成文件功能

for循環

示例

j2文件:

 ...
 {% for port in listen_ports %}
    server {
        listen {
  
                          { port }};
        root /usr/share/nginx/html;

        location / {
        }
    }

    {% endfor %}
...

playbook文件中src指定j2文件,拷貝到遠程主機後記得要修改名稱

---
 - hosts: vm
   gather_facts: no
   vars: 
     listen_ports:
     - 8888
     - 8889
   tasks: 
   - name: template config to remote hosts
     template: src=nginx-server.conf.j2 dest=/etc/nginx/nginx.conf backup=true
     notify: restart nginx

   handlers:
   - name: restart nginx
     service: name=nginx state=restarted

驗證發現服務器nginx.cnf中多出了8888,8889兩個server

...  
    server {
        listen 8888;
        root /usr/share/nginx/html;

        location / {
        }
    }

    server {
        listen 8889;
        root /usr/share/nginx/html;

        location / {
        }
    }
....

vars中變量是字典形式,形如

vars:
    nginx_vhosts:
      - listen: 8080
        server_name: "web1.magedu.com"
        root: "/var/www/nginx/web1/"
      - listen: 8081
        server_name: "web2.magedu.com"
        root: "/var/www/nginx/web2/"

jinja2就需要使用如下方式調用

{% for vhost in nginx_vhosts %}
server {
   listen {
  
                           { vhost.listen }}
   server_name {
  
                           { vhost.server_name }}
   root {
  
                           { vhost.root }}  
}
{% endfor %}

if 判斷

在模板文件中可通過條件判斷,來決定相關配置得生成信息。例如

# cat if-config.yml
---
 - hosts: vm
   gather_facts: no
   vars:
     nginx_vhosts:
      - listen: 80
        server_name: "server1"
        root: "/var/www/nginx/web1"
      - listen: 8080
        root: "var/www/nginx/web2"

   tasks:
    - name: template config if exp
      template: src=if-config.cnf.j2 dest=/root/if-config.cnf

模板文件

# cat templates/if-config.cnf.j2 

{% for vhosts in nginx_vhosts %}
server {
    listen {
  
                            { vhosts.listen }}
    {% if vhosts.server_name is defined %}
    server_name {
  
                            { vhosts.server_name }}
    {% endif %}
    root {
  
                            { vhosts.root }}
}
{% endfor %}

最終生成結果

#結果
server {
    listen 80
    server_name server1
    root /var/www/nginx/web1
}
server {
    listen 8080
    root var/www/nginx/web2
}

playbook使用when

when語句,可實現條件測試。如果需要根據變量,facts或此前任務得執行結果來作爲某task執行與否的前提時要用到條件測試。通過在task後添加when子句即可使用條件測試。

示例

如果ansible_os_family值爲RedHat則創建/root/redhat目錄,否則創建/root/others目錄

---
 - hosts: vm
   tasks:
   - name: mkdir redhat dir
     shell: mkdir /root/redhat
     when: ansible_os_family == "RedHat"
   - name: mkdir other dir
     shell: mkdir /root/otherOs
     when: ansible_os_family != "RedHat"



迭代with_items

作用

當有需要重複性執行的任務時,可以使用迭代機制。對迭代項的引用,固定變量名爲"item"。要在task中使用with_items給定要迭代的元素列表

列表元素格式

  • 字符串
---
 - hosts: vm
   gather_facts: no

   tasks:
    - name: install tools
      yum: name={
   
                                {
   
                                 item }} state=installed
      with_items:
       - lrzsz
       - wget

等同於

---
 - hosts: vm
   gather_facts: no

   tasks:
    - name: install lrzsz
      yum: name=lrzsz state=installed
    - name: install wget
      yum: name=wget state=installed
  • 字典
---
 - hosts: vm
   gather_facts: no

   tasks:
    - name: copy config file
      copy: src={
   
                                {
   
                                 item.src }} dest={
   
                                {
   
                                 item.dest }}
      with_items:
       - {
   
                                 src: /root/src1.cnf, dest: /root/dest1.txt }
       - {
   
                                 src: /root/src2.cnf, dest: /root/dest2.txt }



















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章