从Tuxedo运维走向Kubernetes运维

JetLee 发表了文章 • 0 个评论 • 141 次浏览 • 2019-05-29 09:38 • 来自相关话题

【编者的话】Tuxedo作为一款成熟的交易中间件,具有强大的交易处理性能、高度的可靠性和无限的伸缩性。Kubernetes作为新兴容器编排调度引擎,基于容器技术,实现资源管理的自动化以及跨多个数据中心的资源利用率最大化。前者以交易事务管理闻名,后者以容器编排著 ...查看全部
【编者的话】Tuxedo作为一款成熟的交易中间件,具有强大的交易处理性能、高度的可靠性和无限的伸缩性。Kubernetes作为新兴容器编排调度引擎,基于容器技术,实现资源管理的自动化以及跨多个数据中心的资源利用率最大化。前者以交易事务管理闻名,后者以容器编排著称。无论是Tuxedo还是Kubernetes,其运行离不开网络、设备及存储等基础设施的支撑。

本文重点对运行于基础设施之上两者运行特点进行分析对比,使具有Tuxedo运维经验的运维人员对Kubernetes有进一步的了解,给后续Kubernetes运维提供参考借鉴。
#Tuxedo

1.jpg

Tuxedo ATMI体系架构图

大多数Tuxedo应用都是采用ATMI来实现运行环境和编程接口的,其体系架构如上图所示,整个架构划分为外部接口和内部服务层两个部分。外部接口层的基础是ATMI层,之上是Client。Tuxedo服务层包括通讯模型、管理信息库(MIBs)、应用服务器及管理服务器等。通讯模型指的是Tuxedo客户端和服务端、Tuxedo服务端与服务端之间传递消息的模型。管理信息库为其他应用程序管理和配置Tuxedo系统提供接口,通过该接口,使用人员可以对Tuxedo配置信息进行动态调整及对其运行状态进行实时监控(如某些系统通过MIBs获取Tuxedo队列地址、队列深度等实现流量控制)。应用服务为ATMI应用程序提供了数路由、编码、负载均衡和命名服务等。管理服务为ATMI应用程序提供事件、安全等服务。
##Kubernetes

Kubernetes作为一个开源的大规模容器集群管理软件,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部属容器化的应用简单并且高效,Kubernetes提供了应用部署、规划、更新和维护的一种机制。典型Kubernetes架构图如下所示:
2.jpg

典型Kubernetes架构图

如上图所示,Kubernetes将集群中的机器划分为一个Master节点和一群工作节点(Node)。其中,在Master节点上运行着集群管理相关的一组进程:kube-apiserver、kube-controller-manager、kube-scheduler、etcd和kube-ctl。这些进程实现了整个集群的资源管理、Pod调度、弹性伸缩、安全控制、系统监控和纠错等管理功能,并且都是全自动完成的。Node作为集群中的工作节点,运行真正的应用程序,在Node上Kubernetes管理的最小运行单元是Pod。Node上运行着Kubernetes的kubelet、kube-proxy、docker和kube-ctl,这些服务进程负责Pod的创建、启动、监控、重启、销毁,以及实现软件模式的负载均衡器。如果你想和更多Kubernetes技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态

上面对Tuxedo和Kubernetes的基本架构和组成要素进行了简要介绍,下面通过如下几个方面对两者进行对比分析:
##运行态

应用程序要正常运行并提供服务,除了依赖的底层基础设施(如网络、服务器、存储等)外,还依赖应用本身的可执行文件及对应配置文件。基于Tuxedo应用在生产部署及运行时主要依赖应用程序包(可执行文件)、配置文件(ubb和bdm),基于Kubernetes应用在生产部署及运行时同样主要依赖应用程序包、配置文件(YAML或ConfigMap)。二者均通过配置文件和执行文件的组合,实现了服务的正常运行、服务(或服务数)控制或弹性伸缩、负载均衡、容错、监控检测等功能。Tuxedo中进程或可执行文件做为服务的载体,其在

Tuxedo配置文件主要参数如下所示(节选):
*RESOURCES  

……

LDBAL Y 负载均衡

SCANUNIT 10 健康检查控制

SANITYSCAN 12

*MACHINES

gumby LMID=SITE1

……

APPDIR=”/usr/apps/bin” 可执行程序目录

……

*SERVERS

DEFAULT: RESTART=Y MAXGEN=5 GRACE=3600 容错控制

TLR SRVGRP=BANKB1 SRVID=10 MIN=1 MAX=2 副本控制

RQADDR=QNAME REPLYQ=Y -p [L][low_water][,[terminate_time]][:[high_water][,create_time]] 弹性伸缩控制

……

*SERVICES

SRVGRP=BANKB1

LOAD=25 PRIO=70 负载因子及优先级控制

Kubernetes配置文件主要参数如下所示(节选):
……

metadata:

name: nginx

spec:

replicas: 2 副本数

……

spec:

restartPolicy:Always 重启策略

container:

- name: nginx

image: nginx 镜像

livenessProbe: 健康检查

httpGet:

……

initialDelaySeconds: 15 表明第一次检测在容器启动后多长时间后开始

timeoutSeconds: 1 检测的超时时间

……

##弹性伸缩

对于一些和电商促销或外部行情紧密相关系统,其业务量随着促销或行情变化出现交易高峰,待促销结束或行情稳定后,业务量又快速回落。无论是基于Tuxedo的应用还是基于Kubernetes应用,均提供弹性伸缩功能。

基于Tuxedo应用通过在ubb中配置min、max值,以及队列深度基线值,可实现服务数随业务量变化而动态扩缩容(当然也可通过手工方式快速增加或减少服务),也即Tuxedo是基于业务量进行扩缩容。具体配置如下:
*SERVERS

BillServer SRVGRP=GROUP1 SRVID=1 MIN=2 MAX=4

RQADDR=QNAME REPLYQ=Y -p [L][low_water][,[terminate_time]][:[high_water][,create_time]]

如果MAX>1,并且使用了MSSQ(RQADDR, RQPERM)的Server可以配置-p来控制进程的动态增加和减少。控制算法如下:如果请求队列中的请求个数大于high_water 后超过create_time 秒,就增加该服务的一个新进程;如果请求队列中的请求个数小于low_water后超过terminate_time秒,就停止该服务的一个进程。low_water缺省是平均每个服务进程有一个请求消息或者workload 50;high_water 缺省是平均每个服务进程有两个请求消息或者workload 100。create_time 缺省最小是50秒, and terminate_time 缺省最小是60秒。

基于Kubernetes应用,通过Kubernetes的HPA(Horizontal Pod Autoscaler)实现Pod横向自动扩容(Kubernetes管理最小单位为Pod)。属于一种Kubernetes资源对象。通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性的调整目标Pod的副本数。HPA可以根据CPU使用率或应用自定义metrics自动扩展Pod数量(也即Kubernetes基于系统资源进行扩缩容)。
3.png

HPA自动扩缩容示意图

工作流程:

  1. 创建HPA资源(通过编写YAML文件进行创建),设定目标CPU使用率限额,以及最大、最小实例数;
  2. 控制管理器每隔30s(可以通过–horizontal-pod-autoscaler-sync-period修改)查询metrics的资源使用情况;
  3. 然后与创建时设定的值和指标做对比(平均值之和/限额),求出目标调整的实例个数;
  4. 目标调整的实例数不能超过1中设定的最大、最小实例数,如果没有超过,则扩容;超过,则扩容至最大的实例个数;

重复2-4步。

基于Tuxedo的应用和Kubernetes应用,在弹性伸缩方面有相同处,也有不同处。相同点为两者通过弹性伸缩可以控制运行服务数量,有效应对业务的突变,不同之处为Tuxedo弹性伸缩(以及负载、服务发现、容错等)均在原服务器(原Node、原IP)上进行,而Kubernetes的扩缩容与服务器(原Node、原IP)没有绑定关系,可以跨Node伸缩、容错,IP也会发生改变。

在Kubernetes中,Node节点可以在运行期间动态增加到Kubernetes集群中,在默认情况下kubelet会向Master节点注册自己。一旦Node被纳入集群管理范围,Master可以根据负载情况将部分流量负载到新加入Node节点。而在Tuxedo中,SHM模式中不具备类似Kubernetes中Node节点的扩容,在MP模式下动态增加节点也相对比较复杂。
##容错和故障隔离

对线上业务来说,保证服务的正常稳定是重中之重,对故障服务的及时处理避免影响业务以及快速恢复一直是开发运维的难点。无论Tuxedo还是Kubernetes都提供了健康检查服务,对于检测到故障服务会被及时自动下线,以及通过重启服务的方式使服务自动恢复。Tuxedo和Kubernetes依据配置文件(ubb或yaml)配置策略,按照约定间隔对应用服务进行探测,在约定时间段内探测失败则进行重启或隔离。Tuxedo的容错和故障隔离既可基于服务级别,也可基于节点级别(仅针对集群部署模式,目前集群部署模式较少)。Tuxedo具体配置如下:
……

*RESOURCES

MASTER SITE1,SITE2//site2为备用Master,site1宕机了site2顶替

MODEL MP //模式是multiple machine

OPTIONS LAN //置为lan,这和MP配对使用

SCANUNIT 10 // 健康检查控制

SANITYSCAN 12

*MACHINES

"node1"//master主机名

LMID=SITE1

"node2"//从主机主机名

LMID=SITE2

*GROUPS

APPGRP1

LMID=SITE1 GRPNO=1

APPGRP2

LMID=SITE2 GRPNO=2

*NETWORK//配置集群不可少的网络配置

SITE1

NADDR="//IP1:port1-1"//bridge进程使用的网络地址及端口

NLSADDR="//IP1:port1-2"//tlisten进程使用的网络地址及端口

SITE2

NADDR="//IP2:port2-1"

NLSADDR="//IP2:port2-2"

*SERVERS

DEFAULT: RESTART=Y MAXGEN=5 GRACE=3600 //容错控制

server SRVID=10 SRVGRP=APPGRP1

server SRVID=20 SRVGRP=APPGRP2

Tuxedo按照探测间隔,定期对相关服务或节点进行健康检查,发现某个服务异常(coredump)后会自动拉起该服务,如果发现某个节点异常后会自动将该节点从集群中剔除,通过这种方法实现容错和故障隔离功能。

Kubernetes采用Liveness和Readiness探针进行健康检查,其中Liveness探针主要用于判断Container是否处于运行状态,比如当服务crash或者死锁等情况发生时,kubelet会kill掉Container, 然后根据其设置的restart policy进行相应操作,而Readiness探针主要用于判断服务是否已经正常工作,如果服务没有加载完成或工作异常,服务所在的Pod的IP地址会从服务的endpoints中被移除,也就是说,当服务没有ready时,会将其从服务的load balancer中移除,不会再接受或响应任何请求。具体配置如下:
……

spec:

restartPolicy:Always 重启策略

……

livenessProbe: 健康检查

httpGet:

path: /health

port: 8080

initialDelaySeconds: 15 表明第一次检测在容器启动后多长时间后开始

timeoutSeconds: 1 检测的超时时间

……

Kubernetes具体容错和故障隔离流程如下:
  1. 如果服务的健康检查(Readiness)失败,故障的服务实例从service endpoint中下线,外部请求将不会再转发到该服务上,一定程度上保证正在提供的服务的正确性,如果服务自我恢复了(比如网络问题),会自动重新加入service endpoint对外提供服务。
  2. 如果设置了Container(Liveness)的探针,对故障服务的Container(Liveness)的探针同样会失败,container会被kill掉,并根据原设置的container重启策略,系统倾向于在其原所在的机器上重启该container、或其他机器重新创建一个Pod。
  3. 由于上面的机制,整个服务实现了自身可用与自动恢复。

##服务发现

Tuxedo使用公告板来提供命名服务。Bulletin Board(公告板)是一块共享内存,Tuxedo把系统的配置保存在一个该共享内存中,主要包括服务进程、服务、消息队列、事件、运行环境的配置和统计信息等,TUXEDO通过BBL对公告板等进行管理。Tuxedo在服务启动时根据配置文件首先会创建一片共享内存作为公告板并将相关参数加载到共享内存中,在服务启动时会将服务相关信息(如服务名、队列名、服务数量、服务状态、请求数等)注册到BB中,在服务调用过程中,调用方通过BB的命名服务获取后台服务信息,实现服务的发现和调用。
4.png

Tuxedo服务发现及调用(一)
5.png

Tuxedo服务发现及调用(二)

Tuxedo服务发现及调用如上图一所示,客户端连接到Tuxedo公告板,根据服务名查找(Looks up)公告板、获取(Gets)所调用服务相关信息、调用(Invokes)服务。由于tuxedo是基于队列通过ATMI接口进行信息交互,具体ATMI、Message Queue、Bulletin Board交互如图二所示,客户端通过ATMI接口将消息发送到服务端队列(队列信息通过BB获取),服务端处理完后通过ATMI接口将处理结果返回到客户端队列。

Kubernetes提供了Service的概念,可以通过VIP访问Pod提供的服务,但是在使用的时候还有一个问题:怎么知道某个应用的 VIP?比如我们有两个应用,一个App,一个是db,每个应用使用rc进行管理,并通过service暴露出端口提供服务。App需要连接到db应用,我们只知道db应用的名称,但并不知道其VIP地址。起初,kubernetes采用了Docker使用过的方法——环境变量。每个Pod启动时候,会通过环境变量设置所有服务的IP和port信息,这样Pod中的应用可以通过读取环境变量来获取依赖服务的地址信息。这种方式服务和环境变量的匹配关系有一定的规范,使用起来也相对简单,存在的问题是:依赖的服务必须在Pod启动之前就存在,否则不会出现在环境变量中。理想方案是:应用能够直接使用服务的名字,不需要关心它实际IP地址,中间的转换能够自动完成,名字和IP之间的转换就是DNS系统的功能,因此Kubernetes也提供了DNS 方法来解决这个问题。
6.jpg

Kubernetes服务发现

如有两个服务frontend和backend,服务frontend调用服务backend。其调用过程如下:

* 先通过本Node上运行的DNS Server查找到backend服务的Cluster IP。
* 再通过本Node上运行的代理Kube-proxy,将请求分发给其中任意一个backend实例。

##一次完整的请求

我们从Tuxedo ATMI体系架构图中可以看出,Tuxedo系统服务层包括管理信息库(MIBs),管理信息库为其他应用程序管理和配置Tuxedo系统提供了一套编程接口,通过这套接口可以对Tuxedo系统进行动态调整和监控。如动态增加Tuxedo服务时,用户通过ATMI Client调用管理信息库(MIBs),通过管理信息库完成服务的增加,最后将服务信息注册到公告板(BB)。

类似地,Kubernetes也提供了一套接口供使用者进行服务的管理维护,具体流程如下:
7.jpg

Kubernetes一次完整的服务请求示意图

使用人员通过Kubectl提交一个创建RC的请求,该请求通过API Server被写入etcd中,此时Controller Manager通过API Server的监听资源变化的接口监听到这个RC事件,分析之后,发现当前集群中还没有它所对应的Pod实例,于是根据RC里的Pod模板定义生成一个Pod对象,通过API Server写入etcd中,接下来,此事件被Scheduler发现,它立即执行一个复杂的调度流程,为这个新Pod选定一个落户的Node,然后又通过API Server将这一结果写入到etcd中。随后,目标Node上运行的Kubelet进程通过API Server检测到这个“新生的”Pod并且按照它的定义,启动该Pod并负责他的一生。

