• 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
    
  • 相关阅读:
    python简介
    Error:unknown filesystem
    Ubuntu 12.04 相关问题
    C/C++版数据结构之链表<一>
    C/C++版数据结构之链表<二>
    C/C++版数据结构之树<二>
    C/C++版数据结构之树<一>
    C/C++版数据结构之链表<三>
    C/C++版数据结构之排序算法
    php 操作文件简单例子
  • 原文地址:https://www.cnblogs.com/ywb123/p/11223103.html
Copyright © 2020-2023  润新知