第278篇:K8s Ingress 与 Service Mesh 网络

关键词:Ingress、Ingress Controller、Service Mesh、Istio、Envoy、侧车代理、L7路由


一、引言

在Kubernetes集群中,Service提供了Pod间的基本负载均衡和服务发现能力,但对于外部流量的管理和微服务间的精细流量控制,需要更高级的网络抽象:Ingress和Service Mesh。

Ingress是Kubernetes原生的L7入口控制器,负责将外部流量路由到集群内的Service。Service Mesh则通过在应用中注入侧车代理(Sidecar),实现了微服务间的流量管理、安全通信和可观测性。

二、核心概念

2.1 Ingress 资源

Ingress是Kubernetes的原生API资源,定义了L7层的路由规则:

Ingress的核心能力:

能力 说明
基于Host的路由 根据HTTP Host头路由到不同Service
基于Path的路由 根据URL路径路由到不同Service
TLS终止 在Ingress层处理HTTPS解密
负载均衡 后端Service的多Pod负载均衡

Ingress 资源 - 图示

2.2 Ingress Controller

Ingress Controller是实现Ingress路由规则的控制器:

Controller 特点 适用场景
Nginx Ingress 成熟稳定, 功能丰富 通用场景
Traefik 自动发现, 云原生友好 动态环境
HAProxy Ingress 高性能, TCP/HTTP 高性能需求
AWS ALB Ingress AWS集成 AWS环境
Cilium Ingress eBPF加速 Cilium环境

2.3 Service Mesh 架构

Service Mesh通过侧车代理(Sidecar)实现微服务间通信的管理:

Service Mesh的核心组件:

组件 说明 示例
数据面(Data Plane) 侧车代理, 处理服务间流量 Envoy, Linkerd-proxy
控制面(Control Plane) 配置管理, 证书分发 Istio Pilot, Linkerd Control
侧车(Sidecar) 与业务容器同Pod部署 Envoy Sidecar
网关(Gateway) 入口/出口流量管理 Istio Gateway

2.4 Service Mesh vs Ingress

维度 Ingress Service Mesh
作用域 集群入口(南北向) 服务间(东西向)
L7路由 ✓ ✓
流量分割 有限 金丝雀/蓝绿/AB测试
安全(mTLS) TLS终止 全链路mTLS
可观测性 入口日志 全链路追踪
性能开销 低 中(Sidecar代理)
复杂度 低 高
部署方式 独立Pod Sidecar注入

三、技术细节

3.1 Ingress 路由规则

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - app.example.com
    secretName: tls-secret
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /users
        pathType: Prefix
        backend:
          service:
            name: user-service
            port:
              number: 80
      - path: /orders
        pathType: Prefix
        backend:
          service:
            name: order-service
            port:
              number: 80
  - host: web.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-frontend
            port:
              number: 80

3.2 Istio 流量管理

Istio VirtualService(流量路由):

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: my-app-vs
spec:
  hosts:
  - my-app
  http:
  - match:
    - headers:
        x-canary:
          exact: "true"
    route:
    - destination:
        host: my-app
        subset: canary
      weight: 100
  - route:
    - destination:
        host: my-app
        subset: v1
      weight: 90
    - destination:
        host: my-app
        subset: v2
      weight: 10

Istio DestinationRule(子集定义):

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: my-app-dr
spec:
  host: my-app
  trafficPolicy:
    connectionPool:
      http:
        h2UpgradePolicy: DEFAULT
        maxRequestsPerConnection: 100
    outlierDetection:
      consecutive5xxErrors: 5
      interval: 30s
      baseEjectionTime: 30s
  subsets:
  - name: v1
    labels:
      version: v1
  - name: canary
    labels:
      version: canary

3.3 Istio mTLS 安全通信

Istio mTLS 安全通信 - 图示

3.4 金丝雀发布与灰度发布

Service Mesh支持精细化的流量分割,实现金丝雀发布:

# 金丝雀发布配置
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: my-app-canary
spec:
  hosts:
  - my-app
  http:
  # 规则1: 内部测试用户走金丝雀版本
  - match:
    - headers:
        x-user-type:
          exact: "tester"
    route:
    - destination:
        host: my-app
        subset: canary
      weight: 100
  # 规则2: 5%的随机流量走金丝雀
  - route:
    - destination:
        host: my-app
        subset: stable
      weight: 95
    - destination:
        host: my-app
        subset: canary
      weight: 5
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: my-app-subsets
spec:
  host: my-app
  subsets:
  - name: stable
    labels:
      version: v1
  - name: canary
    labels:
      version: v2
发布策略 流量分配 适用场景
全量发布 100%→新版本 非关键变更
金丝雀发布 5%→金丝雀, 95%→稳定 新功能验证
灰度发布 按用户分群路由 面向特定用户群测试
A/B测试 按特征分流 功能对比实验
蓝绿发布 0%→100%原子切换 快速回滚需求

3.5 熔断与限流策略

熔断(Circuit Breaker):

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: my-app-circuit-breaker
spec:
  host: my-app
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100
        connectTimeout: 30ms
      http:
        h2UpgradePolicy: DEFAULT
        maxRequestsPerConnection: 10
        maxPendingRequests: 1000
        maxRetries: 3
    outlierDetection:
      consecutive5xxErrors: 5    # 连续5次5xx错误
      interval: 10s              # 检测间隔
      baseEjectionTime: 30s      # 基础熔断时间
      maxEjectionPercent: 50     # 最大熔断比例

限流(Rate Limiting):

