运维自动化
随着互联网的高速发展,公司的业务也不断的发生变化,从最简单的单台服务器演变成了大数据、超大集群服务器阵列,这对运维的工作挑战着实不小。
前期采用shell脚本简化工作、提升效率的方法对于目前海量机器运维环境也显得无能为力了。
所以,为了能让大家的运维能力从百台到千台甚至更大的量级,我们需要引入自动化管理工具,对机器及业务实现批量部署,批量管理。从而提升运维的管理能力,解决工作中的管理难题。
未使用自动化运维平台公司运维现状:
公司有200多台机器,其中集群中的RS(业务机器)有50多台,每次对业务机器进行业务升级或者优化时,总需要运维人员分别登陆到RS机器分别执行命令或者分别执行脚本。运维的瓶颈也就凸显出来了,主要表现在以下几个方面:
重复性工作:50个RS需要重复50次登陆,50次业务操作
劳民伤财:大量的机器维护需要大量的时间,运维人员也比较烦躁
容错率低:人手动执行容易出错 `rm -rf data/` 往往是不经意间提前回车造成的
运维自动化平台是由管理机器[S]和业务机器[C]组成的,C/S
管理机器:任务定制及发布
业务及其:接收任务并执行发布
运维自动化平台的优势:
一次性任务定制:任务一次性发布给所有机器
节省任务执行时间:任务主机并发完成任务 节省部署时间
错误率低:避免重复 保证一次任务定制准确即可
常见的自动化工具
-
Puppet
-
Ansible
-
SaltStack
puppet:
基于Ruby开发,有产品线已经在用,优点是历史悠久,比较成熟,在可远程可本地,功能强劲,批量执行需要写专门的配置文件,费力费时。而且有客户端在,和授权系统结合比较麻烦。
saltstack:
saltstack和ansible都是python流的,而且就功能上来讲,两者也极为相似,不同之处是salt stack是有客户端的,并且execution模块还用0MQ实现了pub-sub,命令和执行结果因此可以高效并行传输,不过成也萧何败也萧何,第一个sub阶段(将querystring下发到所有机器,然后收集机器响应的阶段)太依赖与客户端返回了,如果客户端未能及时返回或未响应的话,playbook执行阶段可能会直接漏掉这部分机器而没有任何提示,这对于运维来说是不可接受的。
ansible:
与前两者比起来,在特性上似乎并不抢眼,配置管理方面(playbook)绝对比不过老大哥puppet,批量执行方面也只是多线程,不像saltstack那么高大上,不过ansible搜索热度高出saltstack三倍多,显然靠的不是吹牛,至少,ansible至少不会悄悄的丢机器,这给了我们一个定心丸,而且仅依赖ssh,与登录授权管理系统天然集成,简单即有效,没有比这更美妙的事情了。
1、Ansible:python,Agentless,中小型应用环境
2、Saltstack:python,一般需部署agent(需要代理) 执行效率更高
3、Puppet:ruby,功能强大 配置复杂 重型 适合大型环境
ansible介绍
ansible是一种由Python开发的自动化运维工具,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括:
-
连接插件connection plugins:负责和被监控端实现通信;
-
ansible管理端和客户端基于ssh协议通信
-
host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;提供主机管理列表,定义管理谁
-
各种模块核心模块、command模块、自定义模块;提供了日常模块
-
借助于插件完成记录日志邮件等功能; 根据需求后续添加模块,邮件、日志模块
-
playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。一次发布多条指令给客户端
特性
-
no agents:不需要在被管控主机上安装任何客户端;
-
no server:无服务器端,使用时直接运行命令即可;
-
modules in any languages:基于模块工作,可使用任意语言开发模块;
-
yaml,not code:使用yaml语言定制剧本playbook;
-
ssh by default:基于SSH工作;
-
strong multi-tier solution:可实现多级指挥。
优点
-
轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
-
批量任务执行可以写成脚本,而且不用分发到远程就可以执行;
-
使用python编写,维护更简单,Ruby语法过于复杂;
-
支持sudo
对于普通用户来说,很多命令执行是不一定有权限
find / -name nginx.conf
只能够使用管理员来进行操作?不建议,因为root用户很特殊(天神)
以root身份授权了yk具备sudo权限
xmg(普通用户) -> yk(具备一定的sudo权限)
以xmg的身份进行登录,命令执行的时候以yk身份执行
sudo用户不指定用户的情况下,但是我们指定开启了sudo功能,默认会使用root
基本架构

