K8s服务调用的方法和原理,一篇文章给你说明白
在Kubernetes (K8s) 环境中,服务之间的调用和通信是微服务架构中的关键组成部分。本文将详细介绍K8s中服务调用的方法和原理,帮助你深入理解服务间如何相互作用。
1. 名称解释
当在Kubernetes中进行服务调用时,特别是在使用Headless Service时,服务的完整DNS名称遵循以下格式:
<pod-name>.<headless-service-name>.<namespace>.svc.cluster.local
或者,当通过Service(非Headless)进行调用时,使用:
<service-name>.<namespace>.svc.cluster.local
-
<pod-name>
:Pod的名称,它是每个Pod的唯一标识符。在Headless Service与StatefulSet结合使用时,这个名称尤为重要,因为每个Pod会根据StatefulSet的命名规则有一个稳定、可预测的名称,例如web-0
、web-1
等。 -
<service-name>
:标准Service的名称,用于在Kubernetes内部网络中定位服务。这个名称由用户在创建Service时指定。 -
<headless-service-name>
:Headless Service的名称,与标准Service类似,但它不分配ClusterIP,直接暴露Pod的IP地址给调用者。 -
<namespace>
:命名空间是Kubernetes用来隔离不同应用组的一种方式。每个Service和Pod都属于一个特定的命名空间。如果不指定,默认为default
命名空间。 -
svc.cluster.local
:这是Kubernetes集群的默认域,用于服务发现。
2. 服务间调用的方法
标准Service调用
K8s中,服务(Service)提供了一种抽象,允许内部Pod之间通过Service名进行网络通信。例如,如果你有一个名为frontend
的Service,它可以通过frontend
或frontend.<namespace>.svc.cluster.local
的DNS名称让同一命名空间中的另一个服务访问。
Headless Service调用
Headless Service(无头服务)通过设置spec.clusterIP
为None
来创建。它主要用于那些需要直接访问Pod IP而不是通过单一入口(ClusterIP)的场景。
- 服务发现:客户端可以通过DNS查询获取所有后端Pod的IP地址列表。例如,
myapp-headless.default.svc.cluster.local
将返回所有myapp-headless
服务后端Pods的IP。 - Pod直接访问:在StatefulSet应用中,每个Pod都有一个稳定的网络标识符,如
<pod-name>.<headless-service-name>.<namespace>.svc.cluster.local
。
简写
- 在相同的命名空间内调用Service时,可以省略
.svc.cluster.local
部分,甚至可以省略命名空间(如果是default
命名空间)。例如,同一命名空间下的一个Pod访问<service-name>
只需使用Service名称即可。 - 在进行跨命名空间的调用时,不能省略命名空间,但
.svc.cluster.local
仍然可以省略。这样做虽然简化了名称,但完整的域名有助于防止DNS解析的潜在问题。 - 如果端口是80或是443,也可以省略端口
总结来说,如果是普通service,端口80,同命名空间,服务间最简单的调用方式:
<service-name>
3. Ingress的负载均衡原理
如果你写了一个<service-name>
K8s是怎么负载多个节点,来提供服务的呢?
K8s Ingress和Ingress Controller
K8s Ingress提供了从外部网络到集群内服务的HTTP/HTTPS路由。Ingress由Ingress资源和Ingress Controller两部分组成:
- Ingress资源定义了访问规则。
- Ingress Controller负责实现这些规则,它可以是Nginx、HAProxy等。
Ingress Controller监听Ingress资源的变化,并根据定义的规则将流量路由到相应的后端服务。这种机制允许实现基于路径、主机名的路由、SSL终端、重定向等高级HTTP路由功能。
4. Ingress Controller的实现方式
Ingress Controller在Kubernetes(K8s)中不是自带的功能,而是一个用于实现Ingress资源规则的控制器。虽然K8s提供了Ingress这一API资源,用于定义进入集群的外部访问路由规则,但是实际上使这些规则生效的是Ingress Controller。它负责监听Kubernetes API服务器上的Ingress资源变化,并根据Ingress中定义的规则来管理外部访问到集群内服务的流量。
工作原理
- 当你在Kubernetes集群中创建一个Ingress资源时,你实际上是在定义一组规则,指定如何将外部请求路由到集群内的不同服务。
- Ingress Controller负责读取这些规则,并使用它们配置其后端(如Nginx、HAProxy等),以便根据这些规则将流量正确地转发到相应的服务。
常见的Ingress Controller实现
Kubernetes社区提供了多种Ingress Controller实现,其中一些最流行的包括:
- Nginx Ingress Controller:使用Nginx作为反向代理和负载均衡器。是最广泛使用的Ingress Controller之一。
- Traefik:一个现代的HTTP反向代理和负载均衡器,可以完全自动化TLS证书的获取和更新过程。
- HAProxy Ingress:基于HAProxy的Ingress Controller,为高性能和可靠性提供支持。
- Istio Ingress Gateway:虽然Istio首先是一个服务网格,但它也提供了Ingress Gateway,允许以类似于Ingress Controller的方式来管理入口流量。
安装和使用
- Ingress Controller不是K8s默认安装的组件。要使用Ingress,您需要根据需求选择一个Ingress Controller并在您的集群中部署它。
- 每个Ingress Controller都有自己的安装和配置指南。安装过程通常涉及部署一个或多个Kubernetes Deployment和Service对象。
为什么需要Ingress Controller
- 集中式流量管理:Ingress提供了一个集中的方式来管理进入集群的流量,允许您通过单一的入口点暴露多个服务。
- 高级路由规则:Ingress允许您基于请求的HTTP路径、主机名等定义复杂的路由规则。
- 自动TLS管理:许多Ingress Controller支持自动管理TLS证书,为您的服务提供安全的HTTPS连接。