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

Ansible批量部署編譯安裝nginx

1、ansible介紹:

此次爲你們介紹一款批量部署工具ansible,主要有如下幾點優勢:1、充分利用現有設施。使用 Ansible 無需安裝服務端和客戶端,只要 SSH 便可。這意味着,任何一臺裝有 Ansible 的機器均可以成爲強大的管理端。我以爲,這種去中心化的思路顯得更爲靈活。可能有人會擔憂 SSH 的效率,Ansible 的並行執行及加速模式或許能夠打消你的顧慮。2、使用簡單,快速上手至關容易。Ansible 上手十分快,用 Ad-Hoc 能夠應付簡單的管理任務,麻煩點的也能夠定義 Playbook 文件來搞定。3、採用人類易讀的格式。Ansible 的主機定義文件使用 INI 格式,支持分組,可以指定模式;此外也能動態生成,這對管理雲主機應當頗有用。而 Playbook 則是 YAML 格式。4、可以使用你熟悉的語言來編寫模塊。雖然 Ansible 是使用 Python 開發的,但它不會將你限制到某種具體的編程語言,BashPythonPerlRuby 等等均可以,你擅長什麼就用什麼。php

一言以蔽之,Ansible 背後的簡單化哲學深得我心。這也比較符合我選擇軟件的一向原則。可能還有人會比較關心目前 Ansible 都有誰在用。畢竟,榜樣的力量是無窮。Puppet 不正是由於 Google 在用而吸引了很多眼球麼?據我所知,當前使用 Ansible 較爲知名的用戶包括 FedoraRackspaceEvernote 等等。html

Ansible企業應用:python

 

23f68d34f8bf34f942cb05210dc86e42.png

2、主要架構功能:

   Ansible Core.    //核心功能nginx

   Modules:web

        Core Modules    //核心功能shell

        Customed Modules  //自定義模塊編程

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

        Filevim

        CMDB(配置管理數據)bash

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

        Hosts.        //主機

        roles.         //角色

   Connection Plugins.  //鏈接插件,鏈接至被管控主機,完成併發鏈接,默認一次管理5臺,可是能夠修改。

 

3、安裝配置

安裝:

    # yum install ansible -y  (epel倉庫中)

程序:

    ansible

    ansible-playbook   //唱劇本

    ansible-doc        //獲取幫助文檔

配置文件

    /etc/ansible/ansible.cfg    //核心配置文件

主機清單:

    /etc/ansible/hosts 

插件目錄:

    /usr/share/ansible_plugins/

 

一、設置ansble到各個主機的免密鑰通信:

[root@cml1~]# ssh-keygen

[root@cml1~]# ssh-copy-id 192.168.5.102

 

二、定義主機組:

[root@cml1~]# cd /etc/ansible/

[root@cml1ansible]# vim hosts

[webserver]

192.168.5.102

192.168.5.104

 

三、查看主機組內的主機:

[root@cml1ansible]# ansible webserver --list-hosts

  hosts (2):

    192.168.5.102

     192.168.5.104

四、定義角色路徑

[root@cml1~]# cat /etc/ansible/nginx.yaml

- hosts: 192.168.5.102

 remote_user: root

  roles:

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

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

五、查看目錄結構:

[root@cml1 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

[root@cml1roles]# cd nginx_install/

[root@cml1nginx_install]# ls

default  files handlers  meta  tasks templates  vars

6、task定義開始任務:

[root@cml1nginx_install]# cd tasks/
[root@cml1tasks]# cat main.yml 
- name: copynginx package to remote host   
  copy: src=nginx-1.12.0.tar.gz   dest=/tmp/nginx-1.12.0.tar.gz  ##拉取nginx解壓吧
  tags: cppkg
- name: tarnginx
  shell: cd /tmp;tar -xf nginx-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&& make install      ####編譯安裝
- name: copyconf file nginx.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: createuser nginx
  shell: /bin/bash /tmp/create_users.sh
  tags: addnginx
  notify: start nginx service


爲何要寫這個腳本?由於加入有些主機建立的用戶已存在就會報錯

[root@cml1tasks]# cat /opt/create_users.sh 
#!/bin/bash
a=`cat/etc/passwd | grep nginx | wc -l`
if [ $a == 0];then
       useradd nginx
fi


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

[root@cml1nginx_install]# cd files/
[root@cml1files]# ls
nginx-1.12.0.tar.gz


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

[root@cml1nginx_install]# cd templates/
[root@cml1templates]# ls
nginx.conf
[root@cml1templates]# cat nginx.conf 
 
user  nginx;
worker_processes  {{ ansible_processor_vcpus }};
 
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
 
#pid        logs/nginx.pid;
 
 
events {
    worker_connections  65535;
}
 
 
http {
  
 
    include       mime.types;
    default_type  application/octet-stream;
 
    #log_format main  '$remote_addr - $remote_user[$time_local] "$request" '
    #                  '$status $body_bytes_sent"$http_referer" '
    #                  '"$http_user_agent""$http_x_forwarded_for"';
   log_format xiaoluo  '$remote_addr -$remote_user  [$time_local]  '
                             '"$request"  $status$body_bytes_sent '
                             '"$http_referer" "$http_user_agent" ';
    #access_log logs/access.log  main;
 
    sendfile        on;
    #tcp_nopush     on;
 
    #keepalive_timeout  0;
    keepalive_timeout  65;
 
    #gzip on;
    
    server {
        listen       {{ ngxport }};  
        server_name  wwwNaNl.com
        access_log logs/wwwNaNl.com  xiaoluo;
        #location / {
        #   proxy_pass http://192.168.5.101;
        #}
 
        #error_page  404              /404.html;
 
        # redirect server error pages to thestatic page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
 
        # proxy the PHP scripts to Apachelistening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #   proxy_pass   http://127.0.0.1;
        #}
 
        # pass the PHP scripts to FastCGIserver listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
            root           /web;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME$document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
 
        # deny access to .htaccess files, ifApache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #   deny  all;
        #}
    }
   include vhosts/*.conf;
}

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

八、在vars定義變量:

[root@cml1nginx_install]# cd vars/
[root@cml1vars]# cat main.yml 
ngxport:"8080"


九、定義觸發器:

[root@cml1nginx_install]# cd handlers/
[root@cml1handlers]# cat main.yml 
- name: startnginx service 
  shell: /usr/loal/nginx/sbin/nginx


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

[root@cml1roles]# cd nginx_config/
[root@cml1nginx_config]# ls
default  files handlers  meta  tasks templates  vars
[root@cml1nginx_config]# cd templates/
[root@cml1templates]# ls
temp_server.conf
[root@cml1templates]# cat temp_server.conf 
server 
{ 
listen 80; 
server_name {{server_name }}; 
index index.phpindex.html; 
root {{root_dir }}; 
}


###在var定義變量:

[root@cml1templates]# cd ../vars/
[root@cml1vars]# cat main.yml 
server_name: "www.xiaoluo.com"
root_dir:"/web"


11、寫配置nginx的tasks步驟:

[root@cml1nginx_config]# cd tasks/
[root@cml1tasks]# ls
main.yml
[root@cml1tasks]# cat main.yml 
- name: createvhosts
  shell: mkdir -p /usr/local/nginx/conf/vhosts/
  tags: create_dir
- name: copyconf file nginx.conf          # 調用templates模塊
  template: src=temp_server.confdest=/usr/local/nginx/conf/vhosts/{{ server_name }}.conf
  tags: ngxconf
  notify: reload nginx service 
###定義重啓觸發器:
[root@cml1tasks]# cd ../handlers/
You have newmail in /var/spool/mail/root
[root@cml1handlers]# cat main.yml 
- name: reloadnginx service
  shell: /usr/local/nginx/sbin/nginx-t;/usr/local/nginx/sbin/nginx -s reload


 

測試:

[root@cml1ansible]# ansible-playbook -C nginx.yaml 
 
PLAY[192.168.5.104] ********************************************************** 
 
GATHERING FACTS*************************************************************** 
ok:[192.168.5.104]
 
TASK:[nginx_install | copy nginx package to remote host] ********************* 
changed:[192.168.5.104]
 
TASK:[nginx_install | tar nginx] ********************************************* 
skipping:[192.168.5.104]
ok:[192.168.5.104]
 
TASK:[nginx_install | install pakger] **************************************** 
changed: [192.168.5.104]=> (item=openssl-devel,pcre-devel,gcc)
 
TASK:[nginx_install | install nginx] ***************************************** 
skipping:[192.168.5.104]
ok:[192.168.5.104]
 
TASK:[nginx_install | copy conf file nginx.conf] ***************************** 
changed:[192.168.5.104]
 
TASK:[nginx_install | copy shell] ******************************************** 
changed:[192.168.5.104]
 
TASK:[nginx_install | create user nginx] ************************************* 
skipping:[192.168.5.104]
ok: [192.168.5.104]
 
TASK:[nginx_config | create vhosts] ****************************************** 
skipping:[192.168.5.104]
ok:[192.168.5.104]
 
TASK:[nginx_config | copy conf file nginx.conf] ****************************** 
changed:[192.168.5.104]
 
NOTIFIED:[nginx_config | reload nginx service] ******************************* 
skipping:[192.168.5.104]
ok:[192.168.5.104]
 
PLAY RECAP******************************************************************** 
192.168.5.104              : ok=6    changed=5   unreachable=0    failed=0
[root@cml1 ansible]# ansible-playbook   nginx.yaml 
PLAY [192.168.5.104] ********************************************************** 
GATHERING FACTS *************************************************************** 
ok: [192.168.5.104]
TASK: [nginx_install | copy nginx package to remote host] ********************* 
ok: [192.168.5.104]
TASK: [nginx_install | tar nginx] ********************************************* 
changed: [192.168.5.104]
TASK: [nginx_install | install pakger] **************************************** 
ok: [192.168.5.104] => (item=openssl-devel,pcre-devel,gcc)
TASK: [nginx_install | install nginx] ***************************************** 
changed: [192.168.5.104]
TASK: [nginx_install | copy conf file nginx.conf] ***************************** 
ok: [192.168.5.104]
TASK: [nginx_install | copy shell] ******************************************** 
ok: [192.168.5.104]
TASK: [nginx_install | create user nginx] ************************************* 
changed: [192.168.5.104]
TASK: [nginx_config | create vhosts] ****************************************** 
changed: [192.168.5.104]
TASK: [nginx_config | copy conf file nginx.conf] ****************************** 
ok: [192.168.5.104]
NOTIFIED: [nginx_install | start nginx service] ******************************* 
changed: [192.168.5.104]
PLAY RECAP ******************************************************************** 
192.168.5.104              : ok=11   changed=5    unreachable=0    failed=0

[root@cml3 ~]# 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


[root@cml3 ~]# 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: maste

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

      

4、定義日誌文件

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

一、ansible倒回去版本:1.9.1

須要安裝gcc、python-devel
[root@cml1 ~]#yum install python-pip
[root@cml1 ~]#pip install ansible==1.9.1


二、callback插件:

[root@cml1tasks]# vim /etc/ansible/ansible.cfg
callback_plugins   = /usr/share/ansible/plugins/callback
bin_ansible_callbacks= True


3、在callback目錄下建立日誌處理文件:

[root@cml1tasks]# cd /usr/share/ansible/plugins/callback
[root@cml1callback]# ls
log.py  log.pyc
[root@cml1callback]# cat log.py
import os
import time
import json
 
TIME_FORMAT="%b%d %Y %H:%M:%S"
MSG_FORMAT="%(now)s- %(category)s - %(data)s\n\n"
 
if notos.path.exists("/var/log/ansible/hosts"):
   os.makedirs("/var/log/ansible/hosts")
 
def log(host,category, data):
    if type(data) == dict:
        if 'verbose_override' in data:
            # avoid logging extraneous datafrom facts
            data = 'omitted'
        else:
            data = data.copy()
            invocation = data.pop('invocation',None)
            data = json.dumps(data)
            if invocation is not None:
                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):
    """
    logs playbook results, per host, in/var/log/ansible/hosts
    """
 
    def on_any(self, *args, **kwargs):
        pass
 
    def runner_on_failed(self, host, res,ignore_errors=False):
        log(host, 'FAILED', res)
 
    def runner_on_ok(self, host, res):
        log(host, 'OK', res)
 
    def runner_on_skipped(self, host,item=None):
        log(host, 'SKIPPED', '...')
 
    def runner_on_unreachable(self, host, res):
        log(host, 'UNREACHABLE', res)
 
    def runner_on_no_hosts(self):
        pass
 
    def runner_on_async_poll(self, host, res,jid, clock):
        pass
 
    def runner_on_async_ok(self, host, res,jid):
        pass
 
    def runner_on_async_failed(self, host, res,jid):
        log(host, 'ASYNC_FAILED', res)
 
    def playbook_on_start(self):
        pass
 
    def playbook_on_notify(self, host,handler):
        pass
 
    def playbook_on_no_hosts_matched(self):
        pass
 
    def playbook_on_no_hosts_remaining(self):
        pass
 
    def playbook_on_task_start(self, name,is_conditional):
        pass
 
    def playbook_on_vars_prompt(self, varname,private=True, prompt=None, encrypt=None, confirm=False, salt_size=None,salt=None, default=None):
        pass
 
    def playbook_on_setup(self):
        pass
 
    def playbook_on_import_for_host(self, host,imported_file):
        log(host, 'IMPORTED', imported_file)
 
    def playbook_on_not_import_for_host(self,host, missing_file):
        log(host, 'NOTIMPORTED', missing_file)
 
    def playbook_on_play_start(self, name):
        pass
 
    def playbook_on_stats(self, stats):
        pass
相關文章
相關標籤/搜索