五个Docker监控工具的对比

aoxiang 发表了文章 • 0 个评论 • 173 次浏览 • 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 个回复 • 211 次浏览 • 2019-05-28 16:16 • 来自相关话题

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

大卫 发表了文章 • 0 个评论 • 176 次浏览 • 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 个评论 • 157 次浏览 • 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 个评论 • 157 次浏览 • 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

使用Docker和Kubernetes将MongoDB作为微服务运行

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

【编者的话】MongoDB是NoSQL排名第一的数据库,Docker是最流行的容器引擎,Kubernetes是谷歌开源的容器编排工具!Kubernetes和Docker使MongoDB的开发运维部署变得更加简单和强大。 #Docker背景介绍 ...查看全部
【编者的话】MongoDB是NoSQL排名第一的数据库,Docker是最流行的容器引擎,Kubernetes是谷歌开源的容器编排工具!Kubernetes和Docker使MongoDB的开发运维部署变得更加简单和强大。
#Docker背景介绍

想快速安装MongoDB吗?现在只需要执行一个Docker命令,就能快速启动一个轻量级,独立的沙盒;在多个不同的服务器环境中搭建集群,快速部署相同的应用?使用Docker容器会非常的简单,构建自己的Docker容器镜像,让开发、测试、运营和支持团队启动相同的环境克隆。

Docker容器正在彻底改变整个软件生命周期:从最早的技术实验和概念证明到开发、测试、部署和支持。

Kubernetes工具可以管理多个Docker容器的创建,升级和高可用性。Kubernetes业务流程还控制容器如何连接以从多个微服务容器构建复杂的应用程序。Docker容器和Kubernetes编排已经成为DevOps团队的最爱,现在广泛融入到持续集成(CI)和持续交付(CD)工作流程中。

本文深入探讨了在Docker容器中运行和编排MongoDB所面临的额外挑战,并介绍这些挑战的解决办法。
#MongoDB容器的注意事项

使用Docker容器和Kubernetes运行MongoDB额外注意事项:

  1. MongoDB数据库节点有状态信息。如果Docker容器发生故障并重新编排可能导致数据丢失,我们并不希望丢失数据(可以从副本集中的其他节点恢复,但需要时间)。为了解决可能的数据丢失问题,可以使用诸如Kubernetes中的Volume卷抽象之类的功能来将容器中临时性MongoDB数据目录映射到持久性位置,这样就可以容忍容器故障和重新编排,而不会丢失数据。
  2. 集群中的MongoDB数据库节点必须相互通信。副本集中的所有节点都必须知道所有节点的地址,但是当Kubernetes重新编排容器时,可能会使用不同的IP地址重新启动。例如,Kubernetes Pod中的所有容器共享一个IP地址,该地址在重新编排Pod时会发生变化。使用Kubernetes,可以通过将Kubernetes服务与每个MongoDB节点相关联来处理,该节点使用Kubernetes DNS服务为通过重新安排保持不变的服务提供主机名。
  3. 每个MongoDB节点运行后(每个节点都在自己的容器中),必须初始化副本集并添加每个节点。这可能需要编排工具之外的代码。具体而言,必须使用目标副本集群中的主MongoDB节点执行rs.initiate和rs.add命令。
  4. 如果Kubernetes编排框架提供容器的自动重新调度(如Kubernetes那样),那么这可以提高MongoDB的弹性,因为可以自动重新创建失败的副本集成员,从而在没有人为干预的情况下恢复正常状态。
  5. 应该注意的是,虽然Kubernetes可能会监视容器的状态,但它不太可能监视容器内运行的应用程序或备份数据。这意味着我们需要再使用强大的监控和备份解决方案非常重要,例如MongoDB企业高级版和MongoDB专业版附带的MongoDB Cloud Manager。考虑创建自己的镜像,其中包含首选的MongoDB版本和MongoDB自动化代理。

#使用Docker和Kubernetes实现MongoDB Replica Set副本集群

如上所述,当使用诸如Kubernetes之类的编排工具部署时,MongoDB等分布式数据库需要特别小心。本节将进一步详细介绍这一点。

我们首先在单个Kubernetes集群中创建整个MongoDB副本集群(通常位于单个数据中心内——显然不提供地理冗余)。实际上,很少需要更改配置来支持跨多个中心的集群架构,这些步骤将在后面介绍。

Replica Set副本集群的每个成员将作为单独的Pod运行,其中一个服务公开外部IP地址和端口。这个“固定”的IP地址很重要,因为外部应用程序和其他副本集成员可以依赖它,在重新编排Pod时保持地址不变。如果你想和更多Kubernetes技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态

下图说明了其中一个Pod以及关联的Replication Controller和服务。
2.png

图1: MongoDB Replica Set副本集群成员配置为Kubernetes Pod并作为服务公开

配置Kubernetes Pod步骤如下:

  1. 开始创建名为mongo-node1的容器。 mongo-node1包含一个名为mongo的镜像,这是一个托管在Docker Hub上的公开可用的MongoDB容器镜像。容器公开集群中的端口27107。
