前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Google:基于容器的服务发现与负载均衡

Google:基于容器的服务发现与负载均衡

作者头像
技术zhai
发布于 2019-02-15 07:40:42
发布于 2019-02-15 07:40:42
1.8K0
举报
文章被收录于专栏:JAVA技术zhaiJAVA技术zhai

曾在Google广告部门任职,负责广告的架构任务,14年回国同年9月创立数人云,主要基于Docker容器技术为企业级客户打造私有的PaaS平台,帮助企业客户解决互联网新业务挑战下的IT问题。

今天主要分享三个议题,首先是Google数据中心的简单介绍:Google的数据中心约有200万台服务器且都是X86PC服务器,Google的数据中心没有买任何大、小型机,完全使用廉价的PC服务器搭建,因规模庞大,对网络的要求非常高,包括交换机都是自己设计后定制的。服务发现、负载均衡的问题,对于Google的量级来说非常复杂,今天跟大家分享下Google内部如何实现服务发现和负载均衡。

静态的服务发现方式其实很好理解——基于IP地址和端口做服务发现,应用程序绑定了服务器的IP地址和端口之后,有请求发到这个IP地址和端口上,应用程序就可以接收到相应的请求。

经典的负载均衡器也是绑定某个特定的IP地址和端口,同时负载均衡器将需要做负载均衡的应用实例预先配置好,当负载均衡器收到请求后即可分发给后台的应用实例。

用IP地址+端口的方式做服务发现对人不友好,因为IP地址不好记忆,所以人们又发明了DNS作为非常经典的服务发现方式。

DNS实现的是域名解析,比较常用的DNS解析方式是A记录:向DNS查询某个域名的A记录会返回该域名对应的一个或多个IP地址,上图展示了向DNS查询某个域名的A记录返回IP地址的例子,给定一个域名,通过查询DNS服务器返回来这个域名所对应的一个IP地址。

另外一种DNS解析方式SRV记录,这是DNS里面实现更高级的服务发现的一种方式,向DNS查询某个域名的SRV记录要返回该域名对应的一对或多对地址和端口,如上图所示,向DNS查询一个域名地址,DNS返回了该域名对应的一系列地址和端口。

DNS除了具有服务发现功能,也可以实现负载均衡的功能,如上图所示,DNS可以根据用户的请求动态的返回某域名的A记录,比如DNS返回的A记录是目前最不繁忙的实例的IP地址,这样DNS就可以实现负载均衡功能。

静态环境下的负载均衡是最常见的负载均衡器使用场景。如上图所示,用户的请求发给负载均衡器,负载均衡器根据一定的策略,如轮转策略或者按照一定的权重把收到的请求分发给后面具体的应用实例,应用实例在处理完请求后把响应返回给负载均衡器,然后负载均衡器再把请求响应返回给最终用户。

常见的负载均衡器支持四层和七层协议,具体讲就是TCP协议和HTTP协议。四层负载均衡器,按照TCP协议来说是实现了一种路由转发:一个TCP请求数据包经过四层负载均衡器时,负载均衡器只修改这个TCP请求数据包的目的地址然后转给后面的应用实例;当负载均衡器收到应用实例返回的TCP响应数据包时,会修改这个TCP响应数据包的目的地址然后返回给用户。

七层负载均衡器和四层负载均衡器的工作原理不一样;当七层负载均衡器收到一个用户的HTTP请求数据包会把该请求包拆掉,然后封装成一个新的HTTP请求数据包传给后面的应用实例;当负载均衡器收到应用实例返回的HTTP响应数据包时,会把HTTP响应数据包拆掉然后重新封装一个新的HTTP响应数据包返回给用户。所以四层和七层负载均衡器的工作原理不同,四层类似于路由转发,七层则是完全重新封装的包。

常见的服务发现方式有三种,分别适用于同的TCP协议或HTTP协议。第一种是用IP地址+端口或者域名+端口的方式做服务发现,比如,“website.com:8080”代表一个应用,“website.com:8081”代表另一个应用,虽然这两个应用的域名相同。这种方式适用于四层和七层协议,即TCP及HTTP协议都可以用。

第二种是子域名的方式,仅适用于七层协议。子域名的方式是指不同的应用可能有共同的根源,但是有不同的子域名,比如,http://service1.zone1.website.comhttp://service2.zone1.website.com,这两个不同的域名(访问端口都是80)),有共同的根域名website.com,但是子域名不同,因此七层协议,比如HTTP协议,会通过不同的子域名解析到不同的应用。

第三种是子路径的方式,也仅适用于七层协议。比如,http://zone1.website.com/service1http://zone1.website.com/service2,这两个路径的域名完全一样,但是子路径不一样,可以用于区分不同的应用服务。

这三种服务发现方式其实总结下来只有IP地址或者域名+端口是同时适用于四层、七层,其他如子域名、子路径的方式只适用于七层服务发现。

