图片 3

SaltStack部署

京东物流系统自动化运维平台技术揭密,物流系统揭密

自动化工具比较

Puppet也许是四款工具中最深入人心的。就可用操作、模块和用户界面而言,它是最全面的。Puppet呈现了数据中心协调的全貌,几乎涵盖每一个运行系统,为各大操作系统提供了深入的工具。初始设置比较简单,只需要在需要加以管理的每个系统上安装主服务器和客户端代理软件。命令行接口(CLI)简单直观,允许通过puppet命令下载和安装模块。然后,需要对配置文件进行更改,好让模块适合所需的任务;应接到指令的客户端与主服务器联系时,会更改配置文件,或者客户端通过立即触发更改配置文件的推送(push)来进行更改。

Ansible关注的重点是力求精简和快速,而且不需要在节点上安装代理软件。因此,Ansible通过SSH执行所有功能。需要管理的节点被添加到Ansible配置环境,SSH授权密钥被附加到每个节点上,这与运行Ansible的用户有关。一旦完成了这步,Ansible主服务器可以通过SSH与节点进行通信,执行所有必要的任务。Ansible可以使用Paramiko(基于SSH2协议的Python实现)或标准SSH用于通信,不过还有一种加速模式,允许更快速、更大规模的通信。

Salt类似Ansible,因为它也是基于CLI的工具,采用了推送方法实现客户端通信。它可以通过Git或通过程序包管理系统安装到主服务器和客户端上。客户端会向主服务器提出请求,请求在主服务器上得到接受后,就可以控制该客户端了。Salt可以通过普通的SSH与客户端进行通信,但如果使用名为minion的客户端代理软件,可以大大增强可扩展性。此外,Salt含有一个异步文件服务器,可以为客户端加快文件服务速度,这完全是Salt注重高扩展性的一个体现。与Ansible一样,你可以直接通过CLI,向客户端发出命令,比如启动服务或安装程序包;你也可以使用名为state的YAML配置文件,处理比较复杂的任务。还有“pillar”,这些是放在集中地方的数据集,YAML配置文件可以在运行期间访问它们。

总结:个人观点puppet最大缺点就是默认情况下Agent每隔30分钟向master同步状态,master主动推送功能比较薄弱(2.7版本),ansible基于SSH服务执行,如果服务器过多不建议使用,他是使用轮训的方式。Salt基于消息队列。性能相当好,适合大量生产环境。

一、基础介绍

作者:赵玉开,十年以上互联网研发经验,2013年加入京东,在运营研发部任架构师,期间先后主持了物流系统自动化运维平台、青龙数据监控系统和物流开放平台的研发工作,具有丰富的物流系统业务和架构经验。在此之前在和讯网负责股票基金行情系统的研发工作,具备高并发、高可用互联网应用研发经验。

简单来理解,自动化运维就是要通过机器的方式来简化整体的运维过程,特别是优化重复类型的工作,以提高运维效率,减少因人工而引起的失误操作。随着运维管理的复杂度和难度增大,自动化运维也基本成为了运维平台演进的必经之路。但如何落地自动化运维平台,不同的企业因为运维发展阶段和业务体量的不同,都有不一样的实现路径。

以京东为例,它的物流系统有很多分支机构,
比如仓库、分拨中心、转运中心等,
业务复杂的分支机构可能会有自己的信息系统,
这些信息系统往往分布式地部署到全国各地,那如何基于自动化运维平台管理好这些分支机构的服务器、
信息系统, 降低因为地域分布造成的运维维护成本呢?京东资深架构师赵玉开向
InfoQ
记者深入介绍了他们在自动化运维平台方面的一些探索和实践。另外,赵玉开也将会在
9 月 10 日举行的 CNUTCon 全球运维技术大会 上分享相关话题,欢迎关注。

InfoQ:可以先介绍下目前京东物流系统自动化运维平台的一些基本情况吗?

赵玉开: 京东物流系统自动化运维平台从 2014
年开始启动到现在已经历了三各阶段,到目前管理了 MySQL、JMQ、 Redis
及自研应用等多种实例。

