【微服务】Kubernetes对象之Service(重要)

目录

Kubernetes Service:

没有 selector 的 Service :

VIP 和 Service 代理:

userspace 代理模式:

iptables 代理模式:

多端口 Service:

选择自己的 IP 地址:

服务发现:

Headless Service:

配置 Selector:

发布服务 —— 服务类型:

NodePort 类型:

LoadBalancer 类型:

AWS 内部负载均衡器:

AWS SSL 支持:

外部 IP:

不足之处:

未来:

避免冲突:

IP 和 VIP:

API 对象:

 

Kubernetes Service:

Kubernetes Service 定义了这样一种抽象:一个 Pod 的逻辑分组,一种可以访问它们的策略 —— 通常称为微服务。
这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector实现的。
对 Kubernetes 集群中的应用,Kubernetes 提供了简单的 Endpoints API,只要 Service 中的一组 Pod 发生变更,应用程序就会被更新。
非 Kubernetes 集群中的应用,Kubernetes 提供了基于 VIP 的网桥的方式访问 Service,再由 Service 重定向到 backend Pod。
一个 Service 在 Kubernetes 中是一个 REST 对象,和 Pod 类似。 
Service 定义可以基于 POST 方式,请求 apiserver 创建新的实例。
Service 能够将一个接收端口映射到任意的 targetPort。
targetPort 可以是一个字符串,引用了 backend Pod 的一个端口的名称。
Kubernetes Service 能够支持 TCP 和 UDP 协议,默认 TCP 协议。
Servcie 抽象了该如何访问 Kubernetes Pod,但也能够抽象其它类型的 backend。
 

没有 selector 的 Service :

希望在生产环境中使用外部的数据库集群,但测试环境使用自己的数据库。
希望服务指向另一个 Namespace 中或其它集群中的服务。
正在将工作负载转移到 Kubernetes 集群,和运行在 Kubernetes 集群之外的 backend。


Service 没有定义 selector,就不会创建相关的 Endpoints 对象。可以手动将 Service 映射到指定的 Endpoints。


ExternalName Service 是 Service 的特例,它没有 selector,也没有定义任何的端口和 Endpoint。 
对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。
当查询主机my-service.prod.svc.CLUSTER时,集群的 DNS 服务将返回一个键为 externalName的值的 CNAME 记录。
 

VIP 和 Service 代理:

Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程。
kube-proxy 负责为 Service 实现了一种 VIP(虚拟 IP)的形式,而不是 ExternalName 的形式。
从 Kubernetes v1.2 起,默认就是 iptables 代理。
 

userspace 代理模式:

kube-proxy 会监视 Kubernetes master 对 Service 对象和 Endpoints 对象的添加和移除。 
对每个 Service,它会在本地 Node 上打开一个端口(随机选择)。
任何连接到“代理端口”的请求,都会被代理到 Service 的backend Pods 中的某个上面。
使用哪个 backend Pod,是基于 Service 的 SessionAffinity 来确定的。
使用哪个 backend Pod,是基于 Service 的 SessionAffinity 来确定的。
任何到达 Service 的 IP:Port 的请求,都会被代理到一个合适的 backend,不需要客户端知道关于 Kubernetes、Service、或 Pod 的任何信息。
默认的策略是,通过 round-robin 算法来选择 backend Pod。
实现基于客户端 IP 的会话亲和性,可以通过设置 service.spec.sessionAffinity 的值为 "ClientIP" 。
 

iptables 代理模式:

kube-proxy 会监视 Kubernetes master 对 Service 对象和 Endpoints 对象的添加和移除。
每个 Service,它会安装 iptables 规则,从而捕获到达该 Service 的 clusterIP(虚拟 IP)和端口的请求,进而将请求重定向到 Service 的一组 backend 中的某个上面。
每个 Endpoints 对象,它也会安装 iptables 规则,这个规则会选择一个 backend Pod。
默认的策略是,随机选择一个 backend。
实现基于客户端 IP 的会话亲和性,可以将 service.spec.sessionAffinity 的值设置为 "ClientIP"。
任何到达 Service 的 IP:Port 的请求,都会被代理到一个合适的 backend,不需要客户端知道关于 Kubernetes、Service、或 Pod 的任何信息。
比 userspace 代理更快、更可靠。
 

多端口 Service:

Kubernetes 支持在 Service 对象中定义多个端口。 
当使用多个端口时,必须给出所有的端口的名称,这样 Endpoint 就不会产生歧义
 

选择自己的 IP 地址:

通过设置 spec.clusterIP 字段来指定自己的集群 IP 地址。 


 

服务发现:

Kubernetes 支持2种基本的服务发现模式 —— 环境变量和 DNS。
环境变量:
kubelet 会为每个活跃的 Service 添加一组环境变量。
支持 Docker links兼容 变量、简单的 {SVCNAME}_SERVICE_HOST 和 {SVCNAME}_SERVICE_PORT 变量
Pod 想要访问的任何 Service 必须在 Pod 自己之前被创建,否则这些环境变量就不会被赋值(DNS 并没有这个限制)。
DNS:
一个可选(尽管强烈推荐)集群插件 是 DNS 服务器。 
DNS 服务器监视着创建新 Service 的 Kubernetes API,从而为每一个 Service 创建一组 DNS 记录。
整个集群的 DNS 一直被启用,那么所有的 Pod 应该能够自动对 Service 进行名称解析。
Kubernetes 也支持对端口名称的 DNS SRV(Service)记录。
Kubernetes DNS 服务器是唯一的一种能够访问 ExternalName 类型的 Service 的方式。 
 

