1. 程式人生 > 實用技巧 >設計模式之代理模式(proxy)

設計模式之代理模式(proxy)

一、變數介紹

1.概念

變數提供了便捷的方式來管理Ansible playbook的每一個專案中的動態值,比如nginx-1.6.3這個軟體包的版本,在其它地方或許會反覆使用,那麼如果講此值設定為變數,然後再在其他的playbook中呼叫,會方便許多。如此一來還方便維護,減少維護的成本。

2.定義變數的方式

1.通過命令列進行變數定義
2.在playbook檔案中進行變數定義
3.通過Inventory主機資訊檔案中進行變數定義
4.通過vars_files的方式定義變數
5.通過host_vars和group_vars定義變數

二、變數的設定

1.在playbook檔案中進行變數定義

1)方式一:在模組下面定義變數

- hosts: web_group
  tasks:
    - name: ensure a list of packages installed
      yum:
        name: "{{ packages }}"
      vars:
        packages:
        - httpd
        - httpd-tools

    - name: remove server
      yum:
        name: "{{ packages }}"
        state: absent
      vars:
        packages:
        
- httpd - httpd-tools #問題:模組下定義變數,變數只在當前動作生效,到其他動作後變數需要重新定義

2)方式二:在hosts下面定義變數

- hosts: web_group
  vars:
    packages:
    - httpd
    - httpd-tools
  tasks:
    - name: ensure a list of packages installed
      yum:
        name: "{{ packages }}"

    - name:
      yum:
        name: "{{ packages }}
" state: absent

3)方式三:在hosts下面定義多個變數

- hosts: web_group
  vars:
    packages:
      - httpd
      - httpd-tools
    db:
      - mariadb-server
      - MySQL-python

  tasks:
    - name: install web server
      yum:
        name: "{{ packages }}"

    - name: install mariadb-server
      yum:
        name: "{{ db }}"
        
#問題:變數解除安裝hosts下面,可以解決多個動作分別設定變數的問題,但是設定的變數只能在當前的playbook中使用,其他的playbook無法使用

2.使用vars_file定義變數

1)定義變數檔案

[root@m01 ~]# vim vars.yml
web: 
  - httpd
  - httpd-tools
db: mariadb-server

2)palybook呼叫變數檔案

[root@m01 ~]# vim moudle_vars.yml 
- hosts: web_group
  vars_files: /root/vars.yml
  tasks:
    - name: install web server
      yum:
        name: "{{ web }}"
        state: absent

    - name: install mariadb-server
      yum:
        name: "{{ db }}"
        state: absent

3)新增變數檔案

[root@m01 ~]# vim vars1.yml 
nfs:
  - nfs-utils
  - rpcbind

4)呼叫多個變數檔案

[root@m01 ~]# vim moudle_vars.yml 
- hosts: web_group
  vars_files: 
    - /root/vars.yml
    - /root/vars1.yml
  tasks:
    - name: install web server
      yum:
        name: "{{ web }}"

    - name: install mariadb-server
      yum:
        name: "{{ db }}"

    - name: install nfs server
      yum:
        name: "{{ nfs }}"

3.在Inventory中定義變數

1)主機清單中定義變數

[root@m01 ~]# vim /etc/ansible/hosts
[web_group]
web01 ansible_ssh_pass='1'
web02 ansible_ssh_pass='1'
web03 ansible_ssh_pass='1'

... ...

[nginx_group:children]
web_group
slb

[web_group:vars]
web=httpd
db=mariadb-server

[nginx_group:vars]
web=nginx
rsync=rsync

2)呼叫變數

- hosts: web_group
  tasks:
    - name: install web server
      yum:
        name: "{{ web }}"
        state: absent

    - name: install db server
      yum:
        name: "{{ db }}"

#問題:
    1.主機清單定義變數,只能給某個組使用,如果所有主機都使用需要定義很多變數
    2.主機清單內容很多的時候,配置變數會使檔案變得太大

3)複合組定義變數

