Kubernetes Service 和 Ingress 详解
Service
什么是 Service
Service 是 Kubernetes 中用于定义一组 Pod 的访问策略的抽象资源。它为 Pod 提供了一个稳定的 IP 地址和 DNS 名称,无论 Pod 如何变化(如重启、扩缩容),Service 都能确保流量被正确路由。
Service 的类型
-
ClusterIP(默认类型):
-
为服务分配一个集群内部的 IP 地址
-
只能在集群内部访问
-
示例:
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 9376
-
-
NodePort:
-
在每个节点上开放一个静态端口(NodePort)
-
通过
<NodeIP>:<NodePort>
可以从集群外部访问 -
示例:
apiVersion: v1 kind: Service metadata: name: my-nodeport-service spec: type: NodePort selector: app: my-app ports: - port: 80 targetPort: 9376 nodePort: 30007
-
-
LoadBalancer:
-
使用云提供商的负载均衡器向外部暴露服务
-
自动创建 NodePort 和 ClusterIP
-
示例:
apiVersion: v1 kind: Service metadata: name: my-loadbalancer spec: type: LoadBalancer selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 9376
LoadBalancer 的完整层级关系
graph TD A[LoadBalancer Service] --> B[云厂商的SLB] A --> C[NodePort] A --> D[ClusterIP] C --> E[所有Node的特定端口] D --> F[集群内部虚拟IP]
具体对应关系:
- 云厂商 SLB ←→ NodePort ←→ ClusterIP ←→ Pod
- 外部请求通过 SLB 公网IP 进入
- SLB 将流量转发到集群任意 Node 的 NodePort
- NodePort 通过 kube-proxy 转发到 ClusterIP
- ClusterIP 最终负载均衡到 后端 Pod
-
-
ExternalName:
-
通过返回 CNAME 记录将服务映射到 externalName 字段的内容
-
用于访问集群外部的服务
-
示例:
apiVersion: v1 kind: Service metadata: name: my-external-service spec: type: ExternalName externalName: my.database.example.com
-
Service 的使用场景
- 为 Pod 提供稳定的访问端点
- 负载均衡流量到多个 Pod
- 服务发现
- 将内部服务暴露给外部访问
Ingress
什么是 Ingress
Ingress 是管理外部访问集群内服务的 API 对象,通常提供 HTTP/HTTPS 路由。它不同于 Service,Ingress 不是一种服务类型,而是一个 API 资源,充当集群的入口点。
Ingress 的核心功能
- 基于路径的路由:将不同路径的请求路由到不同的服务
- 基于主机名的路由:根据请求的主机名路由到不同的服务
- TLS/SSL 终止:在入口处处理 HTTPS 请求
- 负载均衡:在多个后端服务之间分配流量
Ingress 示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: hello-world.info
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 8080
- path: /v2
pathType: Prefix
backend:
service:
name: web-v2
port:
number: 8080
tls:
- hosts:
- hello-world.info
secretName: testsecret-tls
Ingress Controller
Ingress 需要 Ingress Controller 才能工作,常见的 Ingress Controller 包括:
- Nginx Ingress Controller
- Traefik
- HAProxy
- AWS ALB Ingress Controller
- GCE Ingress Controller
Ingress 与 Service 的关系
- Ingress 通常与 Service 配合使用
- Ingress 处理外部请求并将其路由到适当的 Service
- Service 负责将流量负载均衡到 Pod
使用场景对比
特性 | Service | Ingress |
---|---|---|
作用范围 | 集群内部或外部访问 | 主要处理外部访问 |
协议支持 | TCP/UDP/SCTP | 主要 HTTP/HTTPS |
路由功能 | 简单负载均衡 | 复杂路由规则(路径/主机名) |
TLS 终止 | 不支持 | 支持 |
实现方式 | kube-proxy 或云提供商 LB | 需要独立的 Ingress Controller |
最佳实践
- 内部服务:使用 ClusterIP 类型的 Service
- 简单外部访问:使用 NodePort 或 LoadBalancer
- 复杂路由需求:使用 Ingress
- 生产环境:通常结合使用 Ingress + LoadBalancer Service
- TLS 证书:通过 Ingress 统一管理
Ingress 与 LoadBalancer 功能对比
Ingress 和 LoadBalancer 都是 Kubernetes 中用于暴露服务的资源,但它们的功能定位和使用场景有显著区别:
核心区别
特性 | LoadBalancer | Ingress |
---|---|---|
OSI 层 | 主要工作在 L4 (TCP/UDP) | 主要工作在 L7 (HTTP/HTTPS) |
路由能力 | 简单端口转发 | 复杂路由规则(路径/主机名/Header) |
TLS 终止 | 不支持 | 原生支持 |
成本 | 每个服务需要独立 LB (昂贵) | 一个 Ingress 可代理多个服务(经济) |
实现依赖 | 依赖云厂商 LB 服务 | 需要安装 Ingress Controller |
适用协议 | 任何 TCP/UDP 协议 | 主要是 HTTP/HTTPS |
详细功能对比
1. LoadBalancer Service
-
功能特点:
- 直接暴露单个服务到公网
- 每个 LoadBalancer Service 都会创建一个云负载均衡器(和独立公网IP)
- 适合非HTTP服务或需要专用IP的场景
-
示例场景:
- 暴露数据库服务(MySQL/MongoDB)
- 游戏服务器等需要长连接的TCP服务
- 需要固定公网IP的特殊应用
-
YAML示例:
apiVersion: v1 kind: Service metadata: name: my-loadbalancer spec: type: LoadBalancer selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 9376
2. Ingress
-
功能特点:
- 作为集群的"智能入口网关"
- 基于主机名和路径的路由
- 集中管理TLS证书
- 一个Ingress可代理多个后端服务
- 支持高级功能(重定向、重写、限流等)
-
示例场景:
- 暴露多个Web服务(基于不同域名或路径)
- 需要统一管理HTTPS证书
- 实现灰度发布/AB测试
- 需要URL重写等高级路由功能
-
YAML示例:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1 spec: rules: - host: app.example.com http: paths: - path: /v1 pathType: Prefix backend: service: name: v1-service port: number: 80 - path: /v2 pathType: Prefix backend: service: name: v2-service port: number: 80 tls: - hosts: - app.example.com secretName: example-tls
架构关系
graph TD A[外部用户] -->|访问 https://app.example.com| B(Ingress Controller) B -->|路由规则| C[Ingress资源] C --> D1[Service1: ClusterIP] C --> D2[Service2: ClusterIP] D1 --> E1[Pod1] D1 --> E2[Pod2] D2 --> E3[Pod3] style B fill:#f9f,stroke:#333 style C fill:#bbf,stroke:#333
评论需开启科学上网!