使用playbook安装nginx及配置文件管理

使用playbook安装nginx及配置文件管理

Administrator 1100 2018-10-06

本文主要介绍如何使用ansible的playbook功能安装nginx,以及使用ansible管理配置文件。


使用playbook安装nginx

安装准备

  • 首先在一台机器上编译安装好nginx,并且打包好,再使用ansible下发到其他客户机;

  • 在ansible服务端的/etc/ansible下创建nginx_install目录,方便进行管理;

  • 进入nginx_install目录,执行下面的命令创建需要的目录:

    mkdir -p roles/{common,install}/{handlers,files,meta,tasks,templates,vars}
    
  • 上面创建的roles目录下有两个角色目录,其中common目录为一些准备操作,install为安装nginx的操作,在两个角色目录下又有几个目录,其中handlers下面为当发生改变时需要执行的操作,通常用在配置文件发生改变,重启服务时;files为安装时用到的一些文件,meta为说明信息,说明角色依赖等信息,可以留空,tasks里面是核心的配置文件,templates通常存放一些配置文件、启动脚本等模板文件,vars下为定义的变量。

    [root@vm1 nginx_install]# tree
    .
    └── roles
        ├── common
        │   ├── files
        │   ├── handlers
        │   ├── meta
        │   ├── tasks
        │   ├── templates
        │   └── vars
        └── install
            ├── files
            ├── handlers
            ├── meta
            ├── tasks
            ├── templates
            └── vars
    
    
  • 然后进行nginx的编译安装,安装完成后,在nginx中,我们的nginx启动脚本位于/etc/init.d/nginx,而nginx的配置文件则位于/usr/local/nginx/conf/nginx.conf,然后我们将安装好的nginx进行打包,打包时不需要打包配置文件:

    tar zcvf nginx.tar.gz --exclude "nginx.conf" --exclude "vhosts" nginx/
    
  • 打包完成后,将压缩包放到/etc/ansible/nginx_install/roles/install/files目录下:

    mv nginx.tar.gz /etc/ansible/nginx_install/roles/install/files/
    
  • 接着将nginx的配置文件nginx.conf、启动脚本复制到roles/install/templates目录中:

    [root@vm1 local]# cp /usr/local/nginx/conf/nginx.conf /etc/ansible/nginx_install/roles/install/templates/
    [root@vm1 local]# cp /etc/init.d/nginx /etc/ansible/nginx_install/roles/install/templates/
    
    

编辑playbook

  • 进入/etc/ansible/roles/common目录,创建tasks/main.ymlplaybook,用来安装nginx依赖的软件包,写入内容如下:

    - name: Install initializtion require software
      yum: name={{ item }} state=installed
      with_items:
        - zlib-devel
        - pcre-devel
    
    
  • 接着在/roles/install/vars目录下创建main.ymlplaybook,用来定义需要使用到的变量,这些变量可以用来针对不同的客户机,实现分发不同的配置文件,例如配置高的客户机,nginx进程数就设置的多一些,playbook内容如下:

    nginx_user: www
    nginx_port: 80
    nginx_basedir: /usr/local/nginx
    
    
  • 然后定义拷贝文件的playbook,创建roles/install/tasks/copy.yml文件,写入内容如下:

    - name: Copy Nginx Software
      copy: src=nginx.tar.gz dest=/tmp/nginx.tar.gz owner=root group=root
    - name: Uncompression Nginx Software
      shell: tar zxf /tmp/nginx.tar.gz -C /usr/local
    - name: Copy Ningx Start Script
      template: src=nginx dest=/etc/init.d/nginx owner=root group=root mode=755
    - name: Copy Nginx Config
      template: src=nginx.conf dest={{ nginx_basedir }}/conf/ owner=root group=root mode=0644
    
    • 上面的playbook中,src并没有使用绝对路径,因为ansible的copy模块可以到files目录下自动寻找文件,而template模块则会到tempates目录下自动找到文件。
  • 创建roles/install/tasks/install.ymlplaybook,用来创建用户,启动服务,删除压缩包,该playbook为总的playbook,内容如下:

    - 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 Nignx Service
      shell: chkconfig --level 345 nginx on
    - name: Delete Nginx compression files
      shell: rm -rf /tmp/nginx.tar.gz
    
  • 然后再在roles/install/tasks/目录下创建一个main.yml,用来调用copy和install两个脚本,内容如下:

    - include: copy.yml
    - include: install.yml
    
  • 上面的步骤完成后,common和install两个roles就已经定义完成,接着需要定义一个入口配置文件,在/etc/ansible/nginx_install/目录下创建install.yml文件,内容如下:

    ---
    - hosts: testhost
      remote_user: root
      gather_facts: True
      roles:
        - common
        - install
    
    • roles模块能够调用指定角色的playbook,利于代码重复调用,例如针对一批主机执行一个角色(common)的任务,针对另一批主机执行另一个角色(install)的任务,或者两个角色都被调用执行。

