Service

概述

1、服务是将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法

2、使用 Kubernetes,无需修改应用程序去使用不熟悉的服务发现机制,Kubernetes 为 Pod 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名,并且可以在它们之间进行负载均衡

3、Service 在很多情况下只是一个概念,真正起作用的其实是 kube-proxy 服务进程

(1)每个 Node 上都运行一个 kube-proxy 服务进程

(2)当创建 Service 时会通过 api-server 向 etcd 写入创建的 Service 信息

(3)kube-proxy 基于监听机制发现 Service 变动,然后将最新 Service 信息转换成对应的访问规则

 

虚拟 IP 和服务代理

1、Kubernetes 集群中的每个节点会运行一个 kube-proxy(除非你已经部署了自己的替换组件来替代 kube-proxy)

2、kube-proxy 组件负责除 type 为 ExternalName 以外的服务,实现虚拟 IP 机制

3、使用代理转发方式实现 Service 的原因

(1)DNS 的实现不遵守记录的 TTL 约定的历史由来已久,在记录过期后可能仍有结果缓存

(2)有些应用只做一次 DNS 查询,然后永久缓存结果

(3)即使应用程序和库进行了适当的重新解析,TTL 取值较低或为零的 DNS 记录可能会给 DNS 带来很大的压力, 从而变得难以管理

4、在运行 kube-proxy 时,可能会修改内核级别的规则

(1)例如,可能会创建 iptables 规则,在某些情况下,这些规则直到重启才会被清理

(2)因此,运行 kube-proxy 这件事应该只由了解在计算机上使用底层、特权网络代理服务会带来的后果的管理员执行

(3)尽管 kube-proxy 可执行文件支持 cleanup 功能,但这个功能并不是官方特性,因此只能根据具体情况使用

5、代理模式

(1)注意,kube-proxy 会根据不同配置以不同的模式启动

(2)kube-proxy 的配置是通过 ConfigMap 完成的,kube-proxy 的 ConfigMap 实际上弃用了 kube-proxy 大部分标志的行为

(3)kube-proxy 的 ConfigMap 不支持配置的实时重新加载

(4)kube-proxy 不能在启动时验证和检查所有的 ConfigMap 参数。 例如,如果你的操作系统不允许你运行 iptables 命令,标准的 kube-proxy 内核实现将无法工作。 同样,如果你的操作系统不支持 netsh,它也无法在 Windows 用户空间模式下运行

 

iptables 代理模式

1、在这种模式下,kube-proxy 监视 Kubernetes 控制平面,获知对 Service 和 EndpointSlice 对象的添加和删除操作

(1)对于每个 Service,kube-proxy 会添加 iptables 规则,这些规则捕获流向 Service 的 clusterIP 和 port 的流量,并将这些流量重定向到 Service 后端集合中的其中之一

(2)对于每个端点,它会添加指向一个特定后端 Pod 的 iptables 规则

(3)默认情况下,iptables 模式下的 kube-proxy 会随机选择一个后端

(4)使用 iptables 处理流量的系统开销较低,因为流量由 Linux netfilter 处理,无需在用户空间和内核空间之间切换。这种方案也更为可靠

2、如果 kube-proxy 以 iptables 模式运行,并且它选择的第一个 Pod 没有响应,那么连接会失败

(1)这与用户空间模式不同: 在后者这种情况下,kube-proxy 会检测到与第一个 Pod 的连接失败,并会自动用不同的后端 Pod 重试

(2)可以使用 Pod 就绪探针来验证后端 Pod 是否健康。这样可以避免 kube-proxy 将流量发送到已知失败的 Pod 上

 

IPVS 代理模式

1、在 ipvs 模式下,kube-proxy 监视 Kubernetes Service 和 EndpointSlice,然后调用 netlink 接口创建 IPVS 规则,并定期与 Kubernetes Service 和 EndpointSlice 同步 IPVS 规则

(1)该控制回路确保 IPVS 状态与期望的状态保持一致

(2)访问 Service 时,IPVS 会将流量导向到某一个后端 Pod

2、IPVS 代理模式基于 netfilter 回调函数,类似于 iptables 模式

(1)但它使用哈希表作为底层数据结构,在内核空间中生效,这意味着 IPVS 模式下的 kube-proxy 比 iptables 模式下的 kube-proxy 重定向流量的延迟更低,同步代理规则时性能也更好

(2)与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量

3、IPVS 为将流量均衡到后端 Pod 提供了更多选择

(1)rr:轮询

(2)lc:最少连接(打开连接数最少)

(3)dh:目标地址哈希

(4)sh:源地址哈希

(5)sed:最短预期延迟

(6)nq:最少队列

4、说明

(1)要在 IPVS 模式下运行 kube-proxy,必须在启动 kube-proxy 之前确保节点上的 IPVS 可用

