Kubernetes 编排(03):Service 与 Ingress——ClusterIP、NodePort、LoadBalancer、Ingress 控制器、DNS
更新时间:2026-09-01。本文是
cloud/kubernetes/K8s 编排第 03 篇,接 Pod 调度与资源。Service 是 K8s 服务发现的核心,Pod 会变化,Service 提供稳定的访问入口。Ingress 是外部访问集群内部服务的入口,基于域名和路径路由。
本文要回答的问题
- Service 三种类型(ClusterIP/NodePort/LoadBalancer)有什么区别?什么时候用?
- Ingress 是什么?和 Service 的 NodePort 有什么区别?
- kube-proxy 怎么实现服务发现和负载均衡?
- CoreDNS 在 K8s 中怎么工作?
一、Service——服务发现
yaml
# Service 定义
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
selector: # 选择哪些 Pod 作为后端
app: my-app
ports:
- protocol: TCP
port: 80 # Service 的端口
targetPort: 8080 # Pod 的端口
type: ClusterIP # 默认类型Service 三种类型:
| 类型 | 访问方式 | 场景 |
|---|---|---|
| ClusterIP | 集群内部 IP,只能从集群内访问 | 内部服务,如数据库 |
| NodePort | 每个节点 IP + 固定端口 | 外部访问,调试 |
| LoadBalancer | 云服务商负载均衡器 | 生产环境外部访问 |
ClusterIP(默认)
yaml
# 集群内访问,外部不可达
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
type: ClusterIP
# 集群内可以通过 my-app.namespace.svc.cluster.local 访问
# 或通过环境变量(不推荐)NodePort
yaml
# 每个节点开一个端口,外部可以通过 nodeIP:nodePort 访问
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
type: NodePort
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # 可选,默认 30000-32767
# 访问:http://node-ip:30080LoadBalancer
yaml
# 云服务商创建负载均衡器,自动分配公网 IP
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
# 云服务商会创建负载均衡器,分配公网 IP
# 负载均衡器 → 任意节点 nodePort → 后端 Pod二、kube-proxy 原理
text
kube-proxy 运行在每个节点,负责 Service 的网络转发
三种模式:
1. userspace(旧版):用户态代理,性能差
2. iptables(默认):内核态,通过 iptables 规则做 NAT
3. IPVS(推荐):内核态,通过 IPVS 做负载均衡,性能更好
iptables 模式:
每个 Service 创建一组 iptables 规则
请求 → PREROUTING → Service 规则 → DNAT → 随机 Pod IP
IPVS 模式:
每个 Service 创建一个虚拟 IP(VIP)
IPVS 在 netfilter 中注册 hook,直接做负载均衡
支持轮询、最少连接、源地址哈希等算法三、Ingress——外部路由
yaml
# Ingress:基于域名和路径的路由
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /web
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80Ingress 和 NodePort 的区别:
| 对比 | NodePort | Ingress |
|---|---|---|
| 端口 | 随机端口 30000-32767 | 标准 80/443 |
| 域名 | 无 | 基于域名路由 |
| 路径 | 无 | 基于路径路由 |
| TLS | 手动 | 自动终止 |
| 负载均衡 | 简单 | 丰富(限流、重写、认证) |
Ingress 控制器:
- Nginx Ingress Controller(最流行)
- Traefik(配置简单)
- Istio Ingress Gateway(服务网格)
- HAProxy Ingress
四、CoreDNS
text
CoreDNS 是 K8s 集群的 DNS 服务器
Pod 自动注册 DNS 记录:
my-app.default.svc.cluster.local → ClusterIP
Pod 的 DNS 搜索策略:
namespace 内:直接访问服务名 my-app
跨 namespace:my-app.other-ns
DNS 记录类型:
A 记录:ClusterIP
SRV 记录:端口 + 服务名
Pod 的 DNS 配置:
dnsPolicy: ClusterFirst # 默认,先查集群 DNS,再查外部 DNS
dnsPolicy: Default # 使用节点 DNS
dnsPolicy: None # 自定义 DNS 配置五、Headless Service
yaml
# Headless Service:不分配 ClusterIP,直接返回 Pod IP 列表
# 用于 StatefulSet 的有状态应用
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
clusterIP: None # 关键:clusterIP = None
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
# 访问:my-app-0.my-app.default.svc.cluster.local → Pod-0 的 IP
# 每个 Pod 有唯一 DNS 记录六、常见坑对照
| 坑 | 现象 | 对策 |
|---|---|---|
| Service 选不到 Pod | 请求超时,no endpoints | 检查 selector 标签是否匹配 |
| NodePort 端口冲突 | 端口被占用,不能绑定 | 用默认范围 30000-32767,自动分配 |
| Ingress 不生效 | 404 或 502 | 检查 Ingress 控制器是否部署 |
| kube-proxy 模式 | iptables 规则太多,性能差 | 大集群用 IPVS 模式 |
| CoreDNS 解析失败 | 服务名解析不了 | 检查 CoreDNS Pod 状态 |
相关与延伸
下一篇:存储与 PV/PVC——持久卷、动态供给、CSI、StatefulSet 有状态应用;K8s 核心概念,见 K8s 核心概念。
一句话总结
K8s Service 与 Ingress:Service 三种类型:ClusterIP 集群内访问,NodePort 节点端口暴露,LoadBalancer 云服务商负载均衡器;kube-proxy 通过 iptables/IPVS 规则做 DNAT 转发;Ingress 基于域名和路径路由到 Service,比 NodePort 更灵活,支持 TLS 终止和路径重写;CoreDNS 提供集群内 DNS 解析,Pod 可以通过服务名访问;Headless Service(clusterIP: None)返回 Pod IP 列表,StatefulSet 用 Headless Service 实现 Pod 唯一 DNS 名称。