深入了解kubernetes 中Service服务的内在逻辑

背景
深入了解Service服务的内在逻辑

Service
k8s中service是一个面向微服务架构的设计,它从k8s本身解决了容器集群的负载均衡,并开放式地支持了用户所需要的各种负载均衡方案和使用场景。

通常,一个service被创建后会在集群中创建相应的endpoints,随后,controller-manager中的endpointsController会去检查并向该endpoints填入关于这个service,符合下述所有条件的后端端点(即pod):

相同的namespace;
pod的labels能满足service.Spec.selector(除非service.Spec.selector为空,这种情况下不会自动创建endpoints);
如果service开放了port,且是以字符串名字的形式(targetPort=[字符串]),则相应的pod的某个container中必须有配置同名的port;
当endpoints被更新后,kube-proxy会感知,并根据更新后的endpoints,在宿主机上做转发规则的配置,kube-proxy目前支持iptables、ipvs两种负载均衡方式,默认是iptables。

DNS
绝大部分使用k8s的人都会使用kubedns做服务发现和service domain的解析。kubedns会建立长连接即时检查service的变化,一旦发现有service被创建,会根据service的类型,在数据库中构建service domain 到指定的CNAME或IP(cluster-IP)的映射,作为对该service domain 的dns解析结果。

service 的类型
ClusterIP
最普遍的service类型,也是默认类型。ClusterIP类型的service创建时,k8s会通过etcd从可分配的IP池中分配一个IP,该IP全局唯一,且不可修改。所有访问该IP的请求,都会被iptables转发到后端的endpoints中。

该类型下,service的cluster-ip会作为kube-dns的解析结果,返回给客户端。基本上这是私有云中服务内部常用的方案,但是也只能集群内服务互相访问。

NodePort
通过node的IP进行地址转换实现服务的可访问性,外部访问集群中任意一个node:port即可以访问服务。
举个例子:一个单副本的deployment,其pod运行在node2上,通过nodePort方式开放服务,外部client访问node1_ip:port即可访问到容器服务。这个过程中原理是:

client访问node1_ip:port
node1对数据包做SNAT,将来源地址改成node1_ip
node1对数据包做DNAT,将目的地址改成node2_ip
node2收到数据包,根据port查找自身的端口,这个端口在service创建时就会与自身运行的port做映射,所以这里数据包会被转发到真实的容器中
数据响应由容器发给node1,node1再返回给client
这种方案下,node上会产生端口的占用,所以要确保端口可用性。
另外,通过指定service.spec.externalTrafficPolicy=Local可以设置node上kube-proxy不转发到其他node,参照上面的例子,由于node1没有响应的pod在运行,所以node1上会直接drop数据包。

使用这种方案的原因,不外乎是:外部无法访问容器服务。

LoadBalancer
需要外部支持(GCP and Azure),用户访问service.spec.external-ip,该IP对应到一个外部负载均衡的vip,外部服务对这个vip的请求,会被loadbalancer通过健康检查和转发,发送到一个运行着该服务pod的node上,并同样通过nodePort里的端口映射,发送给容器。

上述是几种比较普遍的service,随着社区发展,又出现了一些新的类型,可以做更灵活的适配。

ExternalName
用户可以指定一个任意的名字,作为该service被解析的CNAME,这种类型的servcie不用指定clusterIP,因此kube-proxy不会管理这类service,这类service需要使用1.7版本以上的kubedns。比如用户想创建一个service,但要让所有容器访问该service的请求都引导到用户自己定义的外部域名服务,就可以通过这个方式实现。可以说这个是最自由的一个方式:你希望服务被如何解析,服务就能被如何解析。你甚至可以给多个service配置同一个externalName。

headless service
headless service是一个特殊的ClusterIP类service,这种service创建时不指定clusterIP(--cluster-ip=None),因为这点,kube-proxy不会管这种service,于是node上不会有相关的iptables规则。

当headless service有配置selector时,其对应的所有后端节点,会被记录到dns中,在访问service domain时kube-dns会将所有endpoints返回,选择哪个进行访问则是系统自己决定;

当selector设置为空时,headless service会去寻找相同namespace下与自己同名的pod作为endpoints。这一点被应用到statefulset中,当一个三副本的statefulset(mysql1,mysql2,mysql3)运行在不同节点时,我们可以通过域名的方式对他们分别访问。

原文地址:http://blog.51cto.com/09112012/2287776

时间: 2024-10-31 01:55:37

深入了解kubernetes 中Service服务的内在逻辑的相关文章

Android中Service(服务)的使用

进程的优先级---------------------------------进程的优先级表现为:优先级越高,该进程的“生命力”就越强,反之,则越低,而低优先级的进程更容易被Android系统清除.进程的优先级从高到低为:1. 前台进程2. 可见进程3. 服务进程4. 后台进程5. 空进程 Service(服务)---------------------------------Service是Android系统的核心组件,由Android创建.维护和管理.Service需要在AndroidMan