(2)当 kube-proxy 以 IPVS 代理模式启动时,它会验证 IPVS 内核模块是否可用。如果未检测到 IPVS 内核模块,则 kube-proxy 会退回到 iptables 代理模式运行

 

移除 kube-proxy userspace 模式

1、已弃用一年多的 userspace 代理模式不再受 Linux 或 Windows 支持,并将在 v1.26 中被移除

2、Linux 用户应使用 iptables 或 ipvs,Windows 用户应使用 kernelspace:现在使用 --mode userspace 会失败

 

Endpoints

1、在 Kubernetes API 中,Endpoints (该资源类别为复数)定义了网络端点的列表,通常由 Service 引用,以定义可以将流量发送到哪些 Pod

2、推荐用 EndpointSlice API 替换 Endpoints

 

EndpointSlices

1、EndpointSlices 这些对象表示针对服务的后备网络端点的子集(切片)

2、你的 Kubernetes 集群会跟踪每个 EndpointSlice 表示的端点数量

(1)如果服务的端点太多以至于达到阈值,Kubernetes 会添加另一个空的 EndpointSlice 并在其中存储新的端点信息

(2)默认情况下,一旦现有 EndpointSlice 都包含至少 100 个端点,Kubernetes 就会创建一个新的 EndpointSlice

(3)在需要添加额外的端点之前,Kubernetes 不会创建新的 EndpointSlice

3、Kubernetes 的 EndpointSlice API 提供了一种简单的方法来跟踪 Kubernetes 集群中的网络端点(network endpoints)

4、EndpointSlices 为 Endpoints 提供了一种可扩缩和可拓展的替代方案

 

无头服务(Headless Services)

1、有时不需要或不想要负载均衡,以及单独的 Service IP,可以通过指定 Cluster IP(spec.clusterIP)的值为 "None" 来创建 Headless Service

(1)可以使用一个无头 Service 与其他服务发现机制进行接口,而不必与 Kubernetes 的实现捆绑在一起

(2)对于无头 Services 并不会分配 Cluster IP,kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由

(3)DNS 如何实现自动配置,依赖于 Service 是否定义了选择算符

2、带选择算符的服务

(1)对定义了选择算符的无头服务,Kubernetes 控制平面在 Kubernetes API 中创建 EndpointSlice 对象,并且修改 DNS 配置返回 A 或 AAA 条记录(IPv4 或 IPv6 地址),通过这个地址直接到达 Service 的后端 Pod 上

3、无选择算符的服务

(1)对没有定义选择算符的无头服务,控制平面不会创建 EndpointSlice 对象

(2)然而 DNS 系统会查找和配置以下之一

(3)对于 type: ExternalName 服务,查找和配置其 CNAME 记录

(4)对所有其他类型的服务,针对 Service 的就绪端点的所有 IP 地址,查找和配置 DNS A / AAAA 条记录

(5)对于 IPv4 端点,DNS 系统创建 A 条记录

(6)对于 IPv6 端点,DNS 系统创建 AAAA 条记录

 

发布服务(服务类型) 

1、对一些应用的某些部分(如前端),可能希望将其暴露给 Kubernetes 集群外部的 IP 地址

2、Kubernetes ServiceTypes 允许指定你所需要的 Service 类型

3、Type 的取值以及行为如下

(1)ClusterIP:通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。这也是你没有为服务显式指定 type 时使用的默认值。你可以使用 Ingress 或者 Gateway API 向公众暴露服务

(2)NodePort:通过每个节点上的 IP 和静态端口(NodePort)暴露服务。为了让节点端口可用,Kubernetes 设置了集群 IP 地址,这等同于你请求 type: ClusterIP 的服务

(3)LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上

(4)ExternalName:通过返回 CNAME 记录和对应值,可以将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。无需创建任何类型代理

4、说明:你需要使用 kube-dns 1.7 及以上版本或者 CoreDNS 0.0.8 及以上版本才能使用 ExternalName 类型

5、type 字段被设计为嵌套功能 - 每个级别都添加到前一个级别

(1)这并不是所有云提供商都严格要求的,例如:Google Compute Engine 不需要分配节点端口来使 type: LoadBalancer 工作,但另一个云提供商集成可能会这样做

(2)虽然不需要严格的嵌套,但是 Service 的 Kubernetes API 设计无论如何都需要它

6、也可以使用 Ingress 来暴露自己的服务

(1)Ingress 不是一种服务类型,但它充当集群的入口点

(2)它可以将路由规则整合到一个资源中,因为它可以在同一 IP 地址下公开多个服务

 

NodePort 类型

1、将 type 字段设置为 NodePort

(1)则 Kubernetes 控制平面将在 --service-node-port-range 标志指定的范围内分配端口(默认值:30000-32767)

(2)每个节点将那个端口(每个节点上的相同端口号)代理到你的服务中

