• Ansible批量自动化管理工具 roles标准化


    批量管理服务器的工具,无需部署代理,通过ssh进行管理,是python写的

     ansible 常用模块 :

    (1)shell命令模块执行命令

    (2)copy模块批量下发文件或文件夹

    (3)script模块批量运行脚本 

    Python3与ansible的安装

    使用源码安装Python3.5

    #安装支持包
    yum -y install lrzsz vim net-tools gcc gcc-c++ ncurses ncurses-devel unzip zlib-devel zlib openssl-devel openssl
    #源码编译Python3.5
    tar xf Python-3.5.2.tgz -C /usr/src/
    cd /usr/src/Python-3.5.2/
    ./configure --prefix=/usr/local/python/;make ;make install
    ln -s /usr/local/python/bin/python3 /usr/bin/python3
    python3
    -V Python 3.5.2

    使用pip3安装ansible

    /usr/local/python/bin/pip3 install ansible
    ln -s /usr/local/python/bin/ansible /usr/local/bin/
    ansible --version
    ansible 2.6.3
      config file = None
      configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
      ansible python module location = /usr/local/python/lib/python3.5/site-packages/ansible
      executable location = /usr/local/bin/ansible
      python version = 3.5.2 (default, Sep  2 2018, 22:56:37) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]

    使用公私钥实现SSH无密码登陆

    ansible是无代理的,主要是借用ssh来批量管理服务器.ssh默认登陆是需要密码的,所以管理起来比较麻烦.SSH无密码登陆实现以后,使用ansible批量管理服务器就变得简单了。

     

    ansible

    192.168.50.16
    主机1 192.168.50.168
    主机2 192.168.50.176
    #生成密钥对
    ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ""
    #分发密钥
    yum -y install sshpass      #安装sshpass
    sshpass -p 123456 ssh-copy-id -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 192.168.50.168
    免密码 密码 上传公钥 免交互 去往的主机
    #进行免密码登陆测试
    ssh 192.168.50.176
    hostname -I
    192.168.50.176 

    ansible的简单配置和模块

    ansible的配置文件

    通过PIP安装的ansible是没有配置文件的。我们需要创建一个

    mkdir -p /etc/ansible 
    vim /etc/ansible/hosts       #ansible主机管理配置文件
    [zhujizu]                #被管理的主机组名称
    webA ansible_ssh_host=192.168.50.168 ansible_ssh_port=22 ansible_ssh_user=root                 #第一台主机
    webB ansible_ssh_host=192.168.50.176 ansible_ssh_port=22 ansible_ssh_user=root  ansible_ssh_pass=123456   #第二台主机
    主机名 定义主机IP ssh的默认端口号 以什么身份管理 如果没有上传公钥需要指定连接密码

    ansible语法:ansible -i /etc/ansible/hosts 主机或主机组 -m 指定模块 -a 命令

            不用-i指定配置文件默认为在/etc/ansible/hosts

            主机组,主机,all代表所有

    进行命令测试:

    ansible zhujizu -m ping    #ping整个组
    zhuji2 | SUCCESS => {    #连接成功   
        "changed": false,    
        "ping": "pong"
    }
    zhuji1 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    ansible zhuji1 -m ping     #只ping 主机1
    zhuji1 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    
    ansible all
    -m ping        #ping 配置文件的所有 zhuji2 | SUCCESS => { "changed": false, "ping": "pong" } zhuji1 | SUCCESS => { "changed": false, "ping": "pong" }

    ansible的三个命令模块

    ansible模块command(不支持管道,不建议使用)   #需要python支持,一般都有python

    ansible模块shell(支持管道,支持重定向,常用)    #需要python支持,一般都有python

    ansible模块raw,最原始的方式运行命令(不依赖python,仅通过ssh实现)

    ansible all -m shell -a "echo hehe >>/root/wk"    #在所有主机执行输出hehe并重定向到wk文件
    zhuji1 | SUCCESS | rc=0 >> zhuji2 | SUCCESS | rc=0 >> cat /root/wk           #查看wk文件 hehe

    ansible的copy模块批量下发文件或文件夹

    copy模块概述

    copy模块的参数,ansible 主机组 -m 模块 -a 命令

    • src:指定源文件或目录
    • dest:指定目标服务器的文件或目录
    • backup:是否要备份
    • owner:拷贝到目标服务器后,文件或目录的所属用户
    • group:拷贝到目标服务器后,文件或目录的所属群组
    • mode:文件或目录的权限

    所有被管理端节点必须安装libselinux-python包

    yum -y install libselinux-python

    copy模块拷贝文件

    ansible all -m copy -a "src=/root/server/txt dest=/root/server/"
    # 源文件 目标目录(如果目标没有目录可自动创建)如果目标路径里有与我拷贝的文件同名文件的话,会直接覆盖目标路径下的文件

    copy模块拷贝目录下所有文件

    ansible all -m copy -a "src=/root/server/ dest=/root/server/"
                  源目录下所有 目标目录

    copy模块自动备份

    backup=yes ===>意思是,如果目标路径下,有与我同名但不同内容的文件时,在覆盖前,对目标文件先进行备份。

    ansible all -m copy -a "src=/root/server/ dest=/root/server/ backup=yes"

    copy模块指定用户和属主

    ansible all -m copy -a "src=/service/scripts/ dest=/service/scripts/ owner=nobody group=nobody mode=0600"
                                              属主 属组 权限

    ansible的script模块批量运行脚本

    ansible的script模块能够实现远程服务器批量运行本地的shell脚本。

    #远程批量分发并自动部署nginx
    #所有被管理端都能使用yum
    pwd
    /root/server
    
    ls |xargs -n1
    nginx-1.14.0.tar.gz   #nginx源码包
    nginx-anzhuang.sh    #自动安装nginx脚本
    
    vim /root/server/nginx-anzhuang.sh      #安装nginx脚本
    #!/bin/sh
    #nginx install shell scripts
    test -d /media/cdrom || mkdir -p /media/cdrom
    mount /dev/sr0 /media/cdrom &>/dev/null
    yum -y install gcc gcc-c++ make pcre pcre-devel zlib zlib-devel openssl  openssl-devel &>/dev/null
    test -d /service/scripts || exit 3
    cd /service/scripts/
    tar xf nginx-1.14.0.tar.gz -C /usr/src/
    cd /usr/src/nginx-1.14.0/
    ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module &>/dev/null
    make &>/dev/null
    make install &>/dev/null
    exit 0
    
    vim /root/fenfa.sh        #批量分发脚本
    #!/bin/sh
    #批量分发脚本
    Group=$1
    ansible $Group -m copy -a "src=/root/server/ dest=/service/scripts/"
    ansible $Group -m script -a "/usr/bin/sh /service/scripts/nginx-anzhuang.sh"
    ~                        
    
    sh /root/fenfa.sh all     #激活脚本

    ansible-playbook(剧本)

    playbook的使用,playbook可以把ansible的模块进行组合,然后执行每个模块

    ln -s /usr/local/python/bin/ansible-playbook /usr/local/bin/            #设置playbook的环境变量

     playbook的格式    #ansible是python写的,python很注重格式,因此playbook也很注重格式

    vim hehe.yaml           #playbook的执行模板 结尾必须以.yaml
    ---         #开头三个小-开头
    - hosts: zhuji2
      tasks:
      - name: test
        shell: echo "welcome to yunjisaun" >> /tmp/username
      - name: test2
        shell: echo "welcome to yunjisuan" >> /tmp/username
    模板说明:
    ---  #开头必须有三个小-,顶格写
    - hosts:   #正文配置代码的第一级,必须有两个空格(-占一个空格位)
    - host: webB   #webB是host参数的值,值和hosts:之间要有一个空格
      tasks:        #tasks:表示接下来要执行的具体任务
      - name:     #相对于tasks再多缩进两个格(-占一个空格位),表示属于tasks的下一级
      - name: test  #test只是要执行的具体命令的名字可以随便写。name:后还是有一个空格要注意
        shell:  #表示调用shell模块执行命令相对于tasks仍旧要多缩进两个空格
        shell: echo "xxx" >> xxx     #shell:后边还是要有个空格,需要注意。

    执行playbook配置文件

    ansible-playbook hehe.yaml 

    playbook的简单copy模块的使用

    vim hehe.yaml
    ---
    - hosts: zhuji2
      tasks:
      - name: test
        copy: src=/etc/passwd dest=/root

    ---      
    - hosts: zhuji2
      tasks:
      - name: test
        shell: echo "quzhongrensan"
        register: i      #把shell的命令结果保存在变量i里 变量可以是任意字符
      - debug: var=i      #debug输出变量i debug和var是固定格式 

     playbook使用register输出命令运行结果

    我们在用playbook进行ansible模块操作的时候,并没有命令的执行结果输出,默认被隐藏了。 
    我们可以通过register模块最加输出命令的执行结果

    playbook的自定义变量和内置变量

    在Playbook中使用自定义变量

    vim hehe.yaml
    --- - hosts: zhuji2 vars: #定义变量 - xixi: "xxiixxii" #变量xixi=xxiixxii - hehe: "hheehhee" #变量hehe=hheehhee tasks: - name: xixi shell: echo "{{ xixi }},{{ hehe }}" #调用变量{{ xixi }}固定格式 两个{{}} 变量名与括号间必须有空格 register: i - debug: var=i
    #在使用自定义变量时,我们要特别注意不要和系统的内置保留变量同名,容易引发问题。 定义变量名最好开头字母用大写

    在playbook中使用ansible内置变量

    我们可以使用ansible all -m setup | less查看ansible内置变量

    ---
    - hosts: all
      gather_facts: True    #使用ansible内置变量
      tasks:
      - name: setup var
        shell: echo "ip {{ ansible_all_ipv4_addresses[0] }} cpu {{ ansible_processor_count }}"
        register: var_result
      - debug: var=var_result

    Playbook下发可变配置文件

    配置文件如果使用copy模块去下发的话,那配置都是一样的; 
    如果下发的配置文件里有可变的配置,需要用到template模块。

    利用template模块下发可变的配置文件

    vim /root/server/txt             #编辑将要发送的文件 文件内使用变量
    my name is {{ hehe }}            #自定义变量
    my name is {{ ansible_all_ipv4_addresses[0] }}           #系统变量
                                               
    vim /root/hehe.yaml            #编写发送文件txt的剧本
    ---    
    - hosts: zhuji2
      gather_facts: True       #调用ansible系统变量
      vars:               #设置自定义变量
      - hehe: "hheehhee"
      tasks:       
      - name: xixi
        template: src=/root/server/txt dest=/root/txt  #使用template下发可变配置文件
     
    cat txt                        #查看主机2收到的txt文件,里边已经成功的使用了变量
    my name is hheehhee 
    my name is 192.168.50.176

    下发配置文件里面使用判断语法

    vim /root/server/txt
    {% if PORT %}      #if PORT存在
    ip=0.0.0.0:{{ PORT }}
    {% else %}           #否则
    ip=0.0.0.0:80
    {% endif %}          #结尾
    
    vim /root/hehe.yaml
    ---   
    - hosts: zhuji2
      gather_facts: True
      vars:
      - PORT "80"     
      tasks:
      - name: xixi
        template: src=/root/server/txt dest=/root/txt

    Playbook的notify通知和下发nginx配置

    #实战下发可执行动作的可变的nginx配置文件
    head -1 /tmp/nginx.j2 
    worker_processes  {{ ansible_processor_count }};    #可变的参数
    cat test_nginxvars.yaml 
    ---
    - hosts: all
      gather_facts: True    #开启系统内置变量
      tasks:
      - name: nginx conf
        template: src=/tmp/nginx.j2 dest=/usr/local/nginx/conf/nginx.conf
        notify:
        - reload nginx  #下发通知给handlers模块执行名字叫做reload nginx的动作
      handlers: #定义动作
      - name: reload nginx  #动作的名字
        shell: /usr/local/nginx/sbin/nginx -s reload
    ansible-playbook test_nginxvars.yaml 

    使用roles标准化Playbook

    roles功能可以用来规范playbook的编写

    创建所需要的roles原型目录结构

    tree rolesbzh/   标准化目录 
    rolesbzh/
    ├── nginx.retry #文件:/etc//ansible/hosts里的主机名
    ├── nginx.yam   #文件:触发器,用来触发roles内的不同剧本
    └── roles   #目录:里面存放不同的剧本目录
        └── nginx #目录:存放nginx剧本相关模块
            ├── files #目录:files存放copy模块和script模块的参数src默认会从这个文件夹查找
            │   ├── test  #要上传的文件
            │   └── test.sh #需要在目标主机执行的脚本
            ├── handlers #用来存放notify的
            │   └── main.yaml  
            ├── tasks #用来存放ansible任务的模块,ansible会根据里面写的执行过程进行剧本的执行
            │   └── main.yaml
            ├── templates #template模块的使用,用来存放可变配置文件j2的
            │   └── test.j2
            └── vars #用来存放变量的
                └── main.yaml                    

    入口触发配置文件

    ansible-playbook执行入口配置文件nginx.yaml后,它会自动在roles目录下查找nginx目录并进入后查找tasks任务目录并执行main.yaml的任务配置文件。

    cat /root/rolesbzh/nginx.yaml 
    ---
    - hosts: all              #执行的主机范围
      gather_facts: True      #开启系统内置变量
      roles:                  #启用roles原型配置
      - nginx                 #执行nginx原型模组,即roles里的nginx剧本 

    roles中tasks任务编排模组的使用

    #在nginx模组添加tasks任务配置文件
    vim /root/rolesbzh/roles/nginx/tasks/main.yaml
    ---
    - name: ping          #任务1的名字  ping  (名字可有可无可随意)
      ping:               #执行ping
    - name: 执行shell      #任务2的名字  执行shell
      shell: ls /         #执行ls查看跟目录      
      register: i         #将执行的结果带入一个变量i内
    - debug: var=i        #将变量i输出出来
    - name: 变量           #任务3的名字  变量
      shell: echo my name is {{ my_name }},{{ qq }}   #执行命令可调用vars变量
      register: I         #将执行的结果带入一个变量I内
    - debug: var=I        #将变量I输出出来
    - name: copy          #任务4的名字   copy
      copy: src=test dest=/root/        #将files目录下的test移动到目标主机的root下
    - name: script        #任务5的名字   script
      script: test.sh     #在目标主机执行files目录下的test.sh脚本 
    - name: 可变配置文件    #任务6的名字   可变配置文件
      template: src=test.j2 dest=/root/text1   #将templates目录下的test.j2文件移动到目标主机root目录下改名为text1  并将变量变为值
      notify: reload      #如果template发生变化则执行handles里的动作,如果template没有发生变化则不执行handles里的动作

    roles中vars自定义变量模组的使用

    #创建自定义变量vars模组的配置文件
    vim /root/rolesbzh/roles/nginx/vars/main.yaml
    ---
    my_name: wk   #变量my_name值wk
    qq: 224901    #变量qq值224901

    使用copy,script模块的标准化

    roles模型里使用copy,script模块,默认从roles/nginx/files这里面找

    vim //root/rolesbzh/roles/nginx/files/test         #files存放的文件
    生死阔契
    
    vim /root/rolesbzh/roles/nginx/files/test.sh       #files存放的脚本   files里的脚本在客户机执行完后会自行删除,等于无痕执行了一次脚本
    echo "与子成说"
    > /tmp/test
    chmod +x roles/nginx/files/test.sh

    roles中template模块的使用

     roles模型里使用template模块,默认从roles/nginx/template里面找

    vim /root/rolesbzh/roles/nginx/templates/test.j2  
    my name is {{ my_name }},my qq {{ qq }},my ip {{ansible_all_ipv4_addresses[0]}}   #引用自定义变量和内置变量

    roles中notify模块的使用

    roles使用notify模块,默认从roles/nginx/handles里面找

    vim /root/rolesbzh/roles/nginx/handlers/main.yaml 
    --- - name: start #定义handlers的动作类型 shell /usr/local/nginx/sbin/nginx - name; stop #定义handlers的动作类型 shell /usr/local/nginx/sbin/nginx -s stop - name; reload #定义handlers的动作类型 shell /usr/local/nginx/sbin/nginx -s reload

    notify下发通知只有当之前的任务造成了变化那么才会被执行,如果没有发生任何改变,则notify不会被执行。

  • 相关阅读:
    springboot搭建环境访问Controller层返回404
    SpringMVC使用注解@RequestMapping映射请求
    Redis数据类型
    mysql小结
    将数据四舍五入到十位
    Repeated DNA Sequences
    Reverse Linked List II
    Shortest Palindrome
    Single Number
    Sort Colors
  • 原文地址:https://www.cnblogs.com/ywrj/p/9577833.html
Copyright © 2020-2023  润新知