· 核心引擎:即ansible
· 核心模块(core modules):这些都是ansible自带的模块,ansible模块资源分发到远程节点使其执行特定任务或匹配一个特定的状态。
· 自定义模块(custom modules):如果核心模块不足以完成某种功能,可以添加自定义模块。
· 插件(plugins):完成模块功能的补充,借助于插件完成记录日志、邮件等功能
· 剧本(playbook):定义ansible任务的配置文件,可以将多个任务定义在一个剧本中,由ansible自动执行,剧本执行支持多个任务,可以由控制主机运行多个任务,同时对多台远程主机进行管理。
playbook是ansible的配置、部署和编排语言,可以描述一个你想要的远程系统执行策略,或一组步骤的一般过程。如果ansible模块作为你的工作室工具,playbook就是设计方案。在基本层面上,剧本可以用于管理配置和部署远程机器。在更高级的应用中,可以序列多层应用及滚动更新,并可以把动作委托给其他主机,与监控服务器和负载平衡器交互。
· 连接插件(connection plugins):ansible基于连接插件连接到各个主机上,负责和被管理节点实现通信。虽然ansible是使用ssh连接到各被管理节点,但它还支持其他的连接方法,所以需要有连接插件。
· 主机清单(host inventory):定义ansible管理的主机策略,默认是在ansible的hosts配置文件中定义被管节点,同时也支持自定义动态主机清单和指定配置文件路径。
ansible采用paramiko协议库 (Fabric也使用这个 基于python开发 支持SSHV2) 通过ssh或者ZeroMQ等连接主机
ansible在控制主机主机将ansible模块通过ssh协议 (或者Kerberos LDAP) 推送到被管节点执行 执行完之后自动删除
控制主机与被管理节点之间支持local SSH ZeroMQ三种连接方式 默认使用基于SSH的连接 在规模较大的情况下使用ZeroMQ连接方式会明显改善执行速度
运行原理
工作原理:
1.用户登录管理机器:通过ansible剧本或者单行命令针对业务机器组或者单个机器部署任务
2.管理机器读取用户的部署任务:根据自己hosts文件中定义的业务机器组查找对应的机器地址(ip或者域名)
3.管理机下发任务:管理机通过ssh免密连接业务机器 下发任务给业务机器
4.业务机器执行任务
5.业务机器将执行结果发送给ansible管理机器
反馈字体颜色
绿色 未发生改变
黄色 更改生效
红色 执行错误
部署前准备
-
部署机器准备
-
计算机名解析
-
关闭防火墙、selinux
-
时间同步
-
软件包获得
-
ssh免密登陆
约定事项:
- 所有服务器全部采用静态ip
-
部署机器准备
-
计算机名解析
-
关闭防火墙、selinux
-
时间同步
-
软件包获得
-
ssh免密登陆
约定事项:
- 所有服务器全部采用静态ip
主机名称 | IP地址 |
---|---|
manage01 | 192.168.66.200/24 |
node1 | 192.168.66.201/24 |
node2 | 192.168.66.202/24 |
node3 | 192.168.66.203/24 |
2.主机名及主机名互相绑定
root@manage01 \~\]# cat /etc/hosts 127.0.0.1 localhost ::1 localhost 192.168.66.200 manage01 192.168.66.201 node1 192.168.66.202 node2 192.168.66.203 node3 其他机器同理
3.关闭防火墙, selinux
root@manage01 \~\]# systemctl disable firewalld \[root@manage01 \~\]# sed -i -r '/SELINUX=/c\\SELINUX=disabled' /etc/selinux/config \[root@manage01 \~\]# reboot 其他机器同理
4.采用时间服务器,时间同步
1、修改配置文件,配置时间服务器为阿里云的时间服务器
[root@manage01 ~]# egrep "^server" /etc/chrony.conf
server ntp1.aliyun.com
server ntp2.aliyun.com
server ntp3.aliyun.com
server ntp4.aliyun.com
#注释
# pool 2.centos.pool.ntp.org iburst
2、重启服务chronyd
[root@manage01 ~]# systemctl restart chronyd.service
3、查看源信息
#chronyc chrony的命令行客户端
[root@manage01 ~]# chronyc sources -v
210 Number of sources = 2
.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current synced, '+' = combined , '-' = not combined,
| / '?' = unreachable, 'x' = time may be in error, '~' = time too variable.
|| .- xxxx [ yyyy ] +/- zzzz
|| Reachability register (octal) -. | xxxx = adjusted offset,
|| Log2(Polling interval) --. | | yyyy = measured offset,
|| \ | | zzzz = estimated error.
|| | | \
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^? 116.62.13.223 2 6 1 7 -1647us[-1647us] +/- 27ms
^? 203.107.6.88 2 6 1 9 -8206us[-8206us] +/- 30ms
5.确认和配置yum源(需要epel源)
root@manage01 \~\]# yum -y install epel-\*
ansible管理端部署
管理端安装ansible
安装方式:
1)yum
root@manage01 \~\]# yum -y install ansible \[root@manage01 \~\]# ansible --version ansible 2.8.5 config file = /etc/ansible/ansible.cfg configured module search path = \['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, May 21 2019, 23:51:36) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]
2) 源码
1、官网下载地址:https://releases.ansible.com/ansible
root@manage01 \~\]# wget https://releases.ansible.com/ansible/ansible-2.9.3.tar.gz 2、安装ansible \[root@manage01 \~\]# tar xf ansible-2.9.3.tar.gz \[root@manage01 \~\]# mv ansible-2.9.3 /opt/ansible \[root@manage01 \~\]# cd /opt/ansible # python目前的版本 python2 python3 # pip是python中的下载工具,python2已经不支持的,早就停止更新了 # 如果是python3,pip的名字叫pip3 #python软件包安装--1、安装依赖 \[root@manage01 ansible\]python get-pip.py \[root@manage01 ansible-2.9.0rc3\]# # install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/ #python软件包安装--2、安装软件 \[root@manage01 ansible-2.9.0rc3\]# pip install --user ansible -i https://pypi.tuna.tsinghua.edu.cn/simple/ #安装后设置 \[root@manage01 \~\]# ln -s /opt/ansible/bin/\* /usr/bin/ \[root@manage01 \~\]# cp /opt/ansible/examples/ansible.cfg /etc/ansible/ \[root@manage01 \~\]# cp /opt/ansible/examples/hosts /etc/ansible/
ansible是基于python进行开发的
ll /usr/bin/ansible*
root@localhost soft\]# file /usr/bin/ansible-2.7 /usr/bin/ansible-2.7: Python script, ASCII text executable vim /usr/bin/ansible-2.7 #!/usr/bin/python2 # -\*- coding: utf-8 -\*- # (c) 2012, Michael DeHaan \
相关文件
配置文件
/etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性(一般无需修改)
/etc/ansible/hosts 主机清单(将被管理的主机放到此文件)
/etc/ansible/roles/ 存放角色的目录
程序
/usr/bin/ansible 主程序,临时命令执行工具
/usr/bin/ansible-doc 查看配置文档,模块功能查看工具
/usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台
/usr/bin/ansible-playbook 定制自动化任务,编排剧本工具
/usr/bin/ansible-pull 远程执行命令的工具
/usr/bin/ansible-vault 文件加密工具
/usr/bin/ansible-console 基于Console界面与用户交互的执行工具
/etc/ansible/ansible.cfgdefaults
#inventory = /etc/ansible/hosts # 主机列表配置文件
#library = /usr/share/my_modules/ # 库文件存放目录
#remote_tmp = $HOME/.ansible/tmp # 临时py命令文件存放在远程主机目录
#local_tmp = $HOME/.ansible/tmp # 本机的临时命令执行目录
#forks = 5 # 默认并发数
#sudo_user = root # 默认sudo 用户
#ask_sudo_pass = True # 每次执行ansible命令是否询问ssh密码
#ask_pass = True
#remote_port = 22
#host_key_checking = False # 检查对应服务器的host_key,建议取消注释
#log_path=/var/log/ansible.log # 日志文件,建议启用
#module_name = command # 默认模块,可以修改为shell模块
暂时先启用日志文件
ansible是单次服务 不需要刷新配置文件之类的
主机清单 inventory
Inventory 主机清单
1> ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名
2> 默认的inventory file为/etc/ansible/hosts
3> inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成
/etc/ansible/hosts文件格式
inventory文件遵循INI文件风格,中括号中的字符为组名。
可以将同一个主机同时归并到多个不同的组中;
此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明
ntp.zking.com 不分组,直接加
webservers\] webservers组 www1.zking.com:2222 可以指定端口 www2.zking.com \[dbservers
如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机
示例:
websrvs
www[1:100].example.com ip: 1-100
dbsrvs
db-[a:f].example.com dba-dbff
ansible系列命令
Ansible系列命令
ansible ansible-doc ansible-playbook ansible-vault ansible-console
ansible-galaxy ansible-pull
ansible-doc: 显示模块帮助
ansible-doc [options] [module...]
-a 显示所有模块的文档
-l, --list 列出可用模块
-s, --snippet 显示指定模块的playbook片段(简化版,便于查找语法)
示例:
ansible-doc -l 列出所有模块
ansible-doc ping 查看指定模块帮助用法
ansible-doc -s ping 查看指定模块帮助用法
ansible命令
ansible通过ssh实现配置管理、应用部署、任务执行等功能,
建议配置ansible端能基于密钥认证的方式联系各被管理节点
ansible <host-pattern> [-m module_name] [-a args]
ansible +被管理的主机(ALL) +模块 +参数
--version 显示版本
-m module 指定模块,默认为command
-v 详细过程 --vv -vvv更详细
--list-hosts 显示主机列表,可简写 --list
-k, --ask-pass 提示输入ssh连接密码,默认Key验证
-C, --check 检查,并不执行
-T, --timeout=TIMEOUT 执行命令的超时时间,默认10s
-u, --user=REMOTE_USER 执行远程执行的用户
-b, --become 代替旧版的sudo切换
--become-user=USERNAME 指定sudo的runas用户,默认为root
-K, --ask-become-pass 提示输入sudo时的口令
ansible all --list 列出所有主机ping模块: 探测网络中被管理主机是否能够正常使用,走ssh协议
如果对方主机网络正常,返回pong
ansible-doc -s ping 查看ping模块的语法
检测所有主机的网络状态
1> 默认情况下连接被管理的主机是ssh基于key验证,如果没有配置key,权限将会被拒绝
因此需要指定以谁的身份连接,输入用户密码,必须保证被管理主机用户密码一致
ansible all -m ping -k
2> 或者实现基于key验证 将公钥ssh-copy-id到被管理的主机上 , 实现免密登录
ansible all -m ping
ssh远程连接
管理端和被管理端连接时基于ssh的 所以有两种连接方式
1)基于ssh口令
2)基于ssh证书(重点讲解)
如果想不需要运维人员干预 被管理端必须允许管理端证书免密登录
#管理端manage01生成ssh公私钥
root@manage01 \~\]# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: 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:aufJno2QjPK/V63/PVW13h5oWlKu0jk7HesXYTho0gM root@manage01 The key's randomart image is: +---\[RSA 2048\]----+ \| \| \| E .\| \| o . . o\| \| . = + +.\| \| S o.+ = +\| \| o o ...\* +o\| \| . . \* ....O o.+\| \| o . =.\*.B o +.\| \| ..o+B oo\*oo o\| +----\[SHA256\]-----+ #将公钥传给node1 \[root@manage01 \~\]# ssh-copy-id -i .ssh/id_rsa.pub [email protected] /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub" The authenticity of host '192.168.66.201 (192.168.66.201)' can't be established. ECDSA key fingerprint is SHA256:u+yOQz+E+eF7Oixdz/vClLXlAEu/7K8jy783gzk20dQ. ECDSA key fingerprint is MD5:c0:80:1b:ae:93:32:c2:66:f5:da:2f:1c:26:1e:7e:f8. Are you sure you want to continue connecting (yes/no)? yes /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 [email protected]'s password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh '[email protected]'" and check to make sure that only the key(s) you wanted were added. #将公钥传给node2 \[root@manage01 \~\]# ssh-copy-id -i .ssh/id_rsa.pub [email protected] /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub" The authenticity of host '192.168.66.202 (192.168.66.202)' can't be established. ECDSA key fingerprint is SHA256:X4JeiiFuwV0cja81veAyGCosriEfZm/zv34cfYkuxmU. ECDSA key fingerprint is MD5:7d:17:0f:80:d5:2b:30:ec:2c:62:f9:79:6b:fb:5f:bc. Are you sure you want to continue connecting (yes/no)? yes /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 [email protected]'s password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh '[email protected]'" and check to make sure that only the key(s) you wanted were added. #将公钥传给node3 \[root@manage01 \~\]# ssh-copy-id -i .ssh/id_rsa.pub [email protected] /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub" The authenticity of host '192.168.66.203 (192.168.66.203)' can't be established. ECDSA key fingerprint is SHA256:PtpsYBjaXkE+o3j8QYU5Ju8uPgcW2lVW8wsx4X1PV/c. ECDSA key fingerprint is MD5:50:a1:63:a0:ef:e7:61:26:11:25:ae:06:ec:93:cb:18. Are you sure you want to continue connecting (yes/no)? yes /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 [email protected]'s password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh '[email protected]'" and check to make sure that only the key(s) you wanted were added. 小窍门 免交互创建公私钥 \[root@manage01 ansible\]# ssh-keygen -f /root/.ssh/id_rsa -N "" -f 指定密钥存放路径 -N "" 新密码设置问空 -P "" 老密码是什么 如何可以非交互式传公钥呢 \[root@manage01 ansible\]# yum -y install sshpass \[root@manage01 ansible\]# sshpass -p123456 ssh-copy-id -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa.pub [email protected] sshpass 非交互式传密码 StrictHostKeyChecking 严厉的主机监测=no 就不会问你yes\|no了 测试证书是否生效 \[root@manage01 \~\]# for i in \`seq 201 203\`;do \> ssh [email protected].$i "hostname" \> done #!/bin/bash # 定义变量 USER="root" PASSWORD="123456" PUBLIC_KEY_FILE="/root/.ssh/id_rsa.pub" BASE_IP="192.168.66.1" ssh-keygen -f /root/.ssh/id_rsa -N "" # 循环遍历 IP 地址范围 1 到 10 for i in {47..49} do HOST="${BASE_IP}${i}" echo "设置免密 SSH for $USER@$HOST..." # 使用 sshpass 和 ssh-copy-id 命令来设置免密登录 sshpass -p "$PASSWORD" ssh-copy-id -o StrictHostKeyChecking=no -i "$PUBLIC_KEY_FILE" "$USER@$HOST" if \[ $? -eq 0 \]; then echo "设置成功 for $USER@$HOST." else echo "设置失败 SSH for $USER@$HOST." fi done
ansible的Host-pattern
ansible的Host-pattern
匹配主机的列表
All :表示所有Inventory中的所有主机
ansible all --list
* :通配符
ansible "*" --list (*表示所有主机)
ansible 192.168.66.* --list
ansible "*srvs" --list
或关系 ":"
ansible "websrvs:appsrvs" --list
ansible "192.168.66.10:192.168.66.20" --list
逻辑与 ":&"
ansible "websrvs:&dbsrvs" --list
在websrvs组并且在dbsrvs组中的主机
逻辑非 ":!"
ansible 'websrvs:!dbsrvs' --list
在websrvs组,但不在dbsrvs组中的主机
注意:此处为单引号
综合逻辑
ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' --list
正则表达式
ansible "websrvs:&dbsrvs" --list
ansible "~(web|db).*\.zking\.com" --m ping
websrvs
web1.zking.com ansible_host=192.168.66.10
web2.zking.com ansible_host=192.168.66.11
appsrvs
app1.zking.com ansible_host=192.168.66.20
app2.zking.com ansible_host=192.168.66.21
dbsrvs
db1.zking.com ansible_host=192.168.66.30
db2.zking.com ansible_host=192.168.66.31
ftpsrvs\]99 ftp1.zking.com ansible_host=192.168.66.40 ftp2.zking.com ansible_host=192.168.66.41 # 定义一个组合组,包含所有服务器 \[servers:children
websrvs
appsrvs
dbsrvs
ftpsrvs
使用别名
aliases
alias_web1 ansible_host=192.168.66.10
alias_app1 ansible_host=192.168.66.20
ansible命令执行过程
ansible命令执行过程
加载自己的配置文件 默认/etc/ansible/ansible.cfg
加载自己对应的模块文件,如command
通过ansible将模块或命令生成对应的临时py文件,
并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
给文件+x执行
执行并返回结果
删除临时py文件,sleep 0退出
执行状态:
绿色:执行成功并且不需要做改变的操作
黄色:执行成功并且对目标主机做变更
红色:执行失败
可以通过添加-v观察执行过程
颜色在配置文件中定义
ansible使用示例
以wang用户执行ping存活检测
ansible all -m ping -u wang -k
以wang sudo至root执行ping存活检测
ansible all -m ping -u wang -k -b
以wang sudo至mage用户执行ping存活检测
ansible all -m ping -u wang -k -b --become-user=mage
以wang sudo至root用户执行ls
ansible all -m command -u wang -a 'ls /root' -b --become-user=root -k -K
ansible ping模块测试连接
ansible 192.168.66.126,192.168.66.127 -m ping -k