(3)你的服务在其 .spec.ports[*].nodePort 字段中报告已分配的端口

2、使用 NodePort 可以让你自由设置自己的负载均衡解决方案, 配置 Kubernetes 不完全支持的环境, 甚至直接暴露一个或多个节点的 IP 地址

3、对于 NodePort 服务,Kubernetes 额外分配一个端口(TCP、UDP 或 SCTP 以匹配服务的协议)

(1)集群中的每个节点都将自己配置为监听分配的端口,并将流量转发到与该服务关联的某个就绪端点

(2)通过使用适当的协议(例如 TCP)和适当的端口(分配给该服务)连接到所有节点, 你将能够从集群外部使用 type: NodePort 服务

 

LoadBalancer 类型

1、在使用支持外部负载均衡器的云提供商的服务时,设置 type 的值为 "LoadBalancer",将为 Service 提供负载均衡器

(1)负载均衡器是异步创建的

(2)关于被提供的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段发布出去

(3)来自外部负载均衡器的流量将直接重定向到后端 Pod 上,不过实际它们是如何工作的,这要依赖于云提供商

2、某些云提供商允许设置 loadBalancerIP

(1)在这些情况下,将根据用户设置的 loadBalancerIP 来创建负载均衡器

(2)如果没有设置 loadBalancerIP 字段,将会给负载均衡器指派一个临时 IP

(3)如果设置了 loadBalancerIP,但云提供商并不支持这种特性,那么设置的 loadBalancerIP 值将会被忽略掉

3、实现 type: LoadBalancer 的服务

(1)Kubernetes 通常首先进行与请求 type: NodePort 服务等效的更改

(2)cloud-controller-manager 组件然后配置外部负载均衡器以将流量转发到已分配的节点端口

 

ExternalName 类型

1、类型为 ExternalName 的服务将服务映射到 DNS 名称,而不是典型的选择算符

(1)例如 my-service 或者 cassandra

(2)可以使用 spec.externalName 参数指定这些服务

2、ExternalName 服务接受 IPv4 地址字符串,但作为包含数字的 DNS 名称,而不是 IP 地址

(1)类似于 IPv4 地址的外部名称不能由 CoreDNS 或 ingress-nginx 解析,因为外部名称旨在指定规范的 DNS 名称

(2)要对 IP 地址进行硬编码,请考虑使用无头 Services

3、警告

(1)对于一些常见的协议,包括 HTTP 和 HTTPS,你使用 ExternalName 可能会遇到问题。如果你使用 ExternalName,那么集群内客户端使用的主机名与 ExternalName 引用的名称不同

(2)对于使用主机名的协议,此差异可能会导致错误或意外响应。HTTP 请求将具有源服务器无法识别的 Host: 标头;TLS 服务器将无法提供与客户端连接的主机名匹配的证书

 

Ingress

1、Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP

2、Ingress 可以提供负载均衡、SSL 终结、基于名称的虚拟托管

3、术语

(1)节点(Node): Kubernetes 集群中的一台工作机器,是集群的一部分

(2)集群(Cluster): 一组运行由 Kubernetes 管理的容器化应用程序的节点。在此示例和在大多数常见的 Kubernetes 部署环境中,集群中的节点都不在公共网络中

(3)边缘路由器(Edge Router): 在集群中强制执行防火墙策略的路由器。可以是由云提供商管理的网关,也可以是物理硬件

(4)集群网络(Cluster Network): 一组逻辑的或物理的连接,根据 Kubernetes 网络模型在集群内实现通信

(5)服务(Service):Kubernetes 服务(Service),使用标签选择器(selectors)辨认一组 Pod。 除非另有说明,否则假定服务只具有在集群网络中可路由的虚拟 IP

4、Ingress 是什么

(1)Ingress 公开从集群外部到集群内服务的 HTTP 和 HTTPS 路由

(2)流量路由由 Ingress 资源上定义的规则控制

(3)下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例

(4)Ingress 可为 Service 提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及基于名称的虚拟托管

(5)Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量

(6)Ingress 不会公开任意端口或协议。将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service

5、Ingress 相当于一个 7 层的负载均衡器

(1)是 Kubernetes 对反向代理的一个抽象,工作原理类似于 Nginx

(2)Ingress:Kubernetes 中的一个对象,作用是定义请求如何转发到 Service 的规则

(3)Ingress Controller:具体实现反向代理及负载均衡的程序,对 Ingress 定义的规则进行解析,根据配置的规则来实现请求转发

6、Ingress 控制器

(1)为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器

(2)与作为 kube-controller-manager 可执行文件的一部分运行的其他类型的控制器不同, Ingress 控制器不是随集群自动启动的

(3)Kubernetes 作为一个项目,目前支持和维护 AWS、GCE、Nginx Ingress 控制器

posted @   半条咸鱼  阅读(142)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示