• Ansible运维自动化


    一,工具与环境介绍

     

    1.1 Ansible简介

    • 批量管理服务器的工具。
    • 优点:无需部署agent,没客户端,客户端只要支持Python即可。
    • 通过ssh进行管理,远程登录管理。
    • 目前github上最流行的自动化运维工具,没有之一。
     

    1.2 Jenkins简介

    • 可视化运维(主要用在可视化部署):能够把脚本或者管理工具的一些信息输出放在Web界面让你看,同时还可以看一些历史的信息输出。
    • 可持续构建,和git,svn结合,可以发出指令把开发新写的代码从代码仓库里直接tar打包发送到对面服务器里同时启动自动安装程序。 
      git,svn:一种开发可以存放代码的仓库
    • 与ssh和ansible结合均可实现可视化运维
     

    1.3 环境说明

    • 关闭防火墙
    • 关闭sekinux
     

    二, Python3与Ansible的安装

     

    2.1 使用源码安装Python3.5

     

    2.1.1 安装支持包

    装两个云yum源: 
    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
    wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
    安装支持包: 
    yum -y install lrzsz vim net-tools gcc gcc-c++ ncurses ncurses-devel unzip zlib-devel zlib openssl-devel openssl libffi-devel epel-release libselinux-python

     

    2.1.2 源码包编译 Python3.5

    云yum下载地址: 
    wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz

    tar xf Python-3.5.2.tgz -C /usr/src/ 
    cd /usr/src/Python-3.5.2/ 
    ./configure --prefix=/usr/local/python 
    image_1csiuqp4v44eane12mh7ga47b9.png-5kB

    make && make install 
    image_1csj3mavq118iamb2em1idp1350m.png-8.2kB

     

    2.1.2 做软连接

    ln -s /usr/local/python/bin/python3 /usr/bin/python3

     

    2.1.3 查版本号

    python3 -V

     

    2.2 使用pip3安装ansible

     

    2.2.1 安装ansible最新版本

    /usr/local/python/bin/pip3 install ansible

     

    2.2.2 做软连接

    ln -s /usr/local/python/bin/ansible /usr/local/bin 
    which ansible 
    ansible --version(查看版本号)

     

    2.3 Ansible查看帮助

    /usr/local/python/bin/ansible-doc -l 查看总帮助 
    /usr/local/python/bin/ansible-doc -s shell 查看Shell模块的帮助

     

    三,使用公钥实现ssh无密码登陆

    • 下载SCP
     

    3.1 生成密钥对

    ssh-keygen -t rsa -f ~/.ssh/id_rsa -P "" 
    ``

     

    3.2 分发密钥

      sshpass -p 对方电脑登陆密码 ssh-copy-id -i ~/.ssh/id_dsa.pub "-o StrictHostKeyChecking=no 192.168.200.63"
    -o StrictHostKeyChecking=no 不记录

     

    四,Ansible的简单配置和ping模块

     

    4.1 Ansible的配置文件

    通过pip3安装的ansible是没有配置文件的,需要我们自己创建一个

     
    1. mkdir -p /etc/ansible
    2. vim /etc/ansible/hosts
     
    1. cat /etc/ansible/hosts
    2. [nginx] #被管理的主机组名称
    3. webA ansible_ssh_host=192.168.200.132 ansible_ssh_port=22 ansible_ssh_user=root #第一台主机
    4. webB ansible_ssh_host=192.168.200.138 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=666666 #第二台主机
    5. 特别提示:
    6. WebA ===> 主机名
    7. ansible_ssh_host ===>主机IP
    8. ansible_ssh_port ===>ssh的默认端口
    9. ansible_ssh_user ===>ssh的用户名
    10. ansible_ssh_pass ===>ssh的用户的连接密码

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

     

    下载epel源安装sshpass

     
    1. 2.[root@ansible python]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
    2. 3.[root@ansible python]# yum -y install sshpass
    3. 4.[root@ansible python]# which sshpass
    4. 5./usr/bin/sshpass
     

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

     

    1.语法:

    ansible Web1 -m command -a 'uptime'-->获取Web1服务器的平均负载值 
    ansible 主机组 -m ansible内置功能模块名 -a 命令

    all:代表所有主机 
    nginx:模块名,只发nginx模块下的主机 
    单发:Web1=主机名 
    多发:Web1:Web2 
    指定all但不包含web2:all: !web1,注意!前需要加转意符号()

     

    2.进行命令测试:

     
    1. 1.#进行ping模块的连接测试
    2. 2.[root@ansible python]# ansible nginx -m ping
    3. 3.webB | FAILED! => { #我们发现webB还是没链接成功,这是因为本机的known_hosts文件还没有记录对方主机的信息。
    4. 4. "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."
    5. 5.}
    6. 6.webA | SUCCESS => { #webA成功
    7. 7. "changed": false,
    8. 8. "ping": "pong"
    9. 9.}
     

    4.3 ansible的简单使用方式

    ansible -i /etc/ansible/hosts 主机或主机组 -m 指定模块 -a 命令 
    -i:指定配置文件位置,不指定默认去/etc/ansible/hosts 里找 
    -m : 指定操作模块,后跟模块名 
    -a :发布,后面跟命令

     

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

    ansible all -m ping

     

    操作测试

     
    1. #A
    2. [root@ansible .ssh]# ansible webA -m ping
    3. webA | SUCCESS => {
    4. "changed": false,
    5. "ping": "pong"
    6. }
     
    1. # all
    2. [root@ansible .ssh]# ansible all -m ping
    3. webA | SUCCESS => {
    4. "changed": false,
    5. "ping": "pong"
    6. }
    7. webB | SUCCESS => {
    8. "changed": false,
    9. "ping": "pong"
    10. }
     
    1. #A:B
    2. [root@ansible .ssh]# ansible webA:webB -m ping
    3. webA | SUCCESS => {
    4. "changed": false,
    5. "ping": "pong"
    6. }
    7. webB | SUCCESS => {
    8. "changed": false,
    9. "ping": "pong"
    10. }
     
    1. #!A
    2. [root@ansible .ssh]# ansible all:!webA -m ping
    3. webB | SUCCESS => {
    4. "changed": false,
    5. "ping": "pong"
    6. }
     

    五,Ansible的三个命令模块

     

    5.1 ansible模块command

     

    1.command支持直接回显命令的执行结果

     
    1. [root@ansible ~]# ansible all -m command -a "pwd"
    2. webA | SUCCESS | rc=0 >>
    3. /root
    4. webB | SUCCESS | rc=0 >>
    5. /root

    注:command不支持管道符不支持重定向,不建议使用

     

    5.2 Ansible模块shell

     

    1.shell模块支持管道符

     
    1. [root@ansible ~]# ansible all -m shell -a "echo testansible | grep a"
    2. webA | SUCCESS | rc=0 >>
    3. testansible
    4. webB | SUCCESS | rc=0 >>
    5. testansible
     

    2.shell支持重定向

     
    1. [root@ansible ~]# ansible all -m shell -a "echo bb >> /tmp/testansible"
    2. webA | SUCCESS | rc=0 >>
    3. webB | SUCCESS | rc=0 >>

    注:如果遇到特殊符号需要加入转义,ansible才能正常运行

     

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

     

    1.清除yum缓存

     
    1. [root@ansible ~]# ansible all -m raw -a "yum -y clean all"
    2. webB | SUCCESS | rc=0 >>
    3. Loaded plugins: fastestmirror
    4. Cleaning repos: c7-media
    5. Cleaning up everything
    6. Shared connection to 192.168.200.63 closed.
    7. webA | SUCCESS | rc=0 >>
    8. Loaded plugins: fastestmirror
    9. Cleaning repos: c7-media epel
    10. Cleaning up everything
    11. Cleaning up list of fastest mirrors
    12. Shared connection to 192.168.200.132 closed.
     

    4.建立yum缓存

     
    1. [root@ansible ~]# ansible all -m raw -a "yum makecache"
    2. webA | SUCCESS | rc=0 >>
    3. Loaded plugins: fastestmirror
    4. c7-media | 3.6 kB 00:00
    5. Loading mirror speeds from cached hostfile
    6. * c7-media:
    7. Metadata Cache Created
    8. Shared connection to 192.168.200.132 closed.
    9. webB | SUCCESS | rc=0 >>
    10. Loaded plugins: fastestmirror
    11. c7-media | 3.6 kB 00:00
    12. Loading mirror speeds from cached hostfile
    13. * c7-media:
    14. Metadata Cache Created
    15. Shared connection to 192.168.200.138 closed.
     

    3.yum装nmap包

     
    1. ansible all -m raw -a "yum -y install nmap"
     

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

     

    1. copy模块概述

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

    osrc:指定源文件或目录 
    odest:指定目标服务器的文件或目录 
    obackup:是否要备份 
    oowner:拷贝到目标服务器后,文件或目录的所属用户 
    ogroup:拷贝到目标服务器后,文件或目录的所属群组 
    omode:文件或目录的权限

     

    准备工作

     
    1. [root@ansible ~]# mkdir -p /service/scripts
    2. [root@ansible ~]# echo "aaa" > /service/scripts/test.txt
    3. [root@ansible ~]# echo "bbb" > /service/scripts/test2.tx
    4. 所有被管理端节点必须安装libselinux-python
    5. yum -y install libselinux-python
     

    2. copy模块拷贝文件

    特别提示:如果目标路径不存在会自动创建 : src===>源文件路径 dest=目标路径位置

     
    1. [root@ansible ~]# ansible all -m copy -a "src=/service/scripts/test.txt dest=/service/scripts/"
    2. webB | FAILED! => { #节点未安装libselinux-python
    3. "changed": false,
    4. "checksum": "972a1a11f19934401291cc99117ec614933374ce",
    5. "msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"
    6. }
    7. webA | SUCCESS => {
    8. "changed": true,
    9. "checksum": "972a1a11f19934401291cc99117ec614933374ce",
    10. "dest": "/service/scripts/test.txt",
    11. "gid": 0,
    12. "group": "root",
    13. "md5sum": "5c9597f3c8245907ea71a89d9d39d08e",
    14. "mode": "0644",
    15. "owner": "root",
    16. "secontext": "system_u:object_r:svc_svc_t:s0",
    17. "size": 4,
    18. "src": "/root/.ansible/tmp/ansible-tmp-1529035954.8010113-22928023490467/source",
    19. "state": "file",
    20. "uid": 0
    21. }
     
    节点安装libselinux-python后在进行发送测试
     
    1. [root@ansible ~]# ansible webB -m copy -a "src=/service/scripts/test.txt dest=/service/scripts/"
    2. webB | SUCCESS => { #发送成功
    3. "changed": true,
    4. "checksum": "972a1a11f19934401291cc99117ec614933374ce",
    5. "dest": "/service/scripts/test.txt",
    6. "gid": 0,
    7. "group": "root",
    8. "md5sum": "5c9597f3c8245907ea71a89d9d39d08e",
    9. "mode": "0644",
    10. "owner": "root",
    11. "secontext": "system_u:object_r:svc_svc_t:s0",
    12. "size": 4,
    13. "src": "/root/.ansible/tmp/ansible-tmp-1529036146.1609693-94270890826089/source",
    14. "state": "file",
    15. "uid": 0
    16. }
     

    3. copy模块拷贝文件夹

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

     
    1.拷贝/service/scripts/ 目录下所有内容到dest的路径下
     
    1. [root@ansible ~]# ansible webA -m copy -a "src=/service/scripts/ dest=/service/scripts/"
    2. webA | SUCCESS => {
    3. "changed": true,
    4. "dest": "/service/scripts/",
    5. "src": "/service/scripts/"
    6. }
     
    2.拷贝/service/scripts目录本身及其内部的所有内容到dest的路径下
     
    1. [root@ansible ~]# ansible webA -m copy -a "src=/service/scripts dest=/service/scripts/"
    2. webA | SUCCESS => {
    3. "changed": true,
    4. "dest": "/service/scripts/",
    5. "src": "/service/scripts"
    6. }
     

    4 copy模块自动备份

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

     
    1. [root@ansible ~]# ansible webB -m copy -a "src=/service/scripts/ dest=/service/scripts/ backup=yes"
    2. webB | SUCCESS => {
    3. "changed": true,
    4. "dest": "/service/scripts/",
    5. "src": "/service/scripts/"
    6. }
     

    5 copy模块指定用户和属主属组权限

     
    1. [root@ansible ~]# ansible webA -m copy -a "src=/service/scripts/ dest=/service/scripts/ owner=nobody group=nobody mode=0600"
    2. webA | SUCCESS => {
    3. "changed": true,
    4. "dest": "/service/scripts/",
    5. "src": "/service/scripts/"
    6. }
     

    5.5 Ansible的script模块批量运行脚本

    能够实现远程服务器批量运行本地的shell脚本

     

    1.远程批量分发并自动部署nginx

    所有被管理端需要挂载光盘,并创建本地yum配置文件 
    scripts目录下需要两个脚本和解压包: 
    1,自动分安装脚本 
    2,分发脚本 
    3.nginx-1.10.2.tar.gz #nginx源码包

     

    1.自动安装脚本

     
    1. #!/bin/sh
    2. #nginx install shell scripts
    3. test -d /media/cdrom || mkdir -p /media/cdrom #有没有目录
    4. mount /dev/sr0 /media/cdrom &>/dev/null #挂在光盘
    5. yum -y install gcc gcc-c++ make pcre pcre-devel zlib zlib-devel openssl openssl-devel &>/dev/null #安装软件包
    6. test -d /service/scripts || mkdir -p /service/scripts #有没有目录没有创建
    7. cd /service/scripts/ #进入目录
    8. tar xf nginx-1.10.2.tar.gz -C /usr/src/ #解压包
    9. cd /usr/src/nginx-1.10.2/ #进入Nginx目录
    10. ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module &>/dev/null #编译
    11. make &>/dev/null
    12. make install &>/dev/null #安装
    13. exit 0
     

    2.分发脚本

     
    1. #!/bin/sh
    2. Group=$1 #对方服务器位置(主机名或主机组明)
    3. ansible $Group -m copy -a "src=/server/scripts/ dest=/service/scripts/ mode=0755" #分发范围
    4. ansible $Group -m script -a "/service/scripts/auto_nginx.sh" #远程激活
     

    3.激活脚本

    ansible web1:web2 -m script -a "/bin/sh /service/scripts/auto_nginx.sh"

     

    六,Ansible-playbook的初步使用

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

     

    6.1 作软连接

    ln -s /usr/local/python/bin/ansible-playbook /usr/local/bin/

     

    6.2 playbook的简单shell模块的使用

     
    1.playbook的执行模板**
     
    1. --- #开头三个小-开头
    2. - hosts: webB
    3. tasks: #任务,标注
    4. - name: test #任务名字
    5. shell: echo "welcome to yunjisaun" >> /tmp/username #模块名:命令
    6. - name: test2
    7. 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:后边还是要有个空格,需要注意。

     
    2.激活剧本

    ansible-playbook test_shell.yaml

     

    6.3 playbook的简单copy模块的使用

     
    1.做一个copy文件

    ehco "welcome to yunjisuan" >> /tmp/test_copy

     
    2.做剧本
     
    1. vim test_copy.yaml
    2. ---
    3. - hosts: all
    4. tasks:
    5. - name: test copy
    6. copy: src=/tmp/copy_test dest=/tmp/
     
    3.剧本激活

    ansible-playbook /service/scripts/test_copy.yaml

     

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

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

     
    1.写剧本
     
    1. ---
    2. - hosts: all
    3. tasks:
    4. - name: test register
    5. shell: echo "welcome to yunjisuan"
    6. register: print_result #将之前命令的输出结果保存在变量print_result里
    7. - debug: var=print_result #将变量的值作为debug输出出来
     
    2.执行剧本

    ansible-playbook test_register.yaml

     

    6.4 nginx配置下发并检测

     
    1.写脚本
     
    1. vim test_nginx_conf.yaml
    2. ---
    3. - hosts: all
    4. tasks:
    5. - name: copy nginx.conf
    6. copy: src=/tmp/nginx.conf dest=/usr/local/nginx/conf/ backup=yes
    7. - name:
    8. shell: /usr/local/nginx/sbin/nginx -t
    9. register: nginx_result
    10. - debug: var=nginx_result
     
    2.执行脚本

    ansible-playbook test_nginx_conf.yaml

     

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

     

    7.1 在Playbook中使用自定义变量

     
    1.写剧本
     
    1. ---
    2. - hosts: all
    3. vars: #定义变量
    4. - name: "yunjisuan" #第一个name变量
    5. age: "3" #第二个age变量
    6. tasks:
    7. - name: "{{ name }}" #{{}}两对大括号引用变量,变量名两头空格
    8. shell: echo "myname {{ name }},myage {{ age }}"
    9. register: var_result
    10. - debug: var=var_result
    11. 特别提示:
    12. 引用变量需要在双引号中引用

    注:会有一个警告:因为自定义变量的名字和自定义变量名字冲突[WARNING]: Found variable using reserved name: name 
    把name修改为Name即可

     
    2.执行剧本

    ansible-playbook /service/scripts/test_vars.yaml

     

    7.2 在playbook中使用ansible内置变量

    查看内置变量:ansible 127.0.01 -m setup | less 
    image_1csjpqd3q1iicd8hvd1gru1jiq9.png-39.7kB

     
    1. 写剧本
     
    1. vim est_setupvars.yaml
    2. ---
    3. - hosts: all
    4. gather_facts: True #使用ansible内置变量
    5. tasks:
    6. - name: setup var
    7. shell: echo "ip {{ ansible_all_ipv4_addresses[0] }} cpu {{ ansible_processor_count }}"
    8. register: var_result
    9. - debug: var=var_result
     
    2. 执行脚本

    ansible-playbook test_setupvars.yaml

     

    八,Playbook下发可变配置文件

     

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

     
    1.写一个含有变量的文件
     
    1. vim /tmp/test
    2. my name is {{ myname }} #自定义变量
    3. my name is {{ ansible_all_ipv4_addresses[0] }} #系统变量
     
    2.写一个文件的含有变量
     
    1. vim test_filevars.yaml
    2. ---
    3. - hosts: all
    4. gather_facts: True #开启系统变量
    5. vars:
    6. - myname: "yunjisuan" #自定义变量
    7. tasks:
    8. - name: template test
    9. template: src=/tmp/test dest=/root/test #使用template下发可变配置文件
     
    执行剧本

    ansible-playbook test_filevars.yaml

     

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

     
    1.写一个半段语法的文件,以.j2结尾
     
    1. vim /tmp/if.j2
    2. {% if PORT %} #if PORT存在
    3. ip=0.0.0.0:{{ PORT }}
    4. {% else %} #不为真
    5. ip=0.0.0.0:80
    6. {% endif %} #结尾

    测试:

     
    1. vim test_ifvars.yaml ---
    2. - hosts: all
    3. gather_facts: True #开启系统内置变量
    4. vars:
    5. - PORT: 90 #自定义变量
    6. tasks:
    7. - name: jinja2 if test
    8. template: src=/tmp/if.j2 dest=/root/test
     
    2.执行剧本
     

    九, Playbook的notify通知和下发nginx配置

     

    1.实战下发可执行动作的可变的nginx配置文件

     
    1. # cat test_nginxvars.yaml
    2. ---
    3. - hosts: all
    4. gather_facts: True #开启系统内置变量
    5. tasks:
    6. - name: nginx conf
    7. template: src=/tmp/nginx.j2 dest=/usr/local/nginx/conf/nginx.conf
    8. notify:
    9. - reload nginx #下发通知给handlers模块执行名字叫做reload nginx的动作
    10. handlers: #定义动作
    11. - name: reload nginx #动作的名字
    12. shell: /usr/local/nginx/sbin/nginx -s reload
     
    2.执行剧本

    ansible-playbook test_nginxvars.yaml

    注:当你的上一条使得对方发生了改变才会触发notify通知

    对新装的操作系统部署服务: 
    1.自动安装服务 
    2.把写好的配置文件覆盖到远程主机服务目录下 
    3.启动服务

    已经部署好的服务,更新配置文件 
    1.Nginx反向代理引流(发个配置文件重启服务)

    搭建LNMP步骤模块划分 
    1.搭建Nginx 
    2.搭建PHP 
    3.搭建MySQL 
    4.分发Nginx,php,MySQL的配置文件 
    4.启动nginx,php,mysql

  • 相关阅读:
    洛谷 P3521 [POI2011]ROT-Tree Rotations 解题报告
    洛谷 P1640 [SCOI2010]连续攻击游戏 解题报告
    vector-pop_back
    vector-push_back
    vector-push_back
    vector-max_size
    vector-max_size
    vector-insert
    vector-insert
    vector-front
  • 原文地址:https://www.cnblogs.com/wangyinuo/p/9993376.html
Copyright © 2020-2023  润新知