综上所述,Tuxedo软件在金融等行业已应用多年,经过多年积累,运维人员对Tuxedo维护积累了丰富的运维经验。Kubernetes作为后起之秀,逐步在互联网、金融等行业开始应用,相关运维积累存在提升空间。本文通过对两者运行态、容错、扩缩容、服务发现以及一次完整的请求等方面进行对比,希望通过对两者的对比,找出两者运行及运维的相通之处,能够给运维人员维护Kubernetes提供一个思路和借鉴,使得具备Tuxedo等传统软件运维经验的运维人员快速具备Kubernetes运维能力。

原文链接:https://mp.weixin.qq.com/s/P77jueYtBiM_bQy4dtvEag

Docker容器互联方法

翔宇 发表了文章 • 0 个评论 • 320 次浏览 • 2019-05-28 22:34 • 来自相关话题

【编者的话】本文为Eddy Mavungu博士于DEIS官方博客中发布的系列文章的第二部分,Eddy博士在本篇系列文章中分享了Docker容器间互联的方法,并且做了演示。Eddy博士是DEIS公司的创始人,同时也是一位高级研究顾问。本文根据他于DEIS官方博客 ...查看全部
【编者的话】本文为Eddy Mavungu博士于DEIS官方博客中发布的系列文章的第二部分,Eddy博士在本篇系列文章中分享了Docker容器间互联的方法,并且做了演示。Eddy博士是DEIS公司的创始人,同时也是一位高级研究顾问。本文根据他于DEIS官方博客上发布的文章翻译而成。

这篇系列文章的第二部分会看一下如何连接Docker各容器。

我们在第一节谈及了Docker的bridge接口,它可以让我们连接所有在相同Docker宿主机上的容器。特别需要指出的是,我们看了三个基本并且比较早先的网络驱动技术:端口公开(port exposure),端口绑定(port binding)以及链接(linking)。如果你想和更多Docker技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态

在本文,我们将来看这些更高级并且最新的基于bridge接口的使用案例。

同时,我们也会看看使用overlay技术来将不同宿主机上的Docker容器连接起来。
#用户定义的网络(User-Defined Networks)
Docker公司在2015年11月初发布了Docker 1.9.0,随之而来整合了一些令人兴奋的关于网络方面的新内容。通过这些更新,如果我们现在为了让两个容器间可以相互通信,那么只需要将他们放在同一网络或者子网中。

让我们来证明一次。

首先,来看看我们准备了哪些:
$ sudo docker network ls
NETWORK ID NAME DRIVER
362c9d3713cc bridge bridge
fbd276b0df0a singlehost bridge
591d6ac8b537 none null
ac7971601441 host host

现在,让我们来创建网络:
$ sudo docker network create backend

如果起作用了,我们的网络列表上会显示刚才新建立的网络:
$ sudo docker network ls
NETWORK ID NAME DRIVER
362c9d3713cc bridge bridge
fbd276b0df0a singlehost bridge
591d6ac8b537 none null
ac7971601441 host host
d97889cef288 backend bridge

我们可以看到在这里backend已经被bridge驱动创建出来了。这是一个桥接(bridge)网络,就像在前文的第一部分中提到的一样,它也同样适用于所有在该宿主机上的容器。

我们将会用到上一节中创建的client_img和server_img镜像。如果你还没有在你的主机上配置好他们,可以现在查阅第一节并且设置好,这并不会花费太长时间。

什么?你说你已经设置好了?太棒了。

让我们从server_img镜像中运行一个服务器容器并且通过--net选项把它放置于之前配置的backend网络中。

就像下面命令一样:
$ sudo docker run -itd --net=backend --name=server server_img /bin/bash

像之前一样,登录到该容器:
$ sudo docker attach server

如果你看不见shell提示符,按键盘方向键的上箭头。

现在让我们启动在该容器里基于Apache的HTTP服务:
$ /etc/init.d/apache2 start

到这里为止,任何位于backend网络中的容器将可以连接到我们刚才创建的Apache HTTP服务器上。

我们可以通过在另一个终端上开启一个客户端容器并且把它至于backend网络进行测试。

就像这样:
$ sudo docker run -itd --net=backend --name=client client_img /bin/bash

进入容器:
$ sudo docker attach client

同样地,如果你看不见shell提示符,按键盘方向键的上箭头。
接着运行:
$ curl server

你应该可以看见默认的HTML页面。这意味着我们配置的网络是可以正常运行的。

就像在本系列文章的第一节中提及到的一样,Docker负责设置容器名称便于解析,这就是为什么我们可以直接用curl server 这个命令而不用知晓它的IP地址。

我们可以创建多个用户定义的网络,并且可以根据应用程序的拓扑结构把这些容器放在单个或多个网络中。这是非常灵活的,特别是对于那些需要交付微服务(microservices),多租户(multitenancy)及微分段(micro-segmentation)的人员来说是非常有用的。
#多主机网络(Multi-Host Networking)
如果我们想要建立一个跨越多台主机的网络该怎么做呢?当然,自从Docker1.9.0之后,你就可以这么做了!

目前为止,我们已经使用了基于本地范围的bridge网络驱动,这意味着桥接网络是在Docker宿主机本地的。Docker现在提供了一个新的全局范围的overlay网络驱动,这意味着overlay的网络可以跨越多台Docker宿主机。并且这些Docker宿主机可以存在于不同的数据中心,甚至不同的云服务提供商中!

为了设置一个overlay网络,以下几点是必须的:

* 一台内核版本高于3.16的主机
* 关键的key-value存储(例如 etcd, ConsulApache ZooKeeper
* 集群内的主机可以保证连接到以上的key-value存储
* 每一个集群内的主机都正确配置了基于 Docker Engine的后台实例

让我们来看一个案例吧。

我将会使用multihost-local.sh脚本和Docker Machine这个命令去开启三台虚拟主机。

这个脚本是用于虚拟机的而不是用于容器的。在这之后,我们在这些虚拟机上面运行Docker命令去模拟一个Docker宿主机集群。

在运行过脚本之后,可以看到我现在有的主机清单:
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM ERRORS
mhl-consul - virtualbox Running tcp://192.168.99.100:2376
mhl-demo0 - virtualbox Running tcp://192.168.99.101:2376
mhl-demo1 - virtualbox Running tcp://192.168.99.102:2376

好了,那么让我们倒退回去看下刚才发生了些什么。

这个脚本利用了Docker Machine,这意味着你必须安装它。在本篇文章中,我们安装了0.5.2版本的Docker Machine。你可以参考该版本的发行注释说明来下载并安装它。

该脚本(multihost-local.sh)使用了Docker Machine去部署三台基于VirtualBox的虚拟机并且安装并适当的配置了Docker Engine。

Docker Machine可以与很多主流虚拟化管理程序以及云服务提供商一起协助。它现在支持AWS、Digital Ocean、Google Cloud Platform、IBM Softlayer、Microsoft Azure和Hyper-V、OpenStack、Rachspace、VitrualBox、VMware Fusion®、vCloud® Air™ and vSphere®。

我们现在有了三个虚拟机:

* mhl-consul: 运行 Consul
* mhl-demo0: Docker 集群节点
* mhl-demo1: Docker 集群节点

这些Docker集群节点是被配置为协调通过VM来运行Consul,我们的key-value仓库。这也就是这些集群所涉及到的。

很酷吧,让我们再快速地往前看一看。

现在,让我们设置一个overlay网络。

首先,我们需要用一个在mhl-demo0这个VM上的终端,像这样:
$ eval $(docker-machine env mhl-demo0)

然后运行:
$ docker network create -d overlay myapp

该命令建立了一个名为myapp的跨越所有集群中主机的overlay网络。由于Docker通过key-value与该集群上的其他主机协调使得该操作变成了可能。

为了确保它正常的工作,我们可以通过终端登录到每一个集群中的VM去列出这些Docker网络。

复制下面所有的eval命令,然后用相对应的主机名去替换mhl-demo0。

然后运行:
$ docker network ls
NETWORK ID NAME DRIVER
7b9e349b2f01 host host
1f6a49cf5d40 bridge bridge
38e2eba8fbc8 none null
385a8bd92085 myapp overlay

到这里你就看到名为myapp的overlay网络了。

咱们成功啦!

但请记住:我们目前仅仅是创建了一个基于Docker 虚拟机的集群并配置了用于共享的overlay网络。我们实际上并没有创建任何Docker容器。所以让我们接着创建它们并来试一下这个overlay网络。

我们将做以下步骤:

1. 在mhl-demo0宿主机上运行默认地nginx镜像(这提供给了我们一个预先配置好的Nginx HTTP服务器)
2. 在mhl-demo1宿主机上运行默认的busybox镜像(它提供给我们一个基本的操作系统并且还包含一个类似于基于GNU的Wget工具)
3. 将两个容器添加进myapp网络
4. 测试他们之间的网络连通性

首先,让我们调出在mhl-demo0宿主机上的终端:
$ eval $(docker-machine env mhl-demo0)

然后启动nginx镜像:
$ docker run --name ng1 --net=myapp -d nginx

简而言之,我们现在有以下环境:

* 一台基于Nginx的HTTP服务器
* 该服务跑在名为ng1的容器里
* 它处在myapp网络中
* 该容器位于mhl-demo0宿主机上

让我们从其他宿主机上的另外一个容器试着去访问该环境,去验证它是可用的。

这一次调出mhl-demo1宿主机上的终端:
$ eval $(docker-machine env mhl-demo1)

然后运行:
$ docker run -it --net=myapp busybox wget -qO- ng1

以上命令其实做了以下几点:

* 从busybox镜像中创建了一个未命名的容器
* 将它添加进了myapp网络
* 运行了wget -qO- ng1命令
* 并且停止了该容器(我们在这之前是让容器运行的)

在以上的Wget命令中,ng1是我们Nginx的容器名称。Docker可以让我们使用解析到的主机名作为容器名称,甚至该容器是运行在不同的Docker宿主机上。

如果所有操作都是成功的,那么我们应该会看见以下类似的内容:






Welcome to nginx!

你看吧!我们现在拥有了一个基于多主机的容器网络。
#总结
Docker给予了诸如轻量级且独立地并能隔离的环境这样的优点。然而,要使容器对我们而言有用途,容器之间以及容器与主机网络之间要能互相通信才是至关重要的。

在这一系列文章中,我们探索了一些容器间本地互联和跨多个宿主机互联的方法。同样地,我们也聊了聊该如何在主机网络中去连接多个容器。

原文链接:Connecting Docker Containers, Part Two (翻译:薛开成)

===========================================
译者介绍
薛开成,趋势科技南京研发中心工程工具服务事业部基础架构高级工程师,负责容器仓库实施及落地。

Docker网络原则入门:EXPOSE,-p,-P,-link

aoxiang 发表了文章 • 0 个评论 • 146 次浏览 • 2019-05-28 22:31 • 来自相关话题

【编者的话】构建多容器应用程序,需要定义网络参数来设置容器间的通信,可以通过EXPOSE或者-expose暴露端口、使用-p发布特定端口,还可以用-link等等来实现,这些方法可能会得到一样的效果,但是这些方法之间是否有不同,应该选择什么样的方法,将是本文讨论 ...查看全部
【编者的话】构建多容器应用程序,需要定义网络参数来设置容器间的通信,可以通过EXPOSE或者-expose暴露端口、使用-p发布特定端口,还可以用-link等等来实现,这些方法可能会得到一样的效果,但是这些方法之间是否有不同,应该选择什么样的方法,将是本文讨论的重点内容。

如果你已经构建了一些多容器的应用程序,那么肯定需要定义一些网络规则来设置容器间的通信。有多种方式可以实现:可以通过`--expose`参数在运行时暴露端口,或者在Dockerfile里使用`EXPOSE`指令。还可以在Docker run的时候通过`-p`或者`-P`参数来发布端口。或者通过`--link`链接容器。虽然这些方式几乎都能达到一样的结果,但是它们还是有细微区别。那么到底应该使用哪一种呢?如果你想和更多Docker技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态

# TL;DR
使用-p或者-P来创建特定端口绑定规则最为可靠,EXPOSE可以看做是容器文档化的方式,谨慎使用--link的方式。



在比较这些不同方式之前,我们先分别了解细节。

#通过EXPOSE或者-expose暴露端口

有两种方式可以用来暴露端口:要么用`EXPOSE`指令在Dockerfile里定义,要么在docker run时指定`--expose=1234`。这两种方式作用相同,但是,`--expose`可以接受端口范围作为参数,比如 `--expose=2000-3000`。但是,`EXPOSE`和`--expose`都不依赖于宿主机器。默认状态下,这些规则并不会使这些端口可以通过宿主机来访问。

基于`EXPOSE`指令的上述限制,Dockerfile的作者一般在包含`EXPOSE`规则时都只将其作为哪个端口提供哪个服务的提示。使用时,还要依赖于容器的操作人员进一步指定网络规则。和`-P`参数联合使用的情况,下文会进一步阐述。不过通过`EXPOSE`命令文档化端口的方式十分有用。

本质上说,`EXPOSE`或者`--expose`只是为其他命令提供所需信息的元数据,或者只是告诉容器操作人员有哪些已知选择。

实际上,在运行时暴露端口和通过Dockerfile的指令暴露端口,这两者没什么区别。在这两种方式启动的容器里,通过`docker inspect $container_id | $container_name`查看到的网络配置是一样的:

"NetworkSettings": {
"PortMapping": null,
"Ports": {
"1234/tcp": null
}
},
"Config": {
"ExposedPorts": {
"1234/tcp": {}
}
}

可以看到端口被标示成已暴露,但是没有定义任何映射。注意这一点,因为我们查看的是发布端口。

ProTip:使用运行时标志`--expose`是附加的,因此会在Dockerfile的`EXPOSE`指令定义的端口之外暴露添加的端口。

#使用-p发布特定端口
可以使用`-p`参数显式将一个或者一组端口从容器里绑定到宿主机上,而不仅仅是提供一个端口。注意这里是小写的p,不是大写。因为该配置依赖于宿主机器,所以Dockerfile里没有对应的指令,这是运行时才可用的配置。`-p`参数有几种不同的格式:

ip:hostPort:containerPort| ip::containerPort \
| hostPort:containerPort | containerPort

实际中,可以忽略ip或者hostPort,但是必须要指定需要暴露的containerPort。另外,所有这些发布的规则都默认为tcp。如果需要udp,需要在最后加以指定,比如`-p 1234:1234/udp`。如果只是用命令`docker run -p 8080:3000 my-image`运行一个简单的应用程序,那么容器里运行在3000端口的服务在宿主机的8080端口也就可用了。端口不需要一样,但是在多个容器都暴露端口时,必须注意避免端口冲突。

避免冲突的最佳方法是让Docker自己分配hostPort。在上述例子里,可以选择`docker run -p 3000 my_image`来运行容器,而不是显式指定宿主机端口。这时,Docker会帮助选择一个宿主机端口。运行命令`docker port $container_id | $container_name`可以查看Docker选出的端口号。除了端口号,该命令只能显示容器运行时端口绑定信息。还可以通过在容器上运行`docker inspect`查看详细的网络信息,在定义了端口映射时,这样的信息就很有用。该信息在Config、HostConfig和NetworkSettings部分。我们查看这些信息来对比不同方式搭建的容器间的网络区别。

ProTip:可以用`-p`参数定义任意数量的端口映射。

#-expose/EXPOSE和-p对比
为了更好得理解两者之间的区别,我们使用不同的端口设置来运行容器。

运行一个很简单的应用程序,会在curl它的时候打印'hello world'。称这个镜像为no-exposed-ports:

FROM ubuntu:trusty
MAINTAINER Laura Frank
CMD while true; do echo 'hello world' | nc -l -p 8888; done

实验时注意使用的是Docker主机,而不是`boot2docker`。如果使用的是`boot2docker`,运行本文示例命令前先运行`boot2docker ssh`。

注意,我们使用`-d`参数运行该容器,因此容器一直在后台运行。(端口映射规则只适用于运行着的容器):

$ docker run -d --name no-exposed-ports no-exposed-ports
e18a76da06b3af7708792765745466ed485a69afaedfd7e561cf3645d1aa7149

这儿没有太多的信息,只是回显了容器的ID,提示服务已经成功启动。和预期结果一样,运行`docker port no-exposed-ports`和`docker inspect no-exposed-ports`时没显示什么信息,因为我们既没有定义端口映射规则也没有发布任何端口。

因此,如果我们发布一个端口会发生什么呢,`-p`参数和`EXPOSE`到底有什么区别呢?

还是使用上文的`no-exposed-ports`镜像,在运行时添加`-p`参数,但是不添加任何expose规则。在`config.ExposedPorts`里重新查看--expose参数或者EXPOSE指令的结果。

$ docker run -d --name no-exposed-ports-with-p-flag -p 8888:8888 no-exposed-ports
c876e590cfafa734f42a42872881e68479387dc2039b55bceba3a11afd8f17ca
$ docker port no-exposed-ports-with-p-flag
8888/tcp -> 0.0.0.0:8888

太棒了!我们可以看到可用端口。注意默认这是tcp。我们到网络设置里看看还有什么信息:

"Config": {
[...]
"ExposedPorts": {
"8888/tcp": {}
}
},
"HostConfig": {
[...]
"PortBindings": {
"8888/tcp": [
{
"HostIp": "",
"HostPort": "8888"
}
]
}
},
"NetworkSettings": {
[...]
"Ports": {
"8888/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "8888"
}
]
}
}

