Google Kubernetes设计文档之服务篇

【编者按】Kubernetes是Google开源的容器集群管理系统。它构建于Docker技术之上,为容器化的应用提供资源调度、部署运行、服务发现、扩容缩容等整一套功能,本质上可看作是基于容器技术的mini-PaaS平台。为帮助国内开发者了解Kubernetes技术,CSDN联合浙江大学SEL实验室共同翻译Kubernetes的系列设计文档,本文为系列的第三篇:服务。 Pod是在Kubernetes中,创建、调度和管理的最小部署单位,这些Pod之间是如何互相通信的,本文将进行详细阐述。

概述

Kubernetes中 Pods 不是一成不变的。它们可以随着时间进行迁移,特别是当受到 ReplicationControllers 支配时。虽然每个pod都有属于自己的IP地址,但是却不能保证每个Pod的IP地址随着时间的变化依然保持不变。这就导致了一个问题:如果在Kubernetes集群里,有一系列的pods(我们姑且称之为后端)为其他的pods(称为前端)提供功能,那前端该如何去找到后端?

服务

Kubernetes中的服务是一种抽象概念,它定义了一个pods逻辑集合以及访问它们的策略,有时它也被称为微服务(Micro-service)。服务的目标是提供一种桥梁,使得非Kubernetes原生应用程序,在无需为Kubernetes编写特定代码的前提下,轻松访问后端。服务会为用户提供一对IP地址和port端口,用于在访问时重定向到相应的后端。服务里Pods集合的选定是由一个标签选择器(label selector)来完成的。

举个例子,首先假设一个“镜像处理”后端,它运行着三个可用的副本。这些副本是无状态的,前端根本不关心自己具体使用的是后端的哪个副本。因此,尽管组成后端集合的实际pods可能已经发生了改变,但是前端用户完全不需要知晓这些改变。这种服务的抽象性实现了前端访问与后端服务的解耦。

定义服务

这里是一个使用服务的例子。在Kubernetes中,服务是REST对象,类似于pod。如pod一般,服务的定义,可以通过一个发给apiserver的POST请求,来完成创建一个新的实例。例如,假设你有一组pods,都暴露9376端口,并携带一个"app=MyApp"的标签。

{ "id": "myapp", "selector": { "app": "MyApp" }, "containerPort": 9376, "protocol": "TCP", "port": 8765}

上述定义将创建一个名为"myapp"的新服务,它使得所有带有"app=MyApp"标签的pod都监听TCP协议上的端口9376。而客户可以通过端口$MYAPP_SERVICE_PORT连接到$MYAPP_SERVICE_HOST,从而访问该服务。

服务是如何工作的?

在Kubernetes集群中的每个节点(node)上都运行着一个服务代理(service proxy)。该代理应用监听Kubernetes Master,以此来添加和删除服务对象及端点(endpoints,即满足服务标签选择器的pods),同时该代理应用还存储一个服务到端点列表的映射。它为每个服务在本地节点上打开一个端口,并转发该端口上的所有流量到后端。名义上是依据策略来执行的,但现在唯一支持的策略是轮转调度(round-robin)。

当一个pod被编入,Master为每一个存活的服务增加一组环境变量。我们支持 Docker-links-compatible 变量(参见makeLinkVariables)以及更简单的{SVCNAME}_SERVICE_HOST和{SVCNAME}_SERVICE_PORT变量,其中的服务名要求大写,破折号将转换为下划线。具体的服务工作图如图1 。例如,服务"redis-master"监听TCP端口637,并分配IP地址10.0.0.11,将产生以下环境变量:

REDIS_MASTER_SERVICE_HOST=10.0.0.11REDIS_MASTER_SERVICE_PORT=6379REDIS_MASTER_PORT=tcp://10.0.0.11:6379REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379REDIS_MASTER_PORT_6379_TCP_PROTO=tcpREDIS_MASTER_PORT_6379_TCP_PORT=6379REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11

这意味着要有先后次序,即一个pod希望访问的服务必须在pod本身创建之前被创建,否则环境变量不会被加载。不过支持DNS服务后,该限制将不再存在。

服务通过它的标签选择器,可以解析到0或多个端点。在服务的生命周期内,组成该服务的pods集合可以增加、缩减,或全部失效。用户只有在当他们正在使用的后端从服务中被移除时,才会遇到问题(即使如此,已经打开的连接也会因为某些协议的缘故,继续保持)。

图1.服务工作图

细节明细

前文的内容对于大多数只是想要使用服务的人来说应该已经足够了。然而,有很多发生在这背后的事情也值得去深入了解。

避免冲突

Kubernetes的一个主要理念是,用户不应该遭遇可能导致其操作失败的情景,尤其是用户本身并未引起错误。在此背景下,我们考虑网络端口的问题—不应该让用户选择一个可能与其他用户发生冲突的端口号。否则,将是隔离上的失败。

