zoukankan      html  css  js  c++  java
  • Ansible

    1. 概述

      Ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。Ansible是一个批量的自动化部署工具。

    ansible:

          模块:

                 1) yaml           用来编写yaml脚本的语言

                 2) paramiko    模拟ssh协议连接linux客户端

                 3) jinja2           模板语言

    工作原理:

                  ansible通过hosts文件和免秘钥(配置文件用户名密码端口号)来实现批量管理主机。

      

       Ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括:

      1> Ansible:Ansible的核心程序;

      2> connection plugins:连接插件,负责和被监控端实现通信,即Ansible和host的通信;

      3> Host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;

      4> Core Modules:核心模块,Ansible执行任何管理任务都不是由Ansible自己完成,而是由核心模块完成;Ansible管理主机之前,先调用core Modules中的模块,然后指明管理Host Lnventory中的主机,就可以完成管理主机。

      5> Custom Modules自定义模块,完成Ansible核心模块无法完成的功能,此模块支持任何语言编写。

    Ansible将很多命令集成为模块调用。

      6> Playbook:YAML格式文件,多个任务定义在一个文件中,使用时可以统一调用,“剧本”用来定义那些主机需要调用那些模块来完成的功能。剧本执行多个任务时,非必需可以让节点一次性运行多个任务。

    简而言之ansible有如下的特点:

    • Stupied Simple ,上手简单,学习曲线平滑
    • SSH by default ,安全,无需安装客户端(agent)
    • 配置简单、功能强大、扩展性强
    • 支持API及自定义模块,可通过Python轻松扩展
    • 通过Playbooks来定制强大的配置、状态管理
    • 提供一个功能强大、操作性强的Web管理界面和REST API接口——AWX平台(web界面很少用)
    • 幂等性:一种操作重复多次结果相同

    2. Ansible的安装

      三台主机,192.168.16.4为服务机,.5、.6为服务机

      Ansible安装需要用到扩展源(epel源),扩展源配置完成即可用yum进行下载

      在.3上下载安装

    [root@localhost ~]# yum install ansible -y
    稍等……..
    Complete!

    Ansible的配置文件

      /etc/ansible/ansible.cfg

      /etc/ansible/hosts

    3. Ansible客户端配置

    有两种方法

    1> 进入服务端配置文件进行配置

    #在文件末尾写入配置
    [root@localhost ~]# vim /etc/ansible/hosts
    [zxj]                                                    #组名
    192.168.16.5 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=zxjwrl
    192.168.16.6 ansible_ssh_user=root ansibel_ssh_port=22 ansible_ssh_pass=zxjwrl
       #远程节点主机        用户               端口           密码
    [root@localhost ~]# vim /etc/ansible/ansible.cfg
    host_key_checking = False                  #进入配置文件,关掉检查

    2> 免秘钥登录

    sshd服务

    配置完成后,查看Ansible是否与管理节点通

    [root@localhost ~]# ansible zxj -m ping       #主机组名可以替换为单独的节点ip或者直接改为all,all表示所有主机,ip表示组名下单独的一个节点
    192.168.16.6 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    192.168.16.5 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }

    4. Ansible支持的模块

    查看Ansible的模块

    [root@localhost ~]# ansible-doc -l
    常用的模块
    ping 模块:            尝试连接主机,如果测试成功会返回‘pong’
    command模块:          在远程节点执行命令
    yum模块:              使用yum软件包管理工具管理软件包
    shell模块:            和command模块类似,执行命令,支持变量等符号
    cron模块 :            管理定时任务,计划任务
    service模块:          管理程序服务
    file模块:             设置文件属性
    copy模块:             复制本地文件到远程主机
    script模块:           传送本地的一个脚本并在远程主机上执行
    setup模块:            获取远程主机的参数信息
    user模块:             管理用户账户
    group模块:            添加或者删除用户组

    查看具体模块的用法,以yum模块为例

    [root@localhost ~]# ansible-doc -s yum
    - name: Manages packages with the `yum' package manager
      yum:
          allow_downgrade:       # Specify if the named
    …….
    state:                 # Whether to install (`present' or `installed', `latest'), or remove (`absent' or `removed') a package. `present' and `installed' will simply ensure that a
                                   desired package is installed. `latest' will update the specified package if it's not of the latest available version. `absent'
                                   and `removed' will remove the specified package. Default is `None', however in effect the default action is `present' unless the
                                   `autoremove' option is¬ enabled for this module, then `absent' is inferred.

    5. Ansible常用命令相关概念

      协程:线程的处理单元;

      线程:最小的调度单位;

      进程:是最小的管理单元;

      一个进程里面至少1个线程,一个线程或者多个线程可以在一个进程里面。

    hoc命令行下的命令:

    ansible-doc -l

    查看支持的模块

    ansible-doc -s MODEL_NAME

    查看模块的用法

    -f forks

    指定启动并发线程数以减少服务器压力,如ansible -f 5 表示启动五个线程

    -m model_name

    要使用的模块

    -a args1

    特有的参数,即调用的模块里面的参数,使用-a调用

    ansible all -m ping

    查看client端是否正常ping通

    通过调用来执行命令举例详解

    格式: ansible  组名 -m model_name -a 执行命令

    #查看客户端信息
    [root@localhost ~]# ansible zxj -m setup
    ……..
    
    #复制文件
    #复制并改名
    [root@localhost ~]# ansible zxj -m copy  -a "src=/root/zxj.txt dest=/root/wrl.txt"
    192.168.16.6 | CHANGED => {                        #源文件        目标文件
        "changed": true,                               #注意幂等性
        "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
        "dest": "/root/wrl.txt",
        "gid": 0,
        "group": "root",
        "md5sum": "d41d8cd98f00b204e9800998ecf8427e",
        "mode": "0644",
        "owner": "root",
        "secontext": "system_u:object_r:admin_home_t:s0",
        "size": 0,
        "src": "/root/.ansible/tmp/ansible-tmp-1557345658.29-197424182241042/source",
        "state": "file",
        "uid": 0
    }
    192.168.16.5 | CHANGED => {
        "changed": true,
        "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
        "dest": "/root/wrl.txt",
        "gid": 0,
        "group": "root",
        "md5sum": "d41d8cd98f00b204e9800998ecf8427e",
        "mode": "0644",
        "owner": "root",
        "secontext": "system_u:object_r:admin_home_t:s0",
        "size": 0,
        "src": "/root/.ansible/tmp/ansible-tmp-1557345658.28-200767865941415/source",
        "state": "file",
        "uid": 0
    }
    
    #在客户机下查看
    .5:
    [root@localhost ~]# ls
    anaconda-ks.cfg  wrl.txt
    .6:
    [root@localhost ~]# ls
    anaconda-ks.cfg  wrl.txt
    
    #command命令
    [root@localhost ~]# ansible zxj -m command -a 'date'              #-a后面的引号内可以加任何正确的命令
    192.168.16.6 | CHANGED | rc=0 >>
    Thu May  9 03:52:53 CST 2019
    192.168.16.5 | CHANGED | rc=0 >>
    Thu May  9 03:52:53 CST 2019
    
    #command命令会进行警告。进入配置文件/etc/ansible/ansible.cfg改command_warnings = False
    
    #创建、删除用户
    [root@localhost ~]# ansible zxj -m user -a "name=zxj state=present"   #user模块  用户名  执行状态(此处为别名)
    [root@localhost ~]# ansible zxj -m user -a "name=zxj state=absent"
    
     
    #安装、卸载软件
    [root@localhost ~]# ansible zxj -m yum -a "name=httpd state=latest"
    [root@localhost ~]# ansible zxj -m yum -a "name=httpd state=absent"
    #如果用install、remove等必须写成单词的过去式
    #注意:yum模块和yum命令同名,因此执行时会警告,进入配置文件/etc/ansible/ansible.dfg改deprecation_warnings = False
    
     
    #启动apache服务
    [root@localhost ~]# ansible zxj -m service -a "name=httpd state=started"
    #stopped、restarted、started等均为过去式,ansible不支持systemctl,用centos6及以前版本的service代替
    
    #运行脚本
    [root@localhost ~]# ansible zxj -m script -a "/tmp/test.sh"        #为脚本绝对路径
    
    等等

      

    6. Playbook

    一个任务为play,多个任务为playbooks

    6.1  yaml(yml)

      yaml是一个可读性高的用来表达资料序列的格式,yaml参考了其他多种语言,包括:xml,c语言,python,perl以及电子邮件格式RFC2822等,ClarkEvans在2001年在首次发表了这种语言。

      yaml的可读性好

      yaml和脚本语言的交互性好

      yaml使用实现语言的数据类型

      yaml有一个一致的信息模型

      yaml易于实现

      yaml可以基于流程来处理

      yaml表达能力强,扩展性好

    6.2  playbook下的5种模块

      tasks:主程序;

      variables:变量,以变量形式传参;

      templates:模板;

      handlers:触发器;

      roles:角色。

    6.3  playbook书写规范

      脚本名以 .yaml或yml结尾;

      一定不能使用tab键,yaml有严格的缩进要求;

      每个冒号:后面必须有空格;

      注意:

        1)以冒号结尾不需要空格

         2)表示文件路径的模版可以不需要空格

       想要表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为同一个列表的一部。

    6.4 ansiblb-playbook常用命令

      1)对剧本语法检测

        ansible-playbook --syntax-check  /root/ansible/httpd.yaml

      2)-C模拟执行剧本

        ansible-playbook  -C /root/ansible/httpd.yaml

      3)执行剧本

          ansible-playbook   /root/ansible/httpd.yaml

    6.5  ansible实例详解

    #创建实例文件
    [root@localhost ~]# vim example.yaml           # 以yaml或者yml
    - hosts: zxj                                   # - 必须顶格写,后面必须加空格,hosts:表示定义主机组,冒号后面必须加空格,后面跟的内容可以是all、ip或主机名
      remote_user: root                            # 指定远程用户,以root运行,remote必须和host对齐,冒号后面必须加空格
      tasks:                                       # 调用任务模块,tasks必须与remote对齐,在tasks下面开始写命令
      - name: create userzxj                       # 横杆和task对齐,与name之间必须有空格,冒号后面必须加空格,后面定义任务名
        user: name=userzxj                         # 调用user模块,user必须与name对齐,冒号后面必须加空格。一个任务已经完成,可以继续往下添加任务,格式一致
    
    #如添加复制任务
      - name: copy httpd.conf
        copy: src=/etc/httpd/conf/httpd.conf  dest=/root/test/httpd.conf
    #或者定义变量,通过jinjia2里的模板语言{{ }}来引用变量执行
    - hosts: zxj remote_user: root vars: #定义变量 - p: httpd.conf #p为变量名,与横杠间必须有空格,http为变量值 tasks: - name: create userzxj user: name=userzxj - name: copy httpd.conf copy: src=/etc/httpd/conf/{{ p }} dest=/root/test/{{ p }} #引用变量 #再定义触发器,触发器仅由相邻的上一个任务触发,上一个任务执行成功才触发执行 - hosts: zxj remote_user: root vars: - p: httpd.conf tasks: - name: create userzxj user: name=userzxj - name: copy httpd.conf copy: src=/etc/httpd/conf/{{ p }} dest=/root/test/{{ p }} notify: #申明定义触发器 - service httpd restarted #定义触发器名字 handlers: #定义触发器,必须在最后,必须与hosts对齐 - name: service httpd restarted #定义任务名,必须与触发器名字相同 service: name=httpd state=restarted #调用service模块,执行命令
    :wq #执行yaml文件用命令ansible
    -playbook [root@localhost ~]# ansible-playbook example.yaml PLAY [zxj] ********************************************************
    TASK [Gathering Facts]
    ********************************************** #测试ansible是否与客户端连通,该任务自动执行 ok: [192.168.16.5] #幂等性,由于先前执行过,并没有改变,但该命令执行成功 ok: [192.168.16.6]
    TASK [create userzxj]
    ********************************************* #执行第一个任务 ok: [192.168.16.6] ok: [192.168.16.5] TASK [copy httpd.conf] ********************************************** #执行第二个任务 changed: [192.168.16.5] #幂等性,由于先前并没有执行过,因此改变,任务执行成功 changed: [192.168.16.6] RUNNING HANDLER [service httpd restarted] ************************* #第二个命令执行成功自动触发 changed: [192.168.16.6] changed: [192.168.16.5] PLAY RECAP ***************************************************** 192.168.16.5 : ok=4 changed=2 unreachable=0 failed=0 192.168.16.6 : ok=4 changed=2 unreachable=0 failed=0 #服务端查看httpd启动 #.5 [root@localhost ~]# ss -tnl LISTEN 0 128 :::80 :::* .6 [root@localhost ~]# ss -tnl LISTEN 0 128 :::80 :::* #端口前的星号表示ipv4,冒号表示ipv6和ipve4 #可以创建多个触发器,依托于上一个任务
    #还可以进行迭代创建
    - hosts: zxj remote_user: root vars: - p: httpd.conf tasks: - name: create many users user: name={{ item }} #进行迭代创建 with_items: #使用迭代 - zxj1 #创建多个用户 - zxj2 - zxj3 #模块均可进行迭代执行 #对于模板模块template,在配置文件里写入对应模板,yaml文件在执行命令模块的时候调用模板模块就可以了,如: #要执行复制http文件任务,进入httpd配置文件,将监听端口改为jinjia2的模板文件,紧接着修改ansible的配置文件 [root@localhost ~]# vim /etc/httpd/conf/httpd.conf #Listen 12.34.56.78:80 Listen {{ port }} # 变量名可以任意取 [root@localhost ~]# vim example.yaml - name: copy httpd.conf template: src=/etc/httpd/conf/{{ p }} dest=/root/test/{{ p }} [root@localhost ~]# vim /etc/ansible/hosts ## db-[99:101]-node.example.com [zxj] 192.168.16.5 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=zxjwrl port=5000 #写入端口,写入变量 192.168.16.6 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=zxjwrl port=6000 #引用多个模板文件时可以在该配置文件后面空格后继续写

    7. Roles

      什么情况下用到roles:

      假如现在有3个被管理主机,第一个要配置成httpd,第二个要配置成php服务器,第三个要配置成MySQL服务器。要如何来定义playbook?

      第一个play用到第一个主机上,用来构建httpd,第二个play用到第二个主机上,用来构建php,第三个play用到第三个主机上,用来构建MySQL。这些个play定义在playbook中比较麻烦,将来也不利于模块化调用,不利于多次调用。比如说后来又加进来一个主机,这个第4个主机既是httpd服务器,又是php服务器,只能写第4个play,上面写上安装httpd和php。这样playbook中的代码就重复了。这时我们可以通过roles来实现,将各个模块命令集成在roles下的服务里面,直接调用服务即可。

    Roles实例详解

      使用目录代替命令,各个目录如下:

        files:定义src(源)文件

        handlers:定义触发器

        tasks:定义任务

        templates:定义模板文件

        vars:定义变量

      各个目录写入文件后放入server目录,执行时直接调用目录。

    #1 创建级联目录
    [root@localhost ~]#mkdir-p playbooks/roles/{webservers,dbservers}/{files,handlers,tasks,templates,vars}
    [root@localhost ~]# tree playbooks/             #查看定义的roles树
    playbooks/
    └── roles
        ├── dbservers                               #角色
        │   ├── files
        │   ├── handlers
        │   ├── tasks
        │   ├── templates
        │   └── vars
        └── webservers                              #角色
            ├── files
            ├── handlers
            ├── tasks
            ├── templates
            └── vars
    
    #2. 编辑命令
    [root@localhost ~]# vim playbooks/roles/webservers/tasks/main.yml      #文件名必须是main.yaml或者main.yml在创建的文件里直接写任务,不必再声明组名等信息
    - name: create user userzxj                    #写入多个命令
      user: name=userzxj
    - name: service httpd start
      service: name=httpd state=started
    :wq
    
    #3. 创建与roles同等级别的site(站点)文件
    [root@localhost ~]# cd playbooks/
    [root@localhost playbooks]# vim site.yml       #文件名必须为site
    - hosts: zxj                                   #定义组名和远程用户
      remote_user: root
      roles:                                       #调用roles
      - webservers                                 #写入角色,执行角色下的任务
      - dbservers                                                    
    :wq
     
    #4. 执行任务
    [root@localhost playbooks]# ansible-playbook site.yml  #执行site文件
    PLAY [zxj] *********************************************************
    TASK [Gathering Facts]***********************************************
    ok: [192.168.16.6]
    ok: [192.168.16.5]
    TASK [webservers : create user userzxj]**********************************
    changed: [192.168.16.6]
    changed: [192.168.16.5]
    TASK [webservers : service httpd start]************************************
    changed: [192.168.16.6]
    changed: [192.168.16.5]
    PLAY RECAP *******************************************************
    192.168.16.5           : ok=3    changed=2    unreachable=0    failed=0   
    192.168.16.6           : ok=3    changed=2    unreachable=0    failed=0
    #执行成功

    files目录:定义roles后scr(源文件)不需要写绝对路径,只声明路径即可

    #1. 准备实验文件
    [root@localhost playbooks]# cp /etc/httpd/conf/httpd.conf  roles/webservers/files/
    
    #2. 写入任务目录
    [root@localhost playbooks]# vim roles/webservers/tasks/main.yml
    - name: copy httpd
      copy: src=httpd.conf  dest=/root/test/httpd.conf     #scr不需要再写绝对路径
    :wq
    
    #3. 执行site.yml
    [root@localhost playbooks]# ansible-playbook site.yml
    ……
    192.168.16.5            : ok=2    changed=1    unreachable=0    failed=0  
    192.168.16.6            : ok=2    changed=1    unreachable=0    failed=0

    handlers目录,触发任务

    #1. 写入任务文件,不需要以handlers结尾
    [root@localhost playbooks]# vim roles/webservers/tasks/main.yml
    - name: copy httpd
      copy: src=httpd.conf  dest=/root/test/httpd.conf
      notify:                              #声明触发
      - restart httpd                      #定义名称,不需要再以handlers结尾
    
    #2. 写入handlers下的main.yml
    [root@localhost playbooks]# vim roles/webservers/handlers/main.yml
    - name: restart httpd
      service: name=httpd state=restarted
    
    #3. 执行site.yml
    [root@localhost playbooks]# ansible-playbook site.yml
    PLAY [zxj] ***************
    TASK [Gathering Facts] *********
    ok: [192.168.16.5]
    ok: [192.168.16.6]
    TASK [webservers : copy httpd] **************
    changed: [192.168.16.5]
    changed: [192.168.16.6]
    RUNNING HANDLER [webservers : restart httpd] ************* #触发
    changed: [192.168.16.6]
    changed: [192.168.16.5]
    PLAY RECAP ************
    192.168.16.5            : ok=3    changed=2    unreachable=0    failed=0  
    192.168.16.6            : ok=3    changed=2    unreachable=0    failed=0  

    template目录,执行copy命令时调用定义的模板参数

    #1. 写入任务文件
    [root@localhost playbooks]# vim roles/webservers/tasks/main.yml
    - name: copy httpd
      template: src=httpd.conf  dest=/root/test/httpd.conf   #src不写绝对路径
      notify:
      - restart httpd
    
    #2. 定义模板参数
    [root@localhost playbooks]# cp roles/webservers/files/httpd.conf   roles/webservers/templates/httpd.conf
    [root@localhost playbooks]# vim roles/webservers/templates/httpd.conf
    #Listen 12.34.56.78:80
    Listen {{ port }}                                       #更改监听端口为模板参数
    
    #3. 更改配置文件
    [root@localhost ~]# vim /etc/ansible/hosts
    [zxj]
    192.168.16.5 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=zxjwrl port=5000                                    #写入参数
    192.168.16.6 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass=zxjwrl port=6000                                    #写入参数
    
    #4. 执行site.yml文件
    [root@localhost playbooks]# ansible-playbook site.yml
    PLAY [zxj]…….
    TASK [webservers : copy httpd] *
    changed: [192.168.16.5]
    changed: [192.168.16.6]
    RUNNING HANDLER [webservers : restart httpd]
    changed: [192.168.16.6]
    changed: [192.168.16.5]
    PLAY RECAP ***************
    changed: [192.168.16.6]
    changed: [192.168.16.5]
    PLAY RECAP ***************
    192.168.16.5            : ok=3    changed=2    unreachable=0    failed=0  
    192.168.16.6            : ok=3    changed=2    unreachable=0    failed=0

    var目录,定义参数

    #1. 定义var的main.yml
    [root@localhost playbooks]# vim  roles/webservers/vars/main.yml
    p: httpd.conf                #定义变量p,变量值为httpd.conf
    
    #
    2. 修改任务变量 [root@localhost playbooks]# vim roles/webservers/tasks/main.yml - name: copy httpd template: src={{ p }} dest=/root/test/{{ p }} notify: - restart httpd
    #
    3. 执行site.yml

      roles下的角色,如webserver、dbserver等可以并排写入与roles同级的site.yml文件,执行多个角色,每个角色都可以写入多个任务,实现不同量的批量部署。 

  • 相关阅读:
    kvm virtio
    GPU 线程块/线程束
    ubuntu source
    React
    分布式系统
    honpeyhonepy
    css是干什么的
    bootstrap中的横的列
    数据安全之 alert logic
    viewset的使用的方法
  • 原文地址:https://www.cnblogs.com/ajunyu/p/10898065.html
Copyright © 2011-2022 走看看