Bootstrap

Ansible运维实战

Ansible自动安装nginx

节点规划

IP主机名
192.168.63.34server
192.168.63.36host1

1.编译安装nginx

使用wget下载nginx包,下载地址:http://mirrors.sohu.com/nginx/nginx-1.9.6.tar.gz

(1)解压下载nginx包

[root@server ~]# wget http://mirrors.sohu.com/nginx/nginx-1.9.6.tar.gz

[root@server ~]# mv nginx-1.9.6.tar.gz /usr/local/

[root@server ~]#cd /usr/local

[root@server local]# tar -zxvf nginx-1.9.6.tar.gz

[root@server local]# cd nginx-1.9.6

[root@server nginx-1.9.6]# yum install gcc gcc-c++ openssl-devel zlib-devel zlib pcre-devel-y

[root@server nginx-1.9.6]# ./configure --prefix=/usr/local/nginx

[root@server nginx-1.9.6]# make && make install

(2)编写/etc/init.d/nginx文件

[root@server conf]# cat /etc/init.d/nginx

#!/bin/bash

# chkconfig: - 30 21

# description: http service.

# Source Function Library

. /etc/init.d/functions

# Nginx Settings

NGINX_SBIN="/usr/local/nginx/sbin/nginx"

NGINX_CONF="/usr/local/nginx/conf/nginx.conf"

NGINX_PID="/usr/local/nginx/logs/nginx.pid"

RETVAL=0

prog="Nginx"

start()

{

        echo -n $"Starting $prog: "

        mkdir -p /dev/shm/nginx_temp

        daemon $NGINX_SBIN -c $NGINX_CONF

        RETVAL=$?

        echo

        return $RETVAL

}

stop()

{

        echo -n $"Stopping $prog: "

        killproc -p $NGINX_PID $NGINX_SBIN -TERM

        rm -rf /dev/shm/nginx_temp

        RETVAL=$?

        echo

        return $RETVAL

}

reload()

{

        echo -n $"Reloading $prog: "

        killproc -p $NGINX_PID $NGINX_SBIN -HUP

        RETVAL=$?

        echo

        return $RETVAL

}

restart()

{

        stop

        start

}

configtest()

{

        $NGINX_SBIN -c $NGINX_CONF -t

        return 0

}

case "$1" in

        start)

                start

                ;;

        stop)

                stop

                ;;

        reload)

                reload

                ;;

        restart)

                restart

                ;;

        configtest)

                configtest

                ;;

        *)

                echo $"Usage: $0 {start|stop|reload|restart|configtest}"

                RETVAL=1

esac

exit $RETVAL

[root@server conf]# chmod +x /etc/init.d/nginx //给于执行权限

(3)清空配置文件并编写

[root@server ~]# cat /usr/local/nginx/conf/nginx.conf

user nginx nginx;

worker_processes 1;

error_log /usr/local/nginx/logs/nginx_error.log crit;

pid /usr/local/nginx/logs/nginx.pid;

worker_rlimit_nofile 51200;

events

{

use epoll;

worker_connections 6000;

}

http

{

include mime.types;

default_type application/octet-stream;

server_names_hash_bucket_size 3526;

server_names_hash_max_size 4096;

log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_local]'

'$host "$request_uri" $status'

'"$http_referer" "$http_user_agent"';

sendfile on;

tcp_nopush on;

keepalive_timeout 30;

client_header_timeout 3m;

client_body_timeout 3m;

send_timeout 3m;

connection_pool_size 256;

client_header_buffer_size 1k;

large_client_header_buffers 8 4k;

request_pool_size 4k;

output_buffers 4 32k;

postpone_output 1460;

client_max_body_size 10m;

client_body_buffer_size 256k;

client_body_temp_path /usr/local/nginx/client_body_temp;

proxy_temp_path /usr/local/nginx/proxy_temp;

fastcgi_temp_path /usr/local/nginx/fastcgi_temp;

fastcgi_intercept_errors on;

tcp_nodelay on;

gzip on;

gzip_min_length 1k;

gzip_buffers 4 8k;

gzip_comp_level 5;

gzip_http_version 1.1;

gzip_types text/plain application/x-javascript text/css text/htm

application/xml;

server

