SALT TRANSPORT - SaltStack的通信与传输

SALT TRANSPORT - Salt的通信与传输

Salt的基本功能之一是远程执行。 Salt有两个基本的“通道”用于与minions沟通。 每个通道都需要一个客户端(minion)和一个服务器(master)实现才能在Salt中工作。 这些通道对一起工作实现了通道接口所需的特定消息传递功能。

相同内容,也可以参见这份github上的资料:SALT TRANSPORT - Salt的通信与传输

PUB CHANNEL

pub channel, 或是称为 publish channel,是一个master服务节点将作业(有效负载)发送给minions的工作方式。 这是一个基本的pub/sub模式,它具有特定的目标语义。 通过publish系统发布的所有数据都会被加密处理,以便只有Salt集群的成员才能解密发布的信息。

REQ CHANNEL

req channel是minions将数据发送给master的方式。 此接口主要用于获取文件和返回作业结果。 在与master设备通信时,req channel有两个基本接口。 send是加密处理消息发送的基本方法,只有连接到同一master服务器的minions才能读取它,但不能保证minion-master通信的机密性。另外有crypted_transfer_decode_dictentry方法可以确保minion-master的机密通信。

ZEROMQ TRANSPORT

注意:Zeromq 是Salt目前默认使用的传输方式。

Zeromq是一个消息通信库,得到了多种语言的支持。 Zeromq实现了一个用于消息传递的socket接口,具有一套socket类型的特定语义。

PUB CHANNEL

pub channel使用zeromq的pub/sub套接字实现。 默认情况下,我们不使用zeromq的过滤器功能,在使用zeromq filtering功能时所有发布作业都会发送到所有minions,然后由minion端过滤后使用。 Zeromq也提供了在publish端过滤的功能,这可以在salt中通过配置zmq_filtering启用。

REQ CHANNEL

req channel是使用zeromq的req/rep套接字实现的。 在这些套接字上强制执行send/recv模式,强制salt通过这些套接字对序列化消息。 这意味着虽然接口在minion上是异步的,但是在我们收到第一条消息的回复之前,不能发送第二条消息。

TCP TRANSPORT

tcp传输是使用原始tcp套接字实现Salt的通信通道。 由于这不是通过预定义的消息传递库实现的,因此我们将在本文档中对通信协议和消息语义等做简单介绍。

通过在每个Salt minion和Salt master上将transport参数更改为tcp来启用tcp传输功能。

transport: tcp

警告:目前我们建议在使用了Salt Syndics功能时,保证所有Masters和Minions节点都使用相同的传输设置。 我们收到了一些在非常重的负载下使用混合传输类型时的错误报告,并且正在做进一步的分析研究。

WIRE PROTOCOL

TCP上的这种实现侧重于绝对效率之上的灵活性。 这意味着我们需要花费几个字节的传输线路空间来提高未来的灵活性。 话虽这么说,wire framing非常有效,看起来像:

msgpack({'head': SOMEHEADER, 'body': SOMEBODY})

由于msgpack是一个经过迭代解析处理的序列化数据,我们可以简单地将序列化的有效负载写入线路。 在该有效载荷内,我们有两个属性“head”和“body”。 Head包含标题信息(例如“message id”)。 body包含我们发送的实际消息。 通过这种灵活的线路协议,我们可以实现我们想要的任何消息语义——包括在单个socket上传递的多路复用消息。

TLS SUPPORT

New in version 2016.11.1.

TCP传输允许将 master/minion通信包装在TLS连接中。 启用它很简单,master和minion需要使用tcp连接,然后启用ssl选项。 ssl选项作为dict传递,对应于传递给Python ssl.wrap_socket函数的选项。

一个简单的设置如下所示,在Salt Master上将ssl选项添加到master配置文件中:

ssl:
  keyfile: <path_to_keyfile>
  certfile: <path_to_certfile>
  ssl_version: PROTOCOL_TLSv1_2

minion配置文件中的ssl选项的最小化配置如下所示:

ssl: True
# Versions below 2016.11.4:
ssl: {}

特定选项也可以发送给minion,如Python ssl.wrap_socket函数中所定义。

注意:虽然设置ssl_version不是必需的,但我们建议使用它。 一些旧版本的python不支持最新的TLS协议,如果您的python版本就是这种情况,我们强烈建议您升级您的Python版本。

CRYPTO

当前实现中使用的是与zeromq传输相同的加密方法。

PUB CHANNEL

对于pub channel,我们发送没有“message ids”的消息,远程端将其解释为单向发送。

注意:截至当前,我们将所有publishes发送给所有minions,并依赖于minion-side进行过滤。

REQ CHANNEL

对于req channel,我们发送带有“message id”的消息。 这个“message id”允许我们在套接字上多路复用消息。

THE RAET TRANSPORT

注意:RAET传输处于早期开发阶段,虽然功能齐全,但尚未就其可靠性或安全性做出承诺。 至于可靠性和安全性,使用的加密已经过审核,我们的测试显示raet是可靠的。 据此,我们仍在进行更多的安全审计并提高可靠性。 本文档概述了RAET中使用的加密

New in version 2014.7.0.

