天天看點

Ansible的Playbook基操

  • playbook

    是由一個或多個

    "play"

    組成的清單
  • play的主要功能在于将預定義的一組主機,裝扮成事先通過ansible中的task定義好的角色。
  • Task實際是調用ansible的一個module,将多個play組織在一個

    playbook

    中, 即可以讓它們聯合起來,按事先編排的機制執行預定義的動作
  • Playbook

    采用

    YAML

    語言編寫
---
- hosts: test # 指定主機清單
  remote_user: root # 遠端操作以什麼身份執行
  tasks:
    - name: Install Redis  # 提示字段,表示目前處于什麼進度
      command:  install redis # 目前執行的具體指令操作           

複制

1.0 PlayBook核心元素

  • Hosts

    :playbook中的每一個play的目的都是為了讓特定主機以某個指定的使用者身份執行任務,hosts用于指定要執行指定任務的主機,須事先定義在主機清單中.
    • 詳細請看
  • remote_user

    : 可用于Host和task中。也可以通過指定其通過sudo的方式在遠端主機上執行任務,其可用于play全局或某任務.此外,甚至可以在sudo時使用sudo_user指定sudo時切換的使用者.
  • varniables

    : 内置變量或自定義變量在playbook中調用
  • Templates模闆

    : 可替換模闆檔案中的變量并實作一些簡單邏輯的檔案
  • Handlers和notify

    : 結合使用,由特定條件觸發的操作,滿足條件方才執行,否則不執行
  • tags

    : 指定某條任務執行,用于選擇運作playbook中的部分代碼.
ansible-playbook -C hello.yaml 
- C 選項檢查劇本是否成功,并不實際執行           

複制

1.0.1 忽略錯誤資訊

tasks:
 - name: run this 
   shell: /usr/bin/ls || /bin/true            

複制

也可以使用

ignore_errors

來忽略錯誤資訊

tasks:
 - name: run this 
   shell: /usr/bin/ls || /bin/true 
   ignore_errors: True           

複制

1.0.2 常用選項

  • --check

    : 隻檢測可能會發生的改變,但是不會執行
  • --list-hosts

    : 列出運作任務的主機
  • --limit

    : 主機清單,隻針對主機清單中的主機執行
  • -v

    : 顯示過程
  • --list-tasks

    : 檢視任務清單
ansible-playbook hello.yaml  --check
ansible-playbook hello.yaml  --list-hosts
ansible-playbook hello.yaml  --limit 10.1.6.111           

複制

2.0 Handlers和notify

由于playbook執行會有次序問題,是以當出現次序問題的時候,可以使用handlers結合notify
  • Handlers

    : 是

    task

    清單,這些task與前述的task沒有本質的差別,用于當不同的資源發生變化的時候,才會采取一定的操作.
  • Notify

    : 此action可以用在每個play的最後被觸發,這樣可以避免多次有改變的發生時每次都執行指定的操作,僅僅在所有變化發生完後,一次性執行制定操作,在notify中列出的操作稱為

    hendler

    ,也就是notify中定義的操作.

Handlers

notify

可以寫多個
---
- hosts: test
  remote_user: root
  tasks:
    - name: "create new file"
      file: name=/data/newfile state=touch
    - name: "create new user"
      user: name=test2 system=yes shell=/sbin/nologin
    - name: "install httpd"
      yum:   name=httpd state=installed
      notify: restart service  # 表示執行完yum操作以後需要執行handlers的操作
    - name: "copy log"
      copy: src=/var/log/httpd/error_log   dest=/data
  handlers:
    - name: restart service 
      service: name=httpd state=restarted           

複制

3.0 PlayBook的tags使用

  • 給特定的内容打上tags可以單獨的執行标簽内容
---
- hosts: test
  remote_user: root
  tasks:
    - name: "create new file"
      file: name=/data/newfile state=touch
      tags: newfile
    - name: "create new user"
      user: name=test2 system=yes shell=/sbin/nologin
      tags: newuser
    - name: "install httpd"
      yum:   name=httpd state=installed
      notify: restart service  # 表示執行完yum操作以後需要執行handlers的操作
    - name: "copy log"
      copy: src=/var/log/httpd/error_log   dest=/data
  handlers:
    - name: restart service 
      service: name=httpd state=restarted           

複制

ansible-playbook -t newfile test.yaml # 表示隻執行newfile标簽的動作
ansible-playbook -t newfile,newuser test.yaml # 表示隻執行newfile标簽的動作           

複制

4.0 PlayBook中變量的使用

  • 變量名:僅能由字母、數字和下劃線組成,且隻能以字母開頭
  • 變量的來源
    • 通過

      setup

      子產品
    • /etc/ansible/hosts

      中定義
  1. 普通變量:主機組中的主機單獨定義,優先級高于公共變量
  2. 公共變量:針對主機組所有主機定義統一變量
  3. 通過指令行指定變量: 優先級最高

4.0.1 通過指令行指定變量

---
- hosts: test
  remote_user: root
  tasks:
    - name: "create new file"
      file: name=/data/{{filename}} state=touch
      tags: newfile
      
ansible-playbook -e 'filename=app1'  # /data/app1           

複制

4.0.2 在playbook中定義

# 在playbook中定義
---
- hosts: test
  remote_user: root
  vars:
   - filename: app1
  tasks:
    - name: "create new file"
      file: name=/data/{{filename}} state=touch
      tags: newfile           

複制

4.0.3 通過setup子產品擷取變量

ansible setup facts 遠端主機的所有變量都可直接調用 (系統自帶變量)
setup子產品可以實作系統中很多系統資訊的顯示
ansible all -m setup -a 'filter="ansible_nodename"'     查詢主機名
ansible all -m setup -a 'filter="ansible_memtotal_mb"'  查詢主機記憶體大小
ansible all -m setup -a 'filter="ansible_distribution_major_version"'  查詢系統版本
ansible all -m setup -a 'filter="ansible_processor_vcpus"' 查詢主機cpu個數           

複制

4.0.4 在hosts中定義變量

  • 定義主機組單獨的變量
[test]
192.168.1.1 http_port=81
192.168.1.2 http_port=82
---
- hosts: test
  remote_user: root
  tasks:
    - name: "create new file"
      hostname: name=www{{http_port}}.baidu.com           

複制

  • 定義公共變量
# 針對test主機組當中的所有主機都有效
[test:vars]
nodename=www
domain=baidu.com           

複制

4.0.5 通過檔案加載變量

# vars.yaml
filename: applications
# playbook.yaml
- hosts: test
  remote_user: root
  vars_files:
    - vars.yaml
  tasks:
    - name: "create new file"
      file: name=/data/{{filename}}           

複制

5.0 模闆Templates

  • 采用

    Jinja2

    語言,使用字面量,有下面形式
  • 數字:整數,浮點數
    • 清單:[item1, item2, …]
    • 元組:(item1, item2, …)
    • 字典:{key1:value1, key2:value2, …}
    • 布爾型:true/false
  • 算術運算:+, -, *, /, //, %, **
  • 比較操作:==, !=, >, >=, <, <=
  • 邏輯運算:and,or,not
  • 流表達式:For,If,When
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes {{ansible_processor_vcpus**2}}; # 例如,你可以将nginx核心數動态的設定為主機的CPU數量
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;           

複制

5.0.1 When文法

  • 條件測試:如果需要根據變量、facts或此前任務的執行結果來做為某task執行與否的前提時要用到條件測試, 通過when語句實作,在task中使用,jinja2的文法格式
  • 在task後添加when子句即可使用條件測試;when語句支援Jinja2表達式文法

ansible_distribution

=CentOS的時候才會去執行template
---
- hosts: test
  remote_user: root
  tasks:
    - name: "Install Nginx"
      yum: name=nginx 
    - name: Config conf
      template: src=/templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf
      when: ansible_distribution == "CentOS"
    - name: start nginx
      service: name=nginx state=started enabled=yes           

複制

5.0.2 With_item

  • 疊代寫法
---
- hosts: test
  remote_user: root
  tasks:
    - name: "Create new file"
      file: name=/data/{{items}} state=touch
      with_items:
        - app1
        - app2
        - app3           

複制

  • 疊代嵌套子變量
- hosts: test
  remote_user: root
  tasks:
    - name: "Create new file"
      file: name=/data/{{item.name}}_{{item.date}} state=touch
      with_items:
        - {name: 'app1', date: '2022'}           

複制

5.0.3 for循環

---
- hosts: test
  remote_user: root
  vars:
    ports:
      - 81
      - 82
      - 83
  tasks:
    - name: copy template
      template: src=/root/templates/for.j2 dest=/data/for.conf
# 或者
---
- hosts: test
  remote_user: root
  vars:
    ports:
      - listen:81
      - listen:82
      - listen:83
  tasks:
    - name: copy template
      template: src=/root/templates/for.j2 dest=/data/for.conf
# 或者
---
- hosts: test
  remote_user: root
  vars:
    config:
      - host1:
        port: 81
        name: host1.do.com
        rootdir: /root/     
  tasks:
    - name: copy template
      template: src=/root/templates/for.j2 desc=/data/for.conf           

複制

建立一個模闆檔案
{%for i in ports%}
server {
 listen {{i}}
}
{%endfor%}
# 或者
{%for i in ports%}
server {
 listen {{i.listen}}
}
{%endfor%}
# 或者
{%for i in ports%}
server {
 listen {{ i.port }}
 name  {{ i.name }}
}
{%endfor%}           

複制

5.0.4 if判斷

{%for i in ports%}
server {
 listen {{ i.port }}
 {% if i.name is defind %}
 name  {{ i.name }}
 {% endif %}
}
{%endfor%}a           

複制

6.0 Role角色

  • 将目錄進行拆分,變量放在變量檔案夾,劇本放在劇本檔案夾
  • 複雜場景:建議使用roles,代碼複用度高
  • 存放在

    /etc/ansible/roles/

    目錄下
[root@bogon ansible]# tree
.
├── ansible.cfg
├── hosts
└── roles
    ├── httpd
    ├── nginx
    └── redis           

複制

  • 一般的角色檔案結構
    • nginx
      • tasks: 定義role的基本原色,至少包含一個

        main.yaml

        的檔案,其他檔案需要在此檔案中包含
      • files: 存放

        COPY

        或者

        Script

        的子產品腳本檔案
      • vars: 至少包含一個

        main.yaml

        的檔案
      • default: 設定預設變量時使用此目錄的

        main.yaml

      • templates:

        template

        子產品查抄所需要模闆檔案的目錄
      • handlers: 至少包含一個

        main.yaml

        的檔案
      • meta: 定義目前角色的特殊設定及其依賴關系,至少包含一個

        main.yaml

        的檔案