众所周知,京东业务发展迅猛,每周都需要开仓,数量多达十几个。最初开仓过程特别冗长和复杂,开仓过程中涉及到研发人员部署系统、运营人员手动填写多种申请、运维人员不仅要负责中间件安装,还要负责整个流程中每个环节的进展确认及协调,这直接导致了开仓慢,且涉及到的各部门都需要投入大量的人力成本。

基于此,2014 年初我们启动了一期自动化运维平台研发的项目,2014 年 10
月项目一期上线时,已基本解决了开仓慢和人力成本的问题,也减少了开仓过程中运维同学的重复性工作内容,制定标准化模板,解放了研发人员的重复性部署工作。运营人员可通过模板直接设置,将之前一些繁琐的密码、JMQ
Token 等数据实现自动化配置,大大减少了流程耗费的时间。

一期上线后,得到了流程中各环节涉及部门的赞赏,并在得到大家积极反馈后,迅速进入到二期项目。二期项目完成后,数据的初始化问题和研发日常批量部署问题也得到了解决,系统的自动化程度已可以满足日常的工作需求。

今年初,为接入更多物流作业单位,如分拣中心,
亚洲一号自动化物流中心等,我们开启了三期项目,目前项目还在持续前行中。

InfoQ:谈谈你们的自动化运维架构?以及具体涉及到的技术栈?

赵玉开: 我们的自动化运维的核心组件是 SaltStack, 我们基于 SaltStack
做了很多自定义的模块、Grains 和 Runner, 通过这些自定义的模块、Grains
以及 Runner 来支撑我们的开仓、部署、数据同步等功能。

如下图是一个指令执行过程图, 分为两个部分, 上面部分为部署在 IDC
的模块, 下半部分则是部署在库房机房的模块。

我们先逐个介绍部署在 IDC 部分的模块:

  1. Web 使用 Java 技术, 为用户提供操作界面, 控制操作权限, 使用
    Activiti 工作流引擎驱动各种流程, 下发开仓过程中的自动化运维指令;

  1. Salt-API-Proxy 是 Salt-API 的代理层, 通过 Nginx 实现了反向代理, 在
    Nginx 的配置中对发送指令的服务器 IP 做了限制,
    另外可以通过配置指向工作的 Salt-API 服务器;

  1. Salt-API 负责和 Salt-Master 交互发送 SaltStack 的 Runner 与 Module
    的 API 指令, Runner 指令是运行在 Salt-Master 服务器上的, 可以读取
    master 配置, 也可以在一个 Runner 中协调执行多个 Module 运行结果;

  1. Salt-Master 有两个职责, 一是接受 salt-api 指令, runner
    在本地执行, module 下发指令到对应的 salt-minion,
    另一职责是运维同学手动下发指令, 完成一些非常见的 minion 配置工作;

  2. RsyncServer 负责中间件安装文件, 自研软件的文件存储和下发,
    RsyncServer 的文件存储是由 Salt-Master 发起的, Salt-Master 接受到
    salt-api 的应用部署指令后, 会从部署指令中获得部署包下载地址,
    然后下载到指定部署包存储目录, 并做解压操作; RsyncServer
    的文件下发指令则是有 salt-minion 端的 Module 执行触发的。

仓库部门和 IDC 之间通过 VPN 联通, 每个仓库的服务器上都安装了 SaltStack
的 minion 端, minion 端是一个 Python 进程, 负责接收 Master 的 Module
指令, 并在本地执行。另外 minion
端在执行指令过程中需要将执行过程中的输出及时的输出给用户端,
让用户可以通过 Web 端查看执行过程的情况, 即运维的可视化, 我们是通过
minion 端的可视化模块, 将执行过程输出通过 HTTP POST 方式发送给 Web 端,
Web 端将 POST 内容存储到任务执行过程输出表中,
前端通过轮询方式读取输出表中的增量消息显示给用户端。

我们采用的技术栈是 Java + Python。  前端界面展示、
工作流、权限控制、任务下发这些都是用的 Java 的 Spring MVC + MyBatis;
后端用的是 Python + Shell, Python 写了大量的 SaltStack 自定义模块。

InfoQ:为什么当初要选择 SaltStack 而没有选择 Ansible?