Reliable Asynchronous Event Transport(RAET)是一种专门为Salt开发的替代传输介质。 它被设计为允许在应用层上进行排队,并提供套接字层加密。 它还对套接字层的大量控制逻辑做了抽象,并且使得调度错误和异常变得更加容易。

RAET还提供非常强大的消息路由功能,允许在单个机器上的进程之间路由消息,直到多台机器上的进程。 也可以对消息路由进行限制,允许进程从特定源发送特定类型的消息,从而允许建立起信任关系。

USING RAET IN SALT

在Salt中使用RAET很容易,主要区别在于核心依赖性发生变化,不再需要pycrypto,M2Crypto,ZeroMQPYZMQ,而是需要依赖于libsodium,libnacl,iofloraetlibnacl非常干净地处理加密,而排队和流量控制由ioflo处理。 libsodium可以从源代码轻松安装,或者许多发行版都可以为其提供安装软件包。 libnacl和ioflo软件包可以从pypi轻松安装, distribution packages正在开发中。

安装新的deps后,需要安装2014.7版或更高版本的Salt。

安装后,需要修改minion和master的配置文件以将传输设置为raet
/etc/salt/master:

transport: raet

/etc/salt/minion:

transport: raet

现在像往常那样启动salt,,minion将连接到master并共享长期密钥,然后可以通过salt-key进行管理。 远程执行模块和Salt states状态管理的运行方式与Salt over ZeroMQ相同。

LIMITATIONS

RAET 2014.7版本尚未完成! Syndic和Multi Master尚未完成,预计将在2015.5.0版本中完成。

此外,Salt-Raet允许对客户端进行更多控制,但这些hooks尚未实现,因此客户端仍然使用与ZeroMQ客户端相同的系统。 这意味着RAET实现的额外可靠性尚未在CLI客户端中实现。

WHY?

CUSTOMER AND USER REQUEST

为什么要为Salt要做替代的传输方案? 原因有很多,但主要动机来自客户要求,许多大公司都提出了通过替代传输方案运行Salt的请求,其原因各不相同,从性能和规模改进到许可问题都有。 这些客户与SaltStack合作,使RAET成为现实。

MORE CAPABILITIES

RAET旨在让Salt具有更强的通信能力。 它被设计为允许开发一些ZeroMQ拓扑架构所无法匹配的功能。

许多提议的功能仍处于开发阶段,并将在进入概念验证阶段时公布,这些功能包括salt-fuse,一个salt filesystem系统,salt-vt - 在salt传输上实现的并行api驱动的shell以及许多其他功能。

RAET RELIABILITY

RAET是可靠的,也正是因此而命名(可靠的异步事件传输)。

一些人对RAET可靠性的担忧是基于RAET使用UDP而不是TCP并且UDP没有内置协议可靠性这一事实。

RAET本身实现了UDP中本身不存在的又需要使用的可靠性层,这使得RAET能够以保持可靠和异步的方式动态优化数据包的传送。

RAET AND ZEROMQ

使用RAET时,不需要ZeroMQ。 RAET是一个完整的网络实现方案。 值得注意的是,RAET并非一般意义上的替换ZeroMQ,ZeroMQ结构不会在RAET中做重新实现,而是以特定于Salt需求的方式实现。

RAET是真正的基于异步连接上实现的异步通信层,默认为UDP。 ZeroMQ则是通过TCP通信实现并在套接字层中抽象异步构造。

Salt没有放弃ZeroMQ支持,也没有计划立即这样做。

ENCRYPTION

RAET使用Dan Bernstein的NACL加密库和CurveCP handshake。 libnacl python binding绑定到libsodium和tweetnacl以执行底层加密。 这使我们完全依赖外部开发的加密系统。

PROGRAMMING INTRO

Intro to RAET Programming

注意:该章节的资料还在完善中。

要讨论的第一件事是RAET没有提供一个socket api,它提供的是queueing api,RAET中的所有消息都可用于通过队列通信。 这是RAET与其他网络库相比最具差异化的因素。不是创建套接字,而是创建堆栈。 不是调用send()或recv(),而是将消息放在要发送的堆栈上,并将接收的消息显示在堆栈中。

支持可以使用不同类型的堆栈,目前存在两个堆栈,UDP堆栈和UXD堆栈。 UDP堆栈用于通过udp sockets进行通信,UXD堆栈用于通过Unix Domain Sockets进行通信。

UDP堆栈运行用于通过网络进行通信的上下文,而UXD堆栈具有用于进程之间通信的上下文。

UDP Stack Messages

要在RAET中创建UDP堆栈,只需创建堆栈、管理队列和处理消息:

from salt.transport.road.raet import stacking
from salt.transport.road.raet import estating

udp_stack = stacking.StackUdp(ha=('127.0.0.1', 7870))
r_estate = estating.Estate(stack=stack, name='foo', ha=('192.168.42.42', 7870))
msg = {'hello': 'world'}
udp_stack.transmit(msg, udp_stack.estates[r_estate.name])
udp_stack.serviceAll()

猜你喜欢

转载自blog.csdn.net/watermelonbig/article/details/90458662