[root@m01 ~]# vim /etc/ansible/hosts
[web_group]
web01 ansible_ssh_pass='1'
web02 ansible_ssh_pass='1'
web03 ansible_ssh_pass='1'

... ...

[nginx_group:children]
web_group
slb

[web_group:vars]
web=httpd
db=mariadb-server

[nginx_group:vars]
web=nginx
rsync=rsync

4)呼叫變數

[root@m01 ~]# vim mkdir.yml 
- hosts: nginx_group
  tasks:
    - name: Mkdir dir
      file:
        path: /tmp/{{web}}
        state: directory

    - name: Mkdir dir
      file:
        path: /tmp/{{rsync}}
        state: directory
        
#執行結果
[root@m01 ~]# ansible-playbook mkdir.yml

[root@web01 ~]# ll /tmp/
total 0
drwxr-xr-x 2 root root 6 Sep 23 17:52 httpd
drwxr-xr-x 2 root root 6 Sep 23 17:52 rsync

[root@lb01 ~]# ll /tmp/
total 0
drwxr-xr-x 2 root root 6 Sep 23 17:52 nginx
drwxr-xr-x 2 root root 6 Sep 23 17:52 rsync

#結論:主機清單定義變數時,複合組定義的變數優先順序低於主機組定義的

4.使用內建變數

1)直接使用內建變數

[root@m01 ~]# vim mkdir.yml 
- hosts: nginx_group
  tasks:
    - name: Mkdir dir
      file:
        path: /backup/{{ansible_fqdn}}_{{ansible_eth1.ipv4.address}}_{{ansible_date_time.date}}
        state: directory

2)內建變數設定變數

[root@m01 ~]# vim mkdir.yml 
- hosts: nginx_group
  vars:
    - remote_ip: "{{ansible_eth1.ipv4.address}}"
    - host: "{{ansible_fqdn}}"
    - date: "{{ansible_date_time.date}}"
  tasks:
    - name: Mkdir dir
      file:
        path: /backup/{{remote_ip}}_{{host}}_{{date}}
        state: directory

3)內建變數常用方式

#編寫配置檔案
[root@m01 ~]# vim /root/conf/redis.conf
bind {{ansible_eth1.ipv4.address}}

#編寫playbook
[root@m01 ~]# vim redis.yml 
- hosts: web_group
  tasks:
    - name: Install Redis Server
      yum:
        name: redis

    - name: Config Redis Server
      template:
        src: /root/conf/redis.conf
        dest: /etc/
        
#執行
[root@m01 ~]# ansible-playbook redis.yml

#檢視結果
[root@web01 ~]# grep "^bind" /etc/redis.conf 
bind "172.16.1.7"
[root@web02 ~]# grep "^bind" /etc/redis.conf
bind "172.16.1.8"
[root@web03 ~]# grep "^bind" /etc/redis.conf
bind "172.16.1.9"

5.通過host_vars和group_vars定義變數

之前的幾種變數定義都不是很好用,比較好用的是在Ansible專案目錄下建立兩個變數目錄:
host_vars
group_vars
切記,目錄名字一定要一致,不能做任何修改。

1)主機組定義變數

1.建立主機組變數目錄(名字一定是group_vars)
[root@m01 ~]# mkdir group_vars

2.主機組目錄下建立變數檔案(檔名字一定是主機清單中主機組的名字)
[root@m01 ~]# vim group_vars/web_group
web: httpd

3.呼叫變數
[root@m01 ~]# vim mkdir.yml 
- hosts: web_group
  tasks:
    - name: Mkdir dir
      file:
        path: /tmp/{{web}}
        state: directory

2)主機定義變數

1.建立主機變數目錄(名字一定是host_vars)
[root@m01 ~]# mkdir host_vars

2.主機目錄下建立變數檔案(檔名字一定是主機清單中主機的名字)
[root@m01 ~]# vim host_vars/web01
web: web01_host_vars

3.呼叫變數
[root@m01 ~]# vim mkdir.yml 
- hosts: web_group
  tasks:
    - name: Mkdir dir
      file:
        path: /tmp/{{web}}
        state: directory
        