赵玉开: 不可否认 Ansible 也是一个非常好的自动化运维工具,
但是基于以下两点我们最终选择了 SaltStack:

  1. API 的易用性方面和 SaltStack 有差距,
    我们的自动化运维系统一开始就有一个目标,
    将开仓部署以及推广版本这些功能开放给物流运营人员,
    所以必须做好前端用户体验, 这需要好用的 API, SaltStack 恰好有;

  1. 性能,标准 SSH 连接的时候比较耗时,ZeroMQ 传输的速度会快很多。

InfoQ:在应用部署自动化这块,你们是怎么做的?

赵玉开: 应用部署大致分为这么几个步骤:
打包、下发文件、更新配置、停止启动实例、备份部署版本, 具体如下。

  1. 我们使用的公司统一的打包系统, 打包系统打好包,
    部署任务审批通过,自动化运维系统就可以通过 API 获得打包文件,
    然后将部署包上传到版本服务器, 并解压缩,放到对应版本目录下;

  1. 通过 SaltStack 的 API 下发部署指令给部署目标服务器, 部署指令是一个
    SaltStack 自定义模块, 该模块首先会执行 rsync
    指令从版本服务器上同步变更文件;

  1. 文件下发之后更新配置, 通过 Web 接口请求自动化运维的 Web
    端下发配置文件, 然后更新配置文件,
    我们线上的配置文件是通过环境变量来配置的, 所以不管有多少个库房,
    都不需要更新配置文件, 只有在特殊需求是设置环境变量,
    就可以依据当前作业单位的不同改变下发的配置文件的内容;

  1. 调用应用的 stop.sh 脚本停止当前实例, 再调用 start.sh 脚本启动实例,
    这里有一个约定, 不管是 Web 应用还是非 Web 应用必须在部署目录有一个
    bin 目录下面有 start.sh 和 stop.sh 两个文件;

  2. 如果步骤 4 执行成功, 那么将此版本的文件备份到当前服务器上,
    以备回滚使用。

InfoQ:自动化运维解决了你们哪些问题?没有解决哪些问题?

赵玉开: 自动化运维解决了我们开仓周期长,人力成本高的问题,
提升了全国部署推广的效率, 大大减少了运维同事的重复性工作,
把对成熟版本的推广工作交给了运营人员,
减少了研发同事在推广上线工作上的时间。

现阶段正在探索如何通过自动化运维技术快速排查问题,
另外就是我们未来会有一些自动化的物流作业单位,如何用自动化运维平台管理好这些自动化的设备和设备软件也是我们在探索的。

InfoQ:自动化运维平台上线了这么长时间,有做过复盘吗?有哪些经验可以分享给读者?未来有什么计划?

赵玉开: 做过一些复盘, 每一期开发结束下一迭代开始的时候都会做复盘,
对现有问题进行总结, 同时收集下一步的需求。 
目前看最深刻的体会是做自动化运维系统一定要做好元数据的管理,元数据要管理好服务器信息属性、
应用信息、应用配置、实例管理以及作业单位, 这些元数据要在一开始就做好,
能自动化收集的要自动化收集, 动态的参数一定要动态控制, 比如
Redis、MySQL 都有主从关系, 元数据中要存储这个主从关系, 但是不能写死,
必须有机制来更新主从关系, 否则 Redis 哨兵程序更新了 Redis 主从关系,
或者 MySQL DBA 因为某些原因切换了 MySQL 的主从,
自动化运维系统的元数据没有做对应更新,再执行指令时就会出问题,
甚至发生事故。

未来计划有两个方面:

  1. 继续通过自动化运维系统来提升运维效率、 降低研发对应用运维的投入;

  1. 做自动化物流作业系统的自动化运维, 管好其中的设备和软件服务。

InfoQ:在 CNUTCon 全球运维技术大会 上,你将会为读者分享哪些技术点?

赵玉开: 这次大会我会给大家介绍下京东物流自动化运维平台的技术架构,
并详细介绍自动化开仓、批量部署的技术细节。


CNUTCon 全球运维技术大会将于 9 月 10-11
日在上海举行,大会以“智能时代的新运维”为主题,涵盖
AIOps、SRE、DevOps、运维监控与安全等专场,邀请了来自
Google、Uber、eBay、BAT、携程、京东等公司大咖分享他们在最新运维技术实践过程中遇到的坑与经验,现场为你解疑答惑,点击“阅读原文”了解更多精彩!9
折限时优惠,报名时输入 CNUTCon-KAITAO 还可再减 200 !

