文章目录
Kubernetes 服务发现与负载均衡
Kubernetes 提供内置的服务发现和负载均衡机制,用于连接应用的不同组件,并实现高效的请求分发。这些机制使得微服务之间的通信更加稳定和高效。
服务发现
服务发现是指自动检测应用服务的位置(IP 和端口)。在 Kubernetes 中,服务发现分为两种类型:DNS 服务发现 和 环境变量服务发现。
1. 环境变量服务发现
- 每当 Pod 创建时,Kubernetes 会将相关服务的信息(如 IP 地址和端口)以环境变量的形式注入到 Pod 的运行环境中。
- 局限性 :
- 动态性较差。如果服务地址发生变更,环境变量不会自动更新。
- 随着集群规模增大,环境变量会迅速膨胀,不适合复杂场景。
2. DNS 服务发现
- Kubernetes 内置的 CoreDNS 提供了基于 DNS 的服务发现方式。
- 服务创建时,Kubernetes 会在 CoreDNS 中为每个服务分配一个 DNS 域名(例如
myservice.mynamespace.svc.cluster.local
)。 - Pod 可以通过 DNS 名称直接访问目标服务,屏蔽了 IP 地址的动态变化。
- 优点 :
- 动态性强:即使服务的 IP 发生变更,DNS 记录也会同步更新。
- 易用性高:开发者可以使用人类友好的域名。
负载均衡
Kubernetes 提供了多种负载均衡方式,分布在不同层次:Pod 层、节点层、服务层。
1. Pod 层的负载均衡
- Pod 层负载均衡由 kube-proxy 实现,通过为服务创建虚拟 IP(ClusterIP),并使用 iptables 或 IPVS 规则将流量分发到后端 Pod。
- 工作原理 :
- kube-proxy 监视集群中服务和 Endpoint 的变化。
- 根据服务的 Endpoint 列表,设置 iptables 或 IPVS 规则。
- 请求流量通过服务的虚拟 IP 转发到实际的 Pod。
- 缺点:当后端 Pod 数量较多时,iptables 的性能会下降,推荐使用 IPVS。
2. 节点层的负载均衡
- 当外部流量访问集群时,Kubernetes 提供了以下几种类型的负载均衡:
- NodePort :
- 服务暴露在所有节点的某个特定端口(30000-32767)。
- 外部流量可以通过任意节点的该端口访问服务。
- 缺点:端口范围有限,不适合大规模服务。
- LoadBalancer :
- 在云环境下,Kubernetes 会自动调用云提供商的负载均衡服务(如 AWS ELB、GCP LB)。
- 自动分配一个外部 IP 地址,将流量分发到服务后端的节点。
- 缺点:依赖云平台,通常有额外成本。
- Ingress :
- 通过 Ingress Controller(如 NGINX、Traefik)提供基于 HTTP 和 HTTPS 的负载均衡。
- 提供更高级的功能,如路径路由、TLS 终结。
- NodePort :
3. 服务层的负载均衡
- Kubernetes 的服务抽象支持流量分发到多个后端 Pod。
- kube-proxy 使用轮询、随机等算法在多个 Pod 间进行流量分发。
- 服务类型 :
- ClusterIP (默认):
- 服务只能在集群内部访问。
- 适用于微服务内部通信。
- NodePort :
- 服务通过节点端口暴露到集群外部。
- LoadBalancer :
- 服务通过云提供商的负载均衡器暴露到外部。
- ExternalName :
- 将服务映射到外部 DNS 名称。
- ClusterIP (默认):
服务发现与负载均衡的工作流程
服务发现工作流程
- 用户定义一个服务资源(Service),选择器(Selector)匹配后端的 Pod。
- Kubernetes 创建该服务的 ClusterIP 和 DNS 记录。
- 其他 Pod 可以通过服务的 DNS 名称或 ClusterIP 访问该服务。
负载均衡工作流程
- 用户请求服务的虚拟 IP(ClusterIP)。
- kube-proxy 查找服务对应的 Endpoint 列表。
- kube-proxy 按负载均衡算法选择一个后端 Pod,将流量转发到该 Pod。
示例:ClusterIP 服务
yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: default
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80 # 服务的端口
targetPort: 8080 # Pod 的端口
- DNS 名称 :
my-service.default.svc.cluster.local
- ClusterIP:集群内的虚拟 IP,其他 Pod 通过此 IP 或 DNS 名称访问。
示例:NodePort 服务
yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
nodePort: 30080
- 外部访问方式:
<NodeIP>:30080
示例:Ingress 负载均衡
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
- 功能 :
- 根据
example.com
和路径/
将流量路由到my-service
。
- 根据
总结
功能 | 服务发现 | 负载均衡 |
---|---|---|
定义 | 自动检测服务位置和访问方式 | 将流量分发到多个后端 Pod |
实现机制 | 环境变量、DNS | kube-proxy、Ingress |
适用场景 | 微服务通信、动态发现 | 流量分发、访问优化 |
工具支持 | CoreDNS | iptables、IPVS、Ingress |
- 服务发现 提供灵活的微服务通信方式,确保 Pod 之间可以透明地相互访问。
- 负载均衡 通过 kube-proxy 和 Ingress 等机制,优化流量分发和外部访问,提升应用的高可用性和性能。