Ansible使用playbook自動化編譯安裝Nginx
Ansible批量部署編譯安裝nginx
一、ansible介紹:
這次為大家介紹一款批量部署工具ansible,主要有以下幾點優點:1、充分利用現有設施。使用 Ansible 無需安裝服務端和客戶端,只要 SSH 即可。這意味著,任何一臺裝有 Ansible 的機器都可以成為強大的管理端。我覺得,這種去中心化的思路顯得更為靈活。可能有人會擔心 SSH 的效率,Ansible 的並行執行及加速模式或許可以打消你的顧慮。2、使用簡單,快速上手相當容易。Ansible 上手十分快,用 Ad-Hoc 可以應付簡單的管理任務,麻煩點的也可以定義 Playbook 檔案來搞定。3、採用人類易讀的格式。Ansible
一言以蔽之,Ansible 背後的簡單化哲學深得我心。這也比較符合我選擇軟體的一貫原則。可能還有人會比較關心目前 Ansible 都有誰在用。畢竟,榜樣的力量是無窮。Puppet 不正是因為 Google 在用而吸引了不少眼球麼?據我所知,當前使用 Ansible
Ansible企業應用:
二、主要架構功能:
Ansible Core. //核心功能
Modules:
Core Modules //核心功能
Customed Modules //自定義模組
Host Inventory //主機庫和主機清單,用來定義要管理的主機
File
CMDB(配置管理資料)
PlayBooks //劇本,定義沒個主機扮演的角色
Hosts. //主機
roles. //角色
Connection Plugins. //連線外掛,連線至被管控主機,完成併發連線,預設一次管理5臺,但是可以修改。
三、安裝配置
★安裝:
# yum install ansible -y
★程式:
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