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