上述都是非常经典的负载均衡、服务发现的基本概念和做法,但当数据中心规模达到一定程度时,应用和服务器之间或更确切地说应用和具体IP地址+端口之间就不再是静态的绑定关系。

如Google的数据中心里面大约有200万台服务器,如果Google的应用和服务器之间是一一对应的静态绑定关系:即某个应用程序必须要绑在某一个服务器上,或是绑定某个服务器的IP地址+端口上,那么对Google来说,每时每刻大概会有几百万到上千万个应用程序运行在200多万台服务器,这样静态管理应用和服务器会非常复杂。所以对于Google如此大规模的数据中心来讲必须用动态的管理,即要求应用不能静态绑定在服务器的IP地址+端口上,应用可以在不同的服务器之间动态迁移来实现故障自愈:程序运行在某一个服务器上,这个服务器宕机或程序有问题,该程序会被自动迁移到别的服务器上恢复运行。动态的应用调度管理方式可以使得应用的管理及服务器的管理进行解耦,即应用和服务器之间不再是静态的绑定关系。

动态环境下如何做负载均衡和服务发现?首先把问题明确下,动态环境最根本的一点是要把服务发现实现,即客户端要找到服务的后台,它从哪里找?这就是服务发现。在动态环境下如何做到?其实并不复杂,每个服务的后台实例绑定的IP地址和端口注册到一个服务注册中心,注册的方式可以是被动注册也可以是主动注册,被动注册是指负责应用调度的调度器来完成应用实例的IP地址+端口注册;主动注册是指每一个服务的实例要主动的上报自己目前所绑定的IP地址+端口。

有了动态服务注册的机制后,动态环境下的负载均衡也就好实现了。在动态环境下,当负载均衡器收到一个请求后,会去服务注册中心进行查询相应的应用的实例地址,然后把请求路由到该应用的后台实例上。

