4.7 KiB
4.7 KiB
tags, create time
| tags | create time | |||||
|---|---|---|---|---|---|---|
|
2026-05-18 00:30 |
K8s 网络与服务发现 — Service 与 Ingress
概述
Kubernetes 的网络模型解决了容器 IP 频繁变动的问题。Service 提供稳定的服务发现入口,Ingress 提供L7 HTTP 路由能力。本文将梳理核心概念、典型模式和常见问题。
Service 类型
| 类型 | 特点 | 使用场景 |
|---|---|---|
| ClusterIP | 集群内 IP,外部不可访问 | 默认,内部服务间调用 |
| NodePort | 在每个 Node 上开端口 | 调试、临时访问 |
| LoadBalancer | 云厂商分配公网 IP | 对外暴露的服务 |
| ExternalName | CNAME 到外部域名 | 对接外部系统 |
ClusterIP Service — 服务发现的载体
apiVersion: v1
kind: Service
metadata:
name: order-service
spec:
selector:
app: order # 匹配带此 label 的 Pod
ports:
- port: 80 # Service 端口(对外暴露)
targetPort: 8080 # 容器实际监听端口
protocol: TCP
type: ClusterIP
调用方只需 http://order-service:80,K8s 通过 iptables/IPVS 自动实现负载均衡。
[!question] Service 是怎么做到负载均衡的?
每个 Node 上的 kube-proxy 会监控 Service 的变动,自动生成 iptables 规则或 IPVS 虚拟服务器配置。当请求发往 ClusterIP 时,内核将其 DNAT 到后端 Pod IP 之一,负载均衡算法默认是 round-robin。K8s 1.14+ 推荐使用 IPVS 模式(
kube-proxy --proxy-mode=ipvs),性能更高且支持更多算法。
Ingress — HTTP/HTTPS 路由
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: main-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: api.example.com
http:
paths:
- path: /orders
pathType: Prefix
backend:
service:
name: order-service
port:
number: 80
- path: /users
pathType: Prefix
backend:
service:
name: user-service
port:
number: 80
[!info] Ingress Controller 是什么?
Ingress 只是一个 API 对象,真正的 HTTP 路由由 Ingress Controller(如 NGINX、Traefik、Envoy)执行。安装后会在集群中运行一个 LoadBalancer 类型的 Pod 集群,监听 Ingress 资源变化并生成对应配置。
常见 Ingress Annotation(NGINX 为例)
| Annotation | 用途 | 示例值 |
|---|---|---|
rewrite-target |
URL 重写 | / |
ssl-redirect |
强制 HTTPS | "true" |
rate-limit |
限流 | 100 |
whitelist-source-range |
IP 白名单 | 10.0.0.0/8 |
client-max-body-size |
上传文件大小限制 | 50m |
Headless Service — 无头服务
Headless Service (ClusterIP: None) 不分配虚拟 IP,而是返回所有匹配 Pod 的真实 IP。这是 StatefulSet 的灵魂搭档:
apiVersion: v1
kind: Service
metadata:
name: mysql-headless
spec:
clusterIP: None # 关键:不分配 ClusterIP
selector:
app: mysql
ports:
- port: 3306
通过 DNS 可以直接访问单个 Pod:
mysql-cluster-0.mysql-headless.production.svc.cluster.local:3306mysql-cluster-1.mysql-headless.production.svc.cluster.local:3306
K8s 网络模型总结
flowchart LR
EXT["外部流量"] --> INGRESS["Ingress Controller"]
INGRESS --> SVC_A["order-service:80"]
INGRESS --> SVC_B["user-service:80"]
SVC_A --> Pod1["order-pod-1\n10.244.1.5:8080"]
SVC_A --> Pod2["order-pod-2\n10.244.2.3:8080"]
SVC_B --> Pod3["user-pod-1\n10.244.1.8:3000"]
Pod1 -->|DNS解析| COREDNS["CoreDNS<br/>svc.cluster.local"]
style EXT fill:#e3f2fd
style INGRESS fill:#fff3e0
style SVC_A fill:#e8f5e9
style SVC_B fill:#fce4ec
[!tip] 调试技巧:Service 不通怎么办?
kubectl get svc <name>确认 Service 存在且有 ClusterIPkubectl get endpoints <name>检查 Endpoint 列表是否为空- Endpoint 为空 → 检查 selector 标签是否匹配 Pod
- Endpoint 有值但 curl 不通 → 进入 Pod
curl <ClusterIP>:<port>验证- ClusterIP 通但外部不通 → 检查 Ingress / LoadBalancer 配置
关联笔记
- ../01-核心概念与Deployment — Deployment 通过 selector 与 Service 关联
- ../02-配置管理 — Service 的端点配置不直接涉及 ConfigMap/Secret
- ../04-扩缩容与有状态应用 — Headless Service + StatefulSet 配合
- ../hhs/MS/02-服务治理/04-服务发现 — K8s Service 是服务端发现模式的代表