• 运维之ansible


    ansible

    与salt对比

    • 相同
      • 都是为了同时在多台机器上执行相同的命令
      • 都是python开发
    • 不同
      • agent(saltstack需要安装、ansible不需要)
      • 配置(salt配置麻烦,ansible基本不用配置)
      • 学习路线(salt比较陡峭,ansible比较平缓)
      • 第三方工具(salt比较少)
      • 开源社区的对接(salt比较少)
      • 现有用户(salt还是ansible少一些)
      • 二次开发扩展的能力(ansible比较差,尤其是2.0以后)
      • 大规模并发(200以内一样,200以上salt会好一些,当然我们也可以对ansible做一些配置使其在200以上追上salt)
      • Windows的支持(salt会好很多)

    安装

    yum install -y ansible

    查看ansible生成的命令,用到的命令

    ansible            
    ansible-doc        
    ansible-galaxy(下载第三方插件)        
     ansible-playbook

    查看ansible 安装生成的

    rpm -ql ansible |more
    /etc/ansible
    /etc/ansible/ansible.cfg #配置文件
    /etc/ansible/hosts #主要文件

    hosts文件详解

    cat /etc/ansible/hosts
    # This is the default ansible 'hosts' file.
    #
    # It should live in /etc/ansible/hosts
    #
    #   - Comments begin with the '#' character #注释为#
    #   - Blank lines are ignored #空白行被忽略
    #   - Groups of hosts are delimited by [header] elements #主机组名被写在[]里面
    #   - You can enter hostnames or ip addresses #你可以写ip地址也可以写hostnames
    #   - A hostname/ip can be a member of multiple groups #一个主机可以被多个主机组包含

    可以在hosts文件中填写的内容

     ansible_ssh_host
      ansible通过ssh连接的IP或者FQDN
    ansible_ssh_port
      SSH连接端口
    ansible_ssh_user
      默认SSH连接用户
    ansible_ssh_pass
      SSH连接的密码(这是不安全的,ansible极力推荐使用--ask-pass选项或使用SSH keys)
    ansible_sudo_pass
      sudo用户的密码
    ansible_connection
      SSH连接的类型:local,ssh,paramiko,在ansible 1.2之前默认是paramiko,后来智能选择,优先使用基于ControlPersist的ssh(支持的前提)
    ansible_ssh_private_key_file
      SSH连接的公钥文件

    查看ansible的命令帮助

    ansible <host-pattern> [options]

    -a MODULE_ARGS 模块参数
    -m MODULE_NAME 模块名称

    -f forks 指定一次执行的机器

    -C 测试

    --list-hosts 查看运行的机器

    -v 输出详细信息

    第一个ansible程序

    ansible test -m ping

    获取文档

    ansible-doc --help
    -s 指定模块名称
    -l 列出所有的模块
    

    操作日志

    /var/log/message

    命令相关

    shell command script
    command模块 [执行远程命令]
        ansible all -a 'echo "hello world"'
        ansible all -a 'pwd'
        ansible all -a 'echo "oldboy"|passwd --stdin user1' #直接输出结果
    script模块 [在远程主机执行主控端的shell/python脚本 ]  (使用相对路径)
    ansible all -m script -a 'a.sh'  #执行本地脚本
    ansible all -a 'ls /'       #查看文件目录
    shell模块 [执行远程主机的shell/python脚本,支持管道]
    ansible all -m shell -a 'echo oldboy|passwd --stdin user1'  #设置密码
    ansible all -m shell -a 'cat /etc/shadow|grep user1'    #查看用户
    ansible all -m shell -a 'python a.py'  #执行远程脚本

    文件相关

    copy
      dest 目标地址
      src 本地地址  
      mode 权限 wrx/755
      owner  属主
      group  属组
      backup
      content   直接写内容,可以用转移符号
        ansible all -m copy -a 'dest=/data src=/data/a.txt'   #复制单个文件
        ansible all -m copy -a 'src=/etc/init.d dest=/data/'   
        ansible all -m copy -a 'src=/etc/init.d/ dest=/data'  #如果带/则复制里面的内容,不带/则复制目录,如果是目录的话,则会递归复制
        ansible all -m copy -a 'content="hello world" dest=/data/test.txt' 直接输入内容
    file
      path
      src
      state
        file file代表拷贝后是文件
        link link代表最终是个软链接
        directory directory代表文件夹
        hard hard代表硬链接
        touch touch代表生成一个空文件
        absent absent代表删除
            ansible all -m file -a 'dest=/data/html state=directory'   #创建目录
            ansible all -m file -a 'dest=/data/html2 state=link src=/etc'  #创建软链接
            ansible all -m file -a 'dest=/data/a.txt state=touch'
            ansible all -m file -a 'dest=/data/a.txt state=absent' 删除
    fetch   
        dest
        src
        ansible 10.211.55.14 -m fetch -a 'src=/data/test.txt dest=/data'

    软件相关

    pip
    ansible all -m pip -a 'name=django==1.11'
    yum
     name
     state
        absent  #卸载
        installed  #安装
        latest     #安装最新的版本
        present    #安装
        removed    #卸载
            ansible all -m yum -a 'name=python-pip state=latest'
            ansible all -m yum -a 'name=nginx state=latest'
            ansible all -m yum -a 'name=nginx state=absent'

    service

    name
    state
     ansible all -m service -a 'name=nginx state=started'
     ansible all -m service -a 'name=nginx state=stopped'

    cron

    name
    weekday 周
    hour 时
    day 天
    minute 分钟
    month 月
    job
    state
      absent  #删除
      present  #创建
    ansible all -m cron -a 'name=testjob  minute=1 job=ntpdate'
    ansible all -m cron -a 'name=testjob  state=absent'

    user

    name
    password
    shell
    state
    uid
    group
    groups
    update_password 
    home
    ansible all -m user -a 'name=usertest'
    ansible all -m user -a 'name=usertest state=absent'

    group

    gid
    name
    state  #present 创建  absent 删除
    system #是否是系统组
    ansible all -m group -a 'name=usertest '
    ansible all -m group -a 'name=usertest state=absent'

    playbook 剧本

    操作都是幂等的

    • 什么是幂等的
      • 操作过以后就不会操作了

    为什么要用playbook

    • 有一个更好的知识沉淀
    • 有一些好的功能

    知识回顾

    ymal

    格式

    • 字典:
      • key : value 冒号后面必须有空格
    • 列表:
      • -

    建议一个文件处理一个对应一组相关的任务

     ansible-playbook [options] playbook.yml
      -C # 干跑,检查
      -f FORKS # 用来做并发,来指定并发数
      --list-hosts #列出执行命令的主机
      --syntax-check # 检查语法
      --list-tasks #列出playbook要执行的任务列表
      -t TAGS, #指定要运行到tags
       -e EXTRA_VARS #给playbook传递变量
    
    #单个playbook
    - hosts: web  #指定要运行命令的主机
      remote_user: root # 指定运行命令的用户
      tasks: #任务列表
      - name: mkdir # 任务1,name是必须的
        file: path=/data state=directory # 指定的模块: 模块的参数
      - name: copyfile
        copy: src=/etc/fstab dest=/data/f
    
    ##多个playbook
    - hosts: web
      remote_user: root
      tasks:
      - name: mkdir
        file: path=/data state=directory
      - name: copyfile
        copy: src=/etc/fstab dest=/data/f
    
    - hosts: db
      remote_user: root
      tasks:
      - name: wget
        shell: "wget -O /data/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo"
    
    ##指定tags
    - hosts: web
      remote_user: root
      tasks:
      - name: mkdir
        file: path=/data state=directory
      - name: copyfile
        copy: src=/etc/fstab dest=/data/f
        tags: copyfile

    任务是从上到下依次执行,每台机器都执行完才执行下一个任务

    变量引入

    • 写一个playbook,需要多次创建,比如每次需要创建的不同的用户

    第一种设置变量的方法

    ## 传递变量 -e"key=value"
    - hosts: web
      remote_user: root
      tasks:
      - name: yum {{pkg_name}} pkg
        yum: name={{pkg_name}}
    

    第二种设置变量的方法

    - hosts: web
      remote_user: root
      vars:
        - pkg_name: memcached
      tasks:
      - name: yum {{pkg_name}} pkg
        yum: name={{pkg_name}}
    

    第三种设置变量的方法

    #在hosts文件里面写,值可以不同
    [web]
    192.168.19.9 pkg_name=nginx
    192.168.19.26 pkg_name=redis

    第四种设置变量的方法

    [web:vars]
    pkg_name=nginx

    第五种传参方式

    第五种传参方式: 通过register注册,直接用.stdout来获取值
    - hosts: db
      remote_user: root
      tasks:
      - name: installbc
        yum: name=bc
      - name: sum
        shell: echo 20+21|bc
        register: sum 
      - name: echo 
        shell: echo {{sum}} > /tmp/sum.txt
      - name: createuser
        user: name=alex{{sum.stdout}}
    

    变量的应用顺序

    -e > yml文件 > hosts文件 #命令行里面是最高的,hosts文件是最低的

    条件

    when 条件判断

    - hosts: cache
      remote_user: root
      tasks:
      - name: copyfile1
        copy: content='大弦嘈嘈如急雨' dest=/tmp/a.txt
        when: ansible_os_family=="RedHat" #只有为真的时候才会执行上面的操作
      - name: copyfile2
        copy: content='小弦切切如私语' dest=/tmp/b.txt
        when: ansible_os_family=="OpenBSD"
    

    循环

    with_item 循环添加

    - hosts: cache
      remote_user: root
      tasks:
      - name: create user
        user: name={{item}} ## 循环下面的with_items
        with_items:
        - yuchao
        - yantao
      - name: create group
        group: name={{item}}## 循环下面的with_items
        with_items:
        - yuchao2
        - yantao2

    循环嵌套

    - hosts: cache
      remote_user: root
      tasks:
      - name: create group
        group: name={{item}}
        with_items:
        - yuchao4
        - yantao4
      - name: create user
        user: name={{item.name}}  group={{item.group}} #可以通过字典取值
        with_items:
        - {"name":yuchao3,"group":yuchao4}
        - {"name":yantao3,"group":yuchao4}    

    服务启动

    - hosts: web
      remote_user: root
      vars:
      - pkg_name: nginx
      tasks:
      - name: yum {{pkg_name}} pkg
        yum: name={{pkg_name}} state=installed
      - name: start
        service: name={{pkg_name}} state=started

    handlers(每次变更文件需要重启服务)

    - hosts: web
      remote_user: root
      vars:
      - pkg_name: nginx
      tasks:
      - name: yum {{pkg_name}} pkg
        yum: name={{pkg_name}} state=installed
      - name: copyfile
        copy: src=nginx.conf dest=/etc/nginx/nginx.conf 
        notify: restart #变更后才会触发handlers的任务
      handlers:
      - name: restart
        service: name={{pkg_name}} state=restarted
    

    template

    基于janja2语言

    - hosts: cache
      remote_user: root
      tasks:
      - name: install redis
        yum: name=redis
      - name: copyfile
        template: src=redis.conf.j2 dest=/etc/redis.conf ## 模板基于jinja2
      - name: start
        service: name=redis state=started
      #模板文件放在templates,可以直接用相对路径去调用配置文件    

    roles

    作用:

    • 结构清晰
    • 可以重用
    tasks #目录是必须的,存放任务
    templates #是存放模板
    vars #用来存放变量    ### 切记,不能加-,加-报错
    files #用来存放文件
    mkdir -p {nginx,uwsgi,mysql}/{tasks,templates,vars,files} #创建目录结构的命令
     hosts: web
      remote_user: root
      roles:
      - role: nginx
        tags: [ 'web','nginx']  # 指定tags
      - { role: http,tags: [ 'web','http']} # 指定tags
      用 -t 来调用
    - hosts: web
      remote_user: root
      roles:
      - role: nginx
        tags: [ 'web','nginx']
        when: ansible_distribution_major_version== "7" # 条件
      - role: http
        tags: [ 'web','http']
        when: ansible_distribution_major_version== "6" # 条件

     

    Ansible Galaxy

    Ansible Galaxy 是一个自由网站,网站提供所有类型的由社区开发的 roles,这对于实现你的自动化项目是一个很好的参考。网站提供这些 roles 的排名、查找以及下载。

    应用实例

    你现在已经学过 tasks 和 handlers,那怎样组织 playbook 才是最好的方式呢?简单的回答就是:使用 roles ! Roles 基于一个已知的文件结构,去自动的加载某些 vars_files,tasks 以及 handlers。基于 roles 对内容进行分组,使得我们可以容易地与其他用户分享 roles 。
    如果 roles/x/tasks/main.yml 存在, 其中列出的 tasks 将被添加到 play 中
    如果 roles/x/handlers/main.yml 存在, 其中列出的 handlers 将被添加到 play 中
    如果 roles/x/vars/main.yml 存在, 其中列出的 variables 将被添加到 play 中
    如果 roles/x/meta/main.yml 存在, 其中列出的 “角色依赖” 将被添加到 roles 列表中 (1.3 and later)
    所有 copy tasks 可以引用 roles/x/files/ 中的文件,不需要指明文件的路径。
    所有 script tasks 可以引用 roles/x/files/ 中的脚本,不需要指明文件的路径。
    所有 template tasks 可以引用 roles/x/templates/ 中的文件,不需要指明文件的路径。
    所有 include tasks 可以引用 roles/x/tasks/ 中的文件,不需要指明文件的路径。

    production                # inventory file for production servers 关于生产环境服务器的清单文件
    stage                     # inventory file for stage environment 关于 stage 环境的清单文件
    
    group_vars/
       group1                 # here we assign variables to particular groups 这里我们给特定的组赋值
       group2                 # ""
    host_vars/
       hostname1              # if systems need specific variables, put them here 如果系统需要特定的变量,把它们放置在这里.
       hostname2              # ""
    
    library/                  # if any custom modules, put them here (optional) 如果有自定义的模块,放在这里(可选)
    filter_plugins/           # if any custom filter plugins, put them here (optional) 如果有自定义的过滤插件,放在这里(可选)
    
    site.yml                  # master playbook 主 playbook
    webservers.yml            # playbook for webserver tier Web 服务器的 playbook
    dbservers.yml             # playbook for dbserver tier 数据库服务器的 playbook
    
    roles/
        common/               # this hierarchy represents a "role" 这里的结构代表了一个 "role"
            tasks/            #
                main.yml      #  <-- tasks file can include smaller files if warranted
            handlers/         #
                main.yml      #  <-- handlers file
            templates/        #  <-- files for use with the template resource
                ntp.conf.j2   #  <------- templates end in .j2
            files/            #
                bar.txt       #  <-- files for use with the copy resource
                foo.sh        #  <-- script files for use with the script resource
            vars/             #
                main.yml      #  <-- variables associated with this role
            defaults/         #
                main.yml      #  <-- default lower priority variables for this role
            meta/             #
                main.yml      #  <-- role dependencies
    
        webtier/              # same kind of structure as "common" was above, done for the webtier role
        monitoring/           # ""
        fooapp/               # ""

    site.yml

    在 site.yml 中,我们包含了一个定义了整个基础设施的 playbook.注意这个 playbook 是非常短的, 因为它仅仅包含了其他 playbooks.记住, playbook 不过就是一系列的 plays:

    ---
    # file: site.yml
    - include: webservers.yml
    - include: dbservers.yml

    在诸如 like webservers.yml 的文件中(同样也在顶层结构),我们仅仅将 Web 服务器组与对应的 role 行为做映射.同样值得注意的是这也非常的短小精悍.例如:

    ---
    # file: webservers.yml
    - hosts: webservers
      roles:
        - common
        - webtier

    理念是我们能够通过 “运行”(running) site.yml 来选择整个基础设施的配置.或者我们能够通过运行其子集 webservers.yml 来配置. 这与 Ansible 的 “–limit” 类似,而且相对的更为显式:

    ansible-playbook site.yml --limit webservers
    ansible-playbook webservers.yml

    接下来的示例任务文件展示了一个 role 是如何工作的.我们这里的普通 role 仅仅用来配置 NTP,但是如果我们想的话,它可以做更多:

    ---
    # file: roles/common/tasks/main.yml
    
    - name: be sure ntp is installed
      yum: pkg=ntp state=installed
      tags: ntp
    
    - name: be sure ntp is configured
      template: src=ntp.conf.j2 dest=/etc/ntp.conf
      notify:
        - restart ntpd
      tags: ntp
    
    - name: be sure ntpd is running and enabled
      service: name=ntpd state=running enabled=yes
      tags: ntp

    这是个处理文件样例.作为一种审核,它只有当特定的任务报告发生变化时会被触发,并在每个 play 结束时运行:

    ---
    # file: roles/common/handlers/main.yml
    - name: restart ntpd
      service: name=ntpd state=restarted
  • 相关阅读:
    [K/3Cloud] 首页增加一个自定义页签及页面内容
    [K/3Cloud]DBServiceHelper.ExecuteDataSet(this.Context, sql)) 返回数据问题
    [K/3Cloud] 表单python脚本使用QueryService的做法
    [K/3Cloud]有关单据显示行数限制和数据导出的建议
    [K/3Cloud]实现双击列表行后显示具体的某个单据明细。
    [K/3Cloud]K3Cloud的移动审批方面
    [K/3Cloud]K3Cloud的移动审批方面
    [K/3Cloud]关于数据库sa密码更改,管理中心登录不上的问题。
    游戏编程最前沿....
    marmalade android 5.0 JNI 调用失败的解决方案
  • 原文地址:https://www.cnblogs.com/yhq123/p/11209817.html
Copyright © 2020-2023  润新知