2.Kubernetes volumes卷用于将/data/db目录映射到名为mongo-persistent-storage1的持久存储元素;然后映射到在Google Cloud中创建的名为mongodb-disk1的磁盘。这是MongoDB存储数据的位置,以便在容器重新调度时保持不变。
3.Pod内的容器实例,标签mongo-node,实例名称rod。
4.名为mongo-rc1的复制控制器,目的是确保mongo-node1 pod的单个实例始终在运行。
5.名为mongo-svc-a的LoadBalancer服务向外界公开IP地址以及27017的端口,该端口映射到容器中的相同端口号。该服务使用与pod标签匹配的选择器来识别正确的pod。该外部IP地址和端口将由应用程序和副本集成员之间的通信使用。每个容器也有本地IP地址,但这些容器在移动或重新启动容器时会发生更改,因此不会用于Replica Set副本集群。

下图显示了Replica Set副本集群的第二个成员的配置。
3.png

图2:第二个MongoDB副本集群成员配置为Kubernetes Pod

只有这些配置不一样,其他90%的配置是相同的:

* 磁盘和卷名称必须唯一,因此使用名称:mongodb-disk2和mongo-persistent-storage2
* Pod标签:jane和name:mongo-node2,以便新服务可以将它与图1中rod的Pod区分开来。
* 复制控制器名为mongo-rc2
* 该服务名为mongo-svc-b,并获取唯一的外部IP地址(在此示例中,Kubernetes已分配104.1.4.5)

第三个副本集成员的配置遵循相同的模式,下图是完整的Replica Set副本集群:
4.png

图3:配置为Kubernetes服务的完整副本集群成员

请注意,即使在三个或更多节点的Kubernetes集群上运行图3所示的配置,Kubernetes也可能(通常会)在同一主机上安排两个或更多MongoDB Replica Set副本集群成员。 这是因为Kubernetes将三个pod当作三个独立服务。

为了增加冗余(在区域内),可以创建额外的Headless Service服务。 该服务不向外界提供任何服务(甚至不具有IP地址),但它用于通知Kubernetes三个MongoDB pod构成的节点信息,Kubernetes可以尝试在不同节点上编排这些Pod实例。
5.png

图4:Headless service无头服务,以避免MongoDB副本集成员的共同定位

可以在《启用微服务:容器和编排说明》白皮书中找到Kubernetes编排和启动MongoDB Replica Set副本集群所需的实际配置文件和命令。特别是,将三个MongoDB实例组合成一个功能强大的HA集群需要一些特殊步骤,这些副本集在本文中有所描述。
#多个可用区MongoDB Replica Set副本集群

上面创建的副本集存在当机风险,因为一切都在同一个GCE集群中运行,本质上在同一可用区中。如果发生可用区脱机的重大事故,则整个MongoDB副本集将不可用。如果需要做地理空间的分布式冗余,可以在三个不同的可用区域或区域中运行三个窗格。

创建三个可用区域的分布式副本集群,并不需要太多的配置修改——只需要创建三个集群。每个群集都需要自己的Kubernetes YAML文件,该文件为集群中的单个节点定义Pod,Replication Controller和服务。
6.png

图5:在多个可用区域上运行的副本集
#扩展阅读

要了解有关Docker容器和Kubernetes编排的更多信息——包括所涉及的技术及其提供的业务优势——请阅读“启用微服务:容器和编排说明”白皮书。https://www.mongodb.com/collateral/microservices-containers-and-orchestration-explained,这个白皮书还提供了在Google容器引擎中的Docker和Kubernetes上启动并运行本文中描述的副本集群的完整说明。

原文链接:https://yq.aliyun.com/articles/693940

你好,SMI:Service Mesh 互操作性说明书

YiGagyeong 发表了文章 • 0 个评论 • 248 次浏览 • 2019-05-27 23:36 • 来自相关话题

【编者的话】本文主要介绍了最近发布的 Service Mesh Interface(SMI),SMI 为 Service Mesh 技术提供了通用的 API 规范,并且是生态系统友好的,为后续新兴工具的集成提供了保障。 今 ...查看全部
【编者的话】本文主要介绍了最近发布的 Service Mesh Interface(SMI),SMI 为
Service Mesh 技术提供了通用的 API 规范,并且是生态系统友好的,为后续新兴工具的集成提供了保障。

今天,我们兴奋地发布了 `Service Mesh Interface(SMI)`,它定义了一组通用的可移植 API,为开发人员提供跨不同 Service Mesh(服务网格)技术的互操作性,其中包括 Istio,Linkerd 和 Consul Connect。SMI 是一个与微软,Linkerd,HashiCorp,Solo.io,Kinvolk 和 Weaveworks 合作开展的开放项目;同样也得到了 Aspen Mesh,Canonical,Docker,Pivotal,Rancher,Red Hat 和 VMware 的支持。

多年来,网络架构的真言是让网络管道尽可能愚蠢,并在应用中构建智能。网络的职责是转发数据包,而任何关于加密,压缩或身份的逻辑则存在于网络端点内。互联网是以此真言为前提的,所以你会觉得它可以运转良好。如果你想和更多 Service Mesh 技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态

但是,如今随着微服务、容器以及编排系统如 `Kubernetes` 的爆炸式增长,工程团队将要保障、管理和监控越来越多的网络端点。Service Mesh 技术通过使网络更加智能,来解决上述问题。Service Mesh 技术不是教授所有服务来加密会话,授权客户端,发出合理的遥测,并在应用程序版本之间无缝转换流量,而是将此逻辑推入网络,由一组单独的管理 API 控制。

这是 `cloud-native` 系统中比较流行的模式。我们发现,随着许多供应商为应用开发人员提供了令人兴奋的新选择,Service Mesh 技术也随之激增。问题是,转向 Service Mesh 的开发人员必须选择一个供应商,并直接对接其 API。他们被束缚在了某种 Service Mesh 的实现中。如果没有通用接口,开发人员就会失去可移植性以及灵活性,并且从广泛的生态系统中获益的能力也会受限。