为了让用户能够选择他们的服务端口号,我们必须确保不会引起两个服务间的冲突。我们通过为每个服务分配自己的IP地址来做到这一点。

IP和Portal

不同于路由到一个固定的pod的IP地址,服务的IP实际上并不是由单个Master响应的。相反的,我们用iptables(Linux中的数据包处理逻辑)来定义这些需要透明重定向的“虚拟”IP地址。我们将服务IP和服务端口的元组称为Portal。当用户连接到portal上,其访问会被自动转移到一个相应的端点上。实际上,服务的环境变量是依据portal的IP和端口来设定的。此外,我们将增加DNS来支撑服务的访问。

举例来说,考虑上图所展示的应用处理过程。在创建后端服务时,Kubernetes Master分配一个Portal的IP地址,例如10.0.0.1。假设服务端口是1234,portal即为是10.0.0.1:1234。Master将存储该信息,它也被集群中所有的服务代理实例所获取。当代理监测到一个新的portal,它会打开一个新的随机端口,建立一个从Portal到新端口的iptables重定向,然后开始接受对其的连接。

当用户使用portal端口连接MYAPP_SERVICE_HOST时(不论他们将其视为静态端口或视为MYAPP_SERVICE_PORT),iptables规则生效,重定向数据包到服务代理自身的端口上。服务代理选择一个后端,并开始从客户端到后端的代理通信流量。具体原理如图2。

最终的结果是,用户可以选择他们想要的任何服务端口,而没有冲突的危险。客户可以轻松连接IP和端口,而无需了解到他们正在访问哪个pods。

图2.服务中IP和portal原理图

外部服务

对于用户应用程序的某些部分(如前端),用户希望在外部可访问的IP地址(公网IP)上暴露一个服务。

如果你希望你的服务暴露在一个公网IP地址上,你可以选择提供一个服务可以响应的"publicIPs"列表。这些IP地址将被绑定上服务端口,同时被映射到由服务选择的pods集合上。你随后需要负责确保到该公网IP地址的通信流量被发送到一个或多个kubernetes工作节点。与映射内部IP地址一致,每个主机上的每一条IPTables规则,将公网特定IP地址的数据包映射到内部的服务代理。

对于提供外部负载均衡设备的云服务提供商,还有一个更简单的方式来达到同样的效果。在这类供应商(如GCE)上,你可以让publicIPs为空,作为代替,你可以在服务上设置createExternalLoadBalancer标志。这会启动一个云服务提供商的特定负载均衡设备(假设它由你的云提供商支持),并用适当的值来填充这个公网IP值域。

缺点

我们预计,portals使用的iptables将在小规模上可用,而无法扩展到有着成千上万服务的大型集群。查看 portals的原始设计方案 ,可了解更多详情。

今后的工作

在将来,我们设想,代理策略可以变得比简单的轮循调度更加细致入微,比如master筛选或分片。我们还设想,一些服务将具有“真正的”负载均衡器,在这种情况下,portal将可以直接简单地传输数据包。

原文链接: Services in Kubernetes(编译/仇臣 审校/孙宏亮、张磊 责编/周小璐)

相关链接:Google Kubernetes设计文档之安全篇

Google Kubernetes设计文档之Pod篇

译者简介:仇臣, 浙江大学SEL实验室硕士研究生,目前在云平台团队从事科研和开发工作。浙大团队对PaaS,Docker,大数据和主流开源云计算技术有深入的研究和二次开发经验,团队现将部分技术文章贡献出来,希望能对读者有所帮助。

时间: 2024-10-25 21:41:42

Google Kubernetes设计文档之服务篇的相关文章

Google Kubernetes设计文档之Pod篇

[编者按]Kubernetes是Google开源的容器集群管理系统.它构建于Docker技术之上,为容器化的应用提供资源调度.部署运行.服务发现.扩容缩容等整一套功能,本质上可看作是基于容器技术的mini-PaaS平台.为帮助国内开发者了解Kubernetes技术,CSDN联合浙江大学SEL实验室共同翻译Kubernetes的系列设计文档,本文为系列的第二篇Pod. 在Kubernetes中,创建.调度和管理的最小部署单位是Pod,而不是容器. 什么是Pod 一个Pod对应于由若干容器组成的一个

Google Kubernetes设计文档之Volumes

Volumes 本文描述了Kubernetes中Volumes的使用情况,建议在阅读本文前,首先熟悉pods. Volume是一个能够被容器访问的目录,它可能还会包含一些数据.Kubernetes Volumes与Docker Volumes类似,但并不完全相同. 一个Pod会在它的ContainerManifest 属性中指明其容器需要哪些Volumes. 容器中的进程可见的文件系统视图由两个源组成:一个单独的Docker image和零个或多个Volumes.Docker image位于文件