{

listen 80;

server_name localhost;

index index.html index.htm index.php;

root /usr/local/nginx/html;

location ~ \.php$

{

include fastcgi_params;

fastcgi_pass unix:/tmp/php-fcgi.sock;

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME /usr/1ocal/nginx/html$fastcgi_script_name;

}

}

}

(4)编写完成后检查并启动Nginx

[root@server ~]# nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

[root@server ~]# service nginx start

Starting nginx (via systemctl):                            [  确定  ]

2.环境准备

(1)移动目录文件

将nginx.tar.gz复制到/etc/ansible/nginx_install/roles/install/files下
启动脚本和配置文件都放到

/etc/ansible/nginx_install/roles/install/template下

[root@server ~]# mv /usr/local/nginx-1.9.6.tar.gz  /etc/ansible/nginx_install/roles/install/files/

[root@server ~]# cp /usr/local/nginx/conf/nginx.conf /etc/ansible/nginx_install/roles/install/templates/

[root@server ~]# cp /etc/init.d/nginx /etc/ansible/nginx_install/roles/install/templates/

(2)编写需要的用yml文件

[root@server nginx_install]# cat install.yml

---

- hosts: 192.168.63.36

  remote_user: root

  gather_facts: True

  roles:

    - common

- install

[root@server nginx_install]# cat roles/common/tasks/main.yml

- name: install initialization require software

  yum: name={{ item }} state=installed   # 安装依赖包

  with_items:

    - zlib-devel

    - pcre-devel

- gcc

[root@server nginx_install]# cat roles/install/vars/main.yml

nginx_user: nginx   #定义变量

nginx_port: 80

nginx_basedir: /usr/local/nginx

[root@server nginx_install]# cat roles/install/tasks/copy.yml

- name: Copy Nginx Software

  copy: src=nginx-1.9.6.tar.gz dest=/tmp/ owner=root group=root

- name: Uncompression Nginx Software

  shell: tar zxf /tmp/nginx-1.9.6.tar.gz -C /usr/local/

- name: install Nginx

  shell: cd /usr/local/nginx-1.9.6 && ./configure --prefix=/usr/local/nginx && make && make install

- name: Copy Nginx Start Script

  template: src=nginx dest=/etc/init.d/nginx owner=root group=root mode=0755

- name: Copy Nginx Config

  template: src=nginx.conf dest={{ nginx_basedir }}/conf/ owner=root group=root

mode=0644

[root@server nginx_install]# cat roles/install/tasks/install.yml

- name: create nginx user

  user: name={{ nginx_user }} state=present createhome=no shell=/sbin/nologin

- name: start nginx service

  shell: /etc/init.d/nginx start

- name: add boot start nginx service

  shell: chkconfig --level 345 nginx on

- name: delete nginx compression files

  shell: rm -rf /tmp/nginx-1.9.6.tar.gz.tar.gz

[root@server nginx_install]# cat roles/install/tasks/main.yml

- include: copy.yml

- include: install.yml

3.验证

(1)运行install.yml文件

[root@server nginx_install]# ansible-playbook /etc/ansible/nginx_install/install.yml

PLAY [nginx] ********************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************

ok: [host1]

TASK [common : install initialization require software] *************************************************************************************************