SMI 提供了如下功能:

  • Kubernetes 网格的标准界面
  • 最常见的网格用例的基本功能集
  • 随着时间的推移灵活地支持新的网格功能
  • 为生态系统提供利用网格技术进行创新的空间
# SMI 覆盖了哪些功能我们与 HashiCorp,Buoyant,Solo.io 以及其他公司合作,为企业级客户所希冀的三大 Service Mesh 功能构建初始规范:[list=1]
  • 流量策略:应用跨服务应用身份和传输加密等策略
  • 流量遥测:捕获关键指标,如错误率和服务之间的延迟
  • 流量管理:在不同服务之间转移和加权流量

  • 这些只是我们希望通过 SMI 初步实现的功能。由于开发过程中有许多令人兴奋的网格功能,我们完全希望随着时间的推移,不断发展 SMI API,并期待通过新功能扩展当前规范。
    # SMI是如何工作的
    Service Mesh Interface 背后的观点并非新创。它追寻 Ingress,Network Policy 和 CNI 等现有 Kubernetes 资源的足迹。与 Ingress 或 Network Policy 一样,SMI 不提供具体实现。相反,SMI 规范定义了一组通用 API,允许网格提供者提供自己的最佳实现。与 SMI 集成可以通过两种方式实现,工具和网格提供者可以直接使用SMI API,也可以构建运算符将 SMI 转换为原生 API。

    SMI 是 Linkerd 迈向 Service Mesh 大众化的一大步,我们很高兴能够向更多的 Kubernetes 用户提供简洁和易用的 Linker 服务。
    > ——William Morgan,Linkerd 维护者



    对于跨技术和生态系统协作来说,接口的标准化对确保最佳用户体验至关重要。凭借这种精神,我们很高兴能与微软和其他公司合作开发 SMI 规范,并已经通过 Service Mesh Hub 和 SuperGloo 项目提供了首个参考实现。
    > ——Solo.io 创始人兼首席执行官,Idit Levine。



    # 生态系统友好
    对于 Service Mesh 等早期技术,我们必须为其生态系统创造创新空间,并探索解决客户问题的不同方法。随着 service mesh 技术的不断发展,SMI 提供的互操作性将有助于新兴工具和实用程序与现有网格供应商集成,而不是单独集成每个网格,像 flagger 和 SuperGloo 这样的工具就可以与 SMI 集成,从而获得跨网格功能。

    “Service Mesh 的兴趣和动力已达到了行业需要在一系列标准上进行协作的程度,这些标准可以帮助确保他们的成功。”VMware 服务网络首席架构师 Sushil Singh 表示,“Service Meshe 为应用程序的未来提供了丰富的基础功能。现在是制定标准 API 的最佳时机,这些 API 可以简化 Service Mesh 技术的消耗和功能,从而实现健康的生态系统。VMware 很高兴参与这项非常重要的工作。“



    客户和社区成员都在寻求一种方法来更好地标准化 Service Mesh 的配置和操作。随着 Service Mesh Interface(SMI)的出现,我们认为这是一种可以帮助我们最大化 Red Hat OpenShift 客户选择和灵活性的方法。这种灵活性使用户能够优先考虑实现细节的功能。
    > ——Brian Redbeard Harrington,Red Hat Service Mesh 首席产品经理



    原文链接:Hello Service Mesh Interface (SMI): A specification for service mesh interoperability (翻译:李加庆

    Kubernetes Istio微服务架构部署和使用

    翔宇 发表了文章 • 0 个评论 • 197 次浏览 • 2019-05-27 21:40 • 来自相关话题

    #什么是Istio Istio是Service Mesh(服务网格)的主流实现方案。该方案降低了与微服务架构相关的复杂性,并提供了负载均衡、服务发现、流量管理、断路器、监控、故障注入和智能路由等功能特性。 其中,Si ...查看全部
    #什么是Istio

    Istio是Service Mesh(服务网格)的主流实现方案。该方案降低了与微服务架构相关的复杂性,并提供了负载均衡、服务发现、流量管理、断路器、监控、故障注入和智能路由等功能特性。

    其中,Sidecar模式是一种将应用功能从应用本身剥离出来作为单独进程的方式。该模式允许我们向应用无侵入添加多种功能,避免了为满足第三方组件需求而向应用添加额外的配置代码。从某种意义上来说,服务对于网络是无感知的,只知道所附加的sidecar代理,它将网络依赖抽象成了Sidecar。

    在Service Mesh中,我们需要了解Data Plane和Control Plane两个概念:

    * Data Plane:作用是处理网格内服务间的通信,并完成服务发现、负载均衡、流量管理、健康检查等功能;
    * Control Plane:作用是管理和配置智能代理用于路由流量,同时配置Mixers来应用策略、收集指标。

    Istio核心组件:

    * Envoy:Istio 使用 Envoy调解服务网格中所有服务的入站和出站流量。属于数据平面。
    * Mixer:负责在服务网格上执行访问控制和使用策略,以及收集从Envoy和其他服务自动监控到的数据。
    * Pilot:为 Envoy sidecar 提供服务发现功能,为智能路由(例如 A/B 测试、金丝雀部署等)和弹性(超时、重试、熔断器等)提供流量管理功能。属于控制平面。
    * Citadel:提供访问控制和用户身份认证功能。

    Istio可视化管理组件:

    * Vistio:用于近乎实时地监控应用程序和集群之间的网络流量。可以参考:https://www.yangcs.net/posts/vistio-visualize-your-istio-mesh-using-netflixs-vizceral/
    * Kiali:提供可视化服务网格拓扑、断路器和请求率等功能。Kiali还包括 Jaeger Tracing,可以提供开箱即用的分布式跟踪功能。可以参考:https://jimmysong.io/istio-handbook/setup/istio-observability-tool-kiali.html
    * Jaeger:用于展示Istio微服务调用链关系,以及微服务工作状态监测。注意,在生产环境中,你应当使用Elasticsearch或Cassandra持久化存储Jaeger数据。可以参考:https://blog.csdn.net/ywq935/article/details/80599297
    https://mathspanda.github.io/2018/09/19/jaeger-deploy/
    https://blog.frognew.com/2017/12/opentracing-jaeger-3.html

    其中,Kiali、Jaeger、Prometheus、Grafana管理工具,将和Istio一并部署。如果你想和更多Istio技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态
    #使用Helm部署Istio

    依赖环境:

    * Helm > 2.10
    * Kubernetes > 1.9

    下载并解压缩istio的发布包
    wget https://github.com/istio/istio/releases/download/1.0.6/istio-1.0.6-linux.tar.gz
    tar -zxvf istio-1.0.6-linux.tar.gz
    cd istio-1.0.6

    Istio的Chart在istio-1.0.6/install/kubernetes/helm目录中,这个Chart包含了下面的代码文件。
    # tree install/kubernetes/helm/istio
    ......
    ......
    31 directories, 139 files

    如果安装的Helm版本高于2.10,就不再需要手动使用kubectl安装Istio的CRD。反之,则需要执行如下命令安装。
    kubectl apply -f install/kubernetes/helm/istio/templates/crds.yaml

    查看安装的CRD。
    kubectl get CustomResourceDefinition

    通过各个组件在vaule file的enabled flag启用或禁用,下面创建名称为istio.yaml的vaule file,将几个默认禁用的组件也启用。
    tracing:
    enabled: true
    servicegraph:
    enabled: true
    kiali:
    enabled: true
    grafana:
    enabled: true

    首先,创建名称为kiali的secret。
    # echo -n 'admin' | base64
    YWRtaW4=

    # echo -n '1f2d1e2e67df' | base64
    MWYyZDFlMmU2N2Rm

    # cat <
    apiVersion: v1
    kind: Secret
    metadata:
    name: kiali
    namespace: istio-system
    labels:
    app: kiali
    type: Opaque
    data:
    username: YWRtaW4=
    passphrase: MWYyZDFlMmU2N2Rm
    EOF

    执行helm安装命令。
    helm install install/kubernetes/helm/istio --name istio --namespace istio-system -f istio.yaml

    安装完成后确认各个组件的Pod正常运行。
    # kubectl get pod -n istio-system
    NAME READY STATUS RESTARTS AGE
    grafana-59b8896965-5f9j2 1/1 Running 0 23m
    istio-citadel-6f444d9999-s9jrc 1/1 Running 0 23m
    istio-egressgateway-6d79447874-ssbc4 1/1 Running 0 23m
    istio-galley-685bb48846-mvf5w 1/1 Running 0 23m
    istio-grafana-post-install-6m256 0/1 Completed 0 23m
    istio-ingressgateway-5b64fffc9f-mrl9t 1/1 Running 0 23m
    istio-pilot-8645f5655b-k6fcz 2/2 Running 0 23m
    istio-policy-547d64b8d7-6dgkp 2/2 Running 0 23m
    istio-sidecar-injector-5d8dd9448d-zfdsb 1/1 Running 0 23m
    istio-telemetry-c5488fc49-qwwcv 2/2 Running 0 23m
    istio-tracing-6b994895fd-4vjfx 1/1 Running 0 23m
    kiali-5f9ffff7cf-jqk8p 1/1 Running 0 23m
    prometheus-76b7745b64-xjzmm 1/1 Running 0 23m
    servicegraph-cb9b94c-mlhjm 1/1 Running 0 23m

    Istio以一个项目的形式部署到Kubernetes集群中。我们可以看到,部署好的Pod中,除了有istio-citadel、istio-egressgateway、istio-ingressgateway、istio-pilot等Istio本身的功能组件,还集成了微服务相关的监控工具,如:Grafana、jaeger-agent、kiali、Prometheus。正是这些功能丰富且强大的监控工具,帮助Istio实现了微服务的可视化管理。
    #运行示例Bookinfo

    您可以部署自己的应用或者示例应用程序如Bookinfo。 注意:应用程序必须使用HTTP/1.1或HTTP/2.0协议来传递HTTP流量,因为HTTP/1.0已经不再支持。

    如果运行Pod的namespace被标记为istio-injection=enabled的话,Istio-Initializer会向应用程序的Pod中自动注入Envoy容器:
    kubectl label namespace  istio-injection=enabled
    kubectl create -n -f .yaml

    如果您没有安装Istio-initializer-injector的话,您必须使用istioctl kube-inject命令在部署应用之前向应用程序的Pod中手动注入Envoy容器:
    kubectl create -f <(istioctl kube-inject -f .yaml)

    Bookinfo应用由四个单独的微服务构成,用来演示多种Istio特性,包含:

    * productpage:productpage微服务会调用details和reviews两个微服务,用来生成页面。
    * details:这个微服务包含了书籍的信息。
    * reviews:这个微服务包含了书籍相关的评论。它还会调用ratings微服务。
    * ratings:ratings微服务中包含了由书籍评价组成的评级信息。

    reviews微服务有 3 个版本:

    * v1版本不会调用ratings服务。
    * v2版本会调用ratings服务,并使用1到5个黑色星形图标来显示评分信息。
    * v3 版本会调用ratings服务,并使用1到5个红色星形图标来显示评分信息。

    下图展示了这个应用的端到端架构。
    1.png

    运行示例bookinfo,并开启Sidecar自动注入。
    # kubectl label namespace default istio-injection=enabled
    # kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
    # kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
    # kubectl apply -f samples/bookinfo/platform/consul/destination-rule-all.yaml

    访问productpage:http://172.16.0.180:31380/productpage
    2.png

    31380端口可以通过命令获取:
    kubectl -n istio-system get svc istio-ingressgateway -o jsonpath='{.spec.ports[0].nodePort}'

    #使用Ingress暴露管理服务

    完成Istio的安装后,可以看到安装的组件除了Istio架构中的数据平面和控制平面的各个核心组件,还部署了Prometheus、Grafana、Jaeger、Kiali等辅助组件。 在云原生生态中,我们已经对这些组件很熟悉了。

    * Prometheus:监控系统,收集Istio的监控数据
    * Grafana:监控信息的图表展现,Istio部署的Grafana为我们内置了各个组件相关的Dashboard
    * Jaeger:分布式跟踪系统,Istio中集成Jaeger可以对基于Istio的微服务实现调用链跟踪、依赖分析,为性能优化和故障排查提供支持
    * kiali:kiali作为Istio的可视化管理工具,可以认为是Istio的UI,可以展现服务的网络拓扑、服务的容错情况(超时、重试、短路等)、分布式跟踪等

    这些辅助组件都有自己的web界面,这里我们使用ingress的方式将这些组件暴露到集群外,以便在集群外部访问。Istio支持使用自带的istio-ingressgateway将服务暴露到集群外部,这个和Kubernetes中暴露Ingress Controller类似,有很多种方式,如NodePort,LoadBalancer,或直接开启hostNetwork: true等等。为了便于统一管理Kubernetes集群中的服务暴露,笔者更倾向使用Traefik Ingress。

    使用Ingress暴露Istio服务。

    编写ingress yaml文件,如下
    # cat istio-ingress.yaml 
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
    name: jaeger-query
    namespace: istio-system
    annotations:
    kubernetes.io/ingress.class: traefik
    spec:
    rules:
    - host: istio.jaeger-query.com
    http:
    paths:
    - path: /
    backend:
    serviceName: jaeger-query
    servicePort: 16686

    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
    name: prometheus
    namespace: istio-system
    annotations:
    kubernetes.io/ingress.class: traefik
    spec:
    rules:
    - host: istio.prometheus.com
    http:
    paths:
    - path: /
    backend:
    serviceName: prometheus
    servicePort: 9090

    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
    name: grafana
    namespace: istio-system
    annotations:
    kubernetes.io/ingress.class: traefik
    spec:
    rules:
    - host: istio.grafana.com
    http:
    paths:
    - path: /
    backend:
    serviceName: grafana
    servicePort: 3000

    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
    name: kiali
    namespace: istio-system
    annotations:
    kubernetes.io/ingress.class: traefik
    spec:
    rules:
    - host: istio.kiali.com
    http:
    paths:
    - path: /
    backend:
    serviceName: kiali
    servicePort: 20001

    执行部署命令:
    kubectl apply -f istio-ingress.yaml

    外部客户端,配置hosts地址解析,如下:
    172.16.0.180 istio.prometheus.com
    172.16.0.180 istio.jaeger-query.com
    172.16.0.180 istio.grafana.com
    172.16.0.180 istio.kiali.com

    ##访问Jaeger

    浏览器访问Jaeger之前可以多次刷新productpage页面以便产生访问请求等。选择productpage.default可以查看整个调用链。使用istio.jaeger-query.com域名访问,结果展示:
    3.png

    ##访问kiali

    使用域名istio.kiali.com访问kiali页面。用户名admin,密码1f2d1e2e67df。
    4.png

    ##访问Prometheus

    使用域名istio.prometheus.com访问Prometheus页面。
    5.png

    ##访问Grafana

    使用域名istio.grafana.com访问Prometheus页面。
    6.png

    ##Istio对Pod和服务的要求

    要成为服务网格的一部分,Kubernetes 集群中的 Pod 和服务必须满足以下几个要求:

    * 需要给端口正确命名:服务端口必须进行命名。端口名称只允许是<协议>[-<后缀>-]模式;
    * Pod必须关联到 Kubernetes服务:如果一个 Pod 属于多个服务,这些服务不能再同一端口上使用不同协议,例如 HTTP 和 TCP。
    * Deployment应带有app以及version标签:每个 Deployment 都应该有一个有意义的 app 标签和一个用于标识 Deployment 版本的 version 标签。Istio 会用 app 和 version 标签来给监控指标数据加入上下文信息。

    #总结

    本文实践了使用istio官方提供的helm chart在Kubernetes上部署Istio 1.0.6的过程,并使用Traefik Ingress将Istio集成的Prometheus、Grafana、Jaeger、Kiali等辅助组件暴露到集群外部,并对进入集群的流量进行管理。

    在生产环境中,如果是基于公有云,如阿里云、AWS等运行Istio,建议Ingress的IP地址使用ELB地址;如果是自建的平台,则建议使用HAproxy+Keepalived提供的VIP地址,作为Ingress的IP地址,实现高可用。

    如果Ingress服务,需要暴露在公网,应当使用CA认证机构颁发的证书https化(如使用cert-manager)。此外建议使用NFS、Ceph等方案实现Istio监控以及微服务应用的数据持久化存储。

    Istio参考资料:

    * https://istio.io/zh/docs/
    * https://jimmysong.io/istio-handbook/
    * http://www.servicemesher.com/

    原文链接:Kubernetes Istio微服务架构部署和使用

    Kubernetes VS Docker意想不到的结局

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

    浅谈几种常用负载均衡架构

    Andy_Lee 发表了文章 • 0 个评论 • 181 次浏览 • 2019-05-27 17:16 • 来自相关话题

    在网站创立初期,我们一般都使用单台机器对台提供集中式服务,但随着业务量越来越大,无论性能还是稳定性上都有了更大的挑战。这时候我们就会想到通过扩容的方式来提供更好的服务。我们一般会把多台机器组成一个集群对外提供服务。然而,我们的网站对外提供的访问入口都是一个的, ...查看全部
    在网站创立初期,我们一般都使用单台机器对台提供集中式服务,但随着业务量越来越大,无论性能还是稳定性上都有了更大的挑战。这时候我们就会想到通过扩容的方式来提供更好的服务。我们一般会把多台机器组成一个集群对外提供服务。然而,我们的网站对外提供的访问入口都是一个的,比如www.taobao.com。那么当用户在浏览器输入www.taobao.com的时候如何将用户的请求分发到集群中不同的机器上呢,这就是负载均衡在做的事情。

    当前大多数的互联网系统都使用了服务器集群技术,集群即将相同服务部署在多台服务器上构成一个集群整体对外提供服务,这些集群可以是Web应用服务器集群,也可以是数据库服务器集群,还可以是分布式缓存服务器集群等。

    在实际应用中,在Web服务器集群之前总会有一台负载均衡服务器,负载均衡设备的任务就是作为Web服务器流量的入口,挑选最合适的一台Web服务器,将客户端的请求转发给它处理,实现客户端到真实服务端的透明转发。最近几年很火的「云计算」以及分布式架构,本质上也是将后端服务器作为计算资源、存储资源,由某台管理服务器封装成一个服务对外提供,客户端不需要关心真正提供服务的是哪台机器,在它看来,就好像它面对的是一台拥有近乎无限能力的服务器,而本质上,真正提供服务的是后端的集群。

    软件负载解决的两个核心问题是:选谁、转发,其中最著名的是LVS(Linux Virtual Server)。
    1.png

    一个典型的互联网应用的拓扑结构是这样的:
    2.png

    #负载均衡分类

    现在我们知道,负载均衡就是一种计算机网络技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁碟驱动器或其它资源中分配负载,以达到最佳化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。那么,这种计算机技术的实现方式有多种。大致可以分为以下几种,其中最常用的是四层和七层负载均衡:
    ##二层负载均衡

    负载均衡服务器对外依然提供一个VIP(虚IP),集群中不同的机器采用相同IP地址,但机器的MAC地址不一样。当负载均衡服务器接受到请求之后,通过改写报文的目标MAC地址的方式将请求转发到目标机器实现负载均衡。
    ##三层负载均衡

    和二层负载均衡类似,负载均衡服务器对外依然提供一个VIP(虚IP),但集群中不同的机器采用不同的IP地址。当负载均衡服务器接受到请求之后,根据不同的负载均衡算法,通过IP将请求转发至不同的真实服务器。
    ##四层负载均衡

    四层负载均衡工作在OSI模型的传输层,由于在传输层,只有TCP/UDP协议,这两种协议中除了包含源IP、目标IP以外,还包含源端口号及目的端口号。四层负载均衡服务器在接受到客户端请求后,以后通过修改数据包的地址信息(IP+端口号)将流量转发到应用服务器。
    ##七层负载均衡

    七层负载均衡工作在OSI模型的应用层,应用层协议较多,常用http、radius、DNS等。七层负载就可以基于这些协议来负载。这些应用层协议中会包含很多有意义的内容。比如同一个Web服务器的负载均衡,除了根据IP加端口进行负载外,还可根据七层的URL、浏览器类别、语言来决定是否要进行负载均衡。
    3.png

    图:四层和七层负载均衡

    对于一般的应用来说,有了Nginx就够了。Nginx可以用于七层负载均衡。但是对于一些大的网站,一般会采用DNS+四层负载+七层负载的方式进行多层次负载均衡。
    4.png

    #常用负载均衡工具

    硬件负载均衡性能优越,功能全面,但价格昂贵,一般适合初期或者土豪级公司长期使用。因此软件负载均衡在互联网领域大量使用。常用的软件负载均衡软件有Nginx、LVS、HaProxy等。

    Nginx/LVS/HAProxy是目前使用最广泛的三种负载均衡软件。
    ##LVS

    LVS(Linux Virtual Server),也就是Linux虚拟服务器,是一个由章文嵩博士发起的自由软件项目。使用LVS技术要达到的目标是:通过LVS提供的负载均衡技术和Linux操作系统实现一个高性能、高可用的服务器群集,它具有良好可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的服务性能。

    LVS主要用来做四层负载均衡。

    LVS架构:

    LVS架设的服务器集群系统由三个部分组成:最前端的负载均衡层(Loader Balancer),中间的服务器群组层,用Server Array表示,最底层的数据共享存储层,用Shared Storage表示。在用户看来所有的应用都是透明的,用户只是在使用一个虚拟服务器提供的高性能服务。
    5.png

    LVS的各个层次的详细介绍:

    Load Balancer层:位于整个集群系统的最前端,有一台或者多台负载调度器(Director Server)组成,LVS模块就安装在Director Server上,而Director的主要作用类似于一个路由器,它含有完成LVS功能所设定的路由表,通过这些路由表把用户的请求分发给Server Array层的应用服务器(Real Server)上。同时,在Director Server上还要安装对Real Server服务的监控模块Ldirectord,此模块用于监测各个Real Server服务的健康状况。在Real Server不可用时把它从LVS路由表中剔除,恢复时重新加入。

    Server Array层:由一组实际运行应用服务的机器组成,Real Server可以是Web服务器、Mail服务器、FTP服务器、DNS服务器、视频服务器中的一个或者多个,每个Real Server之间通过高速的LAN或分布在各地的WAN相连接。在实际的应用中,Director Server也可以同时兼任Real Server的角色。

    Shared Storage层:是为所有Real Server提供共享存储空间和内容一致性的存储区域,在物理上一般由磁盘阵列设备组成,为了提供内容的一致性,一般可以通过NFS网络文件系统共享数 据,但NFS在繁忙的业务系统中,性能并不是很好,此时可以采用集群文件系统,例如Red hat的GFS文件系统、Oracle提供的OCFS2文件系统等。

    从整个LVS结构可以看出,Director Server是整个LVS的核心,目前用于Director Server的操作系统只能是Linux和FreeBSD,Linux2.6内核不用任何设置就可以支持LVS功能,而FreeBSD作为 Director Server的应用还不是很多,性能也不是很好。对于Real Server,几乎可以是所有的系统平台,Linux、windows、Solaris、AIX、BSD系列都能很好地支持。
    ##Nginx

    Nginx(发音同engine x)是一个网页服务器,它能反向代理HTTP、HTTPS,、SMTP、POP3、IMAP的协议链接,以及一个负载均衡器和一个HTTP缓存。

    Nginx主要用来做七层负载均衡。

    并发性能:官方支持每秒5万并发,实际国内一般到每秒2万并发,有优化到每秒10万并发的。具体性能看应用场景。

    特点:

    * 模块化设计:良好的扩展性,可以通过模块方式进行功能扩展。
    * 高可靠性:主控进程和worker是同步实现的,一个worker出现问题,会立刻启动另一个worker。
    * 内存消耗低:一万个长连接(keep-alive),仅消耗2.5MB内存。
    * 支持热部署:不用停止服务器,实现更新配置文件,更换日志文件、更新服务器程序版本。
    * 并发能力强:官方数据每秒支持5万并发。
    * 功能丰富:优秀的反向代理功能和灵活的负载均衡策略。

    Nginx的基本工作模式:
    6.png

    一个master进程,生成一个或者多个worker进程。但这里master是使用root身份启动的,因为nginx要工作在80端口。而只有管理员才有权限启动小于低于1023的端口。master主要是负责的作用只是启动worker,加载配置文件,负责系统的平滑升级。其它的工作是交给worker。那当worker被启动之后,也只是负责一些web最简单的工作,而其它的工作都是由worker中调用的模块来实现的。

    模块之间是以流水线的方式实现功能的。流水线,指的是一个用户请求,由多个模块组合各自的功能依次实现完成的。比如:第一个模块只负责分析请求首部,第二个模块只负责查找数据,第三个模块只负责压缩数据,依次完成各自工作。来实现整个工作的完成。

    它们是如何实现热部署的呢?是这样的,我们前面说master不负责具体的工作,而是调用worker工作,它只是负责读取配置文件,因此当一个模块修改或者配置文件发生变化,是由master进行读取,因此此时不会影响到worker工作。在master进行读取配置文件之后,不会立即把修改的配置文件告知worker。而是让被修改的worker继续使用老的配置文件工作,当worker工作完毕之后,直接当掉这个子进程,更换新的子进程,使用新的规则。
    ##HAProxy

    HAProxy也是使用较多的一款负载均衡软件。HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,是免费、快速并且可靠的一种解决方案。特别适用于那些负载特大的web站点。运行模式使得它可以很简单安全的整合到当前的架构中,同时可以保护你的web服务器不被暴露到网络上。

    HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。

    Haproxy主要用来做七层负载均衡。

    常见负载均衡算法:

    上面介绍负载均衡技术的时候提到过,负载均衡服务器在决定将请求转发到具体哪台真实服务器时,是通过负载均衡算法来实现的。负载均衡算法可以分为两类:静态负载均衡算法和动态负载均衡算法。

    * 静态负载均衡算法包括:轮询、比率、优先权。
    * 动态负载均衡算法包括:最少连接数、最快响应速度、观察方法、预测法、动态性能分配、动态服务器补充、服务质量、服务类型、规则模式。

    轮询(Round Robin):顺序循环将请求一次顺序循环地连接每个服务器。当其中某个服务器发生第二到第7 层的故障,BIG-IP 就把其从顺序循环队列中拿出,不参加下一次的轮询,直到其恢复正常。

    以轮询的方式依次请求调度不同的服务器; 实现时,一般为服务器带上权重;这样有两个好处:

    * 针对服务器的性能差异可分配不同的负载;
    * 当需要将某个结点剔除时,只需要将其权重设置为0即可;

    优点:实现简单、高效;易水平扩展

    缺点:请求到目的结点的不确定,造成其无法适用于有写的场景(缓存,数据库写)

    应用场景:数据库或应用服务层中只有读的场景

    随机方式:请求随机分布到各个结点;在数据足够大的场景能达到一个均衡分布;

    优点:实现简单、易水平扩展

    缺点:同Round Robin,无法用于有写的场景

    应用场景:数据库负载均衡,也是只有读的场景

    哈希方式:根据key来计算需要落在的结点上,可以保证一个同一个键一定落在相同的服务器上;

    优点:相同key一定落在同一个结点上,这样就可用于有写有读的缓存场景

    缺点:在某个结点故障后,会导致哈希键重新分布,造成命中率大幅度下降

    解决:一致性哈希 or 使用keepalived保证任何一个结点的高可用性,故障后会有其它结点顶上来

    应用场景:缓存,有读有写

    一致性哈希:在服务器一个结点出现故障时,受影响的只有这个结点上的key,最大程度的保证命中率; 如twemproxy中的ketama方案; 生产实现中还可以规划指定子key哈希,从而保证局部相似特征的键能分布在同一个服务器上;

    优点:结点故障后命中率下降有限

    应用场景:缓存

    根据键的范围来负载:根据键的范围来负载,前1亿个键都存放到第一个服务器,1~2亿在第二个结点。

    优点:水平扩展容易,存储不够用时,加服务器存放后续新增数据

    缺点:负载不均;数据库的分布不均衡;

    (数据有冷热区分,一般最近注册的用户更加活跃,这样造成后续的服务器非常繁忙,而前期的结点空闲很多)

    适用场景:数据库分片负载均衡

    根据键对服务器结点数取模来负载:根据键对服务器结点数取模来负载;比如有4台服务器,key取模为0的落在第一个结点,1落在第二个结点上。

    优点:数据冷热分布均衡,数据库结点负载均衡分布;

    缺点:水平扩展较难;

    适用场景:数据库分片负载均衡

    纯动态结点负载均衡:根据CPU、IO、网络的处理能力来决策接下来的请求如何调度。

    优点:充分利用服务器的资源,保证个结点上负载处理均衡

    缺点:实现起来复杂,真实使用较少

    不用主动负载均衡:使用消息队列转为异步模型,将负载均衡的问题消灭;负载均衡是一种推模型,一直向你发数据,那么将所有的用户请求发到消息队列中,所有的下游结点谁空闲,谁上来取数据处理;转为拉模型之后,消除了对下行结点负载的问题。

    优点:通过消息队列的缓冲,保护后端系统,请求剧增时不会冲垮后端服务器;水平扩展容易,加入新结点后,直接取queue即可;
    缺点:不具有实时性;

    应用场景:不需要实时返回的场景;

    比如,12036下订单后,立刻返回提示信息:您的订单进去排队了...等处理完毕后,再异步通知;

    比率(Ratio):给每个服务器分配一个加权值为比例,根椐这个比例,把用户的请求分配到每个服务器。当其中某个服务器发生第2到第7 层的故障,BIG-IP 就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。

    优先权(Priority):给所有服务器分组,给每个组定义优先权,BIG-IP 用户的请求,分配给优先级最高的服务器组(在同一组内,采用轮询或比率算法,分配用户的请求);当最高优先级中所有服务器出现故障,BIG-IP 才将请求送给次优先级的服务器组。这种方式,实际为用户提供一种热备份的方式。

    最少的连接方式(Least Connection):传递新的连接给那些进行最少连接处理的服务器。当其中某个服务器发生第2到第7 层的故障,BIG-IP 就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。

    最快模式(Fastest):传递连接给那些响应最快的服务器。当其中某个服务器发生第二到第7 层的故障,BIG-IP 就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。

    观察模式(Observed):连接数目和响应时间以这两项的最佳平衡为依据为新的请求选择服务器。当其中某个服务器发生第二到第7 层的故障,BIG-IP就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。

    预测模式(Predictive):BIG-IP利用收集到的服务器当前的性能指标,进行预测分析,选择一台服务器在下一个时间片内,其性能将达到最佳的服务器相应用户的请求。(被BIG-IP 进行检测)

    动态性能分配(Dynamic Ratio-APM):BIG-IP 收集到的应用程序和应用服务器的各项性能参数,动态调整流量分配。

    动态服务器补充(Dynamic Server Act.):当主服务器群中因故障导致数量减少时,动态地将备份服务器补充至主服务器群。

    服务质量(QoS):按不同的优先级对数据流进行分配。

    服务类型(ToS):按不同的服务类型(在Type of Field中标识)负载均衡对数据流进行分配。

    规则模式:针对不同的数据流设置导向规则,用户可自行。

    负载均衡的几种算法Java实现代码:

    1. 轮询
    7.png

    1. 加权随机负载均衡算法
    8.png

    1. 随机负载均衡算法
    9.png

    1. 负载均衡 ip_hash算法.
    10.png


    作者:Kingreatwill

    出处:https://www.cnblogs.com/kingreatwill/p/7991151.html