执行playbook

  • 执行命令ansible-playbook /etc/ansible/nginx_install/install.yml,正确执行的结果如下:

    [root@localhost nginx_install]# ansible-playbook /etc/ansible/nginx_install/install.yml
    [DEPRECATION WARNING]: The use of 'include' for tasks has been deprecated. Use
    'import_tasks' for static inclusions or 'include_tasks' for dynamic inclusions. This
    feature will be removed in a future release. Deprecation warnings can be disabled by
    setting deprecation_warnings=False in ansible.cfg.
    [DEPRECATION WARNING]: include is kept for backwards compatibility but usage is
    discouraged. The module documentation details page may explain more about this
    rationale.. This feature will be removed in a future release. Deprecation warnings can
    be disabled by setting deprecation_warnings=False in ansible.cfg.
    
    PLAY [testhost] *************************************************************************
    
    TASK [Gathering Facts] ******************************************************************
    ok: [centos_2]
    ok: [centos_1]
    
    TASK [common : Install initializtion require software] **********************************
    ok: [centos_1] => (item=[u'zlib-devel', u'pcre-devel', u'gcc'])
    changed: [centos_2] => (item=[u'zlib-devel', u'pcre-devel', u'gcc'])
    
    TASK [install : Copy Nginx Software] ****************************************************
    ok: [centos_1]
    changed: [centos_2]
    
    TASK [install : Uncompression Nginx Software] *******************************************
     [WARNING]: Consider using unarchive module rather than running tar
    
    changed: [centos_1]
    changed: [centos_2]
    
    TASK [install : Copy Nginx Start Script] ************************************************
    ok: [centos_1]
    changed: [centos_2]
    
    TASK [install : Copy Nginx Config] ******************************************************
    ok: [centos_1]
    changed: [centos_2]
    
    TASK [install : Create Nginx User] ******************************************************
    ok: [centos_1]
    changed: [centos_2]
    
    TASK [install : Start Nginx Service] ****************************************************
    changed: [centos_1]
    changed: [centos_2]
    
    TASK [install : Add Boot Start Nginx Service] *******************************************
    changed: [centos_2]
    changed: [centos_1]
    
    TASK [install : Delete Nginx Compression files] *****************************************
     [WARNING]: Consider using file module with state=absent rather than running rm
    
    changed: [centos_2]
    changed: [centos_1]
    
    PLAY RECAP ******************************************************************************
    centos_1                   : ok=10   changed=4    unreachable=0    failed=0
    centos_2                   : ok=10   changed=9    unreachable=0    failed=0
    
    
  • 如果出现执行时提示yum安装失败的情况,可以将/etc/ansible/nginx_install/roles/common/tasks/main.yml文件改成如下形式:

    - name: Install initializtion require software
      yum: name="pcre-devel,zlib-devel" state=installed
    
  • 如果在执行到启动nginx时出现失败,注意查看客户机上是否存在80端口被占用的情况。

  • 另外需要注意客户机上不能够存在yum安装的nginx软件包,否则启动时会启动yum安装的nginx。

playbook关系梳理

  • 上面安装nginx的playbook,在完成后整个文件及目录关系如下:

    nginx_install/
    ├── install.retry
    ├── install.yml
    └── roles
        ├── common
        │   ├── files
        │   ├── handles
        │   ├── meta
        │   ├── tasks
        │   │   └── main.yml
        │   ├── templates
        │   └── vars
        └── install
            ├── files
            │   └── nginx.tar.gz
            ├── handles
            ├── meta
            ├── tasks
            │   ├── copy.yml
            │   ├── install.yml
            │   └── main.yml
            ├── templates
            │   ├── nginx
            │   └── nginx.conf
            └── vars
                └── main.yml
    
    
  • 首先nginx_install目录下的总入口文件install.yml定义了执行的主机组以及需要执行的角色roles,根据roles的定义,首先执行了common下的任务;

  • common角色会在tasks目录下找到main.yml的playbook进行执行,完成后再执行install角色的playbook;

  • install角色的playbook中,同样会再tasks目录下先执行main.yml,根据该playbook中定义的过程,会先执行copy.yml,然后执行install.yml

  • install目录下的filestemplates用来存放playbook需要用到的文件,vars则存放变量的playbook。

  • 整体流程图如下:

nginx_playbook


playbook管理配置文件