Headless Service:

通过指定 Cluster IP(spec.clusterIP)的值为 "None" 来创建 Headless Service。
允许开发人员自由寻找他们自己的方式,从而降低与 Kubernetes 系统的耦合性。
应用仍然可以使用一种自注册的模式和适配器,对其它需要发现机制的系统能够很容易地基于这个 API 来构建。
这类 Service 并不会分配 Cluster IP,kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由。
DNS 如何实现自动配置,依赖于 Service 是否定义了 selector。
 

配置 Selector:

对定义了 selector 的 Headless Service,Endpoint 控制器在 API 中创建了 Endpoints 记录,并且修改 DNS 配置返回 A 记录(地址),通过这个地址直接到达 Service 的后端 Pod上。
不配置 Selector:
对没有定义 selector 的 Headless Service,Endpoint 控制器不会创建 Endpoints 记录。 
ExternalName 类型 Service 的 CNAME 记录
记录:与 Service 共享一个名称的任何 Endpoints,以及所有其它类型
 

发布服务 —— 服务类型:

对一些应用(如 Frontend)的某些部分,可能希望通过外部(Kubernetes 集群外部)IP 地址暴露 Service。
Kubernetes ServiceTypes 允许指定一个需要的类型的 Service,默认是 ClusterIP 类型。
Type 的取值:
ClusterIP:
通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType。
NodePort:
通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务。
LoadBalancer:
使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
ExternalName:
通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容。
 

NodePort 类型:

type 的值为 "NodePort",Kubernetes master 将从给定的配置范围内(默认:30000-32767)分配端口,每个 Node 将从该端口(每个 Node 上的同一端口)代理到 Service。
该端口将通过 Service 的 spec.ports[*].nodePort 字段被指定。
需要指定的端口号,可以配置 nodePort 的值,系统将分配这个端口,否则调用 API 将会失败。
Service 将能够通过 :spec.ports[*].nodePort 和 spec.clusterIp:spec.ports[*].port 而对外可见
 

LoadBalancer 类型:

使用支持外部负载均衡器的云提供商的服务,设置 type 的值为 "LoadBalancer",将为 Service 提供负载均衡器。
负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段被发布出去。
 

AWS 内部负载均衡器:

在混合云环境中,有时从虚拟私有云(VPC)环境中的服务路由流量是非常有必要的。
可以通过在 Service 中增加 annotation 来实现。
在水平分割的 DNS 环境中,需要两个 Service 来将外部和内部的流量路由到 Endpoint 上。
 

AWS SSL 支持:

对运行在 AWS 上部分支持 SSL 的集群,可以为 LoadBalancer 类型的 Service 增加两个 annotation:
第一个 annotation 指定了使用的证书。
第二个 annotation 指定了 Pod 使用的协议。
HTTP 和 HTTPS 将选择7层代理:ELB 将中断与用户的连接,当转发请求时,会解析 Header 信息并添加上用户的 IP 地址
TCP 和 SSL 将选择4层代理:ELB 将转发流量,并不修改 Header 信息。
 

外部 IP:

外部的 IP 路由到集群中一个或多个 Node 上,Kubernetes Service 会被暴露给这些 externalIPs。 
通过外部 IP(作为目的 IP 地址)进入到集群,打到 Service 的端口上的流量,将会被路由到 Service 的 Endpoint 上。
externalIPs 不会被 Kubernetes 管理,它属于集群管理员的职责范畴。
Service 的规定,externalIPs 可以同任意的 ServiceType 来一起指定。
 

不足之处:

为 VIP 使用 userspace 代理,将只适合小型到中型规模的集群,不能够扩展到上千 Service 的大型集群。
使用 userspace 代理,隐藏了访问 Service 的数据包的源 IP 地址,这使得一些类型的防火墙无法起作用。 
iptables 代理不会隐藏 Kubernetes 集群内部的 IP 地址,但却要求客户端请求必须通过一个负载均衡器或 Node 端口。
Type 字段支持嵌套功能 —— 每一层需要添加到上一层里面。 
 

未来:

为 Service 实现更加灵活的请求进入模式,这些 Service 包含当前 ClusterIP、NodePort 和 LoadBalancer 模式
 

避免冲突:

Kubernetes 最主要的哲学之一,是用户不应该暴露那些能够导致他们操作失败、但又不是他们的过错的场景。
用户不应该必须选择一个端口号,而且该端口还有可能与其他用户的冲突。
在彼此隔离状态下仍然会出现失败。
为了使用户能够为他们的 Service 选择一个端口号,我们必须确保不能有2个 Service 发生冲突。 
通过为每个 Service 分配它们自己的 IP 地址来实现。
保证每个 Service 被分配到一个唯一的 IP,需要一个内部的分配器能够原子地更新 etcd 中的一个全局分配映射表,这个更新操作要先于创建每一个 Service。
使 Service能够获取到 IP,这个映射表对象必须在注册中心存在,否则创建 Service 将会失败,指示一个 IP 不能被分配。
 

IP 和 VIP:

Service 的 IP 实际上不能通过单个主机来进行应答。
我们使用 iptables来定义一个虚拟IP地址(VIP),它可以根据需要透明地进行重定向。
当客户端连接到 VIP 时,它们的流量会自动地传输到一个合适的 Endpoint。
环境变量和 DNS,实际上会根据 Service 的 VIP 和端口来进行填充。
 

API 对象:

在 Kubernetes REST API 中,Service 是 top-level 资源。

 

 

 

 

内容整理自Kubernetes中文社区:https://www.kubernetes.org.cn/

你可能感兴趣的:(Kubernetes)