zoukankan      html  css  js  c++  java
  • Ansible

    Ansible

    • SSH-based configuration management, deployment, and task execution system

    运维工具的分类:

    • agent:基于专用的agent程序完成管理功能,puppet, func, zabbix, ...
    • gentless:基于ssh服务完成管理,ansible, fabric, ...

    架构:

    Ansible Core
    
    Modules:
        Core Modules
        Customed Modules
    
    Host Iventory
        Files
        CMDB
    
    PlayBooks
        Hosts
        roles
    
    Connection Plugins:
    

    特性:

    • 模块化:调用特定的模块,完成特定的任务
    • 基于Python语言研发,由Paramiko, PyYAML和Jinja2三个核心库实现
    • 部署简单:agentless
    • 支持自定义模块,使用任意编程语言
    • 强大的playbook机制
    • 幂等性

    安装及程序环境:

    • 程序:

      • ansible
      • ansible-playbook
      • ansible-doc
    • 配置文件:

      • /etc/ansible/ansible.cfg
    • 主机清单:

      • /etc/ansible/hosts
    • 插件目录:

      • /usr/share/ansible_plugins/

    基本使用:

    • ansible命令:
    Usage: ansible <host-pattern> [options]
        常用选项:
            -m MOD_NAME -a MOD_ARGS
    
    • 配置Host Inventory:
    /etc/ansible/hosts
    [group_id]
    HOST_PATTERN1
    HOST_PATTERN2
    
    • 模块:
    获取模块列表:ansible-doc -l
    获取指定模块的使用帮助:ansible-doc -s MOD_NAME
    

    常用模块

    • ping:探测目标主机是否存活
    ansible all -m ping
    
    • command:在远程主机执行命令;
    ansible all -m command -a "ifconfig"
    # command模块:不能理解管道命令,要调用shell模块来执行
    ansible all -m command -a "echo 'gmtest' | passwd --stdin centos"
    
    • shell:在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道等
    ansible all -m shell -a "echo 'gmtest' | passwd --stdin centos
    
    注意:command和shell模块的核心参数直接为命令本身;而其它模块的参数通常为“key=value”格式
    
    • copy:Copies files to remote locations.
    用法:
    (1) 复制文件
    -a "src= dest= "
    
    (2) 给定内容生成文件
    -a "content= dest= "
    
    dest中不指文件名,默认随机生成文件名
    
    其它参数:mode, owner, group, ...
    
    ansible all -m copy -a "src=/etc/fstab dest=/tmp/test.gm mode =640"
    ansible all -m copy -a "content='hello
    world
    ' dest=/tmp/test.gm mode =640"
    
    • file:Sets attributes of files
    用法:
    
    (1) 创建目录:
    -a "path= state=directory"
    
    (2) 创建链接文件:
    -a "path= src= state=link"
    
    (3) 删除文件:
    -a "path= state=absent“
    
    ansible all -m file -a "path=/tmp/gm state=directory"
    
    ansible all -m file -a "path=/tmp/gm state=absent"
    
    ansible all -m file -a "path=/tmp/gm src=/etc/fstab state=link"
    
    • fetch:Fetches a file from remote nodes
    从远端主机获取文件,也可以使用scp命令实现
    
    • cron:Manage cron.d and crontab entries
    在远端主机上设置周期性任务
    
    -a ""
    
    minute=
    hour=
    day=
    month=
    weekday=
    job=
    name=
    user=
    
    
    state={present|absent}
    
    state=absent+name="STRING":用于取消此任务计划
    
    ansible all -m cront -a "minute='*/5' job='/usr/sbin/ntpdate 10.1.0.1 &>/dev/null' name='sync time'"
    ansible all -m cront -a "name='sync time' state='absent'"
    
    • hostname:Manage hostname
    name=XXX
    
    • yum:Manages packages with the I(yum) package manager
    -a ""
    
    (1) name= state={present|latest}
    
    (2) name= state=absent
    
    ansible all -m yum -a "name=httpd"
    ansible all -m yum -a "name=httpd state=absent"
    
    • service:Manage services.
    -a ""
    
    name=
    state=
        started
        stopped
        restarted
        reloaded
    
    enabled=on|true
    
    是否开机自启动
    
    runlevel=
    
    ansible websrvs -m yum -a "name=httpd "
    ansible websrvs -m service -a "name=httpd state=start enaled=true"
    ansible websrvs -m service -a "name=httpd state=started"
    
    • script:Runs a local script on a remote node after transferring it
    在远端主机上运行一个本地的shell脚本
    
    -a ""
    
    creates # 一个文件名,当这个文件存在,则该命令不执行
    free_form= # 本地脚本路径
    removes # 一个文件名,这个文件不存在,则该命令不执行
    
    ansible test -m script -a ‘/root/local.sh’
    
    主控端/root/下必须有local.sh脚本
    
    • group: Add or remove groups
    -a ""
    
    name=
    state= # Whether the group should be present or not on the remote host
    system=
    gid=
    
    ansible all -m group -a "name=gm state=present system=fails gid=2000"
    
    • user:Manage user accounts
    -a ""
    
    name=
    group=
    groups=
    comment=
    uid=
    system=
    shell=
    expires=
    home=
    
    ansible all -m user -a "name=gm group=gm groups=tom uid=2000"
    
    • setup:Gathers facts about remote hosts
    获取远端主机关于ansible的变量
    
    ansible 10.1.0.68 -m setup
    

    YAML

    • YAML is a data serialization format designed for human readability and  interaction with scripting languages.

    • 数据结构:

    key:value
      - item1
      - item2
      - item3
    
    {name:jerry, age:21} 
    

    PlayBook:

    • 核心元素:
    Tasks:任务,由模块定义的操作的列表
    Variables:变量
    Templates:模板,即使用了模板语法的文本文件
    Handlers:由特定条件触发的Tasks
    Roles:角色
    
    • playbook的基础组件:
    Hosts:运行指定任务的目标主机
    remote_user:在远程主机以哪个用户身份执行
        sudo_user:非管理员需要拥有sudo权限
    tasks:任务列表
        模块,模块参数:
        格式:
        (1) action: module arguments
        (2) module: arguments
    
    
    • 示例1:<一下内容写入一个.yaml的文件中即可>
    - hosts: all
      remote_user: root
      tasks:
      - name: install a group
        group: name=mygrp system=true
      - name: install a user
        user: name=user1 group=mygrp system=true
    
    - hosts: websrvs
      remote_user: root
      tasks:
      - name: install httpd package
        yum: name=httpd
      - name: start httpd service
        service: name=httpd state=started
    
    - hosts: all
      remote_user: root
      tasks:
      - name: create group
        group: name=hlr gid=3000 state=present
      - name: create user
        user: name=hlr uid=2500 group=hlr
    
    
    • 运行playbook,使用ansible-playbook命令
    (1) 检测语法
        ansible-playbook --syntax-check /path/to/playbook.yaml
    (2) 测试运行
        ansible-playbook -C /path/to/playbook.yaml
            --list-hosts
            --list-tasks
            --list-tags
    (3) 运行
        ansible-playbook  /path/to/playbook.yaml
            -t TAGS, --tags=TAGS :只运行某个标记的tasks
            --skip-tags=SKIP_TAGS
            --start-at-task=START_AT
    
    • handlers:由特定条件触发的Tasks;
    调用及定义方式:
    tasks:
    - name: TASK_NAME
        module: arguments
        notify: HANDLER_NAME
    handlers:
    - name: HANDLER_NAME
        module: arguments
    
    • 示例2:
    - hosts: websrvs
      remote_user: root
      tasks:
      - name: install httpd package
        yum: name=httpd state=latest
      - name: install conf file
        copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
        notify: restart httpd service
      - name: start httpd service
        service: name=httpd state=started
      handlers:
      - name: restart httpd service
        service: name=httpd state=restarted
    
    • tags:给指定的任务定义一个调用标识
    - name: NAME
      module: arguments
      tags: TAG_ID
    
    • 示例3:
    - hosts: websrvs
      remote_user: root
      tasks:
      - name: install httpd package
        yum: name=httpd
      - name: create httpd-conf file
        copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
        tags: file_change
        notify: reload httpd server
      - name: create httpd index.html file
        copy: src=/var/www/html/index.html dest=/var/www/html/index.html
        tags: file_change
        notify: reload httpd server
      - name: start httpd server
        service: name=httpd state=started enabled=on
      handlers:
      - name: reload httpd server
        shell: service httpd restart
        
    ansible-playbook -t file_change web.yaml
      -t TAG_ID1,TAG_ID2可以一次调用多个标签
    

    Variables:

    • 类型:
    - 内建:
    1. facts
    
    - 自定义:
    2.1. 命令行传递
      -e VAR=VALUE
    2.2. 在hosts Inventory中为每个主机定义专用变量值
      2.2.1 向不同的主机传递不同的变量
        IP/HOSTNAME variable_name=value
      2.2.2 向组内的所有主机传递相同的变量
        [groupname:vars]
        variable_name=value
      2.2.3 在playbook中定义<添加在remote_user后面,tasks前面>
        vars:
        - var_name: value
        - var_name: value
      2.2.4 Inventory还可以使用参数:
        用于定义ansible远程连接目标主机时使用的属性,而非传递给playbook的变量
        ansible_ssh_host
        ansible_ssh_port
        ansible_ssh_user
        ansible_ssh_pass
        ansible_sudo_pass
        ...
      2.2.5 在角色调用时传递
        roles:
        - { role: ROLE_NAME, var: value, ...}
    
    变量调用:
        {{ var_name }}
    
    • 示例4:
    2.1. 命令行传递
      -e VAR=VALUE
    
    - hosts: websrvs
      remote_user: root
      tasks:
      - name: remove a server package
        yum: name={{ pkgname }} state=absent
        
    使用:ansible-playbook -e pkgname=vsftpd XXX.yaml
    
    • 示例5:
    2.2. 在hosts Inventory中为每个主机定义专用变量值
      2.2.1 向不同的主机传递不同的变量
        IP/HOSTNAME variable_name=value
    
    /etc/ansible/hosts文件中定义
    [websrvs]
    10.1.43.2 pkgname=httpd
    10.1.43.3 pkgname=nginx
        
    脚本中:
    - hosts: websrvs
      remote_user: root
      vars:
      - name: remove a server package
        yum: name={{ pkgname }} state=absent
    
    • 示例6:
    2.2. 在hosts Inventory中为每个主机定义专用变量值
      2.2.2 向组内的所有主机传递相同的变量
        [groupname:vars]
        variable_name=value
    
    
    /etc/ansible/hosts文件中定义
    [websrvs]
    10.1.43.2
    10.1.43.3
        
    [websrvs:vars]
    pkgname=vsftpd
        
    脚本中:
    - hosts: websrvs
      remote_user: root
      vars:
      - name: remove a server package
        yum: name={{ pkgname }} state=absent
    
    • 示例7:
    2.2. 在hosts Inventory中为每个主机定义专用变量值
      2.2.3 在playbook中定义<添加在remote_user后面,tasks前面>
        vars:
        - var_name: value
        - var_name: value
    
    - hosts: websrvs
      remote_user: root
      vars:
      - pkgname: vsftpd
      tasks:
      - name: remove a server package
       yum: name={{ pkgname }} state=absent
    
    注意:对此配置文件而言,或命令行以-e给出了变量名的值,命令行的优先级更高
    

    Templates:模板

    • 文本文件,内部嵌套有模板语言脚本(使用模板语言编写)

    • Jinja2 is a template engine written in pure Python. It provides a Django inspired non-XML syntax but supports inline expressions and an optional sandboxed environment.

    语法:

    • 字面量:
    字符串:使用单引号或双引号;
    数字:整数、浮点数;
    列表:[item1, item2, ...]
    元组:(item1, item2, ...)
    字典:{key1:value1, key2:value2, ...}
    布尔型:true/false
    
    • 算术运算:
    +, -, *, /, //, %, **
    
    • 比较操作:
    ==, !=, >, <, >=, <=
    
    • 逻辑运算:
    and, or, not
    
    • 执行模板文件中的脚本,并生成结果数据流,需要使用template模块
    template:
        -a ""
            src=
            dest=
            mode=
            onwer=
            group=
    
    注意:此模板不能在命令行使用,而只能用于playbook
    
    • 示例8:
    /root/nginx.conf.j2文件:
    worker_processes  {{ ansible_processor_vcpus }};
    ansible_processor_vcpus:此参数可以使用ansible IP -m setup 获取
        
    脚本
    - hosts: ngxsrvs
      remote_user: root
      tasks:
      - name: install nginx package
        yum: name=nginx state=latest
      - name: install conf file
        template: src=/root/nginx.conf.j2 dest=/etc/nginx/nginx.conf
        tags: ngxconf
        notify: reload nginx service
      - nyuame: start nginx service
        service: name=nginx state=started enabled=true
      handlers:
      - name: reload nginx service
        shell: /usr/sbin/nginx -s reload
    
    • 条件测试:
    when语句:在tasks中使用,Jinja2的语法格式
    
    • 示例9:
    - hosts: all
      remote_user: root
      tasks:
      - name: install nginx package
        yum: name=nginx state=latest
      - name: start nginx service on CentOS6
        shell: service nginx start
        when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "6"
      - name: start nginx service
        shell: systemctl start nginx.service
        when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
        
    - hosts: mysqlsrvs
      remote_user: root
      tasks:
      - name: install DB package
        yum: name=mysql-server
        when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6'
      - name: install DB package
        yum: name=mariadb-server
        when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7'
      - name: start DB service
        service: name=mysqld state=started enabled=on
        when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6'
      - name: start DB service
        service: name=mariadb state=started enabled=on
        when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7'
    
    • 循环:迭代,需要重复执行的任务;
    对迭代项的引用,固定变量名为"item”,使用with_item属性给定要迭代的元素;
        元素:列表
            字符串
            字典
    
    • 基于字符串列表给出元素示例10:
    - hosts: websrvs
      remote_user: root
      tasks:
      - name: install packages
        yum: name={{ item }} state=latest
        with_items:
        - httpd
        - php
        - php-mysql
        - php-mbstring
        - php-gd
    
    • 基于字典列表给元素示例11:
    - hosts: all
      remote_user: root
      tasks:
      - name: create groups
        group: name={{ item }} state=present
        with_items:
        - groupx1
        - groupx2
        - groupx3
      - name: create users
        user: name={{ item.name }} group={{ item.group }} state=present
        with_items:
        - {name: 'userx1', group: 'groupx1'}
        - {name: 'userx2', group: 'groupx2'}
        - {name: 'userx3', group: 'groupx3'}
    

    角色:roles

    • 以特定的层级目录结构进行组织的tasks、variables、handlers、templates、files等
    role_name/
        files/:存储由copy或script等模块调用的文件
        tasks/:此目录中至少应该有一个名为main.yml的文件,用于定义各task;其它的文件需要由main.yml进行“包含”调用
        handlers/:此目录中至少应该有一个名为main.yml的文件,用于定义各handler;其它的文件需要由main.yml进行“包含”调用
        vars/:此目录中至少应该有一个名为main.yml的文件,用于定义各variable;其它的文件需要由main.yml进行“包含”调用
        templates/:存储由template模块调用的模板文本
        meta/:此目录中至少应该有一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系;其它的文件需要由main.yml进行“包含”调用
        default/:此目录中至少应该有一个名为main.yml的文件,用于设定默认变量
    
    • 在playbook中调用角色的方法:
    - hosts: HOSTS
      remote_user: USERNAME
      roles:
      - ROLE1
      - ROLE2
      - { role: ROLE3, VARIABLE: VALUE, ...}
      - { role: ROLE4, when: CONDITION }
    
  • 相关阅读:
    NOIP2009-2018简要题解
    luogu P5023 填数游戏
    Java桌面精灵基础——swing类的使用与关键代码
    c信号处理程序以及setjmp函数longjmp函数的简单应用
    mmapcopy函数的编写
    nm命令的学习以及可执行文件中的段
    关于C中数组和指针的一点理解
    写一个简单的lisp解释器(1)
    House Robber
    SICP_3.31
  • 原文地址:https://www.cnblogs.com/evescn/p/12191554.html
Copyright © 2011-2022 走看看