注意”Config“部分的暴露端口字段。这和我们使用`EXPOSE`或者`--expose`暴露的端口是一致的。Docker会隐式暴露已经发布的端口。已暴露端口和已发布端口的区别在于已发布端口在宿主机上可用,而且我们可以在“HostConfig”和“NetworkSettings”两个部分都能看到已发布端口的信息。

所有发布(`-p`或者`-P`)的端口都暴露了,但是并不是所有暴露(`EXPOSE`或`--expose`)的端口都会发布。

#使用-P和EXPOSE发布端口
因为`EXPOSE`通常只是作为记录机制,也就是告诉用户哪些端口会提供服务,Docker可以很容易地把Dockerfile里的`EXPOSE`指令转换成特定的端口绑定规则。只需要在运行时加上`-P`参数,Docker会自动为用户创建端口映射规则,并且帮助避免端口映射的冲突。

添加如下行到上文使用的Web应用Dockerfile里:

EXPOSE 1000
EXPOSE 2000
EXPOSE 3000

构建镜像,命名为exposed-ports。

docker build -t exposed-ports .

再次用`-P`参数运行,但是不传入任何特定的`-p`规则。可以看到Docker会将`EXPOSE`指令相关的每个端口映射到宿主机的端口上:

$ docker run -d -P --name exposed-ports-in-dockerfile exposed-ports
63264dae9db85c5d667a37dac77e0da7c8d2d699f49b69ba992485242160ad3a
$ docker port exposed-ports-in-dockerfile
1000/tcp -> 0.0.0.0:49156
2000/tcp -> 0.0.0.0:49157
3000/tcp -> 0.0.0.0:49158

很方便,不是么?
#--link怎么样呢?

你可能在多容器应用程序里使用过运行时参数 `--link name:alias`来设定容器间关系。虽然`--link`非常易于使用,几乎能提供和端口映射规则和环境变量相同的功能。但是最好将`--link`当做服务发现的机制,而不是网络流量的门户。

`--link`参数唯一多做的事情是会使用源容器的主机名和容器ID来更新新建目标容器(使用`--link`参数创建的容器)的/etc/hosts文件。

当使用`--link`参数时,Docker提供了一系列标准的环境变量,如果想知道细节的话可以查看相应文档

虽然`--link`对于需要隔离域的小型项目非常有用,它的功能更像服务发现的工具。如果项目中使用了编排服务,比如Kubernetes或者Fleet,很可能就会使用别的服务发现工具来管理关系。这些编排服务可能会不管理Docker的链接,而是管理服务发现工具里包含的所有服务,在Panamax项目里使用的很多远程部署适配器正是做这个的。

#找到平衡
哪一种网络选择更为适合,这取决于谁(或者哪个容器)使用Docker运行的服务。需要注意的是一旦镜像发布到Docker Hub之后,你无法知道其他人如何使用该镜像,因此要尽可能让镜像更加灵活。如果你只是从Docker Hub里取得镜像,使用`-P`参数运行容器是最方便迅速的方式,来基于作者的建议创建端口映射规则。记住每一个发布的端口都是暴露端口,但是反过来是不对的。
#快速参考
1.jpg


原文链接:A Brief Primer on Docker Networking Rules: EXPOSE, -p, -P, –link(翻译:崔婧雯 校对:魏小红)
===========================
译者介绍
崔婧雯,现就职于IBM,高级软件工程师,负责IBM WebSphere业务流程管理软件的系统测试工作。曾就职于VMware从事桌面虚拟化产品的质量保证工作。对虚拟化,中间件技术,业务流程管理有浓厚的兴趣。

使用Spring Cloud和Docker构建微服务架构

老马 发表了文章 • 0 个评论 • 242 次浏览 • 2019-05-28 22:27 • 来自相关话题

【编者的话】如何使用Spring Boot、Spring Cloud、Docker和Netflix的一些开源工具来构建一个微服务架构。本文通过使用Spring Boot、Spring Cloud和Docker构建的概念型应用示例,提供了了解常见的微服务架构模式 ...查看全部
【编者的话】如何使用Spring Boot、Spring Cloud、Docker和Netflix的一些开源工具来构建一个微服务架构。本文通过使用Spring Boot、Spring Cloud和Docker构建的概念型应用示例,提供了了解常见的微服务架构模式的起点。

该代码可以在GitHub上获得,并且在Docker Hub上提供了镜像。您只需要一个命令即可启动整个系统。

我选择了一个老项目作为这个系统的基础,它的后端以前是单一应用。此应用提供了处理个人财务、整理收入开销、管理储蓄、分析统计和创建简单预测等功能。如果你想和更多Spring Cloud技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态
#功能服务
整个应用分解为三个核心微服务。它们都是可以独立部署的应用,围绕着某些业务功能进行组织。
1.png


账户服务

包含一般用户输入逻辑和验证:收入/开销记录、储蓄和账户设置。
2.png


统计服务

计算主要的统计参数,并捕获每一个账户的时间序列。数据点包含基于货币和时间段正常化后的值。该数据可用于跟踪账户生命周期中的现金流量动态。
3.png


通知服务

存储用户的联系信息和通知设置(如提醒和备份频率)。安排工作人员从其它服务收集所需的信息并向订阅的客户发送电子邮件。
4.png


注意

* 每一个微服务拥有自己的数据库,因此没有办法绕过API直接访问持久数据。
* 在这个项目中,我使用MongoDB作为每一个服务的主数据库。拥有一个多种类持久化架构(polyglot persistence architecture)也是很有意义的。
* 服务间(Service-to-service)通信是非常简单的:微服务仅使用同步的REST API进行通信。现实中的系统的常见做法是使用互动风格的组合。例如,执行同步的GET请求检索数据,并通过消息代理(broker)使用异步方法执行创建/更新操作,以便解除服务和缓冲消息之间的耦合。然而,这带给我们是最终的一致性

#基础设施服务
分布式系统中常见的模式,可以帮助我们描述核心服务是怎样工作的。Spring Cloud提供了强大的工具,可以增强Spring Boot应用的行为来实现这些模式。我会简要介绍一下:
5.png

##配置服务
Spring Cloud Config是分布式系统的水平扩展集中式配置服务。它使用了当前支持的本地存储、Git和Subversion等可拔插存储库层(repository layer)。

在此项目中,我使用了native profile,它简单地从本地classpath下加载配置文件。您可以在配置服务资源中查看shared目录。现在,当通知服务请求它的配置时,配置服务将响应回shared/notification-service.yml和shared/application.yml(所有客户端应用之间共享)。

客户端使用

只需要使用sprng-cloud-starter-config依赖构建Spring Boot应用,自动配置将会完成其它工作。

现在您的应用中不需要任何嵌入的properties,只需要提供有应用名称和配置服务url的bootstrap.yml即可:
spring:
application:
name: notification-service
cloud:
config:
uri: http://config:8888
fail-fast: true

使用Spring Cloud Config,您可以动态更改应用配置

比如,EmailService bean使用了@RefreshScope注解。这意味着您可以更改电子邮件的内容和主题,而无需重新构建和重启通知服务应用。

首先,在配置服务器中更改必要的属性。然后,对通知服务执行刷新请求:curl -H "Authorization: Bearer #token#" -XPOST http://127.0.0.1:8000/notifications/refresh。

您也可以使用webhook来自动执行此过程

注意

* 动态刷新存在一些限制。@RefreshScope不能和@Configuraion类一同工作,并且不会作用于@Scheduled方法。
* fail-fast属性意味着如果Spring Boot应用无法连接到配置服务,将会立即启动失败。当您一起启动所有应用时,这非常有用。
* 下面有重要的安全提示

##授权服务
负责授权的部分被完全提取到单独的服务器,它为后端资源服务提供OAuth2令牌。授权服务器用于用户授权以及在周边内进行安全的机器间通信。

在此项目中,我使用密码凭据作为用户授权的授权类型(因为它仅由本地应用UI使用)和客户端凭据作为微服务授权的授权类型。

Spring Cloud Security提供了方便的注解和自动配置,使其在服务器端或者客户端都可以很容易地实现。您可以在文档中了解到更多信息,并在授权服务器代码中检查配置明细。

从客户端来看,一切都与传统的基于会话的授权完全相同。您可以从请求中检索Principal对象、检查用户角色和其它基于表达式访问控制和@PreAuthorize注解的内容。

PiggyMetrics(帐户服务、统计服务、通知服务和浏览器)中的每一个客户端都有一个范围:用于后台服务的服务器、用于浏览器展示的UI。所以我们也可以保护控制器避免受到外部访问,例如:
@PreAuthorize("#oauth2.hasScope('server')")
@RequestMapping(value = "accounts/{name}", method = RequestMethod.GET)
public List getStatisticsByAccountName(@PathVariable String name) {
return statisticsService.findByAccountName(name);
}

##API网关
您可以看到,有三个核心服务。它们向客户端暴露外部API。在现实系统中,这个数量可以非常快速地增长,同时整个系统将变得非常复杂。实际上,一个复杂页面的渲染可能涉及到数百个服务。

理论上,客户端可以直接向每个微服务直接发送请求。但是这种方式是存在挑战和限制的,如果需要知道所有端点的地址,分别对每一段信息执行http请求,将结果合并到客户端。另一个问题是,这不是web友好协议,可能只在后端使用。

通常一个更好的方法是使用API网关。它是系统的单个入口点,用于通过将请求路由到适当的后端服务或者通过调用多个后端服务并聚合结果来处理请求。此外,它还可以用于认证、insights、压力测试、金丝雀测试(canary testing)、服务迁移、静态响应处理和主动变换管理。