Google内部的服务发现和负载均衡外面看不到,数人云借鉴Google的理念实现了Swan(Github地址:https://github.com/Dataman-Cloud/swan),Swan基于Mesos来做容器化应用的动态调度,同时Swan实现了DNS和Proxy支持服务发现和负载均衡,跟Google的方式几乎一模一样,所以后面用Swan作例子给大家分享下Google怎么做服务发现和负载均衡。

先讲一下如何给应用命名,这在动态的应用调度和运行的环境下非常总要,因为经典的应用发现方式都是按照IP和端口,没有对应用有统一的命名,但是Google对于每个应用、每个实例都会有相应的命名。首先明确几个概念:

一个实例,是应用的某个Task,运行在一个容器里,应用会包含多个Task,都是运行同样的二进制程序;

一个应用,是一组运行同样二进制程序的实例集合,每个实例是这个应用的某个Task;

一个服务可以是一组应用程序;

一个服务会由一个用户在某个集群上发起运行。

Swan给每个实例用五个标签来命名,task-app-service-user-cluster,task是从0开始的连续整数,用于标识不同实例;相应地Swan给每个应用四个标签来命名,app-service-user-cluster;进而,Swan给每个服务用是三个标签来命名,service-user-cluster。

Swan实现了DNS用于服务发现,就是Swan DNS把Swan调度的每一个实例所绑定的IP地址+端口的信息都记录下来,或是A记录或是SRV记录。

对于每个应用,Swan的DNS也生成一个相应的域名用于四层服务发现,即 app.service.user.cluster.swan.com。另外,七层的应用Swan Prox会解析应用的另外一个域名http://app.service.user.cluster.gateway.swan.com用于七层应用的服务发现和负载均衡。

上图是Swan架构的一个示意图,简单解释了Swan、DNS、Proxy之间的关系:如何通过Swan对应用动态调度后实现服务发现和负载均衡。举个例子,首先Swan发布一个应用app-app-service-user-cluster,包含三个实例分别是:0-app-service-user-cluster,1-app-service-user-cluster,2-app-service-user-cluster;当Swan把三个实例都运行起来后,Swan会把三个实例目前运行时所绑定的IP+端口信息提交给Swan DNS。比如我们可以访问Swan DNS去解析app.service.user.cluster.swan.com这个域名,会解析出来三个容器的实例;当用户的请求访问app.service.user.cluster.gateway.swan.com,该请求会送达到Swan Proxy上,因为Swan Proxy地址是gateway.swan.com,Swan Proxy采用子域名的方式解析app.service.user.cluster。Swan Proxy解析这个地址时会查Swan DNS,查这个应用所对应的实例,每一个实例分别在哪个IP+端口上。Swan Proxy查询了Swan DNS之后,发现后面它有三个实例,这三个实例分别在不同的IP和端口上。当Swan Proxy收到对这个应用请求时会分别往后面三个实例上进行分发。

上图详细地解析了Swan DNS如何做服务发现,展示的是Swan DNS里面的A记录,图里对应的A纪录是nginx-demo.default.xcm.beijing.swan.com应用,应用名称叫nginx-demo,属于default这个服务,用户名是xcm,default这个服务目前运行在beijing这个数据中心里,swan.com作为一个后缀去表示,完整的表示出这是Swan的内网域名。A纪录展现出来这个应用有6个实例,每个实例都在192.168.1.196的IP地址上。

上图是Swan DNS的SRV记录,SRV记录和A记录不一样的地方是A记录只返回域名的IP地址,SRV记录要返回域名的IP地址+端口。上图所示的SRV查询结果包含了6个不同的应用实例,分别在不同的端口上,6个不同的实例又在同一个IP地址上:192.168.1.196,但它们绑定的端口不一样,从31000、31001、301002、301003、301004、301005、31006。

Swan实现了Proxy用于负载均衡。先讲一下Swan Proxy如何支持七层负载均衡。Swan Proxy支持子域名方式实现七层负载均衡。前面提到过,用户的HTTP请求发往app.service.user.cluster.gateway.swan.com这个域名地址时,先是.gateway.swan.com解析到Swan Proxy的IP地址上,然后因为Swan Proxy针对HTTP协议做解析的时候它会解析HTTP协议里面的域名,这个域名的子域名就是app.service.user.cluster,也就是这个域名里面的前缀。按照这个前缀,Swan Proxy可以区分出该HTTP请求是要访问哪个具体的应用。Swan Proxy在做HTTP这个服务发现负载均衡的时候会支持会话保持,也会支持HTTPS。但是Swan Proxy不支持HTTP子路径方式,因为子路径的方式本质上讲不是一种负载均衡的方式,子路径其实和应用所提供的不同服务相关的,所以具体的子路径服务的注册方式需要用额外的,比如微服务自身的服务发现支持,比如SpringCloud里面的Eurake或者阿里的Dubbo这些服务注册中心来做子路径方式的服务注册。

再讲一下Swan Proxy对于四层的负载均衡。因为四层协议,比如TCP协议,的特殊性,Swan Proxy支持的TCP协议只能是端口方式,根据一个Swan Proxy的IP或者Swan Proxy的域名,加上不同的端口来区分不同的应用。Swan Proxy在对TCP进行负载均衡的时候也会支持会话保持。

最后汇总下Swan的服务发现、负载均衡方式。结合容器目前的几种网络模式:Bridge方式、Host方式还有固定IP的方式,上图给出Swan在不同容器的网络模式下如何做服务发现、负载均衡。

上面所涉及到的技术不是靠几句话就能讲清楚,很多问题其实答案很简单,但是背后的思考和逻辑不简单,要做到知其然还要知其所以然。因此在这里给大家推荐一个架构交流学习群:650385180,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,以下的课程体系图也是在群里获取。

注:加入要求

1、具有一定工作经验的,面对目前流行的技术不知从何下手,需要突破技术瓶颈的可以加。

2、在公司待久了,过得很安逸,但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的可以加。

3、如果没有工作经验,但基础非常扎实,对java工作机制,常用设计思想,常用java开发框架掌握熟练的,可以加。

4、觉得自己很牛B,一般需求都能搞定。但是所学的知识点没有系统化,很难在技术领域继续突破的可以加。

5.阿里Java高级大牛直播讲解知识点,分享知识,多年工作经验的梳理和总结,带着大家全面、科学地建立自己的技术体系和技术认知!

6.小号或者小白之类加群一律不给过,谢谢。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年06月10日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Kubeadm快速部署Kubernetes1.13版本
kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具 ,这个工具能通过两条指令完成一个kubernetes集群的部署,比纯手工安装方便。
kubernetes中文社区
2019/06/24
6280
Kubeadm快速部署Kubernetes1.13版本
kubernetes-1:使用kubeadm搭建K8S单master节点集群
现在官方推荐的是kubespray,但也是基于kubeadm;除此之外,还有kind,minikube,但是并不试用于部署生产级别集群。
千里行走
2019/07/03
2.1K0
国内环境Kubernetes v1.12.1的安装与配置
版权声明:本文为耕耘实录原创文章,各大自媒体平台同步更新。欢迎转载,转载请注明出处,谢谢
耕耘实录
2018/12/20
1.6K0
Ansible部署k8s集群
安装Ansible # 更换清华源 sudo sed -e 's|^mirrorlist=|#mirrorlist=|g' \ -e 's|^#baseurl=http://mirror.centos.org|baseurl=https://mirrors.tuna.tsinghua.edu.cn|g' \ -i.bak \ /etc/yum.repos.d/CentOS-*.repo # 更换阿里epel curl -o /etc/yum.repos
Yuou
2022/09/26
4820
kubernetes部署:基于kubeadm的国内镜像源安装
Kubernetes 1.8开始要求关闭系统的Swap,如果不关闭,默认配置下kubelet将无法启动,关闭系统的Swap方法如下:
机械视角
2019/10/23
16.2K0
kubernetes部署:基于kubeadm的国内镜像源安装
在 Ubuntu 上安装 K8S教程
如果系统本身自带得镜像地址,服务器在国外,下载速度会很慢,可以打开 /etc/apt/sources.lis 替换为国内得镜像源。
痴者工良
2021/04/26
14.3K0
kubeadm安装kubernetes V1.11.1 集群
如果想要用二进制方法安装最新版本的Docker,可以参考我之前的文章在Redhat 7.3中采用离线方式安装Docker
大江小浪
2018/07/25
1.5K0
kubeadm安装kubernetes V1.11.1 集群
腾讯云CVM上用kubeadm安装Kubernetes集群(版本1.14.0)
kubeadm是Kubernetes官方提供的用于快速安装 Kubernetes 集群的工具,通过将集群的各个组件进行容器化安装管理,通过kubeadm的方式安装集群比二进制的方式安装要方便
马凌鑫
2019/04/02
4.1K0
Kubernetes(k8s)1.12.2集群搭建
这里指定了docker和kubelet的版本,如果不指定的话默认下载最新的版本,如果你的服务器可以上Google的话可以选择执行以下命令下载最新版
Java学习录
2019/04/18
8490
使用kubeadm在腾讯云上搭建Kubernetes集群
2.关闭seleniux、iptables、firewalld和NetworkManage
pengsiryan
2020/03/20
2.3K0
kubernetes系列教程(四)离线升级kubernetes集群
kubernetes版本升级迭代非常快,每三个月更新一个版本,很多新的功能在新版本中快速迭代,为了与社区版本功能保持一致,升级kubernetes集群,社区已通过kubeadm工具统一升级集群,升级步骤简单易行。首先来看下升级kubernetes集群需要升级那些组件:
HappyLau谈云计算
2019/09/15
4.3K0
kubernetes系列教程(四)离线升级kubernetes集群
使用 kubeadm 部署 kubernetes 1.13.1
最近有时间重新学习 k8s。k8s 的安装比之前简单了许多,本文介绍如何使用 kubeadm 部署 kubernetns 1.13.1
tanmx
2019/01/03
2.8K0
kubernetes项目部署
上面设置好以后,配置会自动通过连接api server最终存储到etcd中去。但是上面的配置过程十分的复杂,除非你对网络十分的属性
曲奇小点点
2024/08/26
1120
kubernetes项目部署
快速解决Kubernetes从k8s.gcr.io仓库拉取镜像失败问题
 在部署Kubernetes的过程中,需要从k8s.grc.io仓库中拉取部署所需的镜像文件,但是由于国内对国外的防火墙问题导致无法正常拉取,下面介绍一个方法来解决此问题,完成Kubernetes的正常部署。
非著名运维
2022/06/22
4.9K1
kubeadm实现K8S的HA
(1)k8s各节点SSH设置免密登录 所有节点用root用户操作,全部设置免密登陆,不做细分。
用户1499526
2019/07/15
1.2K0
kubeadm搭建单master节点1.20版本kubernetes集群
由于是云服务器,selinux、firewalld、swap都会默认关闭,iptables规则也会清空,所以仅需要配置下主机名、hosts文件以及配置下kubernetes的转发规则就好,如下:
唐旭
2021/11/02
1.6K1
详解kubeadm安装k8s集群常见问题
因为kubeadm需要用到容器,这些镜像都是k8s.gcr网站,因为众所周知的原因,国内是访问不到的,所以无法创建成功。,从其他地方下载。我在docker hub上发现了kubernetes的同步库gotok8s,应该是官方同步过来了,更新比较及时,版本也相互对应,配置好加速器下载也非常快。如果对应版本的库不存在,就找版本相近的(kube开头的几个库版本要相同),在安装的时候指定好对应的版本。
星星在线
2020/10/23
1.4K0
详解kubeadm安装k8s集群常见问题
CentOS7系统上Kubernetes集群搭建
在自己的Mac系统里面利用Parallels Desktop创建3台虚拟机,具体信息如下:
chengcheng222e
2021/11/04
1.8K0
kubeadm部署kubernetes集群
(3) 生成Kube Config文件,kubelet需要用这个文件与Master通信。
星哥玩云
2022/07/28
3250
K8S 之 kubeadm 安装
Kubeadm 是一个工具,它提供了 kubeadm init 以及 kubeadm join 这两个命令作为快速创建 kubernetes 集群的最佳实践。
YP小站
2020/06/04
1.6K0
推荐阅读
相关推荐
Kubeadm快速部署Kubernetes1.13版本
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档