zoukankan      html  css  js  c++  java
  • 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
    

      

  • 相关阅读:
    BZOJ 3506 机械排序臂 splay
    BZOJ 2843 LCT
    BZOJ 3669 魔法森林
    BZOJ 2049 LCT
    BZOJ 3223 文艺平衡树 splay
    BZOJ 1433 假期的宿舍 二分图匹配
    BZOJ 1051 受欢迎的牛 强连通块
    BZOJ 1503 郁闷的出纳员 treap
    BZOJ 1096 ZJOI2007 仓库设计 斜率优化dp
    BZOJ 1396: 识别子串( 后缀数组 + 线段树 )
  • 原文地址:https://www.cnblogs.com/wzcblogs/p/7992983.html
Copyright © 2011-2022 走看看