ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

第六篇:《Service 与 Ingress:服务暴露与负载均衡》

第六篇:《Service 与 Ingress:服务暴露与负载均衡》

Pod 的 IP 是动态的,不能直接作为稳定访问入口。Kubernetes 通过 Service 抽象为一组 Pod 提供固定的访问端点(IP/DNS),并实现负载均衡。而 Ingress 则提供七层路由(基于域名、路径),将外部流量路由到集群内的 Service。本文将详细讲解 Service 的四种类型(ClusterIP、NodePort、LoadBalancer、ExternalName)以及 Ingress 的工作原理和典型配置。

一、为什么需要 Service?
Pod 可能被重建,IP 变化。

多副本 Pod 需要负载均衡。

需要对内部服务发现提供稳定的 DNS 名称。

需要将外部流量引入集群。

Service 通过标签选择器匹配 Pod,并自动维护 Endpoints 列表(Pod IP + 端口)。

二、Service 的四种类型
2.1 ClusterIP(默认)
分配一个虚拟 IP(仅集群内部可访问)。

用于集群内部通信,例如后端服务调用数据库。

YAML 示例:

apiVersion:v1kind:Servicemetadata:name:nginx-svcspec:type:ClusterIPselector:app:nginxports:-protocol:TCPport:80# Service 暴露的端口targetPort:80# Pod 上的端口

访问方式:nginx-svc.default.svc.cluster.local 或直接 nginx-svc(同命名空间下)。

2.2 NodePort
在 ClusterIP 基础上,在每个节点上打开一个端口(默认 30000-32767)。

外部可以通过 : 访问。

适合开发测试或不想用负载均衡器的场景。

YAML 示例:

apiVersion:v1kind:Servicemetadata:name:nginx-nodeportspec:type:NodePortselector:app:nginxports:-port:80targetPort:80nodePort:30080# 可选,不指定则自动分配

访问:curl http://任意节点IP:30080

2.3 LoadBalancer
在 NodePort 基础上,自动向云厂商申请一个外部负载均衡器(如 AWS ELB、GCE LB、Azure LB)。

本地测试可使用 MetalLB 模拟。

适用于公有云生产环境。

YAML 示例:

apiVersion:v1kind:Servicemetadata:name:nginx-lbspec:type:LoadBalancerselector:app:nginxports:-port:80targetPort:80

查看外部 IP:kubectl get svc nginx-lb 等待 EXTERNAL-IP 分配。

2.4 ExternalName
将 Service 映射到外部的 DNS 名称,不会创建任何代理或负载均衡。

用于集群内部访问外部服务(如数据库、第三方 API)。

YAML 示例:

apiVersion:v1kind:Servicemetadata:name:external-dbspec:type:ExternalNameexternalName:mydb.example.com

集群内 Pod 可通过 external-db.default.svc.cluster.local 访问 mydb.example.com。

三、Service 的工作原理
kube-proxy 在每个节点上运行,监控 Service 和 Endpoints 的变化。

维护 iptables 或 IPVS 规则,将 Service 的虚拟 IP 流量负载均衡到后端 Pod。

默认使用轮询算法(iptables 随机选择,IPVS 支持更多调度算法)。

四、Headless Service
当 clusterIP: None 时,Service 不分配虚拟 IP,Kube-DNS 直接返回 Pod IP 列表。适用于 StatefulSet 或需要直接访问每个 Pod 的场景。

apiVersion:v1kind:Servicemetadata:name:mysql-headlessspec:clusterIP:Noneselector:app:mysqlports:-port:3306

查询 DNS:nslookup mysql-headless 返回所有符合标签的 Pod IP。

五、Ingress:七层路由
Ingress 提供 HTTP/HTTPS 路由,根据域名和路径将外部流量转发到不同的 Service。需要部署 Ingress Controller(如 Nginx Ingress、Traefik、Contour)才能生效。

5.1 部署 Nginx Ingress Controller

kubectl apply-fhttps://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml

5.2 Ingress YAML 示例

apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:web-ingressannotations:nginx.ingress.kubernetes.io/rewrite-target:/spec:rules:-host:www.example.comhttp:paths:-path:/apipathType:Prefixbackend:service:name:api-serviceport:number:8080-path:/pathType:Prefixbackend:service:name:web-serviceport:number:80tls:-hosts:-www.example.comsecretName:example-tls

host:可选,不指定则匹配所有域名。

pathType:Prefix(前缀匹配)、Exact(精确匹配)、ImplementationSpecific(由 Controller 决定)。

tls:引用包含证书的 Secret。

5.3 创建 TLS Secret

kubectl create secret tls example-tls--cert=path/to/tls.crt--key=path/to/tls.key

5.4 查看 Ingress 地址

kubectl get ingress

输出会显示 ADDRESS(通常是 LB 的 IP)。

六、访问测试与调试
测试 ClusterIP:kubectl run test --image=busybox -it --rm – sh,然后 wget -O- http://nginx-svc。

测试 NodePort:确保集群节点防火墙开放了 NodePort 端口,用浏览器访问 http://:。

测试 Ingress:配置本地 hosts 或真实域名,访问 http://www.example.com。

七、常见问题与解决

八、最佳实践
内部通信使用 ClusterIP,避免不必要的节点端口暴露。

外部访问优先使用 Ingress(七层),而非直接 NodePort,以获得域名、TLS、路径路由能力。

为 LoadBalancer Service 设置 externalTrafficPolicy: Local,保留客户端真实 IP。

对于 TCP/UDP 服务(如数据库、消息队列),可使用 NodePort 或 LoadBalancer,因为 Ingress 主要支持 HTTP/HTTPS。

使用 NetworkPolicy 控制 Service 访问权限(后续文章介绍)。

九、小结
Service 解决了 Pod 动态 IP 和负载均衡问题,Ingress 提供了灵活的七层路由。理解这几种资源,你可以设计出安全、可伸缩的服务暴露方案。

返回列表