K8s Service 与 Ingress¶
一句话概述:Service 是 K8s 中将一组 Pod 暴露为网络服务的抽象(内部负载均衡),Ingress 是 HTTP 层的反向代理入口(对外暴露),两者配合让外界能访问集群内的应用。
核心知识点¶
| 概念 | 白话解释 |
|---|---|
| ClusterIP | 集群内部 IP = 只能在集群内部访问(默认类型) |
| NodePort | 节点端口 = 在每个节点上开一个端口对外暴露 |
| LoadBalancer | 负载均衡器 = 云厂商提供的外部负载均衡(如 AWS ELB) |
| Ingress | 入口 = HTTP/HTTPS 层的路由规则(域名→服务) |
| Ingress Controller | 入口控制器 = 真正执行路由规则的组件(如 Nginx) |
| Endpoint | 端点 = Service 后面真正的 Pod IP 列表 |
基本使用¶
1. Service 类型¶
# === ClusterIP(集群内部访问) ===
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
type: ClusterIP # 默认类型
selector:
app: api # 选择带 app=api 标签的 Pod
ports:
- port: 80 # Service 端口
targetPort: 8080 # Pod 端口
protocol: TCP
# 集群内用 api-service:80 或 api-service.default.svc.cluster.local:80 访问
# === NodePort(节点端口暴露) ===
apiVersion: v1
kind: Service
metadata:
name: web-nodeport
spec:
type: NodePort
selector:
app: web
ports:
- port: 80 # Service 端口
targetPort: 8080 # Pod 端口
nodePort: 30080 # 节点端口(30000-32767)
# 用 <节点IP>:30080 从外部访问
# === LoadBalancer(云端负载均衡) ===
apiVersion: v1
kind: Service
metadata:
name: web-lb
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 8080
# 云厂商自动分配外部 IP
2. Ingress¶
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # URL 重写
spec:
ingressClassName: nginx # 使用 nginx Ingress Controller
rules:
- host: api.example.com # 域名
http:
paths:
- path: / # 路径
pathType: Prefix # 前缀匹配
backend:
service:
name: api-service # 转发到哪个 Service
port:
number: 80 # Service 端口
- host: web.example.com # 另一个域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
tls: # HTTPS 配置
- hosts:
- api.example.com
- web.example.com
secretName: tls-secret # TLS 证书 Secret
# 安装 Nginx Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.0/deploy/static/provider/cloud/deploy.yaml
kubectl apply -f ingress.yaml # 创建 Ingress
kubectl get ingress # 查看 Ingress
kubectl describe ingress my-ingress # 查看详情
3. 路径分发¶
spec:
rules:
- host: app.example.com
http:
paths:
- path: /api # /api 开头的请求
pathType: Prefix
backend:
service:
name: api-service # 转发到 API 服务
port: { number: 80 }
- path: / # 其他请求
pathType: Prefix
backend:
service:
name: web-service # 转发到 Web 服务
port: { number: 80 }
高级用法¶
ExternalName(外部服务代理)¶
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: db.example.com # 集群内用 external-db 访问外部数据库
Headless Service(直接返回 Pod IP)¶
常见报错¶
| 报错信息 | 原因 | 解决方法 |
|---|---|---|
no endpoints available | Service 没有匹配到任何 Pod | 检查 selector 标签是否匹配 |
connection refused | Pod 端口不对 | 检查 targetPort 是否与容器 EXPOSE 一致 |
503 Service Unavailable | 后端 Pod 不健康 | 检查 Pod 的就绪探针 |
404 Not Found on Ingress | 路径不匹配 | 检查 path 和 pathType |
| Ingress 无外部 IP | Ingress Controller 未安装 | 安装 nginx-ingress-controller |
速查表¶
# === Service ===
kubectl get svc # 列出 Service
kubectl describe svc <name> # 查看详情
kubectl get endpoints <name> # 查看端点(实际 Pod IP)
kubectl expose deploy <n> --port=80 --type=NodePort # 快速创建 Service
# === Ingress ===
kubectl get ingress # 列出 Ingress
kubectl describe ingress <name> # 查看详情
# === Service 类型选择 ===
# ClusterIP → 集群内部通信(默认)
# NodePort → 开发/测试对外暴露
# LoadBalancer → 生产环境对外暴露
# ExternalName → 代理外部服务
# Headless → StatefulSet/直接 Pod 发现
参考:K8s Service 文档 | Ingress 文档 | 更新于 2026 年