在虚拟机环境(CentOS7系统)下将kubernetes中部署服务成功,但在虚拟机外部无法访问到服务

在CentOS7环境下,kubernetes单机版环境,成功部署一个服务,在虚拟机中访问服务没问题,下面这样: curl http://172.27.73.26:8888/eureka-server/default/master {"name":"eureka-server","profiles":["default"],"label":"master","version&qu

Kubernetes集群中Service的滚动更新

Kubernetes集群中Service的滚动更新 二月 9, 2017 0 条评论 在移动互联网时代,消费者的消费行为已经"全天候化",为此,商家的业务系统也要保持7×24小时不间断地提供服务以满足消费者的需求.很难想像如今还会有以"中断业务"为前提的服务系统更新升级.如果微信官方发布公告说:每周六晚23:00~次日凌晨2:00进行例行系统升级,不能提供服务,作为用户的你会怎么想.怎么做呢?因此,各个平台在最初设计时就要考虑到服务的更新升级问题,部署在Kubern

Kubernetes中,通过Service访问Pod快速入门

一.背景 理想状态下,我们可以认为Kubernetes Pod是健壮的.但是,理想与现实的差距往往是非常大的.很多情况下,Pod中的容器可能会因为发生故障而死掉.Deployment等Controller会通过动态创建和销毁Pod来保证应用整体的健壮性.众所周知,每个Pod都拥有自己的IP地址,当新的Controller用新的Pod替代发生故障的Pod时,我们会发现,新的IP地址可能跟故障的Pod的IP地址可能不一致.此时,客户端如何访问这个服务呢?Kubernetes中的Service应运而生

windows中的服务隔离 service isolation and service SID(Virtual Account)

windows 中的服务隔离在windows vista 以及server 2008之后就有了,可以让管理员控制本地资源的使用(如文件.注册表等等).之前windows版本中,系统内置了一些高权限的服务账号,大家所熟悉的有Local System,Network,LocalService 为了最小化权限使用,通常我们需要创建账号来赋予最小权限,然后配置服务以这个账号运行,但是如果服务较多,那么有许许多多的账号要维护,而且如果你有严格的密码策略的话,比如定期要更改服务账号的密码,那真是头疼. wi

大神教你轻松玩转Docker和Kubernetes中如何运行MongoDB微服务

本文介绍了利用Docker和Kubernetes搭建一套具有冗余备份集合的MongoDB服务,从容器对CI和CD引发的改变入手,讨论了容器技术对MongoDB带来的挑战和机会,然后实战如何部署一套稳定的MongoDB服务,非常的干货 介绍 想尝试在笔记本电脑上运行MongoDB么?希望通过执行一个简单的命令,然后就有一个轻量级.自组织的沙盒么?并可再通过一条命令就可以移除所有的痕迹么? 需要在多个环境中运行相同的应用程序栈?创建自己的容器镜像,使得开发.测试.操作和支持团队启动一份完全相同的环境

实用干货:Kubernetes中的负载均衡全解

很多企业在部署容器的时候都会选择Kubernetes作为其容器编排系统.这是对Kubernetes的可靠性,灵活性和特性广泛的肯定.在这篇文章中,我们将对Kubernetes如何处理一个非常常见且必要的工作--负载均衡,进行深入的解读.在许多非容器环境(即服务器之间的均衡)中,负载均衡是一个相对简单的任务,但当涉及到容器时,就需要一些其他的.特殊的处理. 管理容器 要理解Kubernetes的负载均衡,首先需要了解Kubernetes是如何组建容器的. 容器通常用来执行特定的服务或者一组服务,因

如何在Kubernetes中管理有状态应用

在Kubernetes中,StatefulSet被用来管理有状态应用的API对象.StatefulSets在Kubernetes 1.9版本才稳定.StatefulSet管理Pod部署和扩容,并为这些Pod提供顺序和唯一性的保证.与Deployment相似的地方是,StatefulSet基于spec规格管理Pod:与Deployment不同的地方是,StatefulSet需要维护每一个Pod的唯一身份标识.这些Pod基于同样的spec创建,但互相之间不能替换,每一个Pod都保留自己的持久化标识.

Kubernetes中的RBAC

Kubernetes中,授权有ABAC(基于属性的访问控制).RBAC(基于角色的访问控制).Webhook.Node.AlwaysDeny(一直拒绝)和AlwaysAllow(一直允许)这6种模式.需要在kube-apiserver设置–authorization-mode=RBAC参数,启用RABC模式,下面的操作版本为v1.10.1: 当应用没有指定serviceAccountName,它将使用default服务帐户. 在RABC API中,通过如下的步骤进行授权: 1)定义角色:定义角色