管理配置文件更新

  • 生产环境中大多数时候是需要管理配置文件的,安装软件包只是在初始化环境的时候使用,而配置文件则是在使用过程中非常常用的,例如配置的下发、回滚等等;
  • 我们可以使用playbook来实现对配置文件的管理,例如管理nginx配置的playbook,具体步骤如下:
  1. /etc/ansible/目录下创建以下目录:

    mkdir -p /etc/ansible/nginx_config/roles/{new,old}/{files,handlers,vars,tasks}
    

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

  2. 在执行playbook前一定要先备份一下旧的配置,对于老的配置文件的管理一定要严格,不要随意修改线上机器的配置,并且要保证new/files下面的配置和线上机器的配置一致;

  3. 首先将nginx.confvhost目录拷贝到/etc/ansible/nginx_config/roles/new/files/目录下:

    cd /usr/local/nginx/conf
    cp -r nginx.conf vhosts/ /etc/ansible/nginx_config/roles/new/files/
    
  4. 然后在roles/new/vars/目录下创建定义变量的main.yml文件,写入如下内容:

    nginx_basedir:/usr/local/nginx
    
  5. 接着在roles/new/handlers/目录下创建定义重新加载nginx服务的main.yml文件,写入内容如下:

    - name:restart nginx
      shell:/etc/init.d/nginx reload
    
  6. 然后在roles/new/tasks/目录下创建核心人物的main.yml文件,内容如下:

    - name: copy conf file
      copy: src={{ item.src }} dest={{ nginx_basedir }}/{{ item.dest }} backup=yes owner=root group=root m
    ode=0644
      with_items:
        - { src: nginx.conf, dest: conf/nginx.conf }
        - { src: vhosts, dest: conf/ }
      notify: restart nginx
    
    

    这里的{{ item.src }}{{ item.dest }}使用了两个循环变量,并且在下面的with_items中分别定义了两次循环的src和dest变量,最后再执行restart nginx这个handlers。

  7. 最后在/etc/ansible/nginx_config/目录下定义总入口配置文件update.yml,其内容如下:

    ---
    - hosts: testhost
      user: root
      roles:
        - new
    
  8. 执行playbook,查看是否成功:

    [root@localhost nginx_config]# ansible-playbook /etc/ansible/nginx_config/update.yml
    
    PLAY [testhost] **************************************************************************************
    
    TASK [Gathering Facts] *******************************************************************************
    ok: [centos_2]
    ok: [centos_1]
    
    TASK [new : copy conf file] **************************************************************************
    changed: [centos_2] => (item={u'dest': u'conf/nginx.conf', u'src': u'nginx.conf'})
    changed: [centos_1] => (item={u'dest': u'conf/nginx.conf', u'src': u'nginx.conf'})
    changed: [centos_1] => (item={u'dest': u'conf/', u'src': u'vhosts'})
    changed: [centos_2] => (item={u'dest': u'conf/', u'src': u'vhosts'})
    
    RUNNING HANDLER [new : restart nginx] ****************************************************************
    changed: [centos_2]
    changed: [centos_1]
    
    PLAY RECAP *******************************************************************************************
    centos_1                   : ok=3    changed=2    unreachable=0    failed=0
    centos_2                   : ok=3    changed=2    unreachable=0    failed=0
    
    
  9. 我们也可以对/role/new/files/nginx.conf做一些修改,然后重新执行playbook,再查看执行结果:

    [root@localhost new]# ansible-playbook /etc/ansible/nginx_config/update.yml
    
    PLAY [testhost] **************************************************************************************
    
    TASK [Gathering Facts] *******************************************************************************
    ok: [centos_2]
    ok: [centos_1]
    
    TASK [new : copy conf file] **************************************************************************
    changed: [centos_1] => (item={u'dest': u'conf/nginx.conf', u'src': u'nginx.conf'})
    changed: [centos_2] => (item={u'dest': u'conf/nginx.conf', u'src': u'nginx.conf'})
    ok: [centos_1] => (item={u'dest': u'conf/', u'src': u'vhosts'})
    ok: [centos_2] => (item={u'dest': u'conf/', u'src': u'vhosts'})
    
    RUNNING HANDLER [new : restart nginx] ****************************************************************
    changed: [centos_1]
    changed: [centos_2]
    
    PLAY RECAP *******************************************************************************************
    centos_1                   : ok=3    changed=2    unreachable=0    failed=0
    centos_2                   : ok=3    changed=2    unreachable=0    failed=0
    
    
    

    可以看到,只更改nginx.conf时,playbook对远程机器也会只更改nginx.conf。

管理配置文件回滚

  • 回滚操作就是用旧的配置覆盖现有的配置,然后重新加载nginx服务,每次改动nginx配置文件之前,应该先将配置备份到old/files目录中;

  • 首先备份旧的配置文件,使用rsync命令将配置同步到old/files下:

    rsync -av /etc/ansible/nginx_config/roles/new/ /etc/ansible/nginx_config/roles/old/
    
  • 然后在nginx_config目录下创建rollback.yml总入口文件,内容如下:

    ---
    - hosts: testhost
      user: root
      roles:
        - old
    
    
  • 最后执行ansible-playbook rollback.yml即可完成配置的回滚,实际上回滚与更新只改变了配置文件,其余的操作与更新是相同的,所以只需要在playbook的总入口文件中指定使用old角色即可。