4.執行
[root@m01 ~]# ansible-playbook mkdir.yml 

5.檢視結果
[root@web01 ~]# ll /tmp
total 0
drwxr-xr-x 2 root root 6 Sep 23 18:57 web01_host_vars
[root@web02 ~]# ll /tmp
total 0
drwxr-xr-x 2 root root 6 Sep 23 18:57 httpd
[root@web03 ~]# ll /tmp
total 0
drwxr-xr-x 2 root root 6 Sep 23 18:57 httpd

3)測試

#1.配置主機清單
[root@m01 ~]# cat /etc/ansible/hosts 
[web_group]
web01 ansible_ssh_pass='1'
web02 ansible_ssh_pass='1'
web03 ansible_ssh_pass='1'

[slb]
lb01 ansible_ssh_pass='1'

[nginx_group:children]
web_group
slb

#2.配置變數
[root@m01 ~]# cat group_vars/nginx_group
web: nginx_group
[root@m01 ~]# cat group_vars/web_group
web: web_group
[root@m01 ~]# cat host_vars/web01
web: web01_host_vars

#3.呼叫變數
[root@m01 ~]# vim mkdir.yml 
- hosts: nginx_group
  tasks:
    - name: Mkdir dir
      file:
        path: /tmp/{{web}}
        state: directory
        
#4.執行
[root@m01 ~]# ansible-playbook mkdir.yml

#5.檢視結果
[root@lb01 ~]# ll /tmp/
drwxr-xr-x 2 root root 6 Sep 23 19:02 nginx_group
[root@web01 ~]# ll /tmp
total 0
drwxr-xr-x 2 root root 6 Sep 23 19:02 web01_host_vars
[root@web02 ~]# ll /tmp
total 0
drwxr-xr-x 2 root root 6 Sep 23 19:02 web_group
[root@web03 ~]# ll /tmp
total 0
drwxr-xr-x 2 root root 6 Sep 23 19:02 web_group

#6.結論:
    主機定義的優先順序高於主機組,主機組定義的變數優先順序高於複合組

6.通過命令列進行變數定義

通過命令列覆蓋變數,Inventory的變數會被playbook檔案中覆蓋,這兩種方式的變數都會被命令列直接指定變數所覆蓋,使用--extra-vars或者-e設定變數

1)使用命令列定義單個變數

[root@m01 ~]# ansible-playbook mkdir.yml -e "web=commend"

2)使用命令列定義多個變數

[root@m01 ~]# ansible-playbook mkdir.yml -e "web=commend" -e "db=mysql"

#注意:指定的變數會根據命令列執行,沒有指定的變數繼續按照變數的設定執行

7.變數呼叫的優先順序測試

#1.定義vars_file變數
[root@m01 ~]# vim vars.yml
web: vars_file

#2.主機清單定義變數
[root@m01 ~]# vim /etc/ansible/hosts
[nginx_group:vars]
web=host_vars

#3.主機組定義變數
[root@m01 ~]# vim group_vars/nginx_group 
web: group_vars

#4.主機定義變數
[root@m01 ~]# vim host_vars/web01 
web: host_vars

#5.playbook定義變數
[root@m01 ~]# vim mkdir.yml 
- hosts: nginx_group
  vars:
    web: playbook_vars
  vars_files: /root/vars.yml
  tasks:
    - name: Mkdir dir
      file:
        path: /tmp/{{web}}
        state: directory
        
#6.命令列執行定義變數
[root@m01 ~]# ansible-playbook mkdir.yml -e "web=command"

#7.依次執行,得到結論
優先順序排序:從上到下以此降低
    1.命令列
    2.vars_files
    3.playbook中配置變數
    4.主機定義變數
    5.主機組定義變數
    6.主機清單定義變數

8.層級定義變數

#編輯變數檔案
[root@m01 ~]# vim vars_file.yml
lamp:
  framework:
    web_package: httpd
    db_package: mariadb-server
    php_package: php