限流维度 说明 Istio实现
全局限流 整个服务的请求速率 Envoy external rate limit
用户限流 每个用户的请求速率 Envoy local rate limit
路径限流 每个API路径的请求速率 VirtualService + RateLimit
集群限流 每个后端集群的请求速率 DestinationRule连接池

3.6 Service Mesh 性能开销分析

开销维度 无Sidecar 有Sidecar(Envoy) 开销比例
延迟增加 基线 +50-200μs 5-20%
内存占用 应用内存 +50-100MB/Sidecar 20-50%
CPU占用 应用CPU +5-15%/Sidecar 10-30%
启动时间 应用启动 +2-5秒(Sidecar启动) 显著
Pod规模 1容器 2容器(应用+Sidecar) 翻倍

降低Sidecar开销的方法:

方法 说明 效果
资源限制优化 调低Sidecar的CPU/内存请求 减少资源预留
延迟注入关闭 生产环境关闭故障注入 消除额外延迟
mTLS优化 使用会话复用(TLS Session Resumption) 降低握手开销
eBPF Service Mesh 使用Cilium等eBPF方案替代Sidecar 消除Sidecar开销
选择性注入 仅关键服务注入Sidecar 按需启用

四、实战配置/案例分析

4.1 Nginx Ingress Controller 部署

# Nginx Ingress Controller (Deploy模式)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-ingress
  template:
    metadata:
      labels:
        app: nginx-ingress
    spec:
      containers:
      - name: nginx-ingress
        image: registry.k8s.io/ingress-nginx/controller:v1.9.0
        args:
        - /nginx-ingress-controller
        - --publish-service=ingress-nginx/ingress-nginx
        - --election-id=ingress-nginx-leader
        ports:
        - containerPort: 80
        - containerPort: 443
        - containerPort: 10254
          name: metrics
---
# Service (LoadBalancer模式)
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  selector:
    app: nginx-ingress
  ports:
  - name: http
    port: 80
    targetPort: 80
  - name: https
    port: 443
    targetPort: 443

4.2 故障案例:Ingress TLS证书过期导致502

现象:某生产环境Ingress配置的HTTPS站点返回502 Bad Gateway错误,HTTP站点正常。

排查过程:

# 1. 检查Ingress状态
kubectl get ingress
# Ingress状态正常, 外部IP已分配

# 2. 检查TLS Secret
kubectl get secret tls-secret -o yaml
# 解码certificate字段
kubectl get secret tls-secret -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -dates -noout
# notBefore=Jan  1 00:00:00 2024 GMT
# notAfter=Jan  1 00:00:00 2025 GMT
# 证书已过期!

# 3. 检查Ingress Controller日志
kubectl logs -n ingress-nginx nginx-ingress-controller-xxx
# 错误: SSL certificate has expired

根因:Ingress引用的TLS证书已过期,Nginx Ingress Controller拒绝使用过期证书处理HTTPS请求,返回502错误。

解决: 1. 使用cert-manager自动化证书管理:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: app-tls
spec:
  secretName: tls-secret
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
  - app.example.com
  1. 立即更新证书解决当前问题
  2. 部署cert-manager实现证书自动续期

4.3 故障案例:Istio Sidecar注入失败

现象:命名空间已启用Istio自动注入,但新创建的Pod中Sidecar容器启动失败。

排查过程:

# 1. 检查Pod状态
kubectl get pods
# istio-proxy容器状态为CrashLoopBackOff

# 2. 检查Sidecar日志
kubectl logs my-app-pod -c istio-proxy
# 错误: Envoy configuration NACKed
# 具体: cluster "xds-grpc": xds_cluster: xds_cluster connects to non-ipv4/ipv6

# 3. 检查Istio配置
kubectl get configmap -n istio-system istio -o yaml
# meshConfig中proxyMetadata配置错误

# 4. 检查命名空间标签
kubectl get namespace my-namespace --show-labels
# istio-injection=enabled 标签存在

根因:Istio Control Plane的ConfigMap配置中,xds-grpc集群的地址格式不正确(使用了主机名而非IP),导致Envoy Sidecar无法连接到控制面获取配置。

解决: 1. 修正Istio ConfigMap中的meshConfig配置 2. 重启受影响的Pod使其重新注入正确的Sidecar配置 3. 在Istio升级或配置变更时,先在测试命名空间验证

五、总结

组件 层次 功能 性能开销
Service L4 Pod负载均衡 低
Ingress L7 入口路由,TLS终止 低
Service Mesh L7 流量管理,mTLS,可观测性 中(Sidecar)
Service Mesh方案 代理 控制面 特点
Istio Envoy Istiod 功能最全, 社区活跃
Linkerd linkerd-proxy(Rust) linkerd-control 轻量, 安全
Consul Connect Envoy Consul 与Consul集成
Cilium Service Mesh eBPF Cilium Operator 无Sidecar, 高性能
流量管理能力 Ingress Service Mesh
基于Host路由 ✓ ✓
基于Path路由 ✓ ✓
金丝雀发布 有限 ✓(精细化)
熔断/限流 有限 ✓
mTLS 入口TLS 全链路mTLS
全链路追踪 ✗ ✓

思考

  1. Service Mesh通过Sidecar代理拦截所有服务间流量,这种架构对业务应用的性能有什么影响?
  2. Ingress Controller和Service Mesh Gateway在功能上是否有重叠?什么场景下需要同时部署?
  3. Istio的mTLS是自动双向认证,业务应用需要做哪些改动才能支持mTLS?
  4. 金丝雀发布中如何确定金丝雀版本的流量比例应该从多少开始?如何逐步放量?
  5. Service Mesh的熔断机制如何工作?熔断后如何自动恢复?

下篇预告:第279篇:容器网络的多租户隔离方案