1. 程式人生 > >Ansible-playbook自動化運維

Ansible-playbook自動化運維

1.基本語法

playbook檔案格式為yaml語法.示例如下:
1.1 nginx.yaml

---
- hosts: all
  tasks:
      - name: Install Nginx Package
        yum: name=nginx state=present

      - name: Copy Nginx.conf
        template: src=./nginx.conf.j2 dest=/etc/nginx/nginx.conf owner=root group=root mode=0644 validate='nginx -t -c %s'
        notify:
           - Restart
Nginx Service
handlers: - name: Restart Nginx Service service: name=nginx state=restarted
---第一行表示該檔案是yaml檔案,非必須,建議寫上

hosts:all 定義該playbook針對的目標主機,all表示針對所有主機,這個引數支援Ad-Hoc模式的所有引數
tasks: 定義該playbook所有的tasks集合

name: Install Nginx Package定義一個task的名稱,建議根據task實際任務命名
yum: name=nginx state=
present 定義一個狀態的action,這裡使用yum模組,實現nginx軟體包的安裝 第6-9行使用template模板去管理/etc/nginx/nginx.conf檔案,owner,group定義該檔案的屬主及屬組,使用validate引數指檔案生成後使用nginx -t -c 檢測配置檔案語法,notify是觸發handlers,如果同步後,檔案md5值有變化的話會觸發handler 第10-12行定一個一個handler狀態讓Nginx去重啟,

1.2 主機清單檔案

cat /tmp/hosts

[nginx]
192.168.1.1
192.168.1.2
[nginx:vars]
ansible_python_interpreter=/usr/bin/python2.6

1.3 nginx.conf.j2