lnmp:
  framework:
    web_package: nginx
    db_package: mysql
    php_package: php

lnmt:
  framework:
    web_package: nginx
    db_package: mysql
    java_package: tomcat

#編輯playbook檔案
[root@m01 ~]# vim test.yml
- hosts: web_group
  vars_files: ./vars_file.yml
  tasks:
    - name: Install LAMP httpd
      yum:
        name: "{{ lamp.framework.web_package }}"

    - name: Install LAMP mariadb-server
      yum:
        name: "{{ lamp.framework.db_package }}"

    - name: Install LAMP php
      yum:
        name: "{{ lamp.framework.php_package }}"
        
#官方推薦寫法
[root@m01 ~]# vim test.yml
- hosts: web_group
  vars_files: ./vars_file.yml
  tasks:
    - name: Install LAMP httpd
      yum:
        name: "{{ lamp['framework']['web_package'] }}"

    - name: Install LAMP mariadb-server
      yum:
        name: "{{ lamp['framework']['db_package'] }}"

    - name: Install LAMP php
      yum:
        name: "{{ lamp['framework']['php_package'] }}"

#執行playbook
[root@m01 ~]# ansible-playbook test.yml

三、變數註冊

當absible的模組在執行之後,其實都會返回一些result結果,就像是執行指令碼,我們有的時候需要指令碼給我們一些return返回值,我們才知道,上一步是否可以執行成功,但是...預設情況下,ansible的result並不會顯示出來,所以,我們可以把這些返回值'儲存'到變數中,這樣我們就能通過'呼叫'對應的變數名,從而獲取到這些result,這種將模組的返回值,寫入到變數中的方法被稱為變數註冊

1.變數註冊配置

1)配置

[root@m01 ~]# vim list.yml 
- hosts: web01
  tasks:
    - name: list dir
      shell: ls -l /root
      register: list_dir

2)輸出呼叫的變數

[root@m01 ~]# vim list.yml 
- hosts: web01
  tasks:
    - name: list dir
      shell: ls -l /root
      register: list_dir
      
    - name: get list_dir
      debug:
        msg: "{{ list_dir }}"

3)輸出我們想要的部分

[root@m01 ~]# vim list.yml 
- hosts: web01
  tasks:
    - name: list dir
      shell: ls -l /root
      register: list_dir
      
    - name: get list_dir
      debug:
        msg: "{{ list_dir.stdout_lines }}"

2.變數註冊使用場景

1)編寫劇本

#一般使用變數註冊進行判斷
[root@m01 ~]# cat install.yml 
- hosts: nfs
  tasks:
    - name: decide nfs status
      shell: systemctl is-active nfs
      ignore_errors: yes
      register: nfs_status

    - name: Start nfs
      systemd:
        name: nfs
        state: started
      when: nfs_status.rc != 0

    - name: Restart nfs
      systemd:
        name: nfs
        state: restarted 
      when: nfs_status.rc == 0

四、facts快取

1.概述

Ansible facts是在被管理主機上通過Ansible自動採集發現的變數。facts包含每臺特定的主機資訊。比如:被控端的主機名、IP地址、系統版本、CPU數量、記憶體狀態、磁碟狀態等等。

setup模組實際上就是facts快取得到的

2.使用場景

1.通過facts快取檢查CPU,來生成對應的nginx配置檔案
2.通過facts快取檢查主機名,生成不同的zabbix配置檔案
3.通過facts快取檢索物理機的記憶體大小來生成不通的mysql配置檔案

綜上所述的Ansible facts類似於saltstack中的grains對於做自動化的小夥伴是非常有用滴。

3.基本用法

#編輯
[root@m01 ~]# vim facts.yml
- hosts: web_group
tasks:
- name: Get Host Info
debug:
msg: Hostname "{{ ansible_fqdn }}" and IP "{{ ansible_default_ipv4.address }}"

4.關閉facts快取

[root@m01 ~]# vim facts.yml
- hosts: web_group
  gather_facts: no #關閉資訊採集
  tasks: