1. 程式人生 > 實用技巧 >Ansible使用playbook自動化編譯安裝Nginx

Ansible使用playbook自動化編譯安裝Nginx

Ansible批量部署編譯安裝nginx

一、ansible介紹:

這次為大家介紹一款批量部署工具ansible,主要有以下幾點優點:1、充分利用現有設施。使用 Ansible 無需安裝服務端和客戶端,只要 SSH 即可。這意味著,任何一臺裝有 Ansible 的機器都可以成為強大的管理端。我覺得,這種去中心化的思路顯得更為靈活。可能有人會擔心 SSH 的效率,Ansible 的並行執行及加速模式或許可以打消你的顧慮。2、使用簡單,快速上手相當容易。Ansible 上手十分快,用 Ad-Hoc 可以應付簡單的管理任務,麻煩點的也可以定義 Playbook 檔案來搞定。3、採用人類易讀的格式。Ansible

的主機定義檔案使用 INI 格式,支援分組,能夠指定模式;此外也能動態生成,這對管理雲主機應當很有用。而 Playbook 則是 YAML 格式。4、能夠使用你熟悉的語言來編寫模組。雖然 Ansible 是使用 Python 開發的,但它不會將你限制到某種具體的程式語言,BashPythonPerlRuby 等等都可以,你擅長什麼就用什麼。

一言以蔽之,Ansible 背後的簡單化哲學深得我心。這也比較符合我選擇軟體的一貫原則。可能還有人會比較關心目前 Ansible 都有誰在用。畢竟,榜樣的力量是無窮。Puppet 不正是因為 Google 在用而吸引了不少眼球麼?據我所知,當前使用 Ansible

較為知名的使用者包括 FedoraRackspaceEvernote 等等。

Ansible企業應用:

23f68d34f8bf34f942cb05210dc86e42.png

二、主要架構功能:

Ansible Core. //核心功能

Modules:

Core Modules //核心功能

Customed Modules //自定義模組

Host Inventory //主機庫和主機清單,用來定義要管理的主機

File

CMDB(配置管理資料)

PlayBooks //劇本,定義沒個主機扮演的角色

Hosts. //主機

roles. //角色

Connection Plugins. //連線外掛,連線至被管控主機,完成併發連線,預設一次管理5臺,但是可以修改。

三、安裝配置

安裝:

# yum install ansible -y

(epel倉庫中)

程式:

ansible

ansible-playbook //唱劇本

ansible-doc //獲取幫助文件

配置檔案

/etc/ansible/ansible.cfg //核心配置檔案

主機清單:

/etc/ansible/hosts

外掛目錄:

/usr/share/ansible_plugins/

1、設定ansble到各個主機的免金鑰通訊:

[[email protected]~]# ssh-keygen

[[email protected]~]# ssh-copy-id 192.168.5.102

2、定義主機組:

[[email protected]~]# cd /etc/ansible/

[[email protected]]# vim hosts

[webserver]

192.168.5.102

192.168.5.104

3、檢視主機組內的主機:

[[email protected]]# ansible webserver --list-hosts

hosts (2):

192.168.5.102

192.168.5.104

4、定義角色路徑

[[email protected]~]# cat /etc/ansible/nginx.yaml

- hosts: 192.168.5.102

remote_user: root

roles:

-nginx_install ###roles目錄下的nginx_install目錄

-nginx_config ###roles目錄下的nginx_config目錄

5、檢視目錄結構:

[[email protected] roles]# tree

.

├── nginx_config

│ ├── default

│ ├── files

│ ├── handlers

│ │ └── main.yml

│ ├── meta

│ ├── tasks

│ │ └── main.yml

│ ├── templates

│ │ └── temp_server.conf

│ └── vars

│ └── main.yml

└── nginx_install

├──default

├──files

│ └── nginx-1.12.0.tar.gz

├──handlers

│ └── main.yml

├──meta

├──tasks

│ └── main.yml

├──templates

│ └── nginx.conf

└── vars

[[email protected]]# cd nginx_install/

