zoukankan      html  css  js  c++  java
  • Ansible批量自动化管理工具(二)

    Ansible批量自动化管理工具(二)

    链接:https://pan.baidu.com/s/1A3Iq3gGkGS27L_Gt37_I0g
    提取码:ncy2
    复制这段内容后打开百度网盘手机App,操作更方便哦

    1.工具与环境介绍

    1.1 ansible简介

    1.2 jenkins简介

    • 可视化运维(主要用在可视化部署)
    • 持续构建,可以和git,svn结合
    • 可结合ssh实现可视化运维
    • 可结合ansible实现可视化运维

    1.3检查环境

    [root@server ~]# cat /etc/redhat-release
    CentOS Linux release 7.5.1804 (Core) 
    [root@server ~]# uname -m
    x86_64
    [root@server ~]# uname -r
    3.10.0-862.el7.x86_64
    

    2.Python3与ansible的安装

    2.1 使用源码安装Python3.5

    2.1.1安装支持包

    [root@Ansible ~]# yum -y install lrzsz gcc gcc-c++ ncurses ncurses-devel unzip zlib-devel zlib openssl-devel openssl
    
    [root@Ansible ~]# rpm -qa lrzsz gcc gcc-c++ ncurses ncurses-devel unzip zlib-devel zlib openssl-devel openssl
    gcc-c++-4.8.5-28.el7_5.1.x86_64
    ncurses-devel-5.9-14.20130511.el7_4.x86_64
    ncurses-5.9-14.20130511.el7_4.x86_64
    openssl-1.0.2k-12.el7.x86_64
    gcc-4.8.5-28.el7_5.1.x86_64
    openssl-devel-1.0.2k-12.el7.x86_64
    unzip-6.0-19.el7.x86_64
    zlib-1.2.7-17.el7.x86_64
    zlib-devel-1.2.7-17.el7.x86_64
    lrzsz-0.12.20-36.el7.x86_64
    

    2.1.2源码编译Python3.5

    [root@Ansible yang]# pwd
    /yang
    [root@Ansible yang]# ls
    Python-3.5.2.tgz
    [root@Ansible yang]# tar xf Python-3.5.2.tgz -C /usr/src/  #解压缩
    [root@Ansible yang]# cd /usr/src/Python-3.5.2/
    [root@Ansible Python-3.5.2]# ./configure --prefix=/usr/local/python/           #源码编译
    #以下省略。。。
    [root@Ansible Python-3.5.2]# make && make install
    #以下省略。。。
    [root@Ansible Python-3.5.2]# ln -s /usr/local/python/bin/python3 /usr/bin/python3      #建立软连接
    [root@Ansible Python-3.5.2]# which python3
    /usr/bin/python3
    [root@Ansible Python-3.5.2]# python3 -V  python的版本号
    Python 3.5.2
    

    2.2 使用pip3安装ansible

    2.2.1安装ansible最新版本

    [root@Ansible Python-3.5.2]# /usr/local/python/bin/pip3 install ansible
    #以下省略。。。
    

    2.2.2创建软连接

    [root@Ansible Python-3.5.2]# ln -s /usr/local/python/bin/ansible /usr/local/bin/
    [root@Ansible Python-3.5.2]# which ansible
    /usr/local/bin/ansible
    
    [root@Ansible Python-3.5.2]# ansible --version
    ansible 2.6.4    #ansible版本
      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  6 2018, 22:33:20) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
    

    2.3 ansible查看帮助

    [root@ansible ~]# /usr/local/python/bin/ansible-doc -l  #查看总帮助 
    [root@ansible ~]# /usr/local/python/bin/ansible-doc -s shell     #查看shell模块的帮助 
    [root@ansible ~]# /usr/local/python/bin/ansible-doc -s raw
    

    3.使用公私钥实现ssh无密码登陆

    • ansible是无agent的,无agent是怎么批量管理服务器的?主要是借用ssh来批量管理服务器。
    • ssh默认登陆是需要密码的,所以管理起来比较麻烦,这节课主要是介绍ssh的无密码登陆。
    • ssh无密码登陆实现以后,使用ansible批量管理服务器就变得简单了
    Host IP
    ansible 192.168.200.73
    web01 192.168.200.74
    web02 192.168.200.75

    3.1生成密钥对

    [root@Ansible ~]# ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ""
    Generating public/private rsa key pair.
    Created directory '/root/.ssh'.
    Your identification has been saved in /root/.ssh/id_rsa.
    Your public key has been saved in /root/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:AyXvTyhwFx6yOSXrzVUBcmGCzjmgoLjo51Yn+XVdmbk root@Ansible
    The key's randomart image is:
    +---[RSA 2048]----+
    |      +.B =oo.   |
    |.   . .% B .     |
    |o. ..+B.+ .     +|
    |o .  +=B o     = |
    |..    +.S . . . .|
    |o    + o = . . E |
    |.   . + . o      |
    | . o   .         |
    |  +.             |
    +----[SHA256]-----+
    

    3.2分发密钥到 Web01

    [root@Ansible ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 192.168.200.74   #Web01的IP
    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
    root@192.168.200.74's password:    Web01的登录密码
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh -o ' StrictHostKeyChecking=no' '192.168.200.74'"
    and check to make sure that only the key(s) you wanted were added.
    

    3.3进行免密码登陆测试

    [root@Ansible ~]# hostname -I
    192.168.200.73 
    [root@Ansible ~]# ssh 192.168.200.74
    Last login: Thu Sep  6 22:16:49 2018 from 192.168.200.1
    [root@Web01 ~]# hostname -I
    192.168.200.74 
    [root@Web01 ~]# exit
    logout
    Connection to 192.168.200.74 closed.
    

    4.ansible的简单配置和ping模块

    4.1 ansible的配置文件

    [root@Ansible ~]# mkdir -p /etc/ansible
    [root@Ansible ~]# cat /etc/ansible/hosts     #ansible主机管理配置文件
    [nginx]          #被管理的主机组名称 
    Web01 ansible_ssh_host=192.168.200.74 ansible_ssh_port=22 ansible_ssh_user=root     #第一台主机
    Web02 ansible_ssh_host=192.168.200.75 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=111111    #第二台主机
    
    特别提示:
    Web01  ===> 主机名
    ansible_ssh_host ===>主机IP
    ansible_ssh_port ===>ssh的默认端口
    ansible_ssh_user ===>ssh的用户名
    ansible_ssh_pass ===>ssh的用户的连接密码
    

    如果我们已经设置了ssh免密钥了。那么就不需要写密码了。例如:Web01
    我们要是没有设置免密钥,那么就需要安装sshpass工具,并在/etc/ansible/hosts文件里写上主机的连接密码。例如Web02

    #下载epel源安装sshpass
    root@Ansibl ~]# yum -y install wget
    [root@ansible ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
    [root@ansible ~]# yum -y install sshpass
    [root@ansible ~]# which sshpass
    /usr/bin/sshpass
    
    #修改ssh配置文件
    [root@ansible ~]# sed -n '35p' /etc/ssh/ssh_config
    #   StrictHostKeyChecking ask
    [root@ansible ~]# vim /etc/ssh/ssh_config
    [root@ansible ~]# sed -n '35p' /etc/ssh/ssh_config
       StrictHostKeyChecking no     #去掉注释,修改成这样
    #重启ssh服务
    [root@ansible ~]# systemctl reload sshd.service
    

    4.2 进行ansible远程执行命令测试

    #进行ping模块的连接测试
    [root@Ansible ~]# ansible nginx -m ping
    Web01 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    Web02 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    

    4.3ansible的简单使用方式

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

    4.4使用ping模块用来查看服务器是否连接正常,ping模块不需要-a指定参数

    ansible all -m ping

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

    4.4.1主机和主机组注意事项:

    主机组范围 解释
    all 代表所有主机
    Web01:Web02 可以指定多台主机
    all:!Web01 指定all但不包含Web02,注意!前需要加转意符号

    4.4.2操作测试

    [root@Ansible ~]# ansible Web01 -m ping
    Web01 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    [root@Ansible ~]# ansible all -m ping
    Web01 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    Web02 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    [root@Ansible ~]# ansible Web01:Web02 -m ping
    Web01 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    Web02 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    [root@Ansible ~]# ansible all:!Web01 -m ping
    Web02 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    [root@Ansible ~]# ansible Web01:Web02 -m command -a 'uptime'
    Web02 | SUCCESS | rc=0 >>
     23:14:40 up  1:16,  3 users,  load average: 0.05, 0.03, 0.05
    
    Web01 | SUCCESS | rc=0 >>
     23:14:40 up  1:16,  3 users,  load average: 0.06, 0.03, 0.05
    

    5.ansible的三个命令模块

    5.1 ansible模块command(不支持管道,不建议使用)

    #command支持直接回显命令的执行结果
    [root@ansible ~]# ansible all -m command -a "pwd"
    Web01 | SUCCESS | rc=0 >>
    /root
    Web02 | SUCCESS | rc=0 >>
    /root
    
    #command模块不支持管道符操作
    [root@ansible ~]# ansible all -m command -a "echo test | grep t"
    Web01 | SUCCESS | rc=0 >>
    test | grep t
    Web02 | SUCCESS | rc=0 >>
    test | grep t
    
    #command模块不支持重定向操作
    [root@ansible ~]# ansible all -m command -a "echo bb >> /tmp/testansible"
    Web01 | SUCCESS | rc=0 >>
    bb >> /tmp/testansible
    Web02 | SUCCESS | rc=0 >>
    bb >> /tmp/testansible
    

    5.2 ansible模块shell(支持管道,支持重定向)

    #shell模块支持管道符
    [root@ansible ~]# ansible all -m shell -a "echo testansible | grep a"
    Web01 | SUCCESS | rc=0 >>
    testansible
    Web02 | SUCCESS | rc=0 >>
    testansible
    
    #shell支持重定向
    [root@ansible ~]# ansible all -m shell -a "echo bb >> /tmp/testansible"
    Web01 | SUCCESS | rc=0 >>
    Web02 | SUCCESS | rc=0 >>
    [root@Web01 tmp]# cat testansible 
    bb
    [root@Web02 tmp]# cat testansible 
    bb
    
    #如果遇到特殊符号需要加入转义,这样子ansible才能正常运行
    [root@Ansible ~]# ansible all -m shell -a "cat /etc/passwd | awk -F":" '{print $1}'"
    Web01 | SUCCESS | rc=0 >>
    root
    bin
    daemon
    adm
    lp
    sync
    shutdown
    halt
    mail
    operator
    games
    ftp
    nobody
    systemd-network
    dbus
    polkitd
    sshd
    postfix
    chrony
    
    Web02 | SUCCESS | rc=0 >>
    root
    bin
    daemon
    adm
    lp
    sync
    shutdown
    halt
    mail
    operator
    games
    ftp
    nobody
    systemd-network
    dbus
    polkitd
    sshd
    postfix
    chrony
    

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

    5.3.1清除yum缓存

    [root@Ansible ~]# ansible all -m raw -a "yum -y clean all"
    Web02 | SUCCESS | rc=0 >>
    Loaded plugins: fastestmirror
    Cleaning repos: base extras updates
    Cleaning up everything
    Maybe you want: rm -rf /var/cache/yum, to also free up space taken by orphaned data from disabled or removed repos
    Cleaning up list of fastest mirrors
    Shared connection to 192.168.200.75 closed.
    
    
    Web01 | SUCCESS | rc=0 >>
    Loaded plugins: fastestmirror
    Cleaning repos: base extras updates
    Cleaning up everything
    Maybe you want: rm -rf /var/cache/yum, to also free up space taken by orphaned data from disabled or removed repos
    Cleaning up list of fastest mirrors
    Shared connection to 192.168.200.74 closed.
    

    5.3.2建立yum缓存

    [root@Ansible ~]# ansible all -m raw -a "yum makecache"
    Web02 | SUCCESS | rc=0 >>
    Loaded plugins: fastestmirror
    Determining fastest mirrors
    #中间省略。。。   
    Metadata Cache Created
    Shared connection to 192.168.200.75 closed.
    
    
    Web01 | SUCCESS | rc=0 >>
    Loaded plugins: fastestmirror
    Determining fastest mirrors
    #中间省略。。。 
    Metadata Cache Created
    Shared connection to 192.168.200.74 closed.
    

    5.3.3yum装nmap包

    [root@Ansible ~]# ansible all -m raw -a "yum -y install nmap"
    #以下省略。。。
    

    5.3.4 查看安装结果

    [root@Web01 ~]# which nmap
    /usr/bin/nmap
    [root@Web02 ~]# which nmap
    /usr/bin/nmap
    

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

    6.1 copy模块概述

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

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

    6.1.2准备工作

    [root@Ansible ~]# mkdir yangwenbo
    [root@Ansible ~]# cd yangwenbo
    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# echo "welcome to yunjisuan161" > yunwei
    [root@Ansible yangwenbo]# cat yunwei 
    welcome to yunjisuan161
    

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

    [root@Web01 ~]# yum -y install libselinux-python
    [root@Web01 ~]# rpm -qa libselinux-python
    libselinux-python-2.5-12.el7.x86_64
    
    [root@Web02 ~]# yum -y install libselinux-python
    [root@Web02 ~]# rpm -qa libselinux-python
    libselinux-python-2.5-12.el7.x86_64
    

    6.2 copy模块拷贝文件

    特别提示:

    • 如果目标路径不存在会自动创建
    • src===>源文件路径 dest=目标路径位置
    #拷贝文件
    [root@Ansible yangwenbo]# ansible all -m copy -a "src=/root/yangwenbo/yunwei dest=/root/yangwenbo/"
    Web01 | SUCCESS => {
        "changed": true,
        "checksum": "4775b9cf454d1817e252f0678c06d64bc214da1c",
        "dest": "/root/yangwenbo/yunwei",
        "gid": 0,
        "group": "root",
        "md5sum": "38b35e7d3f5c75583ce5e1ee5838a396",
        "mode": "0644",
        "owner": "root",
        "secontext": "system_u:object_r:admin_home_t:s0",
        "size": 24,
        "src": "/root/.ansible/tmp/ansible-tmp-1536310826.228977-17143783285290/source",
        "state": "file",
        "uid": 0
    }
    Web02 | SUCCESS => {
        "changed": true,
        "checksum": "4775b9cf454d1817e252f0678c06d64bc214da1c",
        "dest": "/root/yangwenbo/yunwei",
        "gid": 0,
        "group": "root",
        "md5sum": "38b35e7d3f5c75583ce5e1ee5838a396",
        "mode": "0644",
        "owner": "root",
        "secontext": "system_u:object_r:admin_home_t:s0",
        "size": 24,
        "src": "/root/.ansible/tmp/ansible-tmp-1536310826.2419605-39881113399031/source",
        "state": "file",
        "uid": 0
    }
    
    #检查拷贝结果
    [root@Web01 ~]# cd yangwenbo/
    [root@Web01 yangwenbo]# pwd
    /root/yangwenbo
    [root@Web01 yangwenbo]# cat yunwei 
    welcome to yunjisuan161
    
    [root@Web02 ~]# cd yangwenbo/
    [root@Web02 yangwenbo]# pwd
    /root/yangwenbo
    [root@Web02  yangwenbo]# cat yunwei 
    welcome to yunjisuan161
    

    6.3 copy模块拷贝文件夹

    特别提示:如果目标路径里有与我拷贝的文件同名文件的话,会直接覆盖目标路径下的文件

    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# cat yunwei 
    welcome to yunjisuan161
    #拷贝文件
    [root@Ansible yangwenbo]# ansible Web01 -m copy -a "src=/root/yangwenbo/ dest=/root/yangwenbo/"
    Web01 | SUCCESS => {
        "changed": false,
        "checksum": "4775b9cf454d1817e252f0678c06d64bc214da1c",
        "dest": "/root/yangwenbo/yunwei",
        "gid": 0,
        "group": "root",
        "mode": "0644",
        "owner": "root",
        "path": "/root/yangwenbo/yunwei",
        "secontext": "system_u:object_r:admin_home_t:s0",
        "size": 24,
        "state": "file",
        "uid": 0
    }
    
    #检查拷贝结果
    [root@Web01 yangwenbo]# pwd
    /root/yangwenbo
    [root@Web01 yangwenbo]# cat yunwei 
    welcome to yunjisuan161
    

    6.4 copy模块自动备份

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

    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# cat yunwei 
    hello
    #拷贝文件
    [root@Ansible yangwenbo]# ansible Web01 -m copy -a "src=/root/yangwenbo/ dest=/root/yangwenbo/ backup=yes"
    Web01 | SUCCESS => {
        "backup_file": "/root/yangwenbo/yunwei.1990.2018-09-07@05:30:28~",
        "changed": true,
        "checksum": "f572d396fae9206628714fb2ce00f72e94f2258f",
        "dest": "/root/yangwenbo/yunwei",
        "gid": 0,
        "group": "root",
        "md5sum": "b1946ac92492d2347c6235b4d2611184",
        "mode": "0644",
        "owner": "root",
        "secontext": "system_u:object_r:admin_home_t:s0",
        "size": 6,
        "src": "/root/.ansible/tmp/ansible-tmp-1536312626.9388444-271698353874697/source",
        "state": "file",
        "uid": 0
    }
    
    #检查拷贝结果
    [root@Web01 yangwenbo]# pwd
    /root/yangwenbo
    [root@Web01 yangwenbo]# ls
    yunwei  yunwei.1990.2018-09-07@05:30:28~
    [root@Web01 yangwenbo]# cat yunwei
    hello
    [root@Web01 yangwenbo]# cat yunwei.1990.2018-09-07@05:30:28~ 
    welcome to yunjisuan161
    

    6.5 copy模块指定用户和属主

    #拷贝文件
    [root@Ansible yangwenbo]# ansible Web02 -m copy -a "src=/root/yangwenbo/ dest=/root/yangwenbo/ owner=nobody group=nobody mode=0600"
    Web02 | SUCCESS => {
        "changed": true,
        "checksum": "f572d396fae9206628714fb2ce00f72e94f2258f",
        "dest": "/root/yangwenbo/yunwei",
        "gid": 99,
        "group": "nobody",
        "md5sum": "b1946ac92492d2347c6235b4d2611184",
        "mode": "0600",
        "owner": "nobody",
        "secontext": "system_u:object_r:admin_home_t:s0",
        "size": 6,
        "src": "/root/.ansible/tmp/ansible-tmp-1536312849.3372185-152360920901702/source",
        "state": "file",
        "uid": 99
    }
    
    #检查拷贝结果
    [root@Web02 yangwenbo]# pwd
    /root/yangwenbo
    [root@Web02 yangwenbo]# ls
    yunwei
    [root@Web02 yangwenbo]# cat yunwei 
    hello
    [root@Web02 yangwenbo]# ll
    total 4
    -rw-------. 1 nobody nobody 6 Sep  7 05:34 yunwei
    

    7.ansible的script模块批量运行脚本

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

    #操作示例-->远程批量分发并自动部署nginx
    #所有被管理端需要挂载光盘,并创建本地yum配置文件
    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# ls | xargs -n1
    auto_nginx.sh             #自动安装nginx脚本
    fenfa.sh                  #批量分发脚本
    nginx-1.10.2.tar.gz       #nginx源码包
    
    [root@Ansible yangwenbo]# cat auto_nginx.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 /root/yangwenbo || exit 3
    cd /root/yangwenbo/
    tar xf nginx-1.10.2.tar.gz -C /usr/src/
    cd /usr/src/nginx-1.10.2/
    ./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
    
    [root@Ansible yangwenbo]# cat fenfa.sh     #源码包和安装脚本的批量分发脚本
    #!/bin/sh
    #批量分发脚本
    
    Group=$1
    ansible $Group -m copy -a "src=/root/yangwenbo/ dest=/root/yangwenbo/"
    ansible $Group -m script -a "/root/yangwenbo/auto_nginx.sh"
    
    #激活脚本
    [root@Ansible yangwenbo]# sh fenfa.sh all
    Web02 | SUCCESS => {
        "changed": true,
        "dest": "/root/yangwenbo/",
        "src": "/root/yangwenbo/"
    }
    Web01 | SUCCESS => {
        "changed": true,
        "dest": "/root/yangwenbo/",
        "src": "/root/yangwenbo/"
    }
    Web02 | SUCCESS => {
        "changed": true,
        "rc": 0,
        "stderr": "Shared connection to 192.168.200.75 closed.
    ",
        "stderr_lines": [
            "Shared connection to 192.168.200.75 closed."
        ],
        "stdout": "",
        "stdout_lines": []
    }
    Web01 | SUCCESS => {
        "changed": true,
        "rc": 0,
        "stderr": "Shared connection to 192.168.200.74 closed.
    ",
        "stderr_lines": [
            "Shared connection to 192.168.200.74 closed."
        ],
        "stdout": "",
        "stdout_lines": []
    }
    
    #检查脚本执行结果
    [root@Web01 ~]# ll -d /usr/local/nginx
    drwxr-xr-x. 6 root root 54 Sep  7 06:00 /usr/local/nginx
    
    [root@Web02 ~]# ll -d /usr/local/nginx
    drwxr-xr-x. 6 root root 54 Sep  7 06:00 /usr/local/nginx
    

    此脚本只是个演示示例,工作中需要写的尽量严谨一些

    8.ansible-playbook的初步使用

    playbook的使用,playbook可以把ansible的模块进行组合

    #设置ansible-playbook的软连接
    [root@Ansible /]# ln -s /usr/local/python/bin/ansible-playbook /usr/local/bin/
    [root@Ansible /]# which ansible-playbook
    /usr/local/bin/ansible-playbook
    

    8.1 playbook的简单shell模块的使用

    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# cat test_shell.yaml    #playbook的执行模板 
    ---         #开头三个小-开头
    - hosts: Web01   
      tasks:        
      - name: test
        shell: echo "welcome to yunjisaun" >> /tmp/username
      - name: test2
        shell: echo "welcome to yunjisuan" >> /tmp/username
    
    模板说明:
    ---             #开头必须有三个小-,顶格写
    - hosts:       #正文配置代码的第一级,必须有两个空格(-占一个空格位)
    - host: Web01   #Web01是host参数的值,值和hosts:之间要有一个空格
      tasks:        #tasks:表示接下来要执行的具体任务
      - name:       #相对于tasks再多缩进两个格(-占一个空格位),表示属于tasks的下一级
      - name: test  #test只是要执行的具体命令的名字可以随便写。name:后还是有一个空格要注意
        shell:      #表示调用shell模块执行命令相对于tasks仍旧要多缩进两个空格
        shell: echo "xxx" >> xxx     #shell:后边还是要有个空格,需要注意。
    
    #执行playbook配置文件
    [root@Ansible yangwenbo]# ansible-playbook test_shell.yaml
    
    PLAY [Web01] ***********************************************************************************
    
    TASK [Gathering Facts] *************************************************************************
    ok: [Web01]
    
    TASK [test] ************************************************************************************
    changed: [Web01]
    
    TASK [test2] ***********************************************************************************
    changed: [Web01]
    
    PLAY RECAP *************************************************************************************
    Web01                      : ok=3    changed=2    unreachable=0    failed=0   
    
    #执行结果
    [root@Web01 tmp]# pwd
    /tmp
    [root@Web01 tmp]# ls
    username
    [root@Web01 tmp]# cat username 
    welcome to yunjisaun
    welcome to yunjisuan
    

    8.2 playbook的简单copy模块的使用

    [root@Ansible yangwenbo]# echo "welcom to yunjisuan" >> /root/yangwenbo/test_copy
    [root@Ansible yangwenbo]# cat test_copy 
    welcom to yunjisuan
    
    [root@Ansible yangwenbo]# cat test_copy.yaml     #playbook的执行模板 
    ---
    - hosts: Web02
      tasks:
      - name: test copy
        copy: src=/root/yangwenbo/test_copy dest=/tmp/
    
    #执行playbook配置文件
    [root@Ansible yangwenbo]# ansible-playbook test_copy.yaml 
    
    PLAY [Web02] ***********************************************************************************
    
    TASK [Gathering Facts] *************************************************************************
    ok: [Web02]
    
    TASK [test copy] *******************************************************************************
    changed: [Web02]
    
    PLAY RECAP *************************************************************************************
    Web02                      : ok=2    changed=1    unreachable=0    failed=0   
    
    #执行结果
    [root@Web02 tmp]# pwd
    /tmp
    [root@Web02 tmp]# ls
    test_copy
    [root@Web02 tmp]# cat test_copy 
    welcom to yunjisuan
    

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

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

    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# cat test_register.yaml    #playbook的执行模板
    ---
    - hosts: all
      tasks:
      - name: test register
        shell: echo "hi Tom" >> /tmp/registers
        register: print_result       #将之前命令的输出结果保存在变量print_result里
      - debug: var=print_result      #将变量的值作为debug输出出来
    
    #执行playbook配置文件
    [root@Ansible yangwenbo]# ansible-playbook test_register.yaml
    
    PLAY [all] *************************************************************************************
    
    TASK [Gathering Facts] *************************************************************************
    ok: [Web01]
    ok: [Web02]
    
    TASK [test register] ***************************************************************************
    changed: [Web02]
    changed: [Web01]
    
    TASK [debug] ***********************************************************************************
    ok: [Web01] => {
        "print_result": {
            "changed": true,
            "cmd": "echo "hi Tom" >> /tmp/registers",
            "delta": "0:00:00.007286",
            "end": "2018-09-07 23:43:38.967375",
            "failed": false,
            "rc": 0,
            "start": "2018-09-07 23:43:38.960089",
            "stderr": "",
            "stderr_lines": [],
            "stdout": "",
            "stdout_lines": []
        }
    }
    ok: [Web02] => {
        "print_result": {
            "changed": true,
            "cmd": "echo "hi Tom" >> /tmp/registers",
            "delta": "0:00:00.006651",
            "end": "2018-09-07 23:43:38.957825",
            "failed": false,
            "rc": 0,
            "start": "2018-09-07 23:43:38.951174",
            "stderr": "",
            "stderr_lines": [],
            "stdout": "",
            "stdout_lines": []
        }
    }
    
    PLAY RECAP *************************************************************************************
    Web01                      : ok=3    changed=1    unreachable=0    failed=0   
    Web02                      : ok=3    changed=1    unreachable=0    failed=0 
    
    #执行结果
    [root@Web01 tmp]# pwd
    /tmp
    [root@Web01 tmp]# ls
    registers
    [root@Web01 tmp]# cat registers 
    hi Tom
    
    [root@Web02 tmp]# pwd
    /tmp
    [root@Web02 tmp]# ls
    registers
    [root@Web02 tmp]# cat registers 
    hi Tom
    

    8.4 nginx配置下发并检测

    [root@Ansible tmp]# pwd
    /tmp
    [root@Ansible tmp]# ls
    nginx.conf
    [root@Ansible tmp]# cat nginx.conf  #nginx的配置文件
    worker_processes  1;
    events {
        worker_connections  1024;
    }
    http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
        server {
            listen       80;
            server_name  www.yangwenbo.com; 
            location / {
                root   html;
                index  index.html index.htm;
            }
        }
    }
    
    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# cat test_nginx_conf.yaml     #playbook的执行模板
    ---
    - hosts: all
      tasks:
      - name: copy nginx.conf
        copy: src=/tmp/nginx.conf dest=/usr/local/nginx/conf/ backup=yes
      - name:
        shell: /usr/local/nginx/sbin/nginx -t
        register: nginx_result
      - debug: var=nginx_result
    
    #执行playbook配置文件
    [root@Ansible yangwenbo]# ansible-playbook test_nginx_conf.yaml 
    
    PLAY [all] *************************************************************************************
    
    TASK [Gathering Facts] *************************************************************************
    ok: [Web01]
    ok: [Web02]
    
    TASK [copy nginx.conf] *************************************************************************
    changed: [Web02]
    changed: [Web01]
    
    TASK [shell] ***********************************************************************************
    changed: [Web02]
    changed: [Web01]
    
    TASK [debug] ***********************************************************************************
    ok: [Web01] => {
        "nginx_result": {
            "changed": true,
            "cmd": "/usr/local/nginx/sbin/nginx -t",
            "delta": "0:00:00.720120",
            "end": "2018-09-07 23:14:53.043060",
            "failed": false,
            "rc": 0,
            "start": "2018-09-07 23:14:52.322940",
            "stderr": "nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
    nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful",
            "stderr_lines": [
                "nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok",      #提示nginx配置文件正常
                "nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful"
            ],
            "stdout": "",
            "stdout_lines": []
        }
    }
    ok: [Web02] => {
        "nginx_result": {
            "changed": true,
            "cmd": "/usr/local/nginx/sbin/nginx -t",
            "delta": "0:00:00.628406",
            "end": "2018-09-07 23:14:52.966781",
            "failed": false,
            "rc": 0,
            "start": "2018-09-07 23:14:52.338375",
            "stderr": "nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
    nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful",
            "stderr_lines": [
                "nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok",      #提示nginx配置文件正常
                "nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful"
            ],
            "stdout": "",
            "stdout_lines": []
        }
    }
    
    PLAY RECAP *************************************************************************************
    Web01                      : ok=4    changed=2    unreachable=0    failed=0   
    Web02                      : ok=4    changed=2    unreachable=0    failed=0 
    
    #执行结果
    [root@Web01 /]# cat /usr/local/nginx/conf/nginx.conf
    worker_processes  1;
    events {
        worker_connections  1024;
    }
    http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
        server {
            listen       80;
            server_name  www.yangwenbo.com; 
            location / {
                root   html;
                index  index.html index.htm;
            }
        }
    }
    
    [root@Web02 /]# cat /usr/local/nginx/conf/nginx.conf
    worker_processes  1;
    events {
        worker_connections  1024;
    }
    http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
        server {
            listen       80;
            server_name  www.yangwenbo.com; 
            location / {
                root   html;
                index  index.html index.htm;
            }
        }
    }
    

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

    9.1 在Playbook中使用自定义变量

    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# cat test_vars.yaml    #playbook的执行模板
    ---
    - hosts: all
      vars:        #定义变量
      - names: "yunjisuan"      #第一个name变量
        age: "3"                #第二个age变量
      tasks:
      - name: "{{ names }}"     #{{}}两对大括号引用变量,变量名两头空格
        shell: echo "myname {{ names }},myage {{ age }}" >> /tmp/bianliang
        register: var_result
      - debug: var=var_result
    
    #特别提示:引用变量需要在双引号中引用。
    
    #执行playbook配置文件
    [root@Ansible yangwenbo]# ansible-playbook test_vars.yaml 
    
    PLAY [all] **************************************************************************************
    
    TASK [Gathering Facts] **************************************************************************
    ok: [Web01]
    ok: [Web02]
    
    TASK [yunjisuan] ********************************************************************************
    changed: [Web01]
    changed: [Web02]
    
    TASK [debug] ************************************************************************************
    ok: [Web01] => {
        "var_result": {
            "changed": true,
            "cmd": "echo "myname yunjisuan,myage 3" >> /tmp/bianliang",
            "delta": "0:00:00.007237",
            "end": "2018-09-07 23:37:10.839684",
            "failed": false,
            "rc": 0,
            "start": "2018-09-07 23:37:10.832447",
            "stderr": "",
            "stderr_lines": [],
            "stdout": "",
            "stdout_lines": []
        }
    }
    ok: [Web02] => {
        "var_result": {
            "changed": true,
            "cmd": "echo "myname yunjisuan,myage 3" >> /tmp/bianliang",
            "delta": "0:00:00.009848",
            "end": "2018-09-07 23:37:10.859020",
            "failed": false,
            "rc": 0,
            "start": "2018-09-07 23:37:10.849172",
            "stderr": "",
            "stderr_lines": [],
            "stdout": "",
            "stdout_lines": []
        }
    }
    
    PLAY RECAP **************************************************************************************
    Web01                      : ok=3    changed=1    unreachable=0    failed=0   
    Web02                      : ok=3    changed=1    unreachable=0    failed=0 
    
    #执行结果
    [root@Web01 tmp]# pwd
    /tmp
    [root@Web01 tmp]# ls
    bianliang
    [root@Web01 tmp]# cat bianliang 
    myname yunjisuan,myage 3
    
    [root@Web02 tmp]# pwd
    /tmp
    [root@Web02 tmp]# ls
    bianliang
    [root@Web02 tmp]# cat bianliang 
    myname yunjisuan,myage 3
    

    9.2在playbook中使用ansible内置变量

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

    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# cat test_setupvars.yaml   #playbook的执行模板
    ---
    - hosts: all
      gather_facts: True    #使用ansible内置变量
      tasks:
      - name: setup var
        shell: echo "ip {{ ansible_all_ipv4_addresses[0] }} cpu {{ ansible_processor_count }}" >> /tmp/test
      - name: setup var2
        shell: echo "time {{ ansible_date_time["date"] }}" >> /tmp/test
        register: var_result
      - debug: var=var_result
    
    #执行playbook配置文件
    [root@Ansible yangwenbo]# ansible-playbook test_setupvars.yaml
    
    PLAY [all] *************************************************************************************
    
    TASK [Gathering Facts] *************************************************************************
    ok: [Web01]
    ok: [Web02]
    
    TASK [setup var] *******************************************************************************
    changed: [Web02]
    changed: [Web01]
    
    TASK [setup var2] ******************************************************************************
    changed: [Web01]
    changed: [Web02]
    
    TASK [debug] ***********************************************************************************
    ok: [Web01] => {
        "var_result": {
            "changed": true,
            "cmd": "echo "time 2018-09-07" >> /tmp/test",
            "delta": "0:00:00.005305",
            "end": "2018-09-07 23:49:33.178900",
            "failed": false,
            "rc": 0,
            "start": "2018-09-07 23:49:33.173595",
            "stderr": "",
            "stderr_lines": [],
            "stdout": "",
            "stdout_lines": []
        }
    }
    ok: [Web02] => {
        "var_result": {
            "changed": true,
            "cmd": "echo "time 2018-09-07" >> /tmp/test",
            "delta": "0:00:00.005363",
            "end": "2018-09-07 23:49:33.230051",
            "failed": false,
            "rc": 0,
            "start": "2018-09-07 23:49:33.224688",
            "stderr": "",
            "stderr_lines": [],
            "stdout": "",
            "stdout_lines": []
        }
    }
    
    PLAY RECAP *************************************************************************************
    Web01                      : ok=4    changed=2    unreachable=0    failed=0   
    Web02                      : ok=4    changed=2    unreachable=0    failed=0 
    
    #执行结果
    [root@Web01 tmp]# pwd
    /tmp
    [root@Web01 tmp]# ls
    test
    [root@Web01 tmp]# cat test 
    ip 192.168.200.74 cpu 1
    time 2018-09-07
    
    [root@Web02 tmp]# pwd
    /tmp
    [root@Web02 tmp]# ls
    test
    [root@Web02 tmp]# cat test 
    ip 192.168.200.75 cpu 1
    time 2018-09-07
    

    10.Playbook下发可变配置文件

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

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

    [root@Ansible tmp]# pwd
    /tmp
    [root@Ansible tmp]# ls
    test
    [root@Ansible tmp]# cat test 
    my name is {{ myname }}       #自定义变量
    my name is {{ ansible_all_ipv4_addresses[0] }}    #系统变量
    
    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# cat test_filevars.yaml    #playbook的执行模板
    ---
    - hosts: all
      gather_facts: True       #开启系统变量
      vars:
      - myname: "yunjisuan"    #自定义变量
      tasks:
      - name: template test
        template: src=/tmp/test dest=/tmp/test     #使用template下发可变配置文件
    
    #执行playbook配置文件
    [root@Ansible yangwenbo]# ansible-playbook test_filevars.yaml
    
    PLAY [all] *************************************************************************************
    
    TASK [Gathering Facts] *************************************************************************
    ok: [Web01]
    ok: [Web02]
    
    TASK [template test] ***************************************************************************
    changed: [Web01]
    changed: [Web02]
    
    PLAY RECAP *************************************************************************************
    Web01                      : ok=2    changed=1    unreachable=0    failed=0   
    Web02                      : ok=2    changed=1    unreachable=0    failed=0
    
    #执行结果
    [root@Web01 tmp]# pwd
    /tmp
    [root@Web01 tmp]# ls
    test
    [root@Web01 tmp]# cat test 
    my name is yunjisuan
    my name is 192.168.200.74
    
    [root@Web02 tmp]# pwd
    /tmp
    [root@Web02 tmp]# ls
    test
    [root@Web02 tmp]# cat test 
    my name is yunjisuan
    my name is 192.168.200.75
    

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

    10.2.1 PORT存在有值

    [root@Ansible tmp]# pwd
    /tmp
    [root@Ansible tmp]# ls
    if.j2
    [root@Ansible tmp]# cat if.j2 
    {% if PORT %}       #if PORT存在
    ip=0.0.0.0:{{ PORT }}
    {% else %}          #否则的话
    ip=0.0.0.0:80
    {% endif %}         #结尾
    
    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# cat test_ifvars.yaml   #playbook的执行模板
    ---
    - hosts: all
      gather_facts: True    #开启系统内置变量
      vars:
      - PORT: 90            #自定义变量
      tasks:
      - name: jinja2 if test
        template: src=/tmp/if.j2 dest=/root/test
    
    #执行playbook配置文件
    [root@Ansible yangwenbo]# ansible-playbook test_ifvars.yaml
    
    PLAY [all] *************************************************************************************
    
    TASK [Gathering Facts] *************************************************************************
    ok: [Web02]
    ok: [Web01]
    
    TASK [jinja2 if test] **************************************************************************
    changed: [Web01]
    changed: [Web02]
    
    PLAY RECAP *************************************************************************************
    Web01                      : ok=2    changed=1    unreachable=0    failed=0   
    Web02                      : ok=2    changed=1    unreachable=0    failed=0
    
    #执行结果
    [root@Web01 tmp]# pwd
    /tmp
    [root@Web01 tmp]# ls
    test
    [root@Web01 tmp]# cat test 
           
    ip=0.0.0.0:90
    
    [root@Web02 tmp]# pwd
    /tmp
    [root@Web02 tmp]# ls
    test
    [root@Web02 tmp]# cat test 
           
    ip=0.0.0.0:90
    

    10.2.2如果将变量PORT值为空的话,就会是另外的结果

    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# cat test_ifvars.yaml   #playbook的执行模板
    ---
    - hosts: all
      gather_facts: True   
      vars:
      - PORT:   #置为空
      tasks:
      - name: jinja2 if test
        template: src=/tmp/if.j2 dest=/root/test
    
    #执行playbook配置文件
    [root@Ansible yangwenbo]# ansible-playbook test_ifvars.yaml
    
    PLAY [all] *************************************************************************************
    
    TASK [Gathering Facts] *************************************************************************
    ok: [Web01]
    ok: [Web02]
    
    TASK [jinja2 if test] **************************************************************************
    changed: [Web01]
    changed: [Web02]
    
    PLAY RECAP *************************************************************************************
    Web01                      : ok=2    changed=1    unreachable=0    failed=0   
    Web02                      : ok=2    changed=1    unreachable=0    failed=0
    
    #执行结果
    [root@Web01 tmp]# pwd
    /tmp
    [root@Web01 tmp]# ls
    test
    [root@Web01 tmp]# cat test 
              
    ip=0.0.0.0:80
    
    [root@Web02 tmp]# pwd
    /tmp
    [root@Web02 tmp]# ls
    test
    [root@Web02 tmp]# cat test 
              
    ip=0.0.0.0:80
    

    11.Playbook的notify通知和下发nginx配置(简介)

    #实战下发可执行动作的可变的nginx配置文件
    [root@Ansible tmp]# pwd
    /tmp
    [root@Ansible tmp]# ls
    nginx.j2
    [root@Ansible tmp]# cat nginx.j2 
    worker_processes  {{ ansible_processor_count }};      #可变的参数
    
    [root@Ansible yangwenbo]# pwd
    /root/yangwenbo
    [root@Ansible yangwenbo]# cat test_nginxvars.yaml     #playbook的执行模板
    ---
    - 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
    
  • 相关阅读:
    HDU3336 Count the string —— KMP next数组
    CodeForces
    51Nod 1627 瞬间移动 —— 组合数学
    51Nod 1158 全是1的最大子矩阵 —— 预处理 + 暴力枚举 or 单调栈
    51Nod 1225 余数之和 —— 分区枚举
    51Nod 1084 矩阵取数问题 V2 —— 最小费用最大流 or 多线程DP
    51Nod 机器人走方格 V3 —— 卡特兰数、Lucas定理
    51Nod XOR key —— 区间最大异或值 可持久化字典树
    HDU4825 Xor Sum —— Trie树
    51Nod 1515 明辨是非 —— 并查集 + 启发式合并
  • 原文地址:https://www.cnblogs.com/ywb123/p/11223103.html
Copyright © 2011-2022 走看看