Google Kubernetes设计文档之网络

[编者按]Kubernetes是Google开源的容器集群管理系统.它构建于Docker技术之上,为容器化的应用提供资源调度.部署运行.服务发现.扩容缩容等整一套功能,本质上可看作是基于容器技术的mini-PaaS平台.为帮助国内开发者了解Kubernetes技术,CSDN联合浙江大学SEL实验室共同翻译Kubernetes的系列设计文档,本文为系列的第四篇:网络. 模型和动机Kubernetes从Docker默认的网络模型中独立出来形成一套自己的网络模型.该网络模型的目标是:每一个pod都拥有

Google Kubernetes设计文档之安全篇

[编者按]Kubernetes是Google开源的容器集群管理系统.它构建于Docker技术之上,为容器化的应用提供资源调度.部署运行.服务发现.扩容缩容等整一套功能,本质上可看作是基于容器技术的mini-PaaS平台.为帮助国内开发者了解Kubernetes技术,CSDN联合浙江大学SEL实验室共同翻译Kubernetes的系列设计文档,本文为系列的第一篇:安全. 设计目标 本文讲述了Kubernetes的容器.API和基础设施在安全方面的设计原则. 保证容器与其运行的宿主机之间有明确的隔离:

通向架构师的道路(第二十六天)漫谈架构与设计文档的写作技巧

前言: 这篇是一篇番外篇,没有太多代码与逻辑,完全是一种"软"技巧,但是它对于你如何成为一名合构的架构设计人员很重要. 在此要澄清一点,架构师本身也是"程序员",不是光动嘴皮子的家伙们,如果你不是一名程序虽出身那你根本谈不上也不可能成为一名架构师. 那么架构师还有哪些是作为一名程序员来说不具备的呢? 其中有一项能力就叫做"文档写作能力". 一.Soft Skill与Hard Skill 作为一名架构师除了是一名资深的程序员外,它还必须具有相应的S

用户界面设计文档:手指友好型设计

文章描述:手指友好型设计-为了更好的点击而设计. 玩飞镖的时候,靶心是最难射中的位置,因为靶心是整个靶面上面积最小的部分.越是小的目标,就越是难以达到.这个准则在移动设备的触摸屏幕上同样适用. 众所周知,对于触屏设备用户来说,面积小的目标比面积大的目标更难操纵.所以,在设计移动设备界面的时候,触控目标一定要充分的大,足以让用户操作自如.但是多大才算充分呢?多大才是对于大多数用户最合适的尺寸呢?各大移动设备开发者已经认识到这个问题,最常见的做法是在各大厂商的用户界面设计文档中寻找答案. 那么,设计

互联网产品设计:产品设计文档(PDD)

传统上写产品需求文档(PRD)的做法,就是把用例.流程图和网页原型图一股脑的放到一个Word文档里.一般一个产品都包含乃几十个乃至上百用例,每个用例都有自己的流程图,每个流程图又包含了少则几个多则几十的网页原型图,结果就是产品需求文档变得庞大无比,写的人费事儿,读的人更惨. 自从我受到了这样文档的折磨,我就一直都在琢磨怎么才能把文档写得更简单一点,让阅读的人-通常是设计师和程序员-能够在最短的时间内领会产品的设计. 原来做UI设计师的时候,我创造了一种用流程图来表示产品交互的办法,这个方法受到了

实战从需求文档到设计文档的书写规范(一)

1.前言 本文有两个目的:实现每晚构建平台和探讨一个软件从需求文档到设计文档的书写规范. 每晚构建是软件研发管理中极具价值的手段,对于加快发现和改正缺陷,降低集成风险,提高产品质量,加强成员沟通与协作,缩短产品上市时间,增加项目开发透明度,提高项目组成员信心和斗志有着非常重要的作用和意义.本文从软件工程过程:需求定义,分析,设计出发描述了实战每晚构建平台的大部分过程. 软件工程中文档有着极其重要的地位,良好的文档风格和习惯是一个团队成熟的重要标志.目前有些软件研发人员特别是刚刚走上岗位的研发人员

实战从需求文档到设计文档的书写规范(六)

本文是实战每晚构建系列的第三篇,利用第二篇文章中叙述的开源技术对第一篇中的分析模型进行设计和实现. 1.构建信息显示系统的设计 这是一个典型的web应用系统,不过非常简单.根据<面向对象的系统分析和设计>所描述的,设计主要对四个部分进行描述: 问题域的细化:考虑将来实现语言的特性和利用某些设计模式,对分析模型进行细化,并作某些权衡.实现对未来系统"如何做事情"的描述. 人机界面设计:考虑和使用者的交互,对信息显示的布局和接收用户指令或数据的行为进行设计. 存储设计:考虑如何