[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items

and specifying `name: "{{ item }}"`, please use `name: ['zlib-devel', 'pcre-devel', 'gcc']` and remove the loop. This feature will be removed in version

 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

ok: [host1] => (item=[u'zlib-devel', u'pcre-devel', u'gcc'])

TASK [install : Copy Nginx Software] ********************************************************************************************************************

ok: [host1]

TASK [install : Uncompression Nginx Software] ***********************************************************************************************************

[WARNING]: Consider using the unarchive module rather than running 'tar'.  If you need to use command because unarchive is insufficient you can add

'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.

changed: [host1]

TASK [install Nginx] ************************************************************************************************************************************

changed: [host1]

TASK [install : Copy Nginx Start Script] ****************************************************************************************************************

ok: [host1]

TASK [install : Copy Nginx Config] **********************************************************************************************************************

ok: [host1]

TASK [install : create nginx user] **********************************************************************************************************************

changed: [host1]

TASK [install : start nginx service] ********************************************************************************************************************

changed: [host1]

TASK [install : add boot start nginx service] ***********************************************************************************************************

changed: [host1]

TASK [install : delete nginx compression files] *********************************************************************************************************

[WARNING]: Consider using the file module with state=absent rather than running 'rm'.  If you need to use command because file is insufficient you can

add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.

changed: [host1]

PLAY RECAP **********************************************************************************************************************************************

host1                      : ok=11   changed=6    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

查看端口为80

管理nginx配置文件

生产环境中大多时候是需要管理配置文件的,安装软件包只是在初始化环境的时候用一下。下面我们来写个管理nginx配置文件的playbook

实现

创建目录结构

[root@server ansible]# mkdir  -p /etc/ansible/nginx_config/roles/{new,old}/{files,handlers,vars,tasks}

[root@server ansible]# tree nginx_config/

nginx_config/

└── roles

    ├── new

    │   ├── files

    │   ├── handlers

    │   ├── tasks

    │   └── vars

    └── old

        ├── files

        ├── handlers

        ├── tasks

        └── vars

其中new为更新时用到的,old为回滚时用到的,files下面为nginx.conf和vhosts目录,handlers为重启nginx服务的命令

 关于回滚,需要在执行playbook之前先备份一下旧的配置,所以对于老配置文件的管理一定要严格,千万不能随便去修改线上机器的配置,并且要保证new/files下面的配置和线上的配置一致。

[root@server ~]# cd /usr/local/nginx/conf/

[root@server conf]# ls

fastcgi.conf          fastcgi_params          koi-utf  mime.types          nginx.conf          scgi_params          uwsgi_params          win-utf

fastcgi.conf.default  fastcgi_params.default  koi-win  mime.types.default  nginx.conf.default  scgi_params.default  uwsgi_params.default

[root@server conf]# cp nginx.conf ./vhosts

[root@server conf]# cp -r nginx.conf vhosts  /etc/ansible/nginx_config/roles/new/files/

定义变量

[root@server conf]# cat /etc/ansible/nginx_config/roles/new/vars/main.yml

nginx_basedir: /usr/local/nginx

定义重新加载nginx服务

[root@server conf]# cat /etc/ansible/nginx_config/roles/new/handlers/main.yml

- name: restart nginx

  shell: service nginx restart

核心任务

[root@server conf]# cat /etc/ansible/nginx_config/roles/new/tasks/main.yml

- name: copy conf file

  copy: src={{ item.src }} dest={{ nginx_basedir }}/{{ item.dest }} backup=yes owner=root group=root mode=0644

  with_items:

    - { src: nginx.conf, dest: conf/nginx.conf }

    - { src: vhosts, dest: conf/ }

  notify: restart nginx

定义总入口配置

[root@server conf]# cat /etc/ansible/nginx_config/update.yml

---

- hosts: nginx

  user: root

  roles:

  - new

验证

执行

[root@server conf]#  ansible-playbook /etc/ansible/nginx_config/update.yml

PLAY [nginx] ********************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************

ok: [host1]

TASK [new : copy conf file] *****************************************************************************************************************************

ok: [host1] => (item={u'dest': u'conf/nginx.conf', u'src': u'nginx.conf'})

changed: [host1] => (item={u'dest': u'conf/', u'src': u'vhosts'})

RUNNING HANDLER [new : restart nginx] *******************************************************************************************************************

[WARNING]: Consider using the service module rather than running 'service'.  If you need to use command because service is insufficient you can add

'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.

changed: [host1]

PLAY RECAP **********************************************************************************************************************************************

host1                      : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

将80端口改为8848端口执行剧本查看端口。

回滚

回滚的backup.yml对应的roles为old

[root@server files]# rsync -av  /etc/ansible/nginx_config/roles/new/ /etc/ansible/nginx_config/roles/old/

回滚操作就是把旧的配置覆盖,然后重新加载nginx服务, 每次改动nginx配置文件之前先备份到old里,对应目录为/etc/ansible/nginx_config/roles/old/files

定义总入口配置

[root@server files]# cat /etc/ansible/nginx_config/rollback.yml

---

- hosts: nginx

  user: root

  roles:

  - old

验证

把配置文件的端口改为80端口之后执行new剧本查看端口。

在执行old剧本文件在查看端口。

;