• Ansible


    Ansible简介和应用自动化基础实践

    一.引入:

    1.1  如官方定义,Ansible is The simplest way to automate apps and IT infrastructure.  它的设计灵感来自于作者Michael DeHanan喜欢的一本书《安德的游戏》中的一个通信工具Ansible,这个工具可以远程实时地指挥相距数光年的舰队作战。 由此,我们就可以猜想到作为自动化工具的Ansible功能的特点:远程管理批量的设备以实现应用或IT基础设施自动化。

    https://docs.ansible.com/

     

    1.2 安装

    在CentOS执行如下指令安装最新版本的Ansible

    $ sudo yum install epel-release

    $ sudo yum install ansible

     

    二.简介

    2.1 做什么

    应用自动化:应用环境安装,应用部署

    配置管理:通过inventory管理运维的主机,端口,和组;通过和配置管理数据库的交互实现动态inventory和配置管理数据库更新

    Note. 配置管理的活动包括配置项、工作空间管理、版本控制、变更控制、状态报告、配置审计

    持续交互:在devops的部署和运维环节帮助实现每个sprint的持续交付

    管理批量主机/网络/云:通过相应模块和插件管理远程主机,网络和云上的资源

    2.2 特点

    Agentless,无需在远程主机安装任何代理

    Free and Open Source Software,Ansible是一个很受欢迎的开源项目,github有很多的扩展模块和插件等资源

    Extensible,可通过编程接口开发模块和插件

    Integrating into Existing DevOps Workflows,可通过获取CMDB的数据动态生成inventory;通过git,subversion获取代码将开发和部署连接起来;通过API扩展开发能调用ansible指令和剧本的服务,结合UI实现应用部署的自动调用和可视化管理.

    2.3 如何工作

    主要基于SSH登录和操作远程设备,通过ansible指令调用模块和插件批量管理inventory中的主机。

     

    三.架构

     

    图 1

    3.1 Inventory

    Inventory配置了需要使用anshible管理的主机的组和列表,inventory默认存储在/etc/ansible/hosts,如下配置了两个组localhosts和azurehosts,分别增加了两台主机

    [localhosts]

    host1 ansible_ssh_host = 192.168.0.1

    [azurehosts]

    host2 ansible_ssh_host = **.**.**.**

     

    要确保ansible主机能登录到远程主机,需要再本机生成ssh-key,然后copy到远程主机以实现ssh登录

    ssh-keygen

    #需提供登录用户的密码

    ssh-copy-id -i .ssh/id_rsa.pub root@192.168.153.129

    #测试登录

    ssh root@192.168.153.129

     

    3.2 Modules

    Ansible基于对具体功能的模块的调用来对远程设备进行操作,如下指令,Ansible调用ping模块去检查和远程所有主机的连接状况

    $ ansible -m ping all

    常用模块可分为以下几类

    3.2.1 System

    file: 操作系统级别模块, 文件传输,拷贝,删除

    yum: 安装,管理软件

    command:向远程主机发送linux命令,

    shell: 执行批量指令

     

    3.2.2 Third party(Cloud)

    第三方平台,如azure系列模块

    azure_rm_deployment: 部署虚拟机

    azure_rm_machines: 管理(开机,关机,检查状态 )azure虚拟机

     

    3.2.3 Virtualazation

    docker: 用于管理docker

    http://docs.ansible.com/ansible/list_of_network_modules.html

     

    3.2.4 Networking

    通过调用网络层管理软件的指令,实现网络基本配置(IP,SubNet,Port),网络互连等

    bigip_command(F5),bigip_divice_dns(F5), netconf_config(Netconf)

     

    3.2.5 System Application

    git,subversion,appache2_module

     

    3.3 API(Application Programming Interface)

    Ansible使用Python开发,应用程序编程接口支持Python,PHP等语言进行plugin,module的开发,可以开发调用Ansible指令的服务,开发作为模块补充功能(Email,look_up)的plugin。

     

    3.4 Plugin

    Plugin 是模块功能的补充,模块一遍偏向于公用的系统操作的功能,而Plugin偏向于具体运维业务的功能,如查询,邮件通知等.

     

    3.5 Networking

    Ansible的管理对象包括大部分的网络节点,Ansible网络层面的模块帮助用户实现网络基础配置,网络互连等自动化管理

     

    3.6 CMDB(Configuration Management Database)

    Ansible对于远程对象的管理,是基于inventory中的主机和组的配置,inventory我们可以指定特定文件,而不是用默认文件,也可以从配置管理数据库中实时地获取有效的配置更新到ansible主机.

     

    3.6 Cloud

    Cloud平台如azure可以在azure portal管理云上的服务和虚拟机,Ansible通过azure系列模块,便可方便的管理虚拟机,服务,接口等.

    https://docs.ansible.com/ansible/guide_azure.html

     

    3.7 Playbooks

    我们可以执行一条ad-hoc的ansible指令完成一个操作,如下,向azurehosts这个组的主机复制了一个文件夹.

    ansible azurehosts -m copy -a "src=/etc/hosts dest=/tmp/hosts"

     

    相比于快速的临时的指令,在对远程设备应用部署,环境配置和管理过程中,我们需要执行的是一系列的指令,我们将这些指令编写在一个.yml文件中,这就是一个playbook,使用

    ansible-playbook test.yml –extra-var=”@test.json”

    或者

    ansible-playbook test.yml –extra-var=”group=azurehost”

    就可以批量执行剧本中的任务,通过–extra-var传入json或赋值变量作为参数.

    所以,如果说ansible是一个以模块,Inventory,API和插件为基础工具或者引擎,那么使用Ansible实践的解决方案的核心就是playbooks.

     

     

    四.基础实践

    目标:在多台linux服务器部署并管理一个NodeJS应用

    设备:一台安装Ansible的CentOS虚拟机,两台CentOS虚拟机,一台Azure云虚拟机

    4.1 解决方案1:直接在要部署的机器上进行操作

    步骤:

    (1) 基本环境安装和设置

    1.全局安装node,NPM

    2.打开防火墙目标端口,重启防火墙

    3.安装node 进程管理工具(PM2)

    (2)部署应用

    1.检查应用部署路径

    2.二次部署先,检查应用运行状况

    3.从代码托管服务器下载代码,copy到目标路径

    4.根据package.json安装dependencies

    5.使用pm2启动应用

    (3)管理和维护

    有小的更新时,单独上传代码并重启应用,通过pm2查看应用状态

     

    用xshell登录在多台主机,分别执行以上步骤对应的指令

     

    4.2 解决方案2:使用ansible中心机器对两组主机进行环境安装和部署

    4.2.1 解决方案架构

     

    图 2

    我们将包含批量指令或模块调用的playbooks.yml和运行参数playbooks.json托管在gitlab; 将要部署的代码也放在gitlab;

    Ansible机器的用户使用ansible-playbook执行playbooks完成相应对远程主机的安装,部署,和应用启动等操作

    步骤:

    1.配置inventory

    sudo vi /etc/ansible/hosts

    [azureservers]

    azurehost0 ansible_ssh_host=*.*.*.*

    # azurehost1 ansible_ssh_host=*.*.*.*

    [localhosts]

    localhost1 ansible_ssh_host=192.168.153.129

    localhost2 ansible_ssh_host=192.168.153.132

     

    2.创建source文件夹用于克隆gitlab repo,playbooks, vars.json到本地

    3.编写服务运行环境基本要求,和应用信息(部署目录,应用名称等)的参数

    4.编写playbooks,包含配置和部署目标主机的任务列表

     

    4.2.2扩展

    1. 编写Python plugin从cmdb 动态获取有效的主机列表到ansible机器的inventory

    2. 使用playbook_executer API的方式调用执行playbooks

    3. 使用Pyphon编写web API,调用playbook_executer方法,实现可视化的剧本执行

    4.2.3playbooks

    1.配置远程主机node/express/pm2运行环境

    运行playbook 完成环境配置:

    $ ansible-playbook sys_ensure.yml --extra-var="@vars.json"

    vars.json

    {
    "host_group":"all",
    "app_port":8000,
    "node_download_url":"http://cdn.npm.taobao.org/dist/node/v8.0.0/node-v8.0.0-linux-x64.tar.xz",
    "node_package_name":"node-v8.0.0-linux-x64.tar.xz",
    "download_node_folder_name":"node-v8.0.0-linux-x64",
    "target_node_folder_name":"nodejs",
    "node_install_path":"/usr/local/",
    "usr_local_bin_path":"/usr/local/bin",
    "installed_node_cmd_path":"/usr/local/nodejs/bin/node",
    "installed_npm_cmd_path":"/usr/local/nodejs/bin/npm",
    "pm_tool":"pm2",
    "node_bin_path":"/usr/local/nodejs/bin"
    }
    

    sys_ensure.yml

    ---
    - hosts: "{{ host_group }}"
      gather_facts: no
      tasks:
      - name: Check nodejs installation.
        command: "node -v"
        register: node_v_result
        ignore_errors: True
    
      - name: Check npm installation.
        command: "npm -v"
        register: npm_v_result
        ignore_errors: True
    
      - name: Check wget installation.
        command: "wget -help"
        register: wget_result
        ignore_errors: True
    
      - name: Install wget.
        yum:
          name: wget
          state: latest
        when: wget_result | failed
    
      - name: Download nodejs.
        command: "wget {{ node_download_url }}"
        when: node_v_result | failed or npm_v_result | failed
    
      - name: Decompress nodejs package.
        command: "tar xf {{ node_package_name }} -C {{ node_install_path }}"
        when: node_v_result | failed or npm_v_result | failed
    
      - name: Rename '{{ download_node_folder_name }}' to '{{ target_node_folder_name }}'
        command: "mv {{ node_install_path }}{{ download_node_folder_name }} {{ node_install_path }}{{ target_node_folder_name }}"
        when: node_v_result | failed or npm_v_result | failed
    
      - name: Update system PATH, add node cmd.
        command: "ln -s {{ installed_node_cmd_path }} {{ usr_local_bin_path }}"
        when: node_v_result | failed or npm_v_result | failed
    
      - name: Update system PATH, add npm cmd.
        command: "ln -s {{ installed_npm_cmd_path }} {{ usr_local_bin_path }}"
        when: node_v_result | failed or npm_v_result | failed
      
      - name: Open the application port.
        command: "firewall-cmd --zone=public --add-port={{ app_port }}/tcp --permanent"
        ignore_errors: True
    
      - name: Reload firewall
        command: "firewall-cmd --reload"
        ignore_errors: True
     
    - include: pm2_ensure.yml
      vars: 
        host_group: localhosts
        node_bin_path: "/usr/local/nodejs/bin"
    

    pm2_ensure.yml

    ---
    - hosts: "{{ host_group }}"
      gather_facts: no
      tasks:
      - name: check the installation of pm2
        command: "{{ node_bin_path }}/pm2 -v"
        register: pm2_ensure_result
        ignore_errors: True
    
      - name: Install pm2 node module.
        command: "npm install pm2 -g"
        when: pm2_ensure_result | failed
    

      

     2.上传代码和启动应用

    运行playbook 完成部署

    $ ansible-playbook publish_prepare.yml --extra-var="publish_prepare_vars.json"

    $ ansible-playbook publish.yml --extra-var="@vars.json"

    vars.json

    {
    "app_name":"express_hello",
    "apps_location":"/usr/local/nodejs/apps/express_hello",
    "node_bin_location":"/usr/local/nodejs/bin",
    "host_group":"localhosts",
    "init_file_path":"app/app.js",
    "local_code_path":"../express_hello/app"
    }
    

     

    publish_prepare_vars.json

    {
    "app_name":"express_hello",
    "gitlab_repo":"git@gitlab.com:***.git",
    "dest":"../express_hello",
    "version":"master"
    }
    

      

    publish_prepare.yml

    ---
    - hosts: 127.0.0.1
      gather_facts: no
      tasks:
      - name: remove local source code
        file: "path={{ dest }} state=absent"
        ignore_errors: True 
        connection: local
     
      - name: git source code to center ansible host
        command: "git clone {{ gitlab_repo }} {{ dest }}"
        connection: local

    publish.yml

    ---
    - hosts: "{{ host_group }}"
      gather_facts: no
      tasks:
      - name: stop {{ app_name }} if it is running on server
        command: "{{ node_bin_location }}/pm2 stop {{ app_name }}"
        ignore_errors: True
    
      - name: ensure express_app folder exists
        file: "path={{ apps_location }} state=directory"
    
      - name: upload source code files to servers
        copy: "src={{ local_code_path }} dest={{ apps_location }}"
    
      - name: install app dependencies according to  package.json
        npm: "path={{ apps_location }}/app"
    
      - name: use pm2 to start the app
        command: "{{ node_bin_location }}/pm2 start {{ apps_location }}/{{ init_file_path }} --name {{ app_name }}"
        ignore_errors: True
    

      

  • 相关阅读:
    java 开发面试题小整理(二)
    Java 字符串比较小知识
    适配器、工厂模式、线程池、线程组、互斥锁、Timer类、Runtime类、单例设计模式(二十四)
    多线程、死锁、线程安全、同步方法、代码块、休眠、守护线程、Thread、Runnable(二十三)
    RabbitMQ的几种典型使用场景
    SQL一些问题
    Redis和Memcached的区别
    Mongodb 使用场景和不使用场景
    Adapter as a WCF Binding
    ASP.NET MVC使用Filter解除Session, Cookie等依赖
  • 原文地址:https://www.cnblogs.com/wzcblogs/p/7992983.html
Copyright © 2020-2023  润新知