SaltStack简介与特性

SaltStack 是一种基于 C/S 架构的服务器基础架构集中化管理平台,管理端称为
Master,客户端称为 Minion。SaltStack
具备配置管理、远程执行、监控等功能,一般可以理解为是简化版的 Puppet
和加强版的 Func。SaltStack 本身是基于 Python
语言开发实现,结合了轻量级的消息队列软件 ZeroMQ 与 Python
第三方模块(Pyzmq、PyCrypto、Pyjinjia2、python-msgpack 和 PyYAML
等)构建。

通过部署 SaltStack
环境,运维人员可以在成千上万台服务器上做到批量执行命令,根据不同的业务特性进行配置集中化管理、分发文件、采集系统数据及软件包的安装与管理等。

1、简介

SaltStack是一个服务器基础架构集中化管理平台,具备配置管理、远程执行、监控等功能,一般可以理解为简化版的puppet和加强版的func。SaltStack基于Python语言实现,结合轻量级消息队列(ZeroMQ)与Python第三方模块(Pyzmq、PyCrypto、Pyjinjia2、python-msgpack和PyYAML等)构建。

通过部署SaltStack环境,我们可以在成千上万台服务器上做到批量执行命令,根据不同业务特性进行配置集中化管理、分发文件、采集服务器数据、操作系统基础及软件包管理等,SaltStack是运维人员提高工作效率、规范业务配置与操作的利器。

SaltStack 具有以下特性:

1、部署简单、方便;

2、支持大部分UNIX/Linux及Windows环境;

3、主从集中化管理;

4、配置简单、功能强大、扩展性强;

5、主控端(master)和被控端(minion)基于证书认证,安全可靠。

6、支持API及自定义模块,可通过Python轻松扩展。

2、特性

(1)、部署简单、方便;
(2)、支持大部分UNIX/Linux及Windows环境;
(3)、主从集中化管理;
(4)、配置简单、功能强大、扩展性强;
(5)、主控端(master)和被控端(minion)基于证书认证,安全可靠;

(6)、支持API及自定义模块,可通过Python轻松扩展。

图片 1

SaltStack 的工作原理

SaltStack 采用 C/S
结构来对云环境内的服务器操作管理及配置管理。为了更好的理解它的工作方式及管理模型,将通过图形方式对其原理进行阐述。

SaltStack
客户端(Minion)在启动时,会自动生成一套密钥,包含私钥和公钥。之后将公钥发送给服务器端,服务器端验证并接受公钥,以此来建立可靠且加密的通信连接。同时通过消息队列
ZeroMQ 在客户端与服务端之间建立消息发布连接。具体通信原理图,如图 1
所示,命令执行如图 2 所示:

图片 2

专业术语说明:

Minion 是 SaltStack 需要管理的客户端安装组件,会主动去连接 Master
端,并从 Master 端得到资源状态信息,同步资源管理信息。

Master 作为控制中心运行在主机服务器上,负责 Salt
命令运行和资源状态的管理。

ZeroMQ 是一款开源的消息队列软件,用于在 Minion 端与 Master
端建立系统通信桥梁。

Daemon
是运行于每一个成员内的守护进程,承担着发布消息及通信端口监听的功能。

图片 3

原理图说明:

Minion 是 SaltStack 需要管理的客户端安装组件,会主动去连接 Master
端,并从 Master 端得到资源状态信息,同步资源管理信息。

Master 作为控制中心运行在主机服务器上,负责 Salt
命令运行和资源状态的管理。

Master 上执行某条指令通过队列下发到各个 Minions 去执行,并返回结果。

3、Master与Minion认证

(1)、minion在第一次启动时,会在/etc/salt/pki/minion/(该路径在/etc/salt/minion里面设置)下自动生成minion.pem(private
key)和 minion.pub(public key),然后将 minion.pub发送给master。

(2)、master在接收到minion的public key后,通过salt-key命令accept minion
public
key,这样在master的/etc/salt/pki/master/minions下的将会存放以minion
id命名的 public key,然后master就能对minion发送指令了。