[[email protected]_install]# ls

default fileshandlers meta taskstemplates vars

6、task定義開始任務:

[[email protected]_install]#cdtasks/
[[email protected]]#catmain.yml
-name:copynginxpackagetoremotehost
copy:src=nginx-1.12.0.tar.gzdest=/tmp/nginx-1.12.0.tar.gz##拉取nginx解壓吧
tags:cppkg
-name:tarnginx
shell:cd/tmp;tar-xfnginx-1.12.0.tar.gz##解壓nginx包
-name:installpakger
yum:name={{item}}state=latest##安裝依賴包
with_items:
-openssl-devel
-pcre-devel
-gcc
-name:installnginx
shell:cd/tmp/nginx-1.12.0;./configure--user=nginx--group=nginx--prefix=/usr/local/nginx--with-http_stub_status_module--with-http_ssl_module--with-pcre;make&&makeinstall####編譯安裝
-name:copyconffilenginx.conf
template:src=nginx.confdest=/usr/local/nginx/conf/nginx.conf###複製在template目錄下的配置檔案
tags:ngxconf
-name:copyshell
copy:src=/opt/create_users.shdest=/tmp/create_users.sh##拉取建立使用者的shell指令碼
-name:createusernginx
shell:/bin/bash/tmp/create_users.sh
tags:addnginx
notify:startnginxservice


為什麼要寫這個指令碼?因為加入有些主機建立的使用者已存在就會報錯

[[email protected]]#cat/opt/create_users.sh
#!/bin/bash
a=`cat/etc/passwd|grepnginx|wc-l`
if[$a==0];then
useraddnginx
fi


6、第二行copy對應file目錄:

[[email protected]_install]#cdfiles/
[[email protected]]#ls
nginx-1.12.0.tar.gz


7、template這一行對應的是template這個目錄和主服務端定義的變數:

[[email protected]_install]#cdtemplates/
[[email protected]]#ls
nginx.conf
[[email protected]]#catnginx.conf

usernginx;
worker_processes{{ansible_processor_vcpus}};

#error_loglogs/error.log;
#error_loglogs/error.lognotice;
#error_loglogs/error.loginfo;

#pidlogs/nginx.pid;


events{
worker_connections65535;
}


http{


includemime.types;
default_typeapplication/octet-stream;

#log_formatmain'$remote_addr-$remote_user[$time_local]"$request"'
#'$status$body_bytes_sent"$http_referer"'
#'"$http_user_agent""$http_x_forwarded_for"';
log_formatxiaoluo'$remote_addr-$remote_user[$time_local]'
'"$request"$status$body_bytes_sent'
'"$http_referer""$http_user_agent"';
#access_loglogs/access.logmain;

sendfileon;
#tcp_nopushon;

#keepalive_timeout0;
keepalive_timeout65;

#gzipon;

server{
listen{{ngxport}};
server_namewwwNaNl.com
access_loglogs/wwwNaNl.comxiaoluo;
#location/{
#proxy_passhttp://192.168.5.101;
#}

#error_page404/404.html;

#redirectservererrorpagestothestaticpage/50x.html
#
error_page500502503504/50x.html;
location=/50x.html{
roothtml;
}

#proxythePHPscriptstoApachelisteningon127.0.0.1:80
#
#location~\.php${
#proxy_passhttp://127.0.0.1;
#}

#passthePHPscriptstoFastCGIserverlisteningon127.0.0.1:9000
#
location~\.php${
root/web;
fastcgi_pass127.0.0.1:9000;
fastcgi_indexindex.php;
fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;
includefastcgi_params;
}

#denyaccessto.htaccessfiles,ifApache'sdocumentroot
#concurswithnginx'sone
#
#location~/\.ht{
#denyall;
#}
}
includevhosts/*.conf;
}

##需要注意的就是模板變數(客戶端自動採集)、和在服務端定義的變數`ngx_port`

8、在vars定義變數:

[[email protected]_install]#cdvars/
[[email protected]]#catmain.yml
ngxport:"8080"


9、定義觸發器:

[[email protected]_install]#cdhandlers/
[[email protected]]#catmain.yml
-name:startnginxservice
shell:/usr/loal/nginx/sbin/nginx


10、在nginx_config目錄加入我們經常要增加nginx站點,直接寫好模板推送到vhos目錄:

[[email protected]]#cdnginx_config/
[[email protected]_config]#ls
defaultfileshandlersmetataskstemplatesvars
[[email protected]_config]#cdtemplates/
[[email protected]]#ls
temp_server.conf
[[email protected]]#cattemp_server.conf
server
{
listen80;
server_name{{server_name}};
indexindex.phpindex.html;
root{{root_dir}};
}


###在var定義變數:

[[email protected]]#cd../vars/
[[email protected]]#catmain.yml
server_name:"www.xiaoluo.com"
root_dir:"/web"


11、寫配置nginx的tasks步驟:

[[email protected]_config]#cdtasks/
[[email protected]]#ls
main.yml
[[email protected]]#catmain.yml
-name:createvhosts
shell:mkdir-p/usr/local/nginx/conf/vhosts/
tags:create_dir
-name:copyconffilenginx.conf#呼叫templates模組
template:src=temp_server.confdest=/usr/local/nginx/conf/vhosts/{{server_name}}.conf
tags:ngxconf
notify:reloadnginxservice
###定義重啟觸發器:
[[email protected]]#cd../handlers/
Youhavenewmailin/var/spool/mail/root
[[email protected]]#catmain.yml
-name:reloadnginxservice
shell:/usr/local/nginx/sbin/nginx-t;/usr/local/nginx/sbin/nginx-sreload


測試:

[[email protected]]#ansible-playbook-Cnginx.yaml

PLAY[192.168.5.104]**********************************************************

GATHERINGFACTS***************************************************************
ok:[192.168.5.104]

TASK:[nginx_install|copynginxpackagetoremotehost]*********************
changed:[192.168.5.104]

TASK:[nginx_install|tarnginx]*********************************************
skipping:[192.168.5.104]
ok:[192.168.5.104]

TASK:[nginx_install|installpakger]****************************************
changed:[192.168.5.104]=>(item=openssl-devel,pcre-devel,gcc)

TASK:[nginx_install|installnginx]*****************************************
skipping:[192.168.5.104]
ok:[192.168.5.104]

TASK:[nginx_install|copyconffilenginx.conf]*****************************
changed:[192.168.5.104]

TASK:[nginx_install|copyshell]********************************************
changed:[192.168.5.104]

TASK:[nginx_install|createusernginx]*************************************
skipping:[192.168.5.104]
ok:[192.168.5.104]

TASK:[nginx_config|createvhosts]******************************************
skipping:[192.168.5.104]
ok:[192.168.5.104]

TASK:[nginx_config|copyconffilenginx.conf]******************************
changed:[192.168.5.104]

NOTIFIED:[nginx_config|reloadnginxservice]*******************************
skipping:[192.168.5.104]
ok:[192.168.5.104]

PLAYRECAP********************************************************************
192.168.5.104:ok=6changed=5unreachable=0failed=0
[[email protected]ansible]#ansible-playbooknginx.yaml
PLAY[192.168.5.104]**********************************************************
GATHERINGFACTS***************************************************************
ok:[192.168.5.104]
TASK:[nginx_install|copynginxpackagetoremotehost]*********************
ok:[192.168.5.104]
TASK:[nginx_install|tarnginx]*********************************************
changed:[192.168.5.104]
TASK:[nginx_install|installpakger]****************************************
ok:[192.168.5.104]=>(item=openssl-devel,pcre-devel,gcc)
TASK:[nginx_install|installnginx]*****************************************
changed:[192.168.5.104]
TASK:[nginx_install|copyconffilenginx.conf]*****************************
ok:[192.168.5.104]
TASK:[nginx_install|copyshell]********************************************
ok:[192.168.5.104]
TASK:[nginx_install|createusernginx]*************************************
changed:[192.168.5.104]
TASK:[nginx_config|createvhosts]******************************************
changed:[192.168.5.104]
TASK:[nginx_config|copyconffilenginx.conf]******************************
ok:[192.168.5.104]
NOTIFIED:[nginx_install|startnginxservice]*******************************
changed:[192.168.5.104]
PLAYRECAP********************************************************************
192.168.5.104:ok=11changed=5unreachable=0failed=0

[[email protected] ~]# ifconfig

ens34: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500

inet 192.168.5.104 netmask 255.255.255.0 broadcast 192.168.5.255


[[email protected] ~]# netstat -ntlp

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name

tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 29264/nginx: master

tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 29264/nginx: master


四、定義日誌檔案

下面是介紹如何定義日誌:(在ansible1.9.1版本之後有個bug所以定義不了日誌檔案只能降版本到1.9.1了)

1、ansible倒回去版本:1.9.1

需要安裝gcc、python-devel
[[email protected]~]#yuminstallpython-pip
[[email protected]~]#pipinstallansible==1.9.1


2、callback外掛:

[[email protected]]#vim/etc/ansible/ansible.cfg
callback_plugins=/usr/share/ansible/plugins/callback
bin_ansible_callbacks=True


3、在callback目錄下建立日誌處理檔案:

[[email protected]]#cd/usr/share/ansible/plugins/callback
[[email protected]]#ls
log.pylog.pyc
[[email protected]]#catlog.py
importos
importtime
importjson

TIME_FORMAT="%b%d%Y%H:%M:%S"
MSG_FORMAT="%(now)s-%(category)s-%(data)s\n\n"

ifnotos.path.exists("/var/log/ansible/hosts"):
os.makedirs("/var/log/ansible/hosts")

deflog(host,category,data):
iftype(data)==dict:
if'verbose_override'indata:
#avoidloggingextraneousdatafromfacts
data='omitted'
else:
data=data.copy()
invocation=data.pop('invocation',None)
data=json.dumps(data)
ifinvocationisnotNone:
data=json.dumps(invocation)+"=>%s"%data

path=os.path.join("/var/log/ansible/hosts",host)
now=time.strftime(TIME_FORMAT,time.localtime())
fd=open(path,"a")
fd.write(MSG_FORMAT%dict(now=now,category=category,data=data))
fd.close()

classCallbackModule(object):
"""
logsplaybookresults,perhost,in/var/log/ansible/hosts
"""

defon_any(self,*args,**kwargs):
pass

defrunner_on_failed(self,host,res,ignore_errors=False):
log(host,'FAILED',res)

defrunner_on_ok(self,host,res):
log(host,'OK',res)

defrunner_on_skipped(self,host,item=None):
log(host,'SKIPPED','...')

defrunner_on_unreachable(self,host,res):
log(host,'UNREACHABLE',res)

defrunner_on_no_hosts(self):
pass

defrunner_on_async_poll(self,host,res,jid,clock):
pass

defrunner_on_async_ok(self,host,res,jid):
pass

defrunner_on_async_failed(self,host,res,jid):
log(host,'ASYNC_FAILED',res)

defplaybook_on_start(self):
pass

defplaybook_on_notify(self,host,handler):
pass

defplaybook_on_no_hosts_matched(self):
pass

defplaybook_on_no_hosts_remaining(self):
pass

defplaybook_on_task_start(self,name,is_conditional):
pass

defplaybook_on_vars_prompt(self,varname,private=True,prompt=None,encrypt=None,confirm=False,salt_size=None,salt=None,default=None):
pass

defplaybook_on_setup(self):
pass

defplaybook_on_import_for_host(self,host,imported_file):
log(host,'IMPORTED',imported_file)

defplaybook_on_not_import_for_host(self,host,missing_file):
log(host,'NOTIMPORTED',missing_file)

defplaybook_on_play_start(self,name):
pass

defplaybook_on_stats(self,stats):
pass


轉載於:https://blog.51cto.com/legehappy/1975399