user                                    admin  admin;
worker_processes                        8;
worker_cpu_affinity                     {{ ansible_processor_cores }};
error_log                               /export/servers/nginx/logs/nginx_error.log  warn;
pid                                     /export/servers/nginx/run/nginx.pid;
worker_rlimit_nofile                    65535;
events 
{
                                        use epoll;
                                        worker_connections 65535;
}
http 
{
        include                         mime.types;
        default_type                    application/octet-stream;
        server_tokens                   on;
        log_format main                 '$remote_addr - $remote_user [$time_local] "$http_x_forwarded_for" "$http_j_forwarded_for" '
                                                        '"$request" $status $bytes_sent '
                                                        '"$http_referer" "$http_user_agent" '
                                                        '"$gzip_ratio"';
        #charset                        utf-8;
        server_names_hash_bucket_size   128;
        client_header_buffer_size       32k;
        large_client_header_buffers     4 32k;
        client_max_body_size            300m;
        sendfile                        on;
        tcp_nopush                      on;
        keepalive_timeout               0;
        tcp_nodelay                     on;
        client_body_buffer_size         512k;
        fastcgi_intercept_errors        on;
        proxy_connect_timeout           90;
        proxy_read_timeout              180;
        proxy_send_timeout              180;
        proxy_buffer_size               256k;
        proxy_buffers                   4 256k;
        proxy_busy_buffers_size         256k;
        proxy_temp_file_write_size      256k;
        proxy_intercept_errors          on;
        server_name_in_redirect         off;
        proxy_hide_header       X-Powered-By;

        gzip                            on;
        gzip_min_length                 100;
        gzip_buffers                    4 16k;
        gzip_http_version               1.0;
        gzip_comp_level                 9;
        gzip_types                      text/plain application/x-javascript text/css application/xml;
        gzip_vary                       on;
        gzip_proxied                       any;

include domains/*;
###########status#########
#        server
#                {
#                 listen                 80;
#                 server_name            status.360buy.com;
#        location / {
#                 stub_status            on;
#                 access_log             off;
#                 }
#        }
}

1.hosts檔案裡面定義了一個nginx組,裡面有2個IP
2.組變數ansible_python_interpreter是ansible自帶的影藏變數,是facts套件提供的;如果目標機器上python版本多,指定一個版本來執行
3.nginx.conf.j2是nginx.conf的模板檔案,裡面只針對worker_processes引數通過facts套件中的cpu核心數生成,其他配置都是預設的

1.4 檢查yaml檔案的語法是否正確

$ ansible-playbook -i /tmp/hosts nginx.yaml --syntax-check

1.5 檢查yaml檔案中的tasks任務

$ ansible-playbook -i /tmp/hosts nginx.yaml --list-task

1.6 檢查yaml檔案中的生效主機

$ ansible-playbook -i /tmp/hosts nginx.yaml --list-hosts

1.7 執行playbook

$ ansible-playbook -i /tmp/hosts nginx.yaml

1.8 執行playbook裡面特定的某個task,從某個task開始執行

$ ansible-playbook -i /tmp/hosts nginx.yaml --start-at-task='Copy Nginx.conf'

2.變數與引用
2.1 通過inventory檔案定義主機以及主機組變數
(1)靜態主機檔案

預設的ansible invetory是/etc/hosts檔案,可以通過ANSIBLE_HOSTS環境變數或者通過執行命令的時候加上-i

vim /tmp/hosts
# 定義組
[webservers]
10.187.11.34
10.187.137.191

# 組變數
[webservers:vars]
ansible_ssh_pass = '123456'

多個靜態檔案,可以寫不同的檔案裡,檔名字hosts不是必須

inventory可以指向一個目錄,這樣目錄裡面所有的檔案都會被載入進來,可以通過–list-hosts()來驗證

[admin@host-10-187-196-225 hosts_file]$ ansible -i /tmp/hosts_file/ webservers --list-hosts
    10.187.109.116
    10.189.92.46

(2)動態主機檔案

ansible.cfg配置檔案中的inventory配置項指向一個指令碼
這個指令碼有一定規範和引數要求
1.支援–list或者-l,這個引數執行後會顯示所有的主機以及主機組的資訊(JSON格式)
2.支援–host或者-H,這個引數後面需要指定一個host,執行結果會返回這臺主機的所有資訊(包括認證資訊,主機變數等),也是json格式

#!/usr/bin/env python
# -*- coding=utf-8 -*-
#########################
import argparse
import sys
import json

def lists():
    r = dict()
    h = ['172.17.42.10' + str(i) for i in range(1,4)]
    hosts = {'hosts':h}
    r['docker'] = hosts
    return json.dumps(r,indent=4)

def hosts(name):
    r = {'ansible_ssh_pass':'123456'}
    cpis = dict(r.items())
    return json.dumps(cpis,indent=4)

if __name__ == "__main__":
    '''新增argparse的引數類例項,新增一些-l和-H的幫助顯示提示'''
    parser = argparse.ArgumentParser()
    parser.add_argument('-l','--list',help='hosts list',action='store_true')
    parser.add_argument('-H','--host',help='hosts vars')
    '''vars方法把parser.parse_args()字典轉換過去判斷使用者輸入的內容'''
    args = vars(parser.parse_args())
    if args['list']:
        print lists()
    elif args['host']:
        print hosts(args['host'])
    else:
        parser.print_help()

用實際主機來跑一批任務

ansible -i hosts.py docker -m ping -k 

(3)主機檔案支援的變數

ansible_ssh_host 定義host ssh地址
ansible_ssh_port 定義host ssh埠
ansible_ssh_user 定義hosts ssh認證使用者
ansible_ssh_pass 定義hosts ssh 認證密碼
ansible_sudo 定義hosts sudo使用者
ansible_sudo_pass 定義hosts sudo密碼
ansible_sudo_exe 定義hosts sudo 路徑
ansible_connection 定義hosts連線方式
ansible_ssh_private_key_file 定義hosts私鑰
ansible_shell_type 定義hosts shell型別
ansible_python_interpreter 定義hosts任務執行python路徑
ansible_*_interpreter 定義hosts其他語言解析器路徑
2.2 通過playbook檔案當前目錄下新建group_vars和host_vars這2個目錄(目錄名字固定,不能改)

$ cat group_vars/nginx

---
key: NGINX

在當前目錄下執行playbook的時候,會自動去找group_vars和host_vars這2個目錄

2.3 通過ansible-playbook命令列引數傳入
(1)命令列傳遞變數

$ ansible-playbook -i /tmp/hosts nginx.yaml -e "key=KEY"

(2)命令列傳遞變數檔案

$ cat var.yaml
---
key: YAML
$ cat var.json
{"key":"JSON"}
$ ansible-playbook -i /tmp/hosts nginx.yaml -e "@var.json"
$ ansible-playbook -i /tmp/hosts nginx.yaml -e "@var.yaml"

2.4 在playbook檔案內使用vars(用的很少)

---
- hosts: all
  vars:
        key: Ansible
  tasks:
      - name: xxx
        deubg: msg="The {{ key}}"

2.5 在playbook檔案內使用vars_files引用外部變數檔案(也可以是json檔案,後期開發api模式主要用這種方式)

---
- hosts: all
  vars_files:
    - var.yaml
    - var.json

2.6 使用register內的變數

ansible的task之間還可以互相傳遞資料,把第一個task執行的結果register註冊為變數然後傳遞給第二個task

---
- hosts: all
  tasks:
      - name: register variable
        shell: hostname
        register: info
      - name: display variable
        debug: msg="The msg is {{ info }}"
        debug: msg="The msg is {{ info['stdout'] }}"

實際跑下看下結果(-l呢是在匹配主機inventory裡面再進一步篩選,只跑192.168.1.118主機)

$ ansible-playbook -i /tmp/hosts variable.yaml -l 192.168.1.118

3.迴圈
3.1 標準loops

分別列印one two這2個值

---
- hosts:all
  tasks:
      - name: debug loops
        debug: msg = "name---> {{ item }}"
        with_items:
            - one
            - two

with_items:值呢是python list資料結構,每個task會迴圈讀取list裡面的值,key的名稱是item,當然支援列表裡面巢狀字典,例子如下

---
- hosts:all
  tasks:
      - name: debug loops
        debug: msg = "name-----> {{ item.key }} value---->{{ item.value }}"
        with_items:
            - {key:"one",value:"value1"}
            - {key:"two",value:"value2"}

3.2 巢狀loops

實現一堆多或者多對多的合併

---
- hosts:all
  tasks:
      - name: debug loops
        debug: msg="name ----->{{ item[0] }}  value----->{{ item[1] }}"
        with_nested:
            - ['A']
            - ['a','b','c']

3.3 字典迴圈

---
- hosts:all
  tasks:
      - name: debug loops
        debug: msg="name ----->{{ item.key }}  value----->{{ item.value }}"
        with_dict: user   

3.4 檔案迴圈

---
- hosts:all
  tasks:
      - name: debug loops
        debug: msg="{{ item }}"
        with_fileglob:
            - /tmp/*.yaml

3.5 隨機迴圈

---
- hosts:all
  tasks:
      - name: debug loops
        debug: msg="{{ item }}"
        with_random_choice:
            - "ansible1"
            - "ansible2"
            - "ansible3"

3.6 條件判斷迴圈

---
- hosts:all
  tasks:
      - name: debug loops
        shell: cat /root/ansible
        register: host
        until: host.stdout.startswith('Master')
        retries:5
        delay:5

5秒執行一次cat /root/ansible,將結果註冊給變數host,判斷host.stdout的內容是否以Master開頭,條件成立,task執行完成,條件不成立,5秒後重試,5次還不成立,task執行失敗

4.lookups
從外部拉取資訊,定義給一個變數的形式,lookups外掛

轉載:https://www.cnblogs.com/PythonOrg/p/6593910.html
參考:https://blog.csdn.net/modoo_junko/article/category/3084431