Netflix开源这样的边缘服务,现在用Spring Cloud,我们可以用一个@EnabledZuulProxy注解来启用它。在这个项目中,我使用Zuul存储静态内容(UI应用),并将请求路由到适当的微服务。以下是一个简单的基于前缀(prefix-based)路由的通知服务配置:
zuul:
routes:
notification-service:
path: /notifications/**
serviceId: notification-service
stripPrefix: false

这意味着所有以/notification开头的请求将被路由到通知服务。您可以看到,里面没有硬编码的地址。Zuul使用服务发现机制来定位通知服务实例以及断路器和负载均衡器,如下所述。
##服务发现
另一种常见的架构模式是服务发现。它允许自动检测服务实例的网络位置,由于自动扩展、故障和升级,它可能会动态分配地址。

服务发现的关键部分是注册。我使用Netflix Eureka进行这个项目,当客户端需要负责确定可以用的服务实例(使用注册服务器)的位置和跨平台的负载均衡请求时,Eureka就是客户端发现模式的一个很好的例子。

使用Spring Boot,您可以使用spring-cloud-starter-eureka-server依赖、@EnabledEurekaServer注解和简单的配置属性轻松构建Eureka注册中心(Eureka Registry)。

使用@EnabledDiscoveryClient注解和带有应用名称的bootstrap.yml来启用客户端支持:
spring:
application:
name: notification-service

现在,在应用启动时,它将向Eureka服务器注册并提供元数据,如主机和端口、健康指示器URL、主页等。Eureka接收来自从属于某服务的每个实例的心跳消息。如果心跳失败超过配置的时间表,该实例将从注册表中删除。

此外,Eureka还提供了一个简单的界面,您可以通过它来跟踪运行中的服务和可用实例的数量:http://localhost:8761
6.png

##负载均衡器、断路器和Http客户端
Netflix OSS提供了另一套很棒的工具。

Ribbon

Ribbon是一个客户端负载均衡器,可以很好地控制HTTP和TCP客户端的行为。与传统的负载均衡器相比,每次线上调用都不需要额外的跳跃——您可以直接联系所需的服务。

它与Spring Cloud和服务发现是集成在一起的,可开箱即用。Eureka客户端提供了可用服务器的动态列表,因此Ribbon可以在它们之间进行平衡。

Hystrix

Hystrix是断路器模式的一种实现,它可以通过网络访问依赖来控制延迟和故障。中心思想是在具有大量微服务的分布式环境中停止级联故障。这有助于快速失败并尽快恢复——自我修复在容错系统中是非常重要的。

除了断路器控制,在使用Hystrix,您可以添加一个备用方法,在主命令失败的情况下,该方法将被调用以获取默认值。

此外,Hystrix生成每个命令的执行结果和延迟的度量,我们可以用它来监视系统的行为

Feign

Feign是一个声明式HTTP客户端,能与Ribbon和Hystrix无缝集成。实际上,通过一个spring-cloud-starter-feign依赖和@EnabledFeignClients注解,您可以使用一整套负载均衡器、断路器和HTTP客户端,并附带一个合理的的默认配置。

以下是账户服务的示例:
@FeignClient(name = "statistics-service")
public interface StatisticsServiceClient {
@RequestMapping(method = RequestMethod.PUT, value = "/statistics/{accountName}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
void updateStatistics(@PathVariable("accountName") String accountName, Account account);
}


* 您需要的只是一个接口
* 您可以在Spring MVC控制器和Feign方法之间共享@RequestMapping部分
* 以上示例仅指定所需要的服务ID——statistics-service,这得益于Eureka的自动发现(但显然您可以使用特定的URL访问任何资源)。

##监控仪表盘
在这个项目配置中,Hystrix的每一个微服务都通过Spring Cloud Bus(通过AMQP broker)将指标推送到Turbine。监控项目只是一个使用了TurbineHystrix仪表盘的小型Spring Boot应用。

让我们看看系统行为在负载下:账户服务调用统计服务和它在一个变化的模拟延迟下的响应。响应超时阈值设置为1秒。
7.png

##日志分析
集中式日志记录在尝试查找分布式环境中的问题时非常有用。Elasticsearch、Logstash和Kibana技术栈可让您轻松搜索和分析您的日志、利用率和网络活动数据。在我的另一个项目中已经有现成的Docker配置。
##安全

高级安全配置已经超过了此概念性项目的范围。为了更真实地模拟真实系统,请考虑使用https和JCE密钥库来加密微服务密码和配置服务器的properties内容(有关详细信息,请参阅文档)。
#基础设施自动化

部署微服务比部署单一的应用的流程要复杂得多,因为它们相互依赖。拥有完全基础设置自动化是非常重要的。我们可以通过持续交付的方式获得以下好处:

* 随时发布软件的能力。
* 任何构建都可能最终成为一个发行版本。
* 构建工件(artifact)一次,根据需要进行部署。

这是一个简单的持续交付工作流程,在这个项目的实现:

在此配置中,Travis CI为每一个成功的Git推送创建了标记镜像。因此,每一个微服务在Docker Hub上的都会有一个latest镜像,而较旧的镜像则使用Git提交的哈希进行标记。如果有需要,可以轻松部署任何一个,并快速回滚。
8.png

#如何运行全部?
这真的很简单,我建议您尝试一下。请记住,您将要启动8个Spring Boot应用、4个MongoDB实例和RabbitMq。确保您的机器上有4GB的内存。您可以随时通过网关、注册中心、配置、认证服务和账户中心运行重要的服务。

运行之前

* 安装Docker和Docker Compose。
* 配置环境变量:CONFIG_SERVICE_PASSWORD, NOTIFICATION_SERVICE_PASSWORD, STATISTICS_SERVICE_PASSWORD, ACCOUNT_SERVICE_PASSWORD, MONGODB_PASSWORD

生产模式

在这种模式下,所有最新的镜像都将从Docker Hub上拉取。只需要复制docker-compose.yml并执行docker-compose up -d即可。

开发模式

如果您想自己构建镜像(例如,在代码中进行一些修改),您需要克隆所有仓库(repository)并使用Mavne构建工件(artifact)。然后,运行docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d

docker-compose.dev.yml继承了docker-compose.yml,附带额外配置,可在本地构建镜像,并暴露所有容器端口以方便开发。

重要的端点(Endpoint)

* localhost:80 —— 网关
* localhost:8761 —— Eureka仪表盘
* localhost:9000 —— Hystrix仪表盘
* localhost:8989 —— Turbine stream(Hystrix仪表盘来源)
* localhost:15672 —— RabbitMq管理

注意

所有Spring Boot应用都需要运行配置服务器才能启动。得益于Spring Boot的fail-fast属性和docker-compsoe的restart:always选项,我们可以同时启动所有容器。这意味着所有依赖的容器将尝试重新启动,直到配置服务器启动运行为止。

此外,服务发现机制在所有应用启动后需要一段时间。在实例、Eureka服务器和客户端在其本地缓存中都具有相同的元数据之前,任何服务都不可用于客户端发现,因此可能需要3次心跳。默认的心跳周期为30秒。

原文链接:Microservice Architectures With Spring Cloud and Docker(翻译:Oopsguy

Docker五大优势:持续集成、版本控制、可移植性、隔离性和安全性

Andy_Lee 发表了文章 • 0 个评论 • 192 次浏览 • 2019-05-28 22:18 • 来自相关话题

【编者的话】 随着Docker技术的不断成熟,越来越多的企业开始考虑使用Docker。Docker有很多的优势,本文主要讲述了Docker的五个最重要优势,即持续集成、版本控制、可移植性、隔离性和安全性。 对于Docker,应该不需要 ...查看全部
【编者的话】 随着Docker技术的不断成熟,越来越多的企业开始考虑使用Docker。Docker有很多的优势,本文主要讲述了Docker的五个最重要优势,即持续集成、版本控制、可移植性、隔离性和安全性。

对于Docker,应该不需要进行详细的介绍了。它是最火热的开源项目之一,通过在容器中增加一个抽象层(a layer of abstraction),就可以将应用程序部署到容器中。在看似稳定而成熟的场景下,使用Docker的好处越来越多。在这篇文章中,我不谈论Docker是什么或者Docker是怎么工作的,取而代之,我会提出使用这个不断成长的平台的五大好处。
#持续部署与测试
Docker在开发与运维的世界中具有极大的吸引力,因为它能保持跨环境的一致性。在开发与发布的生命周期中,不同的环境具有细微的不同,这些差异可能是由于不同安装包的版本和依赖关系引起的。然而,Docker可以通过确保从开发到产品发布整个过程环境的一致性来解决这个问题*Docker容器通过相关配置,保持容器内部所有的配置和依赖关系始终不变。最终,你可以在开发到产品发布的整个过程中使用相同的容器来确保没有任何差异或者人工干预。

使用Docker,你还可以确保开发者不需要配置完全相同的产品环境,他们可以在他们自己的系统上通过VirtualBox建立虚拟机来运行Docker容器。Docker的魅力在于它同样可以让你在亚马逊EC2实例上运行相同的容器。如果你需要在一个产品发布周期中完成一次升级,你可以很容易地将需要变更的东西放到Docker容器中,测试它们,并且使你已经存在的容器执行相同的变更。这种灵活性就是使用Docker的一个主要好处。和标准部署与集成过程一样,Docker可以让你构建、测试和发布镜像,这个镜像可以跨多个服务器进行部署。哪怕安装一个新的安全补丁,整个过程也是一样的。你可以安装补丁,然后测试它,并且将这个补丁发布到产品中。如果你想和更多Docker技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态
#多云平台
Docker最大的好处之一就是可移植性。在过去的几年里,所有主流的云计算提供商,包括亚马逊AWS和谷歌的GCP,都将Docker融入到他们的平台并增加了各自的支持。Docker容器能运行在亚马逊的EC2实例、谷歌的GCP实例、Rackspace服务器或者VirtualBox这些提供主机操作系统的平台上。举例来说,如果运行在亚马逊EC2实例上的Docker容器能够很容易地移植到其他几个平台上,比如说VirtualBox,并且达到类似的一致性和功能性,那这将允许你从基础设施层中抽象出来。除了AWS和GCP,Docker在其他不同的IaaS提供商也运行的非常好,例如微软的Azure、OpenStack和可以被具有不同配置的管理者所使用的Chef、Puppet、Ansible等。
#环境标准化和版本控制
通过上面的讨论,Docker容器可以在不同的开发与产品发布生命周期中确保一致性,进而标准化你的环境。除此之外,Docker容器还可以像git仓库一样,可以让你提交变更到Docker镜像中并通过不同的版本来管理它们。设想如果你因为完成了一个组件的升级而导致你整个环境都损坏了,Docker可以让你轻松地回滚到这个镜像的前一个版本。这整个过程可以在几分钟内完成,如果和虚拟机的备份或者镜像创建流程对比,那Docker算相当快的,它可以让你快速地进行复制和实现冗余。此外,启动Docker就和运行一个进程一样快。
#隔离性
Docker可以确保你的应用程序与资源是分隔开的。几个月前,Gartner发表了一篇报告,这份报告说明了运行Docker 容器进行资源隔离的效果和虚拟机(VM)管理程序一样的好,但是管理与控制方面还需要进行完善。

我们考虑这样一个场景,你在你的虚拟机中运行了很多应用程序,这些应用程序包括团队协作软件(例如Confluence)、问题追踪软件(例如JIRA)、集中身份管理系统(例如Crowd)等等。由于这些软件运行在不同的端口上,所以你必须使用Apache或者Nginx来做反向代理。到目前为止,一切都很正常,但是随着你的环境向前推进,你需要在你现有的环境中配置一个内容管理系统(例如Alfresco)。这时候有个问题发生了,这个软件需要一个不同版本的Apache Tomcat,为了满足这个需求,你只能将你现有的软件迁移到另一个版本的Tomcat上,或者找到适合你现有Tomcat的内容管理系统(Alfresco)版本。

对于上述场景,使用Docker就不用做这些事情了。Docker能够确保每个容器都拥有自己的资源,并且和其他容器是隔离的。你可以用不同的容器来运行使用不同堆栈的应用程序。除此之外,如果你想在服务器上直接删除一些应用程序是比较困难的,因为这样可能引发依赖关系冲突。而Docker可以帮你确保应用程序被完全清除,因为不同的应用程序运行在不同的容器上,如果你不在需要一款应用程序,那你可以简单地通过删除容器来删除这个应用程序,并且在你的宿主机操作系统上不会留下任何的临时文件或者配置文件。

除了上述好处,Docker还能确保每个应用程序只使用分配给它的资源(包括CPU、内存和磁盘空间)。一个特殊的软件将不会使用你全部的可用资源,要不然这将导致性能降低,甚至让其他应用程序完全停止工作。
#安全性
如上所述,Gartner也承认Docker正在快速地发展。从安全角度来看,Docker确保运行在容器中的应用程序和其他容器中的应用程序是完全分隔与隔离的,在通信流量和管理上赋予你完全的控制权。Docker容器不能窥视运行在其他容器中的进程。从体系结构角度来看,每个容器只使用着自己的资源(从进程到网络堆栈)。

作为紧固安全的一种手段,Docker将宿主机操作系统上的敏感挂载点(例如/proc和/sys)作为只读挂载点,并且使用一种写时复制系统来确保容器不能读取其他容器的数据。Docker也限制了宿主机操作系统上的一些系统调用,并且和SELinux与AppArmor一起运行的很好。此外,在Docker Hub上可以使用的Docker镜像都通过数字签名来确保其可靠性。由于Docker容器是隔离的,并且资源是受限制的,所以即使你其中一个应用程序被黑,也不会影响运行在其它Docker容器上的应用程序。
#结语
将云计算一起考虑,上面提到的这些好处能够清楚地证明Docker是一个有效的开源平台。使用Docker的好处越来越多,今天我只想强调这前五大好处。如果你使用了Docker,欢迎分享你的使用案例或者任何你觉得使用Docker带来的好处。

原文链接:5 Key Benefits of Docker: CI, Version Control, Portability, Isolation and Security(翻译:肖远昊 校对:魏小红)

五个Docker监控工具的对比

aoxiang 发表了文章 • 0 个评论 • 191 次浏览 • 2019-05-28 22:10 • 来自相关话题

【编者的话】这篇文章作者是Usman,他是服务器和基础架构工程师,有非常丰富的分布式构建经验。该篇文章主要分析评估了五种Docker监控工具,包括免费的和不免费的:Docker Stats、CAdvisor、Scout、Data Dog以及Sensu。不过作者 ...查看全部
【编者的话】这篇文章作者是Usman,他是服务器和基础架构工程师,有非常丰富的分布式构建经验。该篇文章主要分析评估了五种Docker监控工具,包括免费的和不免费的:Docker Stats、CAdvisor、Scout、Data Dog以及Sensu。不过作者还是推荐使用Data Dog。另外还有两个工具:Prometheus与Sysdig Cloud会在下一篇做介绍分析,敬请期待。

随着Docker被大规模的部署应用,如何通过可视化的方式了解Docker环境的状态以及健康变得越来越重要。这篇文章我们来回顾下监控容器的常用工具。我会基于以下标准评估这些工具:

1. 易于部署
2. 信息呈现的详细度
3. 整个部署过程中日志的聚集程度
4. 数据报警能力
5. 是否可以监控非Docker的资源
6. 成本

这些评估标准可能并不全面,但是我试图强调的是最常用的工具以及优化此六项评估标准的工具。
Docker Stats命令

本文中所有使用的命令只在亚马逊EC2上的RancherOS实例中测试过。但是我想它们应该可以在任何的Docker容器中运行。如果你想和更多Docker技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态

我将讨论的第一个工具是Docker本身。你可能不知道Docker客户端已经提供了基本的命令行工具来检查容器的资源消耗。想要查看容器统计信息只需运行`docker stats [CONTAINER_NAME]`。这样就可以查看每个容器的CPU利用率、内存的使用量以及可用内存总量。请注意,如果你没有限制容器内存,那么该命令将显示您的主机的内存总量。但它并不意味着你的每个容器都能访问那么多的内存。另外,还可以看啊都容器通过网络发送和接收的数据总量。

$ docker stats determined_shockley determined_wozniak prickly_hypatia
CONTAINER CPU % MEM USAGE/LIMIT MEM % NET I/O
determined_shockley 0.00% 884 KiB/1.961 GiB 0.04% 648 B/648 B
determined_wozniak 0.00% 1.723 MiB/1.961 GiB 0.09% 1.266 KiB/648 B
prickly_hypatia 0.00% 740 KiB/1.961 GiB 0.04% 1.898 KiB/648 B

如果想要看到更为详细的容器属性,还可以通过netcat,使用Docker远程API来查看(见下文)。发送一个HTTP GET请求`/containers/[CONTAINER_NAME]`,其中`CONTAINER_NAME`是你想要统计的容器名称。你可以从这里看到一个容器stats请求的完整响应信息。在上述的例子中你会得到缓存、交换空间以及内存的详细信息。如果要了解什么是metrics,那么你就需要精读Docker文档的Run Metrics部分

##评分:

  1. 易于部署程度:※※※※※
  2. 信息详细程度:※※※※※
  3. 集成度:无
  4. 生成警报的能力:无
  5. 监测非Docker的资源的能力:无
  6. 成本:免费

CAdvisor

我们可以使用`docker stats`命令和远程API来获取容器的状态信息。但是,如果你想要在图形界面中直接查看这些信息,那你就需要诸如CAdvisor这类的工具。CAdvisor提供了早`docker stats`命令所显示的数据的可视化界面。运行以下Docker命令,并在浏览器里访问`http://:8080/`可以看到CAdvisor的界面。你将看到CPU的使用率、内存使用率、网络吞吐量以及磁盘空间利用率。然后,你可以通过点击在网页顶部的`Docker Containers`链接,然后选择某个容器来详细了解它的使用情况。

docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=8080:8080 \
--detach=true \
--name=cadvisor \
google/cadvisor:latest

1.png

CAdvisor是一个易于设置并且非常有用的工具,我们不用非要SSH到服务器才能查看资源消耗,而且它还给我们生成了图表。此外,当集群需要额外的资源时,压力表(pressure gauges )提供了快速预览。而且,与本文中的其他的工具不一样的是CAdvisor是免费的,并且还开源。另外,它的资源消耗也比较低。但是,它有它的局限性,它只能监控一个Docker主机。因此,如果你是多节点的话,那就比较麻烦了,你得在所有的主机上都安装一个CAdvisor,者肯定特别不方便。值得注意的是,如果你使用的是Kubernetes,你可以使用heapster来监控多节点集群。另外,在图表中的数据仅仅是时长一分钟的移动窗口,并没有方法来查看长期趋势。如果资源使用率在危险水平,它却没有生成警告的机制。如果在Docker节点的资源消耗方面,你没有任何可视化界面,那么CAdvisor是一个不错的开端来带你步入容器监控,然而如果你打算在你的容器中运行任何关键任务,那你就需要一个更强大的工具或者方法。
##评分:(忽略了heapster,因为它仅支持Kubernetes)


  1. 易于部署程度:※※※※※
  2. 信息详细程度:※※
  3. 集成度:※
  4. 生成警报的能力:无
  5. 监测非Docker的资源的能力:无
  6. 成本:免费

Scout

下一个Docker监控的方法是Scout,它解决了CAdvisor的局限性。 Scout是一个应用监控服务,它能够从很多主机和容器中获得各项监测数据,并将数据呈现在有更长时间尺度的图标中。它也可以基于这些指标生成警报。要获取Scout并运行,第一步,在scoutapp.com注册一个Scout帐户,免费的试用账号足以用来集成测试。一旦你创建了自己的帐户并登录,点击右上角的帐户名称,然后点击Account Basics来查看你的Account Key,你需要这个Key从Docker服务器来发送指标。
2.png

3.png

现在在你的主机上,创建一个名为scouts.yml的文件并将下面的文字复制到该文件中,用上边得到的Key替换到account_key。您可以对主机指定任何有意义的变量:display_name、environment与roles等属性。当他们在scout界面上呈现时,这些将用于分离各种指标。我假设有一组网站服务器列表正在运行Docker,它们都将采用如下图所示的变量。

# account_key is the only required value
account_key: YOUR_ACCOUNT_KEY
hostname: web01-host
display_name: web01
environment: production
roles: web

现在,你可以使用scout配置文件通过Docker-scout插件来运行scout。

docker run -d --name scout-agent \
-v /proc:/host/proc:ro \
-v /etc/mtab:/host/etc/mtab:ro \
-v /var/run/docker.sock:/host/var/run/docker.sock:ro \
-v `pwd`/scoutd.yml:/etc/scout/scoutd.yml \
-v /sys/fs/cgroup/:/host/sys/fs/cgroup/ \
--net=host --privileged \
soutapp/docker-scout

这样你查看Scout网页就能看到一个条目,其中display_name参数(web01)就是你在scoutd.yml里面指定的。
4.png

如果你点击它(web01)就会显示主机的详细信息。其中包括任何运行在你主机上的进程计数、cpu使用率以及内存利用率,值得注意的是在docker内部并没有进程的限制。
5.png

如果要添加Docker监控服务,需要单击Roles选项卡,然后选择所有服务。现在点击+插件模板按钮,接下来的Docker监视器会加载详细信息视图。一旦详细信息呈现出来,选择安装插件来添加到您的主机。接着会给你提供一个已安装插件的名称以及需指定要监视的容器。如果该字段是空的,插件将监控主机上所有的容器。点击完成按钮,一分钟左右你就可以在[Server Name] > Plugins中看到从Docker监控插件中获取的详细信息。该插件为每个主机显示CPU使用率、内存使用率、网络吞吐量以及容器的数量。
6.png

你点击任何一个图表,都可以拉取该指标的详细视图,该视图可以让你看到时间跨度更长的趋势。
7.png

该视图还支持过滤基于环境和服务器角色的指标。此外,你可以创建“Triggers”或警报,如果指标高于或低于配置的阈值它就给你发送电子邮件。这就允许您设置自动警报来通知您,比如,如果你的一些容器异常关闭以及容器计数低于一定数量。您还可以设置对平均CPU利用率的警报,举例来说,如果你正在运行的容器超过CPU利用率而发热,你会得到一个警告,当然你可以开启更多的主机到你的Docker集群。

要创建触发器,请选择顶部菜单的Roles>All Servers,然后选择plugins部分的Docker monitor。然后在屏幕的右侧的Plugin template Administration菜单里选择triggers。您现在应该看到一个选项“Add a Trigger”,它将应用到整个部署。
8.png

下面是一个触发器的例子,如果部署的容器数量低于3就会发出警报。
9.png

它的创建是为“所有的服务器”,当然你也可以用不同的角色标记你的主机使用服务器上创建的scoutd.yml文件。使用角色。你可以通过使用不同角色来应用触发器到部署的服务器的一个子集上。例如,你可以设置一个当在你的网络的节点的容器数量低于一定数量时的警报。即使是基于角色的触发器我仍然觉得Scout的警报系统可能做的更好。这是因为许多Docker部署具有相同主机上的多种多样的容器。在这种情况下为特定类型的容器设置触发器将是不可能的由于角色被应用到主机上的所有容器。

比起CAdvisor,使用Scout的另一个优点是,它有大量的插件,除了Docker信息他们可以吸收其他有关你的部署的数据。这使得Scout是你的一站式监控系统,而无需对系统的各种资源来安装各种不同的监控系统。

Scout的一个缺点是,它不显示有关每个主机上像CAdvisor的单独容器的详细信息。这是个问题,如果你在同一台服务器上运行大量的容器。例如,如果你想有一个触发器来提醒您的Web容器的警报,但不是Jenkins容器,这时Scout就无法支持该情况。尽管有这个缺点,Scout还是一个相当有用的工具来监控你的Docker部署。当然这要付出一些代价,每个监控的主机十美元。如果你要运行一个有多台主机的超大部署,这个代价会是个考虑因素。
##评分:


  1. 易于部署程度:※※※※
  2. 信息详细程度:※※
  3. 集成度:※※※
  4. 生成警报的能力:※※※
  5. 监测非Docker的资源的能力:支持
  6. 成本:每个主机$10

Data Dog

从Scout移步到另一个监控服务——DataDog,它既解决几个Scout的缺点又解除了CAdvisor的局限性。要使用DataDog,先在https://www.datadoghq.com/注册一个DataDog账户。一旦你登录到您的帐户,您将看到支持集成的每种类型的指令列表。从列表中选择Docker,你会得到一个Docker run命令(如下),将其复制到你的主机。该命令需要你的预先设置的API密钥,然后你可以运行该命令。大约45秒钟后您的代理将开始向DataDog系统报告。

docker run -d --privileged --name dd-agent \
-h `hostname` \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /proc/mounts:/host/proc/mounts:ro \
-v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro \
-e API_KEY=YOUR_API_KEY datadog/docker-dd-agent \

此时,容器提示你可以在DataDog Web的Events tab上处理和查看有关集群的所有动态。所有容器的启动和终止都是事件流的一部分。
10.png

您也可以点击Dashboards标签并点击创建仪表板以合计您整个群集的指标。 Datadog收集在系统中运行的所有容器的CPU使用率、内存以及I/O的指标。此外,也可以获得容器运行和停止次数以及Docker的镜像数量。Dashboard视图可以创建任何数据的图标,或者设置整个部署、主机群、容器镜像指标的图表。例如下图显示了运行容器的数量并加以镜像类型分类,此刻在我的集群运行了9个Ubuntu:14.04的容器。
11.png

您还可以通过主机分类同样的数据,如下图所示,7个容器在我的Rancher主机上运行,其余的在我的本地的笔记本电脑。
12.png

DataDog还支持一种称为Monitors的警报功能。DataDog的一个monitor相当于Scout的一个触发器,并允许您定义各种指标的阈值。 比起Scout,DataDog的警报系统相当灵活与详细。下面的例子说明如何指定您监视的Ubuntu容器的终止,因此你会监视从Ubuntu:14.04的Docker镜象所创建容器的docker.containers.running信息。
13.png

然后,特定的警报情况是,如果在我们的部署中最后5分钟有(平均)少于十个Ubuntu容器,你就会被警报。尽管这里没有显示,你会被要求填写发送出去时的指定消息在这个警报被触发后,而且还有受到此警报的目标。在当前的例子中,我用一个简单的绝对阈值。您也可以指定一个基于增量的警报,比如是在最后五分钟里停止的容器的平均计数是四的警报。
14.png

最后,使用Metrics Explorer选项卡可以临时聚集你的指标来帮助调试问题或者提取具体的数据信息。该视图允许您基于对容器镜像或主机绘制任何指标的图表。您可以将输出的数据组合成一个单一的图形或者通过镜像或主机的分组来生成一组图形。
15.png

DataDog相比scout在某些功能上做了显著地改善,方便使用以及用户友好的设计。然而这一级别伴随着额外的成本,因为每个DataDog agent价格为$15。

##评分:


  1. 易于部署程度:※※※※※
  2. 信息详细程度:※※※※※
  3. 集成度:※※※※※
  4. 生成警报的能力:支持
  5. 监测非Docker的资源的能力:※※※※※
  6. 成本:每个主机$15

Sensu Monitoring Framework

Scout和Datadog提供集中监控和报警系统,然而他们都是被托管的服务,大规模部署的话成本会很突出。如果你需要一个自托管、集中指标的服务,你可以考虑sensu open source monitoring framework。要运行Sensu服务器可以使用hiroakis/docker-sensu-server容器。这个容器会安装sensu-server、uchiwa Web界面、Redis、rabbitmq-server以及sensu-api。不幸的是sensu不支持Docker。但是,使用插件系统,您可以配置支持容器指标以及状态检查。

在开启sensu服务容器之前,你必须定义一个可以加载到服务器中检查。创建一个名为check-docker.json的文件并添加以下内容到此文件。这个文件告诉Sensu服务器在所有有docker标签的客户端上每十秒运行一个名为load-docker-metrics.sh的脚本。

{
"checks": {
"load_docker_metrics": {
"type": "metric",
"command": "load-docker-metrics.sh",
"subscribers": [
"docker"
],
"interval": 10
}
}
}

现在,您可以使用下面的命令通过我们的检查配置文件来运行Sensu服务器Docker容器。一旦你运行该命令,你就可以在浏览器输入`http://YOUR_SERVER_IP:3000`来访问uchiwa界面。

docker run -d --name sensu-server \
-p 3000:3000 \
-p 4567:4567 \
-p 5671:5671 \
-p 15672:15672 \
-v $PWD/check-docker.json:/etc/sensu/conf.d/check-docker.json \
hiroakis/docker-sensu-server

这样Sensu服务器就开启了,你就可以对每个运行有我们的Docker容器的主机上开启sensu客户端。你告诉容器将有一个名为load-docker-metrics.sh的脚本,所以让我们创建脚本,并将其放到我们的客户端容器内。创建该文件并添加如下所示的文本,将HOST_NAME替换为您的主机的逻辑名称。下面的脚本是为运行容器、所有容器以及镜像而使用Docker远程API来拉取元数据。然后它打印出来sensu的键值标示的值。该sensu服务器将读取标准输出并收集这些指标。这个例子只拉取这三个值,但根据需要,你可以使脚本尽可能详细。请注意,你也可以添加多个检查脚本,如thos,只要早前在服务配置文件中你引用过它们。你也可以定义你想要检查运行Docker容器数量降至三个以下的失败。你还可以使检查通过从检查脚本返回一个非零值失败。

#!/bin/bash
set -e

# Count all running containers
running_containers=$(echo -e "GET /containers/json HTTP/1.0\r\n" | nc -U /var/run/docker.sock \
| tail -n +5 \
| python -m json.tool \
| grep \"Id\" \
| wc -l)
# Count all containers
total_containers=$(echo -e "GET /containers/json?all=1 HTTP/1.0\r\n" | nc -U /var/run/docker.sock \
| tail -n +5 \
| python -m json.tool \
| grep \"Id\" \
| wc -l)

# Count all images
total_images=$(echo -e "GET /images/json HTTP/1.0\r\n" | nc -U /var/run/docker.sock \
| tail -n +5 \
| python -m json.tool \
| grep \"Id\" \
| wc -l)

echo "docker.HOST_NAME.running_containers ${running_containers}"
echo "docker.HOST_NAME.total_containers ${total_containers}"
echo "docker.HOST_NAME.total_images ${total_images}"

if [ ${running_containers} -lt 3 ]; then
exit 1;
fi

现在你已经定义了Docker载入指标检查,那就需要使用usman/sensu-client容器来启动sensu客户端。您可以使用如下所示的命令启动sensu客户端。需要注意的是,容器必须以privileged来运行以便能够访问Unix sockets,它必须有Docker socket挂载以及你上面定义的load-docker-metrics.sh脚本。确保load-docker-metrics.sh脚本在你的主机的权限标记为可执行。容器也需要将SENSU_SERVER_IP、RABIT_MQ_USER、RABIT_MQ_PASSWORD、CLIENT_NAME以及CLIENT_IP作为参数,请指定这些参数到您设置的值。其中RABIT_MQ_USER与RABIT_MQ_PASSWORD默认值是sensu和password。

docker run -d --name sensu-client --privileged \
-v $PWD/load-docker-metrics.sh:/etc/sensu/plugins/load-docker-metrics.sh \
-v /var/run/docker.sock:/var/run/docker.sock \
usman/sensu-client SENSU_SERVER_IP RABIT_MQ_USER RABIT_MQ_PASSWORD CLIENT_NAME CLIENT_IP

16.png

运行完此命令,一会儿你应该看到客户端计数增加1在uchiwa界面。如果您点击客户端图标,你应该看到,包括你刚才添加的客户端的客户端名单。我的客户端1是client-1以及指定的主机IP为192.168.1.1。
17.png

如果你点击客户端名称你应该得到检查的进一步细节。你可以看到load_docker_metrics检查在3月28日的10:22运行过。
18.png

如果你点击检查名称就可以看到检查运行的进一步细节。零表明没有错误,如果脚本失败(例如,如果您的Docker守护进程死掉),你会看到一个错误代码(非零)值。虽然在目前的文章中没有涉及这个,你也还可以使用Handlers在sensu设置这些检查失败处理程序来提醒您。此外,uchiwa只显示检查的值,而不是收集的指标。需要注意的是sensu不存储所收集的指标,它们必须被转发到一个时间序列的数据库如InfluxDB或Graphite。这也是通过Handlers做到的。如何配置指标转发到graphite可以参考这里
19.png

Sensu支持我们所有的评价标准,你可以对我们Docker容器和主机收集尽可能多的细节。此外,你能够聚合所有主机的值到一个地方,并对这些检查发出警报。这些警报并没有DataDog或Sc​​out的先进,因为你仅能够提​​醒单独的主机上检查失败。然而,Sensu的大缺点是部署的难度。虽然我已经使用Docker容器自动部署许多步骤,Sensu仍然是一个需要我们安装,启动和分开维护Redis、RabitMQ、Sensu API、uchiwa与Sensu Core的复杂系统。此外,你将需要更多的工具,如Graphite来呈现指标值以及生产部署需要定制容器,今天我已经使用了一个容器为了密码的安全以及自定义的SSL证书。除了您重启容器后才能添加更多的检查,你将不得不重新启动Sensu服务,因为这是它开始收集新的标准的唯一途径。由于这些原因,我对Sensu的在易于部署的评价相当的低。
##评分:


  1. 易于部署程度:※
  2. 信息详细程度:※※※※
  3. 集成度:※※※※
  4. 生成警报的能力:支持但有限
  5. 监测非Docker的资源的能力:※※※※※
  6. 成本:免费

总结

今天的文章涵盖了多种选项用于监控Docker容器,从免费的选择, 如Docker stats、CAdvisor或Sensu,到有偿服务,如Scout和DataDog。我的研究到目前为止DataDog似乎是用于监控Docker部署的最好的系统。只需几秒的安装以及单行命令,所有主机都在同一个地方报告指标,在UI方面,历史趋势是显而易见的,并且Datadog支持更深层次的指标以及报警。然而,$15一个主机系统对于大型部署是昂贵的。对于较大规模,自托管部署,Sensu是能够满足大多数的要求,不过在建立和管理一个Sensu集群的复杂性可能让人望而却步。很显然,有很多其他的自托管的选项,如Nagios或Icinga,他们都类似Sensu。

但愿今天这篇文章会给你一些想法对于监视容器的选择。我会继续调查其他选项,包括使用CollectD、Graphite或InfluxDB与Grafana的更精简的自我管理的容器监控系统。敬请关注更多的细节。

其他信息:发布本文后,我有一些建议去评估Prometheus和Sysdig云,两个非常好的监控Docker的选择。我在这两个服务上花了一些时间,并添加了第二部分到这个文章中。你可以在这里(译注:过后会翻译这篇)找到它。

想要了解更多关于监控和管理Docker,请参加我们的下一个Rancher在线meetup。

原文:Comparing Five Monitoring Options for Docker (翻译:田浩浩 校对:魏小红)

===========================
译者介绍
田浩浩,USYD研究生,目前在珠海从事手机应用开发工作。业余时间专注Docker的学习与研究,希望通过DockOne把最新最优秀的译文贡献给大家,与读者一起畅游Docker的海洋。

Docker安全性讨论

回复

blood_zer0 回复了问题 • 1 人关注 • 1 个回复 • 230 次浏览 • 2019-05-28 16:16 • 来自相关话题

Service Mesh发展趋势:云原生中流砥柱

大卫 发表了文章 • 0 个评论 • 187 次浏览 • 2019-05-28 15:32 • 来自相关话题

【编者的话】本文主要介绍了 ServiceMesh 最新的产品动态,分析其发展趋势和未来走向;结合蚂蚁的上云实践,阐述在云原生背景下 Service Mesh 的核心价值,以及对云原生落地的关键作用。 内容主要有三个部分: ...查看全部
【编者的话】本文主要介绍了 ServiceMesh 最新的产品动态,分析其发展趋势和未来走向;结合蚂蚁的上云实践,阐述在云原生背景下 Service Mesh 的核心价值,以及对云原生落地的关键作用。

内容主要有三个部分:

  1. Service Mesh 产品动态:介绍最近半年 Service Mesh 的产品动态,包括开源项目和云厂商推出的云上服务
  2. Service Mesh 发展趋势:根据最近的产品动态,总结 Service Mesh 的发展趋势,推断未来的走向
  3. Service Mesh 与云原生:结合云原生,更好的理解 Service Mesh 的价值和作用

#Service Mesh产品动态

##Istio 1.1 发布

Istio 是目前 Service Mesh 社区最引人注目的开源项目,在今年的3月份发布了期待已久的 Istio 1.1 版本,我们来看看 Istio 最近几个版本的发布情况:

* 2018年6月1日,Istio 发布了 0.8 版本,这是Istio历史上第一个LTS版本,也是Istio历史上变动最大的一个版本
* 2018年7月31日,Istio发布了1.0版本,号称 “Product Ready”
* 然后就是漫长的等待,Istio 1.0 系列以每个月一个小版本的方式一路发布了1.0.1 到 1.0.6,然后才开始 1.1.0 snapshot 1到6,再 1.1.0-rc 1到6,终于在2019年3月20日发布了 1.1 版本,号称 “Enterprise Ready”。

从 Istio 1.0 到 Istio 1.1,中间的时间跨度高达 9 个月!我们来看看经过这漫长的开发时间才发布的 Istio 1.1 版本带来了哪些新的东西:
1.png

图中标红的部分,涉及到 Istio 的架构调整,下面将详细介绍 Istio 1.1 版本中带来的架构变化。如果你想和更多 Service Mesh 技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态
##Istio 1.1 架构变化

下图是 Istio 1.0 和 Istio 1.1 的架构图对比:
2.png

Istio 1.1 的第一个架构变化来自 Galley:在 Istio 1.1 的架构图中增加了 Galley 组件。但是实际上在 Istio 1.0 版本中 Gallay 组件就已经存在,只是当时 Galley 的功能非常简单,只是做配置更新之后的验证(Validation),在 Istio 1.0 的架构图中都没有出现。而在 Istio 1.1 版本之后,Galley 的定位发生了巨大的变化:Galley开始分担 Pilot/Mixer 的职责。

在 Istio 1.1 版本之前的设计中,Istio的三大组件 Pilot/Mixer/Citadel 都需要访问 Kubernetes 的 API Server,以获取服务注册信息和配置信息,包括 Kubernetes 原生资源如 Service/Deployment/Pod 等,还有 Istio 的自定义资源(数量多达50多个的 CRD) 。这个设计导致 Istio 的各个组件都不得不和 Kubernetes 的 API Server 产生强绑定,不仅仅代码大量冗余,而且在测试中也因为需要和 Kubernetes 的 API Server 交互导致 Pilot/Mixer 模块测试困难。

为了解决这个问题,在 Istio 1.1 之后,访问 Kubernetes 的 API Server 的工作将逐渐交给 Galley 组件,而其他组件如 Pilot/Mixer 就会和 Kubernetes 解耦。
3.png

这个工作还在进行中,目前 Istio 的CRD 已经修改为由 Galley 读取,而 Kubernetes 的原生资源(Service/Deployment/Pod 等),暂时还是由 Pilot 读取。

为了方便在各个组件中同步数据,Istio 引入了MCP(Mesh Configuration Protocol)协议。在 Istio 1.1 版本中,Pilot 通过 MCP 协议从 Galley 同步数据。MCP是受 xDS v2 协议(准确说是 aDS)的启发而制定的新协议,用于在Istio 各模块之间同步数据。

Istio 1.1 的第二个架构变化来自于 Mixer,在 Istio 1.1 版本中,推荐使用 Out-of-Process Adapter,即进程外适配器。Istio 预计下一个版本将弃用 In-Proxy Adapter,目前所有的 Adapter 都将改为 Out-of-Process adapter。

什么是 In-Proxy Adapter?下图是 Mixer 的架构图,在 Istio 的设计中,Mixer 是一个独立进程,Proxy 通过远程调用来和 Mixer 交互。而 Mixer 的实现了 Adapter 模式,定义了 Adapter API,然后内建了数量非常多的各种 Adapter。这些 Adatper 的代码存放在 Mixer 代码中,运行时也在 Mixer 的进程内,因此称为 In-Process Adapter。
4.png

In-Process Adapter 的问题在于所有的 Adapter 的实现都和 Mixer 直接绑定,包括代码和运行时。因此当 Adapter 需要更新时就需要更新整个 Mixer,任意一个 Adapter 的实现出现问题也会影响整个 Mixer,而且数量众多的 Adapter 也带来了数量众多的CRD。为此,Istio 1.1 版本中通过引入 Out-of-Process Adapter 来解决这个问题。
5.png

Out-of-Process Adapter以独立进程的方式运行在 Mixer 进程之外,因此 Out-of-Process Adapter 的开发/部署和配置都可以独立于 Mixer,从而将 Mixer 从 Adaper 的实现细节中解脱出来。

但是,Out-of-Process Adapter的引入,会导致新的性能问题:原来 Mixer 和 In-Process Adapter 之间是方法调用,现在改成 Out-of-Process Adapter 之后就变成远程调用了。而 Mixer 一直以来都是 Istio 架构设计中最大的争议,之前 Proxy 和 Mixer 之间的远程调用,已经造成非常大的性能瓶颈,而引入 Out-of-Process Adapter 之后远程调用会从一次会变成多次(每个配置生效的 Out-of-Process Adapter 就意味着一次远程调用),这会让性能雪上加霜。

总结 Out-of-Process Adapter 的引入:架构更加的优雅,性能更加的糟糕。

在 Istio 1.1 为了架构而不顾性能的同时,Istio 内部也有其他的声音传出,如正在规划中的 Mixer v2。这个规划最重要的决策就是放弃 Mixer 独立进程的想法,改为将 Mixer 的功能合并到 Envoy 中,从而避免 Envoy 和 Mixer 之间远程调用的开销。关于 Mixer 的性能问题和 Mixer 合并的思路,蚂蚁金服在去年六月份开始 SOFAMesh 项目时就有清晰的认识和计划,时隔一年,终于欣喜的看到 Istio 开始正视 Mixer 的架构设计问题并回到正确的方向上。

对此有兴趣的朋友可以通过阅读下面的文章获取更详细的信息(发表于一年前,但是依然有效):

* 大规模微服务架构下的Service Mesh探索之路:第二节架构设计中的”合并部分Mixer功能”
* Service Mesh架构反思:数据平面和控制平面的界线该如何划定?
* Mixer Cache: Istio的阿克琉斯之踵?: 系列文章,有两篇
* Istio Mixer Cache工作原理与源码分析:系列文章,有四篇

目前 Mixer v2 的规划还处于 Review 状态,实现方式尚未有明确决定。如果要合并 Mixer,考虑到目前 Mixer 是基于 Golang 编写,而 Envoy 是基于 C++ ,这意味着需要用 C++重写所有的 Adapter,工作量巨大,恐怕不是短期之内能够完成的。当然也有另外一个新颖(或者说脑洞大开)的思路:引入 Web Assembly(WASM)。目前 Envoy 在进行支持 Web Assembly 的尝试,如果成功,则通过 Web Assembly 的方式来支持 Mixer Adapter 不失为一个好选择。
##其他社区产品动态

最近,CNCF 在筹建 Universal Data Plane API (UDPA/通用数据平面API)工作组,以制定数据平面的标准 API,为 L4/L7 数据平面配置提供事实上的标准。Universal Data Plane API 的创意来自 Envoy,实现为 xDS API。而目前 xDS v2 API 已经是数据平面API的事实标准,这次的 UDPA 会以xDS v2 API 为基础。工作组的初始成员来自包括 Envoy 和 gRPC 项目的代表,蚂蚁金服也在积极参与 UDPA 工作组,目前还处于非常早期的筹备阶段。

Linkerd2 在2019年4月17日发布了最新的稳定版本 Linkerd 2.3 版本。Linkerd2 是目前开源产品中唯一正面对抗 Istio 的存在,不过在国内知名度不高,使用者也很少。比较有意思的是,开发Linkerd2 的初创公司 Buoyant 最近的B轮融资来自 Google 的投资部门。
##云厂商的产品动态

随着 Service Mesh 技术的发展,和各方对 Service Mesh 前景的看好,各大主流云提供商都开始在 Service Mesh 技术上发力。

首先看 AWS,在2019年4月,AWS 宣布 App Mesh GA。App Mesh 是 AWS 推出的AWS原生服务网格,与AWS完全集成,包括:

* 网络(AWS cloud map)
* 计算(Amazon EC2 和 AWS Fargate)
* 编排工具(AWS EKS,Amazon ECS 和 EC2 上客户管理的 Kubernetes)

6.png

App Mesh 的数据平面采用 Envoy,产品非常有创意的同时支持VM和容器,支持多种产品形态,如上图所示。

Google 的打法则是围绕 Istio 。首先是在2018年底推出了 Istio on GKE,即”一键集成 Istio”,并提供遥测、日志、负载均衡、路由和 mTLS 安全能力。接着 Google 又推出 Google Cloud Service Mesh,这是 Istio 的完全托管版本,不仅仅提供 Istio 开源版本的完整特性,还集成了 Google Cloud上 的重要产品 Stackdriver 。

近期,Google 推出 Traffic Director 的 beta 测试版本,Traffic Director 是完全托管的服务网格流量控制平面,支持全局负载均衡,适用于虚拟机和容器,提供混合云和多云支持、集中式健康检查和流量控制,还有一个非常特别的特性:支持基于流量的自动伸缩。
7.png

微软则推出了 Service Fabric Mesh。Azure Service Fabric 是 Microsoft 的微服务框架,设计用于公共云,内部部署以及混合和多云架构。而 Service Fabric Mesh 是 Azure 完全托管的产品,在 2018 年 8 月推出预览版。
8.png

上周(5月21号)最新消息,微软在 kubeconf 上推出 Service Mesh Interface。SMI 是在 Kubernetes 上运行服务网格的规范,定义了由各种供应商实现的通用标准,使得最终用户的标准化和服务网格供应商的创新可以两全其美,SMI 预期将为 Service Mesh 带来了灵活性和互通性。

SMI是一个开放项目,由微软,Linkerd,HashiCorp,Solo,Kinvolk 和 Weaveworks联合启动;并得到了 Aspen Mesh,Canonical,Docker,Pivotal,Rancher,Red Hat 和 VMware 的支持。
9.png

#Service Mesh发展趋势

在分享完最近半年 Service Mesh 产品的动态之后,我们来分析探讨 Service Mesh 的发展趋势。
##趋势 1:上云 + 托管

在微服务/容器这些年的发展历程中,我们会发现一个很有意思(甚至有些哭笑不得)的现象:
10.png


* 为了解决单体的复杂度问题,我们引入微服务架构
* 为了解决微服务架构下大量应用部署的问题,我们引入容器
* 为了解决容器的管理和调度问题,我们引入 Kubernetes
* 为了解决微服务框架的侵入性问题,我们引入 Service Mesh
* 为了让 Service Mesh 有更好的底层支撑,我们又将 Service Mesh 运行在 Kubernetes 上

在这个过程中,从单个应用(或者微服务)的角度看,的确自身的复杂度降低,在有底层系统支撑的情况下部署/维护/管理/控制/监控等也都大为简化。但是站在整个系统的角度,整体复杂度并没有消失,只是从单体分解到微服务,从应用下沉到 Service Mesh,复杂度从总量上不但没有减少,反而大为增加。

解决这个问题最好的方式就是 上云,使用 托管 版本的 Kubernetes 和 Service Mesh,从而将底层系统的复杂度交给云厂商,而客户只需要在云的基础上享受 Service Mesh 技术带来的使用便利和强大功能。

前面我们分享产品动态时,可以看到目前 Google/AWS/微软这三巨头都已经推出了各自的 Service Mesh 托管产品,而在国内,阿里云/华为云等也有类似的产品推出,我们蚂蚁金服也将在稍后在金融云上推出 SOFAMesh 的云上托管版本。在这里,我总结为一句话:

几乎所有的主要公有云提供商都在提供(或者准备提供)Service Mesh托管方案
##趋势 2:VM 和容器混用

第二个趋势就是 VM 和容器混用,即 Service Mesh 对服务的运行环境的支持,不仅支持容器(尤其指 Kubernetes),也支持虚拟机,而且支持运行在这两个环境下的服务相互访问,甚至直接在产品层面上屏蔽两者的差异。

比如 Google 的 Traffic Director 产品:
11.png

AWS 的 App Mesh产品:
12.png

都是在产品层面直接提供 VM 和容器混用的支持,不管应用是运行在 VM 上还是容器内都可以支持,而且可以方便的迁移。
##趋势 3:混合云和多云支持

混合云和多云支持最近正成为一个新的技术热点和商业模式,甚至 Google Cloud 都喊出口号,要 “All in Hybrid Cloud”!

Google Traffic Director 旗帜鲜明的表达了 Google Cloud 对混合云的重视:
13.png

下图是 Google Traffic Director 给出的一个应用改造示例:从单体结构转为微服务架构,从私有云转为公有云加私有云的混合云模式。
14.png

Service Mesh 毫无疑问是实现上述转型并提供混合云和多云支持的一个非常理想的解决方案。
##趋势 4:和 Serverless 的结合

Service Mesh 技术和 Serverless 技术是工作在不同纬度的两个技术:

* Service Mesh 技术的关注点在于服务间通讯,其目标是剥离客户端 SDK,为应用减负,提供的能力主要包括安全性、路由、策略执行、流量管理等。
* Serverless 技术的关注点在于服务运维,目标是客户无需关注服务运维,提供服务实例的自动伸缩,以及按照实际使用付费。

理论上 Service Mesh 技术和 Serverless 技术并没有冲突的地方,可以结合使用。事实上目前业界也开始出现这个趋势,而融合的方式有两种:

  1. 在Serverless中引入Service Mesh:典型如 Knative 项目和 Knative 的 Google Cloud 托管版本 Google Cloud Run,通过引入对容器的支持和使用 Istio,Knative 将 Serverless 的支持扩展到 Function 之外,在极大的扩展 Serverless 适用范围的前提下,也将服务间通讯的能力引入到 Serverless。
  2. 在Service Mesh 中引入 Serverless:典型如 Google Traffic Director 产品,在提供 Service Mesh 各种能力的同时,支持按照流量自动伸缩服务的实例数量,从而融入了部分 Serverless 的特性。

对于 Serverless 和 Service Mesh 的结合,我们来展望未来形态:未来应该会出现一种新型服务模式,Serverless 和 Service Mesh 合二为一。只要将服务部署上来,就自动可以得到 Service Mesh 的服务间通讯能力和 Serverless 的无服务器运维。在蚂蚁金服,我们将这理解成为是未来云原生应用的终态之一,正在积极的探索其落地的实际方式。
15.png

##趋势 5:Mesh 模式延伸

回顾一下 Service Mesh 模式的核心,其基本原理在于将客户端 SDK 剥离,以 Proxy 独立进程运行;目标是将原来存在于 SDK 中的各种能力下沉,为应用减负,以帮助应用云原生化。

遵循这个思路,将 Service Mesh 的应用场景泛化,不局限于服务间的同步通信,就可以推广到更多的场景:特征是有网络访问,而是通过客户端 SDK 来实现。

在蚂蚁金服的实践中,我们发现 Mesh 模式不仅仅适用于服务间同步通讯,也可以延伸到以下场景:

* Database Mesh: 数据库访问
* Message Mesh:消息机制
* Cache Mesh:缓存

以上模式的产品蚂蚁金服都在探索中,相关的产品正在开发和尝试落地。社区也有一些相关的产品,比如 Database Mesh 方面张亮同学在力推的 Apache Shardingsphere 项目。

通过更多的 Mesh 模式,我们可以覆盖更多的场景,从而实现让应用在各个方面都做到减负,而不仅仅是 Service Mesh 对应的服务间通讯,从而为后续的应用云原生化奠定基础。
##趋势 6:标准化,不锁定

云原生的一个重要主张,就是希望在云上为用户提供一致的用户体验,提倡标准化,避免供应商绑定(Not Lock-In)。

从前面分享的 Service Mesh 产品动态可以看出,目前 Service Mesh 市场上出现了众多的供应商和产品:开源的,闭源的,大公司出的,小公司出的,市场繁荣的同时也带来了市场碎片化的问题——所有围绕业务应用的外围工作,比如通过 Service Mesh 对流量进行控制,配置各种安全/监控/策略等行为,以及在这些需求上建立起来的工具和生态系统,却不得不牢牢的绑死在某个具体的 Service Mesh 实现上,所谓”供应商锁定”。其根本问题在于各家实现不同,又没有统一标准。因此,要想解决上述问题,就必须釜底抽薪:解决 Service Mesh 的标准化问题。

就在最近这一个月,Service Mesh 社区出现了两个推动标准化的大事件:

  1. CNCF筹建 Universal Data Plane API (通用数据平面API)工作组,计划以 xDS v2 API 为基础制定数据平面的标准API,工作组的初始成员来自包括 Envoy 和 gRPC 项目的代表(可以理解为 Google 为首)
  2. 微软在 kubeconf 上推出 Service Mesh Interface,准备定义在 Kubernetes 上运行服务网格的规范,为 Service Mesh 带来了灵活性和互通性。SMI由微软牵头,联合 Linkerd,HashiCorp,Solo,Kinvolk 和Weaveworks。

为了方便理解这两个标准,我为大家准备了一张图:
16.png

其中,Universal Data Plane API 是数据平面的标准,控制平面通过这个 API 来控制数据平面的行为。而 Service Mesh Interface 是控制平面的标准,上层的应用/工具/生态体系通过 Service Mesh Interface 来实现跨不同的 Service Mesh 实现为最终用户提供一致性的体验。

当然这两个标准化 API 都刚刚起步,而且,标准化的工作通常不仅仅是技术问题,涉及到复杂的利益关系,具体未来走向现在难于推断,只能密切关注。
##发展趋势分析

我们总结一下上面列出的 Service Mesh 最近的6个发展趋势:
17.png

这些趋势都和云有关,核心在于让云来提供能力,包括:

* 让云承担更多职责
* 提供更高抽象
* 适用更多场景
* 减少应用负担:实现应用轻量化

最终实现让业务应用专注业务的战略目标。

对于 Service Mesh 技术未来的走向,我的看法是:Service Mesh 技术必然不是孤立的自行发展,而是在云原生的大环境下,与云原生的其他技术、理念、最佳实践一起相互影响、相互促进、相互支撑、共同发展。云原生是一个庞大的技术体系,Service Mesh 需要在这个体系中获得各种支撑和配合,才能最大限度的发挥自身的优势。
#Service Mesh与云原生

在最后一段,我们来谈谈 Service Mesh 技术和云原生的关系,也就是本次分享的标题所说的:云原生中流砥柱。

凭什么?
##什么是云原生?

在解释之前,首先问一个问题:什么是云原生?相信这个问题很多同学都问过,或者被问过,每个人心里可能都有自己的理解和表述。在今年年初,我也特意就这个问题问了自己,然后尝试着给出了一个我的答案:

云原生指 “原生为云设计”,具体说就是:应用原生被设计为在云上以最佳方式运行,充分发挥云的优势。
18.png

关于云原生的理解,以及对这句话的详细阐述,这里不详细展开。
#Service Mesh的核心价值

关于 Service Mesh 的核心价值,我个人的理解,不在于 Service Mesh 提供的玲琅满目的各种功能和特性,而是:

实现业务逻辑和非业务逻辑的分离

将非业务逻辑的功能实现,从客户端 SDK 中剥离出来,放到独立的 Proxy 进程中,这是 Service Mesh 在技术实现上走出的第一步,也是至关重要的第一步:因为这一步,实现了业务逻辑和非业务逻辑的分离,而且是最彻底的物理分离,哪怕需要为此付出一次远程调用的代价。

而这一步迈出之后,前面就是海阔天空:

* 业务逻辑和非业务逻辑分离之后,我们就可以将这些非业务逻辑继续下沉
* 下沉到基础设施,基础设施可以是基于VM的,可以是基于容器和k8s的;也可以是VM和容器混合
* 基础设施也可以以云的形式提供,可以是公有云、私有云,也可以是混合云、多云;
* 可以选择云上托管,完全托管也好,部分托管也好,产品形态可以很灵活

总结说,业务逻辑和非业务逻辑的分离:

* 为下沉到基础设施提供可能
* 为上云提供可能
* 为应用轻量化提供可能

备注:这里说的上云,指的是上云原生(Cloud Native)的云,而不是上云就绪(Cloud Ready)的云。
##Mesh 化是云原生落地的关键步骤

在过去一年中,蚂蚁金服一直在努力探索云原生落地的方式,在这个过程中,我们有一些感悟,其中非常重要的一条就是:Mesh 化是云原生落地的关键步骤。
19.png

如上图所示:

* 最下方是云,基于 Kubernetes 和容器打造,提供各种基础能力,这些能力有一部分来自传统中间件的下沉
* 在云上是 Mesh 层,包含 Service Mesh 以及我们前面提到的各种扩展的 Mesh 模式,实现通信的标准化
* 在通过 Mesh 剥离非业务功能并下沉之后,应用实现了轻量化,传统的 App 和新兴的微服务都可以受益于此
* 更进一步,轻量化之后的业务应用,其工作负载在瘦身减负之后变得相当的干净,基本只剩业务逻辑,包括传统的 App,以 Container 形式运行的服务和新颖的 Function,这些负载在往 Serverless 形态转换时相对要轻松很多

配合 Serverless 技术领域最新的技术潮流和产品发展(如以 knative 项目为代表,Serverless 不再仅仅是 Function 形式,也支持 BaaS 等偏传统的工作负载),Mesh化为现有应用转型为 Serverless 模式提供助力。

在这里我们再分享一下蚂蚁金服对未来中间件产品发展的感悟,我们认为中间件的未来在于 Mesh 化,并融入基础设施,如下图所示:
20.png

左边是传统的中间件形态,在云原生时代,我们希望将非业务功能从传统中间件的富客户端中剥离出来,然后将这些能力以及这些能力背后的中间件能力,下沉到基础设施,下沉到云。而中间件产品也会融入基础设施,如图中右边所示。未来的中间件将作为基础设施和云的一部分,而 Mesh 则成为连接应用和基础设施以及其他中间件产品的桥梁。

更重要的是:业务应用因此而实现轻量化,在剥离各种非业务功能之后,业务应用就实现了只关注业务逻辑的战略目标,从而实现从传统应用到云原生应用的转型。

总结:通过 Service Mesh 技术,我们实现了业务逻辑和非业务逻辑的分离,为应用的轻量化和云原生化提供可能;并通过将非业务逻辑的各种功能下沉到基础设施和云,极大的增强了基础设施和云的能力,为云原生的落地提供了极大助力。

因此,我们认为: Service Mesh 技术将在云原生落地中扮演了非常重要的作用,不可或缺。
##Service Mesh发展展望

最后再次展望一下 Service Mesh 的未来发展。

左边是 Service Mesh 发展初期的最重要的两个原始动力:多语言支持和类库升级。关于这两点,最近这两年中介绍和推广 Service Mesh 理念和产品的同学基本都讲过,但是今天我想指出的是:这只是 Service Mesh 的起点,而远不是 Service Mesh 的终点。

Service Mesh 的未来,不会停留在仅仅满足多语言支持和类库升级,而是跟随云原生的大潮,解决各种实际需求,同时又尽量维持上层业务应用的简单直白。
21.png

在这次分享的最后,我想给大家一个留一个课外作业,有心的同学可以尝试一下:如果您想更深入的理解 Service Mesh 的价值,想对 Service Mesh 未来的发展方向有更清晰的认识,尤其是希望能通过自身的思考和感悟来理解 Service Mesh 而不是简单的被灌输(包括被我灌输),那么请尝试独立的做如下思考:

  1. 抛开左边的这两点,不要将思维局限在这个范围内
  2. 考虑云原生的大背景,结合您自身对云原生的理解,和对云的期望
  3. 针对右边的 Service Mesh 的六个趋势,忘记我前面讲述的内容,只考虑其背后的实际场景和客户需求,以及这个场景带来的业务价值,然后认真对比使用 Service Mesh 和不使用 Service Mesh 两种情况下的解决方案
  4. 请在上述思考的过程中,更多的从业务应用的角度来看待问题,假设你是那个云上的应用(还记得前面图上的小 baby 吗?),你会希望被如何对待

希望这样的思考能让您有所收获。

原文链接:https://skyao.io/talk/201905-servicemesh-development-trend/

Zookeeper 扩展之殇

齐达内 发表了文章 • 0 个评论 • 173 次浏览 • 2019-05-28 12:27 • 来自相关话题

#一、背景 基于公司发展硬性需求,生产VM服务器要统一迁移到ZStack虚拟化服务器。检查自己项目使用的服务器,其中ZooKeeper集群中招,所以需要进行迁移。如果你想和更多ZooKeeper技术专家交流,可以加我微信liyingjiese,备 ...查看全部
#一、背景

基于公司发展硬性需求,生产VM服务器要统一迁移到ZStack虚拟化服务器。检查自己项目使用的服务器,其中ZooKeeper集群中招,所以需要进行迁移。如果你想和更多ZooKeeper技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态
#二、迁移计划

为了使迁移不对业务产生影响,所以最好是采用扩容 -> 缩容 的方式进行。
1.png

说明:

  1. 原生产集群为VM-1,VM-2,VM-3组成一个3节点的ZooKeeper集群;
  2. 对该集群扩容,增加至6节点(新增ZS-1,ZS-2,ZS-3),进行数据同步完成;
  3. 进行缩容,下掉原先来的三个节点(VM-1,VM-2,VM-3);
  4. 替换Nginx解析地址。

OK! 目标很明确,过程也很清晰,然后开干。
#三、步骤(过程已在测试环境验证无问题)

对新增的三台服务器进行zk环境配置,和老集群配置一样即可,最好使用同一版本(版主使用的是3.4.6);

对老节点的zoo.cfg增加新集群的地址(逐一增加),然后对新增加节点逐一重启。
2.png

#四、问题

ZS-1 启动成功,zkServer.sh status报错,用zkServer.sh status查看,反馈如下异常:
[root@localhost bin]# ./zkServer.sh  status
ZooKeeper JMX enabled by default
Using config: /usr/zookeeper/zookeeper-3.4.6/bin/../conf/zoo.cfg
Error contacting service. It is probably not running.

此时查看数据,数据同步正常。

ZS-1数据同步正常,但是无法查看节点的状态信息;

怀疑是因为老节点没有重启的原因;此时去查看原集群节点信息,发现原集群节点状态异常。经排查定位,原集群的状态一直处于异常状态。

初步定位原因可能是原集群的选举存在异常,导致新节点无法正常纳入,继续排查。

恢复集群初始状态,如果集群节点的状态一直没法正常查看。OK 继续定位……
#五、排查过程

以下方法来自于网络:

可能有以下几个原因:

第一、zoo.cfg文件配置:dataLogDir指定的目录未被创建。
1.zoo.cfg
[root@SIA-215 conf]# cat zoo.cfg
...
dataDir=/app/zookeeperdata/data
dataLogDir=/app/zookeeperdata/log
...

2.路径
[root@SIA-215 conf]# cd /app/zookeeperdata/
[root@SIA-215 zookeeperdata]# ll
total 8
drwxr-xr-x 3 root root 4096 Apr 23 19:59 data
drwxr-xr-x 3 root root 4096 Aug 29 2015 log

经排查 排除该因素。

第二、myid文件中的整数格式不对,或者与zoo.cfg中的server整数不对应。
[root@SIA-215 data]# cd /app/zookeeperdata/data
[root@SIA-215 data]# cat myid
2[root@SIA-215 data]#

定位排查后排除不是该原因。

第三、防火墙未关闭。

使用service iptables stop关闭防火墙;使用service iptables status确认;使用chkconfig iptables off禁用防火墙。

确认防火墙是关闭的。
[root@localhost ~]# service iptables status
iptables: Firewall is not running.
确认防火墙是关闭的

第四、端口被占用。
[root@localhost bin]# netstat -tunlp | grep 2181
tcp 0 0 :::12181 :::* LISTEN 30035/java
tcp 0 0 :::22181 :::* LISTEN 30307/java

确认端口没有被占用

第五、zoo.cfg文件中主机名出错。

经测试环境测试,主机名正确,多域名解析也正常,不存在此问题。

第六、hosts文件中,本机的主机名有两个对应,只需保留主机名和IP地址的映射。

经测试环境测试,主机名正确,多域名解析也正常,不存在此问题 排除。

第七、zkServer.sh里的nc命令有问题。

可能是机器上没有安装nc命令,还有种说法是在zkServer.sh里找到这句:

STAT=`echo stat | nc localhost $(grep clientPort “$ZOOCFG” | sed -e ‘s/.*=//’) 2> /dev/null| grep Mode`
在nc与localhost之间加上 -q 1 (是数字1而不是字母l)。

ZooKeeper版本是3.4.6,zkServer.sh里根本没有这一句(获取状态的语句没有用nc命令)
 # -q is necessary on some versions of linux where nc returns too quickly, and no stat result is output
clientPortAddress=`grep "^[[:space:]][i]clientPortAddress[^[:alpha:]]" "$ZOOCFG" | sed -e 's/.[/i]=//'`
if ! [ $clientPortAddress ]
then
clientPortAddress="localhost"
fi
clientPort=`grep "^[[:space:]][i]clientPort[^[:alpha:]]" "$ZOOCFG" | sed -e 's/.[/i]=//'`
STAT=`"$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
-cp "$CLASSPATH" $JVMFLAGS org.apache.zookeeper.client.FourLetterWordMain \
$clientPortAddress $clientPort srvr 2> /dev/null \
| grep Mode`
if [ "x$STAT" = "x" ]
then
echo "Error contacting service. It is probably not running."
exit 1
else
echo $STAT
exit 0
fi
;;

#六、以下是自己排查的方式

目前现象老集群数据同步正常,也能进行leader选举(从日志获取),但是无法查看节点状态,同异常信息;进行集群扩容,数据不能同步。

解决方法:

1、尝试进行foreground 模式启动,选择一台非主节点进行重启,可以前台查看启动日志。
zkserver.sh start-foreground

节点启动正常,无异常输出。
2、查看shell脚本:分析zkServer.sh。

"Error contacting service. It is probably not running." 这块日志出现以下脚本中。
STAT=`"$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
-cp "$CLASSPATH" $JVMFLAGS org.apache.zookeeper.client.FourLetterWordMain \
$clientPortAddress $clientPort srvr 2> /dev/null \
| grep Mode`
if [ "x$STAT" = "x" ]
then
echo "Error contacting service. It is probably not running."
exit 1
else
echo $STAT
exit 0
fi
;;

截取其中一部分脚本内容:我们可以初步定为应该是 $STAT 获取存在异常 如果STAT变量为空,则会显示Error contacting service. It is probably not running.: OK,那就分析下这个$STAT到底是什么鬼?
 if [ “x$STAT” = “x” ]
then
echo “Error contacting service. It is probably not running.”
exit 1
else
echo $STAT
exit 0
fi

3、尝试用shell的debug模式 看下执行过程:

截取片段执行日志如下 :果然STAT变量确实为空,导致输出Error contacting service. It is probably not running.并且退出。
++ grep '^[[:space:]]*clientPort[^[:alpha:]]' /app/zookeeper-3.4.6/bin/../conf/zoo.cfg
+ clientPort=5181
++ grep Mode
++ /opt/jdk1.8.0_131/bin/java -Dzookeeper.log.dir=. -Dzookeeper.root.logger=INFO,CONSOLE -cp '/app/zookeeper-3.4.6/bin/../build/classes:/app/zookeeper-3.4.6/bin/../build/lib/[i].jar:/app/zookeeper-3.4.6/bin/../lib/slf4j-log4j12-1.6.1.jar:/app/zookeeper-3.4.6/bin/../lib/slf4j-api-1.6.1.jar:/app/zookeeper-3.4.6/bin/../lib/netty-3.7.0.Final.jar:/app/zookeeper-3.4.6/bin/../lib/log4j-1.2.16.jar:/app/zookeeper-3.4.6/bin/../lib/jline-0.9.94.jar:/app/zookeeper-3.4.6/bin/../zookeeper-3.4.6.jar:/app/zookeeper-3.4.6/bin/../src/java/lib/[/i].jar:/app/zookeeper-3.4.6/bin/../conf:.:/opt/jdk1.8.0_131/lib/dt.jar:/opt/jdk1.8.0_131/lib/tools.jar' org.apache.zookeeper.client.FourLetterWordMain localhost 5181 srvr
+ STAT=
+ ‘[‘ x = x ‘]’
+ echo ‘Error contacting service. It is probably not running.’
Error contacting service. It is probably not running.
+ exit 1

4、修改shell脚本:分析zkServer.sh 在脚本总增加输出STAT 内容,这次我们不进行过滤。
STAT1=`"$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
-cp "$CLASSPATH" $JVMFLAGS org.apache.zookeeper.client.FourLetterWordMain \
$clientPortAddress $clientPort srvr 2> test.log \ `

echo "$STAT1"

最好的方式是copy一个新脚本,以免污染原本的脚本。我是这么做的;然后运行该脚本。
[root@localhost bin]# ./zkServer.sh  status
ZooKeeper JMX enabled by default
Using config: /usr/zookeeper/zookeeper-3.4.10/bin/../conf/zoo.cfg
Error contacting service. It is probably not running.

然后查看生成的test.log 文件:果然存在异常内容。
in thread “main” java.lang.NumberFormatException: For input string: “2181
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at org.apache.zookeeper.client.FourLetterWordMain.main(FourLetterWordMain.java:76)

从日志信息来看,提示说2181这个端口号造成的。 不是一个合法的数字。

zkServer.sh里有这么一句:
clientPort=`grep “^[[:space:]][i]clientPort[^[:alpha:]]” “$ZOOCFG” | sed -e ‘s/.[/i]=//’`
grep “^[[:space:]][i]clientPort[^[:alpha:]]” “$ZOOCFG” | sed -e ‘s/.[/i]=//’在执行过程中,实际命令如下:
grep ‘^[[:space:]][i]clientPort[^[:alpha:]]’ /app/zookeeper-3.4.6/bin/../conf/zoo.cfg | sed -e ‘s/.[/i]=//’

最终可以基本确认配置文件存在问题。

替换配置文件:重启,问题解决。

存在原因可能是编辑zoo.cfg编码格式等等引起文件内容解析异常。

原文链接:http://college.creditease.cn/detail/252

DevOps时代测试应该如何应对?

阿娇 发表了文章 • 0 个评论 • 173 次浏览 • 2019-05-28 11:12 • 来自相关话题

#背景 DevOps的概念最早起源于2009年的欧洲,但由于当时配套技术和工具的匮乏,导致DevOps并没有迅速兴起。近几年随着云计算和大数据等新技术的高速发展以及微服务架构理念的深入实践,提倡持续高效的交付使DevOps成为了一种趋势,容器技术 ...查看全部
#背景

DevOps的概念最早起源于2009年的欧洲,但由于当时配套技术和工具的匮乏,导致DevOps并没有迅速兴起。近几年随着云计算和大数据等新技术的高速发展以及微服务架构理念的深入实践,提倡持续高效的交付使DevOps成为了一种趋势,容器技术又使得DevOps的实施变得相对容易,所以DevOps在各行业各种规模的组织中开始逐步落地实施。

DevOps是Development和Operations的组合词,它是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(Quality Assurance)部门之间的沟通、协作与整合,旨在以高质量持续发布的产品应对瞬息万变的市场需求。DevOps中质量保障贯穿了整个产品的交付周期,是连接开发和运维之间的桥梁。如果没有全面的质量保障和测试策略,就无法实现持续开发和交付。
1.jpg

QA等同于测试么?回答肯定是否定的。QA包含QC(Quality Control)和测试两部分,其主要目标是规划和建立质量评估体系,以确保产品的预期质量;测试是用来验证产品并找到可能缺陷的过程。QA和测试二者相互关联,不可互换与替代。

持续测试作为DevOps的一个关键环节,是产品质量保证最重要的方法,那么传统的测试人员应该如何转型去适应DevOps呢?如果你想和更多DevOps技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态
#传统测试、敏捷测试和持续测试有何不同

传统测试以手工测试为主,对代码级别的测试投入较少,整体呈倒三角模式, 侧重于发现缺陷并修复;敏捷的出现增大了自动化测试的比例,以底层运行速度快、消耗小的单元测试为主,整体呈正三角模式,相比传统测试反馈更及时,修复缺陷的成本低;持续测试在敏捷测试的基础上,强调测试持续进行,通过各部门的协同工作,持续发现缺陷并迅速修复。
2.jpg

传统测试、敏捷测试和DevOps测试

从传统的瀑布型测试到敏捷测试再到DevOps,三者之间具体有什么区别?这一系列的转型对测试提出了什么样的挑战?DevOps中的测试人员需要掌握哪些技能才能做到全面的质量保障?
##传统测试

传统瀑布式软件开发模式中,开发、测试和运维团队之间无协作关系。开发团队负责代码编写和对应的单元测试;测试团队编写手动测试用例并执行,以业务场景测试和系统集成测试为主;QA团队编写自动化测试用例,往往在产品发布前才进行大规模的产品质量验证。

由此可见,传统测试遵循自上而下的顺序方法,产品的质量在测试阶段确定,对产品进行任何更改都非常困难。自动化测试执行效率低,测试用例执行成本高。各部门之间的独立必然导致重复性测试,无法保证全面的产品质量。
##敏捷测试

随着市场需求的加快,传统的瀑布式软件开发模式已经不能够满足频繁的软件交付,敏捷开发模式应运而生。在敏捷测试中,测试不再是一个单独的阶段,它属于迭代计划的一个组成部分,测试人员始终与开发人员保持同步,共同负责产品的质量保障。敏捷提倡频繁且更快地进行测试,因此自动化测试在敏捷测试中至关重要。

从开发到运营的整体流程来看,敏捷模型仅仅融合了开发和测试两个部分,加快了软件开发的频率。但是实际部署到生产环境仍然是由运维团队独立完成,开发和运维之间依然隔着厚厚的一堵墙,繁琐的发布周期使敏捷工作重新回到了瀑布模式。DevOps的出现成功打破了开发和运维之间的隔阂,解决了从开发到部署的这一难题。
##持续测试

持续测试可以看作敏捷测试的进阶版,意味着持续不断的测试,贯穿了整个软件交付周期,包括从需求分析到产品部署的各种测试阶段。持续测试提倡尽早测试、频繁测试和自动化测试。测试与代码开发同时进行,开发人员和测试人员共同分析测试需求,共同编写和维护测试用例,每开发完一项任务就立即运行自动化测试集对交付质量进行验证,从而形成持续验证。代码一旦成功通过了自动化测试集就会立刻部署到生产环境中,进行生产阶段的持续监控。
#DevOps时代的测试应该怎么做

Laurent曾经从测试左移、右移的角度描述了当软件开发模式从瀑布到敏捷、再到DevOps转型时,测试应该如何相应变化。

测试左移,是指测试人员更早地参与到软件项目前期的各项活动中,在功能开发之前定义好相关的测试用例,提前发现质量问题。早期引入测试过程有助于防止缺陷,并为开发人员提供了在整个开发阶段应用动态变更的灵活性。

测试右移,就是直接在生产环境中监控,并且实时获取用户反馈。在这种方法中,从用户侧收集反馈,根据用户反馈持续改进产品的用户体验满意度,提高产品质量。测试右移有助于更好的响应意外情况。

传统测试主要集中在软件开发周期的最后,产品发布之前。为了迎合不断加快的交付频率,越来越多团队的测试活动开始向左右两侧移动。一般问题修复成本较高和面向企业收费的软件,一旦生产环境中出现了问题会造成比较大的损失,通常采取测试左移的方式;对于具有展示功能的软件产品,更容易在生产环境中发现问题,通常采取测试右移的方式。面对测试左右摇摆的问题,小编从以下几个阶段阐述了DevOps中的测试具体应该如何实现。
3.jpg

DevOps中的测试
##用户需求分析

DevOps模式下,与产品相关的所有角色都要参与到用户需求的分析与拆分中,包括开发、测试、运维、产品经理、市场等角色,需全部角色共同确定需求的质量标准和验收条件,并采取BDD(Behavior Driven Development)的方式定义,从而使产品交付流水线上的所有相关人员都能对需求达成一致的理解。
##编码、构建阶段

测试与开发采用TDD(Test-Driven Development)的方式工作,共同分析用户故事、制定验收条件。测试用例与产品开发同步进行和完成,代码一旦开发完会立即通过这些测试套件。这一阶段的测试多以自动化的代码级测试为主,比如单元测试、组件测试、接口/服务级测试等。通常这类的测试不需要启动整个应用程序,运行时间短,从而获得更快的反馈,因此这些测试位于测试套件的前端。
##验收阶段

验收测试用来验证用户需求是否得到了满足,产品是否可以进入部署阶段。制定全面的用户/业务级的验收测试,既验证了软件产品是否交付了用户期望的业务价值,又可以防止回归问题或者缺陷破坏了软件原有的功能。验收测试分为功能验收测试和非功能验收测试。

功能验收测试

功能验收测试运行在类生产环境中,通过模拟用户在真实环境中的操作来验证用户故事是否完成。手工验收测试将代码部署到UAT(User Acceptance Test)环境中,手动模拟用户的操作进行验证;自动化验收测试采用自动化测试工具和应用交付的方式来模拟用户的使用。常见的功能验收测试包括UI(User Interface)测试、集成测试和服务测试等。

非功能验收测试

这一类测试通常运行在特定的环境中,使用的工具类型取决于被测的产品,一般需要花费较长时间和较复杂的环境来运行,所以这类测试一般位于测试套件的后端。常见的非功能验收测试包括容量测试、易用性测试、安全性测试和兼容性测试等满足其交叉功能特性的测试。
##部署阶段(持续监控)

Jez Humble曾指出:“如果真的想获得持续交付的好处,应该尽早将软件产品部署到生产环境中”。代码通过了开发过程中自动化测试套件后,就直接部署到生产环境中,从而获取更直接的反馈。

部署阶段的测试,更准确的说应该叫做生产环境中的监控,从基础监控、应用监控到业务监控,既覆盖了对新功能的可用性测试,也囊括了对已有功能的实时监控,并通过不断的收集用户意见,及时整理、分析并反馈给研发部门,最终实现产品价值的不断提升。常见的监控有两种:一是直接在生产环境上自动运行测试用例;二是通过向生产环境中引入问题来发现产品在生产环境中的潜在问题。
##持续集成(Continuous Integration)

理想的DevOps周期,是从代码开发到生产环境运行的一键部署。显然DevOps非常重视构建、测试和部署的自动化,使用持续集成成为了持续测试的基础。实现持续测试的重要一步,是创建全面的自动化测试套件以在持续集成构建中使用,代码提交后会立刻经过这套自动化测试套件得以验证。常见的自动化测试套件由单元测试、组件检测和验收测试组成,其中每种测试的代码或功能覆盖率至少要达到80%以上才能保证不引入回归问题。
##协作

持续测试的成功实施离不开团队内、团队间及跨团队的协作。新项目从开始就要保证所有成员的共同参与,在协作开发中,开发人员和测试人员在各自的用户故事上并行工作,如开发人员开始编译代码,测试驱动也需跟着启动。代码开发完成就能迅速获取反馈,大大缩短了反馈周期,协同工作也帮助开发人员更好的理解用户故事的真正实现。测试人员同时要积极的参与到持续部署的流程中,在将产品部署到生产环境的过程中跟运维人员做好无缝衔接,尽早制定在生产环境中的监测计划,并根据运维人员的反馈及时调整测试方案。
#对DevOps测试的一些思考

DevOps中质量保证(QA)不再是测试人员的专属责任,而是全体人员都要为之努力的方向。测试人员提前介入到开发工作中,与开发人员一起制定测试计划;开发人员可以参与配置部署;运维人员可以向自动化测试用例库填写测试用例;测试人员随时将自动化测试用例配置到持续交付链中,所有成员的共同目的都是交付高效、高质量的产品。

持续测试要求测试人员具有一定的编码能力。测试人员不但要掌握常用的测试工具、版本控制工具和集成工具的使用,还要能读懂代码,检查构建日志,不断的优化整个测试策略和测试用例。测试人员还必须参与到整个持续交付过程中,以最高效的方式保证产品的质量。

测试人员应该专注于测试策略的不断优化。自动化测试固然是实现持续集成最重要的方式,但并不是所有的测试都适合自动化,比如易用性测试和界面一致性测试等。测试人员需要集中在不断的测试策略优化上,通过调整各种测试用例的比例、增加测试覆盖度、提高测试用例的质量以及快速的反馈来提高测试效率,实现全面的质量保障。

原文链接:https://cloud.tencent.com/developer/article/1423363