zoukankan      html  css  js  c++  java
  • 干货 | Ansible 上手指南

    版权声明:本文为博主原创文章。未经博主同意不得转载。

    https://blog.csdn.net/O4dC8OjO7ZL6/article/details/79765539

    点击上方“中兴开发人员社区”,关注我们

    每天读一篇一线开发人员原创好文

    640?wx_fmt=png

    前言

    近期在重构一款命令行工具。使用 golang 又一次开发。但须要继续维持原有的命令,同一时候添加新命令。


    在重构的过程中,须要对现命令行工具和原命令行工具的命令输出结果进行比对,确保全然一致(项目要求)。命令行工具须要在部署完毕系统之后进行使用,每一个系统完毕时的部署组件又略微有点差异。

    所以事实上须要在多套服务主机上进行測试。

    须要做这些动作:

    • 拷贝一些配置文件到主机上:用户配置、IP和port文件

    • 安装命令行工具,确保使其在服务主机上能够使用

    • 运行一堆測试命令

    按理说,我不断把须要的配置和二进制文件复制到主机上进行測试也能完毕。


    但在使用的过程中存在以下几个问题:

    • 測试发现,结果不正确时须要及时改动代码。再次拷贝二进制文件到主机上

    • 主机环境须要多次推倒,又一次部署,验证版本号更新问题

    • 须要手动一个一个命令的运行

    • 測试有几套主机

    看上去手动的方法。有点费劲。


    眼下我从事的工作就是 PaaS 部署相关的,部署层面的脚本的运行、组件的安装、服务的启动等都是使用 Ansible 来操作。详细的脚本编写由其它同事,我仅仅知道这个东西是干嘛的。没实质性的学习。于是想借这个机会主动学习下 Ansible.

    学习之处,差点犯了老问题,即:从头開始看官方文档,而不注重当前须要解决的问题。

    由于事实上整个 Ansible 的内容体系非常多。

    不注重当前须要解决的问题,会导致你抓不住重点。

    意识到后专注在当前须要解决的问题上:

    • 拷贝配置文件和安装脚本到多个主机上

    • 在多个主机上測试命令行工具


    Ansible

    看了上面的事件背景。你大概知道这个 Ansible 究竟是个什么东西。


    Ansible 是一个配置管理和应用部署工具。即在管理主机上操作一些命令就能在节点主机上进行对应的动作。由 Python 编写。由模块化组成,即运行动作的实体。在 ansible 上都是靠着对应的模块运行动作,比方拷贝 copy 模块、运行 command 模块、shell 模块、文件 file 模块等。


    Ansible 的目标有例如以下:

    • 自己主动化部署应用

    • 自己主动化管理配置

    • 自己主动化的持续交付

    • 自己主动化的(AWS)云服务管理。


    原理

    管理主机从 hosts 里读取主机清单,通过 playbook 按顺序同一时候对管理的主机进行对应的操作。

    如图:

    640?wx_fmt=png

    640?</p><p>wx_fmt=png

    管理主机主要是对主机的定义和配置、编写 playbook(即节点主机的运行动作)。

    运行:

    1. 命令行

    ansible all -m ping

    2. playbook

    ansible-playbook example.yml

    主机清单

    编辑文件:/etc/ansible/hosts

    即:定义主机名称,变量等

    主机的变量包括什么: 主机的运行用户、连接port、password等

    相似于 ini 格式的文件

    [test-new-cli]
    10.62.60.72
    
    [test-old-cli]
    10.62.62.88

    上面的样例:将两个主机的分为两组:test-new-cli 和 test-old-cli

    主机的变量有这么些:

    • ansible_ssh_host
      将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置.

    • ansible_ssh_port
      sshport号.假设不是默认的port号,通过此变量设置.

    • ansible_ssh_user
      默认的 ssh username

    • ansible_ssh_pass
      ssh password(这样的方式并不安全,我们强烈建议使用 —ask-pass 或 SSH 密钥)

    • ansible_sudo_pass
      sudo password(这样的方式并不安全,我们强烈建议使用 —ask-sudo-pass)

    • ansible_sudo_exe (new in version 1.8)
      sudo 命令路径(适用于1.8及以上版本号)

    • ansible_connection
      与主机的连接类型.比方:local, ssh 或者 paramiko.

    • ansible_ssh_private_key_file
      ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.

    • ansible_shell_type
      目标系统的shell类型.默认情况下,命令的运行使用 ‘sh’ 语法,可设置为 ‘csh’ 或 ‘fish’.

    • ansible_python_interpreter
      目标主机的 python 路径.

    看不懂怎么用:

    举个样例,你想连接主机 192.168.100.100 , 切换到 root 用户下运行对应的操作。

    假设你直接ssh username@192.168.100.100 会要求你输入username和password。

    假如我编辑主机清单使得自己不须要输入usernamepassword,怎么操作?

    [test-new-cli]
    example ansible_ssh_host=192.168.100.100 ansible_ssh_user=username ansible_ssh_pass=root

    即配置好192.168.100.100 的主机别名为example, 主机的username和password为:username/root


    Yaml

    包括三种类型:

    • 键值对:key: value

    • 数组

    • 纯量:整型、字符串、布尔型

    这个非常好理解:假设你熟悉Python, 这三种类型就相当于:map, list, 变量

    假设你熟悉golang, 这三种类型就相当于: map, 数组。 变量

    演示样例:

    ---
    - name: "execute command nodepool node list by { {item.name} }"
      shell: "{ {item.cli} } nodepool node list { {item.id} }"
      register: result
    - name: show result
      debug:
        msg: "{ {result.stdout_lines} }"
      with_items:
        - { name: "new-cli", cli: "new-cli", id: "1" }
        - { name: "old-cli", cli: "old-cli", id: "1" }

    模块

    Ad-doc

    ansible 命令行式,适合运行单条命令。

    # 操作 192.168.100.100 主机。看管理主机是否和192.168.100.100的主机连通
    
    ansible example -m ping
    
    # 操作 192.168.100.100 主机,拷贝管理主机下的/root/opcli/conf 文件至节点主机/etc/opcli/conf 下
    ansible test-new-cli -m copy -a="src=/root/opcli/conf dest=/etc/opcli/conf"
    • m: 模块

    • a: 接參数

    能够看出适合运行单条命令


    Patterns

    假如你的节点主机分组非常多了。Ad-hoc 怎样选择特定特征的节点主机分组呢?

    使用类正則表達式。

    比方触发全部节点主机进行动作:

    ansible all -m ping
    ansible * -m ping
    
    两者等价,都是选择全部的节点主机

    演示样例:

    1. 主机别名或者IP
    one.example.com
    one.example.com:two.example.com
    192.168.1.50
    192.168.1.*
    2. 一个或多个groups
    webservers
    webservers:dbservers
    3. 排除一个组
    webservers:!phoenix 
    # 隶属 webservers 组但同一时候不在 phoenix组
    4. 两个组的交集
    webservers:&staging
    # 同一时候隶属于 webservers 和 staging 组
    5. 列表
    webservers[0]
    webservers[0-25]
    6. 其它

    有什么需求,看官方文档吧。


    Playbook

    编写 yaml 文件。适合运行多步操作的复杂操作。能够看成是Ad-doc 命令的集合。甚至能够看成是一门编程语言。

    运行:ansible-playbook example.yml

    依照 example.yml 文件中的任务集合按步运行任务。


    演示样例

    命令演示样例,仅举几例。有带參数、有没带參数的。

    我们终于的目标是:在节点主机上运行这些命令进行比对两者结果。

    新版本号:

    命令说明
    command-cli nodepool list查询资源池
    command-cli nodepool node list 查询资源池节点
    command-cli node list查询节点
    command-cli node show 查询某个节点
    command-cli task list查询部署任务

    旧版本号:

    命令说明
    old-cli nodepool list查询资源池
    old-cli nodepool node list 查询资源池节点
    old-cli node list查询节点
    old-cli node show 查询某个节点
    old-cli task list查询部署任务

    文件夹结构:

    demo-for-ansible:
    ---nodepool/nodepool-list.yml
    ---nodepool/nodepool-node-list.yml
    ---node/node-list.yml
    ---node/node-show.yml
    ---task/task-list.yml
    ---main.yml

    第一步:编写主机清单

    /etc/ansible/hosts

    [test_client]
    192.168.100.100 ansible_ssh_user=xiewei ansible_ssh_pass=root ansible_connection=ssh
    192.168.100.101 ansible_ssh_user=xiewei ansible_ssh_pass=root ansible_connection=ssh
    192.168.100.102 ansible_ssh_user=xiewei ansible_ssh_pass=root ansible_connection=ssh

    定义主机连接类型、username、password


    第二步:编写 yaml 文件

    主要动作:

    • 在节点主机上创建两个文件夹: /etc/client/conf  /et/client/commands

    • 拷贝管理主机文件夹:/etc/client/conf 文件至节点主机: /etc/client/conf

    • 拷贝管理主机二进制文件:/root/gosrc/src/client/command-cli 至节点主机 /etc/client/commands

    • 软连接节点主机二进制文件/etc/client/commands/command-cli 至节点主机 /usr/bin/command-cli

    • 运行上表中查询命令:nodepool, node, task

    main.yml

    ---
    - hosts: test_client
      remote_user: root
      become: yes
      become_user: root
      become_method: sudo
      tasks:
        # 在节点主机上创建文件夹:/etc/client/conf
        - name: create /etc/client/conf /etc/client/commands
          file:
            path: "/etc/client/{ {item} }"
            owner: root
            group: root
            mode: 0755
            state: directory
          with_items:
          - "conf"
          - "commands"
    
    
        # 拷贝管理主机配置文件/etc/client/conf和二进制文件至 /etc/client/conf, /etc/client/commands
        - name: copy /etc/client/conf
          copy: src="{ { item.src } }" dest="{ { item.dest } }" owner=root group=root mode=0644
          with_items:
          - { src: "/etc/client/conf", dest: "/etc/client/conf" }
          - { src: "/root/gosrc/src/client/command-cli", dest: "/etc/client/commands"}
    
        # 软连接到 /usr/bin/command-cli
        - name: link  /etc/client/commands
          file: src="/etc/client/commands/command-cli" dest="/usr/bin/command-cli" state=link
    
        # nodePool list
        - include_tasks: "nodepool/nodepool-list.yml"
          with_items:
          - { client: "new client", name: "command-cli"}
          - { client: "old client", name: "old-cli"}
    
        # nodePool node list <id>
        - include_tasks: "nodepool/nodepool-node-list.yml"
          with_items:
          - { id: "1", client: "new client", name: "command-cli"}
          - { id: "1", client: "old client", name: "old-cli"}
    
        # node list
        - include_tasks: "node/node-list.yml"
          with_items:
          - { client: "new client", name: "command-cli"}
          - { client: "old client", name: "old-cli"}
    
        # node show <id>
        - include_tasks: "node/node-show.yml"
          with_items:
          - { client: "new client", name: "command-cli", id: 1}
          - { client: "old client", name: "old-cli", id: 1}
    
        #  task list
        - include_tasks: "task/task-list.yml"
          with_items:
          - { client: "new client", name: "command-cli"}
          - { client: "old client", name: "old-cli"}

    task-list.yml

    ---
    - name: execute command task list
      shell: "{ {item.name} } task list"
      register: result
    - name: show result
      debug:
        msg: "{ {result.stdout_lines} }"

    第三步: 检查语法

    两种方法

    1. ansible-playbook main.yml --syntax-check

    2. 先安装 pip install ansible-lint

    ansible-lint main.yml

    第四步: 运行

    ansible-playbook main.yml

    整个的编写流程大概是这样。核心是编写 yml 文件,调用 ansible 支持的各种模块完毕任务。


    下一步

    1. 熟悉 playbook

    2. 熟悉 ansible 模块

    3. 熟悉 ansible api

    关注你当前须要解决的问题,切入学习,事半功倍。

    640?wx_fmt=png

  • 相关阅读:
    接口开发中的 RestTemplate 传参问题
    逆流成河:五年软件开发生涯
    .NET Web开发技术简单整理
    2011-05-29 21:48 VS.NET2010水晶报表安装部署[VS2010]
    WPF 基础到企业应用系列3——WPF开发漫谈
    C# WinForm开发系列
    接口和委托的区别
    通过jquery触发select自身的change事件
    php去掉字符串中的最后一个字符和汉字
    Go语言学习之数据类型
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/9899624.html
Copyright © 2011-2022 走看看