Service 与 Ingress
Service 概述
Service 为一组 Pod 提供稳定的访问入口和负载均衡。Pod 是动态的(随时创建/销毁),Service 通过 Label Selector 自动发现后端 Pod。
Service 类型
| 类型 | 访问范围 | 适用场景 |
|---|---|---|
| ClusterIP | 集群内部 | 微服务间通信(默认) |
| NodePort | 集群外(Node IP + 端口) | 开发/测试 |
| LoadBalancer | 云厂商 LB | 生产环境对外暴露 |
| ExternalName | DNS CNAME | 访问集群外部服务 |
ClusterIP(默认)
service-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
spec:
type: ClusterIP # 默认,可省略
selector:
app: myapp # 匹配 Pod 标签
ports:
- name: http
port: 80 # Service 端口
targetPort: 8080 # Pod 端口
protocol: TCP
# 集群内通过 DNS 访问
curl http://myapp-svc.default.svc.cluster.local:80
# 或简写
curl http://myapp-svc:80 # 同 Namespace
curl http://myapp-svc.prod:80 # 跨 Namespace
NodePort
service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-nodeport
spec:
type: NodePort
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # 30000-32767 范围
# 通过任意 Node 的 IP + NodePort 访问
curl http://<NodeIP>:30080
LoadBalancer
service-lb.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-lb
annotations:
# 云厂商特定注解
service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
type: LoadBalancer
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
Headless Service
service-headless.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-headless
spec:
clusterIP: None # Headless:不分配 ClusterIP
selector:
app: mysql
ports:
- port: 3306
DNS 直接返回 Pod IP 列表,适合 StatefulSet:
mysql-0.mysql-headless.default.svc.cluster.localmysql-1.mysql-headless.default.svc.cluster.local
Ingress
Ingress 是 HTTP/HTTPS 入口,提供域名路由、路径匹配、TLS 终止。
Ingress 需要 Ingress Controller
Ingress 资源只是规则定义,需要安装 Ingress Controller(如 Nginx、Traefik)才能生效。
ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx # 指定 Ingress Controller
tls:
- hosts:
- app.example.com
secretName: app-tls-secret # TLS 证书 Secret
rules:
# 基于域名路由
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: backend-svc
port:
number: 80
# 另一个域名
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-svc
port:
number: 80
创建 TLS Secret
# 从证书文件创建
kubectl create secret tls app-tls-secret \
--cert=tls.crt \
--key=tls.key
# 使用 cert-manager 自动签发 Let's Encrypt
# 安装 cert-manager 后,通过 ClusterIssuer + Certificate 自动管理
常用 Ingress Controller 对比
| Controller | 特点 |
|---|---|
| Nginx Ingress | 最成熟,功能丰富,社区版/Plus 版 |
| Traefik | 自动服务发现,原生支持 Let's Encrypt |
| Kong | API 网关功能,插件生态 |
| Istio Gateway | 服务网格集成 |
K8s DNS
CoreDNS 是 K8s 默认的 DNS 服务器,提供服务发现。
DNS 解析规则
| 资源 | DNS 格式 | 示例 |
|---|---|---|
| Service | <svc>.<ns>.svc.cluster.local | myapp.default.svc.cluster.local |
| Pod | <pod-ip>.<ns>.pod.cluster.local | 10-244-0-3.default.pod.cluster.local |
| StatefulSet Pod | <pod-name>.<svc>.<ns>.svc.cluster.local | mysql-0.mysql-headless.default.svc.cluster.local |
简写规则:
- 同 Namespace:
myapp-svc - 跨 Namespace:
myapp-svc.prod
NetworkPolicy
控制 Pod 之间的网络流量。
network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
- Egress
ingress:
# 只允许来自 frontend 的流量
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- port: 8080
egress:
# 只允许访问数据库和 DNS
- to:
- podSelector:
matchLabels:
app: database
ports:
- port: 5432
- to: # DNS
- namespaceSelector: {}
ports:
- port: 53
protocol: UDP
常见面试问题
Q1: Service 的 ClusterIP、NodePort、LoadBalancer 区别?
答案:
- ClusterIP:只在集群内可访问,通过虚拟 IP 负载均衡。适合微服务间通信
- NodePort:在 ClusterIP 基础上,每个 Node 开放一个端口(30000-32767)。适合开发测试
- LoadBalancer:在 NodePort 基础上,请求云厂商创建外部负载均衡器。适合生产环境暴露服务
三者是递进关系:LoadBalancer ⊃ NodePort ⊃ ClusterIP
Q2: Service 底层是如何工作的?
答案:
- kube-proxy 监听 API Server 获取 Service 和 Endpoints 变化
- 根据 Service 配置更新iptables 规则或 IPVS 规则
- 客户端访问 ClusterIP,内核通过规则将流量 DNAT 到后端 Pod IP
- kube-proxy 有三种模式:
- iptables(默认):O(n) 规则匹配,中小规模
- IPVS:O(1) 哈希查找,大规模集群推荐
- userspace:已弃用
Q3: Ingress 和 Service 的区别?
答案:
| 维度 | Service | Ingress |
|---|---|---|
| 工作层级 | L4(TCP/UDP) | L7(HTTP/HTTPS) |
| 路由能力 | 按端口 | 按域名+路径 |
| TLS 终止 | ❌ | ✅ |
| 一个入口多个服务 | ❌ | ✅ |
| 依赖组件 | kube-proxy | Ingress Controller |
Ingress 适合 HTTP 流量,Service (LoadBalancer) 适合非 HTTP 的 TCP/UDP 流量。