Kubernetes Ingress Controller对比解析

描述

前言

Kubernetes集群对外提供服务时,Ingress是标准的服务暴露方式。Ingress资源定义了HTTP/HTTPS路由规则,而Ingress Controller则是这些规则的实现者。Ingress Controller负责监控Ingress资源的变化,将路由规则翻译为具体的反向代理配置,并动态更新。

主流的Ingress Controller包括Nginx Ingress Controller、Traefik和Envoy Proxy。它们各有特点和适用场景,选择合适的Ingress Controller对集群的稳定性、性能和可维护性都有重要影响。

本文面向初中级运维工程师,从架构原理、配置方式、功能特性、性能表现、选型建议等维度对这三款Ingress Controller进行深入对比。通过本文,读者能够理解每种Ingress Controller的工作机制,并根据自己的场景做出合理选择。

第一章 Ingress基础概念

1.1 Kubernetes网络模型

Kubernetes采用扁平化的网络模型,每个Pod都有独立的IP地址,Pod之间可以直接通信,不需要NAT。Service是Pod的抽象,通过标签选择器将一组Pod统一暴露,提供负载均衡和发现机制。

ClusterIP是Service的默认类型,仅在集群内部可访问。要从外部访问服务,通常需要以下几种方式:NodePort在每个节点上开放一个端口;LoadBalancer需要云服务商支持,创建外部负载均衡器;Ingress则基于HTTP/HTTPS主机名和路径提供七层路由。

1.2 Ingress资源定义

Ingress是Kubernetes的标准资源,用于配置HTTP/HTTPS外部访问路由。

 

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: demo.example.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 80
          - path: /web
            pathType: Prefix
            backend:
                service:
                name: web-service
                port:
                  number: 8080
  tls:
    - hosts:
        - demo.example.com
      secretName: demo-tls-secret

 

Ingress的配置通过注解(annotations)扩展,不同的Ingress Controller支持不同的注解。ingressClassName字段指定使用的Ingress Controller类,Kubernetes 1.18起支持此字段。

1.3 Ingress Controller职责

Ingress Controller的核心职责包括:监控Kubernetes API获取Ingress、Service、Endpoints等资源变化;将路由规则翻译为反向代理配置;热更新配置而不丢失请求;提供健康检查和指标暴露;处理TLS终止;实现负载均衡算法。

理解Ingress Controller的实现机制,有助于选择合适的方案和排查问题。每种Ingress Controller本质上都是一个运行在集群中的Deployment,它持续监听Kubernetes API并更新自己的配置。

第二章 Nginx Ingress Controller

2.1 架构与原理

Nginx Ingress Controller基于原生Nginx构建,部署模式分为两种:Deployment模式和DaemonSet模式。Deployment模式适合大规模集群,可以通过HPA实现自动扩缩容;DaemonSet模式在每个节点都运行一个实例,适合低延迟要求的场景。

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-ingress
  template:
    metadata:
      labels:
        app: nginx-ingress
    spec:
      containers:
        - name: controller
          image: registry.k8s.io/ingress-nginx/controller:v1.9.4
          args:
            - /nginx-ingress-controller
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
            - --election-id=ingress-controller-leader
            - --controller-class=k8s.io/ingress-nginx
            - --ingress-class=nginx
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443
          livenessProbe:
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 5
          resources:
            requests:
              cpu: 100m
              memory: 90Mi
            limits:
              cpu: 1
              memory: 1Gi

 

Nginx Ingress Controller的工作流程:用户创建或更新Ingress资源;Controller监听到变化并生成Nginx配置文件;Nginx reload加载新配置;请求通过Service NodePort或LoadBalancer进入Nginx。

2.2 配置方式

Nginx Ingress Controller支持两种配置方式:通过Ingress注解和通过ConfigMap全局配置。

Ingress注解示例:

 

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cafe-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/limit-rps: "100"
    nginx.ingress.kubernetes.io/limit-connections: "50"
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
    nginx.ingress.kubernetes.io/websocket-services: "ws-service"
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: nginx
  rules:
    - host: cafe.example.com
      http:
        paths:
          - path: /tea
            pathType: Exact
            backend:
              service:
                name: tea-svc
                port:
                  number: 80
          - path: /coffee
            pathType: Prefix
            backend:
              service:
                name: coffee-svc
                port:
                  number: 80

 

常用注解说明:

注解 说明 示例值
nginx.ingress.kubernetes.io/ssl-redirect 是否强制HTTPS true/false
nginx.ingress.kubernetes.io/limit-rps 限流每秒请求数 100
nginx.ingress.kubernetes.io/limit-connections 限流并发连接数 50
nginx.ingress.kubernetes.io/proxy-body-size 请求体大小限制 50m
nginx.ingress.kubernetes.io/proxy-read-timeout 后端读取超时 60
nginx.ingress.kubernetes.io/rewrite-target URL重写目标 /
nginx.ingress.kubernetes.io/use-regex 是否使用正则匹配 true/false
nginx.ingress.kubernetes.io/canary 开启金丝雀发布 true
nginx.ingress.kubernetes.io/canary-weight 金丝雀权重 50

2.3 全局配置ConfigMap

通过ConfigMap可以设置Nginx的全局默认配置:

 

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
data:
  proxy-body-size: "50m"
  proxy-connect-timeout: "30"
  proxy-read-timeout: "60"
  proxy-send-timeout: "60"
  use-forwarded-headers: "true"
  compute-full-forwarded-for: "true"
  use-proxy-protocol: "false"
  enable-underscores-in-headers: "true"
  large-client-header-buffers: "4 16k"
  client-header-buffer-size: "4k"
  keep-alive: "75"
  keep-alive-requests: "1000"
  upstream-keepalive-connections: "50"
  upstream-keepalive-timeout: "60"
  upstream-keepalive-requests: "10000"
  enable-brotli: "true"
  enable-gzip: "true"
  gzip-level: "6"
  gzip-types: "application/json application/javascript application/xml text/css text/html text/javascript"

 

2.4 TLS配置

Nginx Ingress Controller支持多种TLS配置方式。

简单TLS配置:

 

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - example.com
        - www.example.com
      secretName: example-tls
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend
                port:
                  number: 80

 

自签名证书创建:

 

# 创建私钥
openssl genrsa -out tls.key 2048

# 创建证书
openssl req -new -x509 -key tls.key -out tls.crt -days 365 
    -subj "/CN=example.com/O=MyOrg"

# 创建Secret
kubectl create secret tls example-tls 
    --cert=tls.crt 
    --key=tls.key

# 或使用kubectl直接创建
kubectl create secret tls example-tls 
    --cert=tls.crt 
    --key=tls.key 
    --dry-run=client -o yaml | kubectl apply -f -

 

2.5 金丝雀发布

Nginx Ingress Controller支持基于权重和Header的金丝雀发布:

 

# 主版本Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: main-ingress
spec:
  ingressClassName: nginx
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: main-service
                port:
                  number: 80
---
# 金丝雀Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-ingress
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "30"
spec:
  ingressClassName: nginx
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: canary-service
                port:
                  number: 80

 

基于Header的金丝雀:

 

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: header-canary-ingress
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
    nginx.ingress.kubernetes.io/canary-by-header-value: "always"
spec:
  ingressClassName: nginx
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: canary-service
                port:
                  number: 80

 

2.6 限流配置

Nginx Ingress Controller提供多维度限流功能:

 

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rate-limit-ingress
  annotations:
    nginx.ingress.kubernetes.io/limit-rps: "100"
    nginx.ingress.kubernetes.io/limit-rpm: "1000"
    nginx.ingress.kubernetes.io/limit-connections: "50"
    nginx.ingress.kubernetes.io/limit-burst-multiplier: "5"
spec:
  ingressClassName: nginx
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 80

 

全局限流通过ConfigMap配置:

 

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
data:
  limit_req_zone: "$binary_remote_addr zone=api:10m rate=10r/s"
  limit_conn_zone: "$binary_remote_addr zone=addr:10m"
  proxy-limit-rate: "0"

 

第三章 Traefik

3.1 架构与原理

Traefik是一个现代云原生的反向代理和负载均衡器,采用动态配置机制。与传统Nginx不同,Traefik的配置变更不需要重载进程,它通过监听Kubernetes API或Consul等配置中心实时更新路由规则。

Traefik的架构由多个组件构成:Provider负责从不同来源获取配置;Router负责将请求匹配到相应的服务;Middleware在请求到达服务前进行修改,如认证、限流、重试等;Service将请求转发到实际的后端。

Traefik Ingress Controller的部署:

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: traefik
  namespace: ingress
spec:
  replicas: 2
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-ingress-controller
      containers:
        - name: traefik
          image: traefik:v3.0.4
          args:
            - --api.insecure
            - --accesslog
            - --entrypoints.http.address=:80
            - --entrypoints.https.address=:443
            - --providers.kubernetesingress
            - --providers.kubernetescrd
            - --log.level=INFO
            - --metrics.prometheus
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443
            - name: admin
              containerPort: 8080
          livenessProbe:
            httpGet:
              path: /ping
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ping
              port: 8080
            periodSeconds: 5
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi

 

3.2 IngressRoute资源

Traefik提供了自己的CRD——IngressRoute,它比Kubernetes原生Ingress更强大,支持更多配置选项:

 

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: demo-ingressroute
  namespace: default
spec:
  entryPoints:
    - web
    - websecure
  routes:
    - match: Host(`demo.example.com`) && PathPrefix(`/api`)
      kind: Rule
      services:
        - name: api-service
          port: 80
      middlewares:
        - name: strip-api-prefix
        - name: rate-limit
    - match: Host(`demo.example.com`) && PathPrefix(`/`)
      kind: Rule
      services:
        - name: frontend-service
          port: 80
  tls:
    secretName: demo-tls-cert

 

3.3 Middleware中间件

Traefik的Middleware是强大的请求处理组件,可以在路由层面添加认证、重试、重定向、限流等功能。

基本认证中间件:

 

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: basic-auth
  namespace: default
spec:
  basicAuth:
    secret: basic-auth-secret
---
apiVersion: v1
kind: Secret
metadata:
  name: basic-auth-secret
  namespace: default
type: Opaque
stringData:
  users: |
    admin:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/

 

IP白名单中间件:

 

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: ip-whitelist
  namespace: default
spec:
  ipWhiteList:
    sourceRange:
      - "10.0.0.0/8"
      - "192.168.1.0/24"
    ipStrategy:
      depth: 0

 

限流中间件:

 

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: rate-limit
  namespace: default
spec:
  rateLimit:
    average: 100
    burst: 50
    period: 1s

 

重试中间件:

 

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: retry
  namespace: default
spec:
  retry:
    attempts: 3
    initialInterval: 100ms

 

重定向中间件:

 

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: https-redirect
  namespace: default
spec:
  redirectScheme:
    scheme: https
    permanent: true

 

StripPrefix中间件:

 

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: strip-prefix
  namespace: default
spec:
  stripPrefix:
    prefixes:
      - /api/v1
      - /static

 

3.4 动态服务发现

Traefik支持多种Provider,除了Kubernetes Ingress和CRD外,还支持Consul、Etcd、ZooKeeper等外部配置源。

Consul Provider配置示例:

 

# 在Consul中注册服务
curl -X PUT http://consul:8500/v1/agent/service/register 
    -d '{
      "ID": "web-1",
      "Name": "web",
      "Address": "10.0.1.100",
      "Port": 8080,
      "Check": {
        "HTTP": "http://10.0.1.100:8080/health",
        "Interval": "10s"
      }
    }'

 

Traefik Provider配置:

 

apiVersion: v1
kind: ConfigMap
metadata:
  name: traefik-config
  namespace: ingress
data:
  providers-consul-catalog: |
    address: consul:8500
    endpoint: http://consul:8500
    prefix: traefik
    requireConsistent: true
    refreshInterval: 10s
    exposedByDefault: false

 

3.5 TCP服务支持

Traefik不仅支持HTTP/HTTPS,还支持TCP和UDP服务:

 

apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: mysql-ingressroute
  namespace: default
spec:
  entryPoints:
    - mysql
  routes:
    - match: HostSNI(`mysql.example.com`)
      services:
        - name: mysql-service
          port: 3306
  tls:
    passthrough: true
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
  namespace: default
spec:
  type: ClusterIP
  ports:
    - name: mysql
      port: 3306
      targetPort: 3306

 

TCP EntryPoint配置:

 

apiVersion: v1
kind: ConfigMap
metadata:
  name: traefik-config
  namespace: ingress
data:
  servers-transport: |
    [serversTransport]
      insecureSkipVerify = true
  entrypoints: |
    [entryPoints]
      [entryPoints.mysql]
        address = ":3306"
      [entryPoints.redis]
        address = ":6379"

 

第四章 Envoy Proxy

4.1 架构与原理

Envoy是Lyft开发的开源边缘和服务代理,专为云原生架构设计。Envoy的架构基于xDS协议,通过监听配置源动态更新路由规则,无需重启进程。

Envoy的核心概念包括:Listener监听入口流量;Route配置路由规则;Cluster定义后端服务;Endpoint是具体的Pod地址;Filter是请求处理链;Health Check用于检测后端服务健康状态。

Envoy在Kubernetes中的部署通常通过Contour或Istio等项目实现。Contour是最常用的Envoy Ingress Controller实现。

4.2 Contour部署

Contour是Envoy的Kubernetes Ingress Controller实现,由Heptio(现VMware)开发。

 

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: contour
  namespace: projectcontour
spec:
  replicas: 2
  selector:
    matchLabels:
      app: contour
  template:
    metadata:
      labels:
        app: contour
    spec:
      containers:
        - name: contour
          image: ghcr.io/projectcontour/contour:v1.28.2
          command:
            - contour
            - serve
            - --xds-address=0.0.0.0
            - --xds-port=8001
            - --envoy-http-port=8080
            - --envoy-https-port=8443
            - --config-path=/config/contour.yaml
          ports:
            - name: xds
              containerPort: 8001
              protocol: TCP
            - name: http
              containerPort: 8080
              protocol: TCP
            - name: https
              containerPort: 8443
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8001
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8001
            periodSeconds: 5
      - name: envoy
        image: ghcr.io/projectcontour/contour:v1.28.2
        command:
          - envoy
          - -c /config/envoy.json
          - --service-cluster projectcontour
          - --service-node $(NODE_NAME)
        env:
          - name: NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
        ports:
          - name: http
            containerPort: 8080
            protocol: TCP
          - name: https
            containerPort: 8443
            protocol: TCP

 

Contour也支持Gateway API,这是Kubernetes网络的新标准:

 

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: prod-gateway
  namespace: ingress
spec:
  gatewayClassName: contour
  listeners:
    - name: http
      port: 80
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: Same
    - name: https
      port: 443
      protocol: HTTPS
      allowedRoutes:
        namespaces:
          from: Same
      tls:
        mode: Terminate
        certificateRefs:
          - name: demo-cert
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: demo-route
  namespace: default
spec:
  parentRefs:
    - name: prod-gateway
      namespace: ingress
  hostnames:
    - "demo.example.com"
  rules:
    - backendRefs:
        - name: demo-service
          port: 80

 

4.3 HTTPProxy资源

Contour扩展了Kubernetes Ingress,提供了更强大的HTTPProxy CRD:

 

apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: demo-proxy
  namespace: default
spec:
  virtualhost:
    fqdn: demo.example.com
    cors:
      allow-credentials: true
      allow-headers:
        - X-Custom-Header
      allow-methods:
        - GET
        - POST
        - PUT
        - DELETE
      allow-origin:
        - "https://allowed.example.com"
      max-age: "86400"
  routes:
    - conditions:
        - prefix: /api
      services:
        - name: api-service
          port: 80
          healthcheck:
            path: /health
            interval: 10s
            timeout: 5s
            unhealthythreshold: 3
            healthythreshold: 2
      loadBalancerPolicy:
        strategy: WeightedLeastRequest
      retryPolicy:
        retryOn: gateway-error,connect-failure,reset
        numRetries: 3
        perTryTimeout: 10s
    - conditions:
        - prefix: /
      services:
        - name: frontend-service
          port: 80
      rateLimit:
        global:
          descriptors:
            - entries:
                - key: remote_addr
                  rateLimitValue:
                    requests: 100
                    unit: minute
  tcpproxy:
    services:
      - name: tcp-service
        port: 9000
        weight: 1

 

4.4 限流配置

Envoy支持多种限流策略:全局限流基于令牌桶算法,所有服务共享限流配额;本地限流在每个Envoy实例独立执行;基于请求属性的限流可以组合多个维度。

全局限流示例:

 

apiVersion: projectcontour.io/v1
kind: TLSPolicy
metadata:
  name: ratelimit-policy
  namespace: default
spec:
  limits:
    - units: second
      requests: 100
      condition:
        - requestHeader:
            headerName: X-Forwarded-For
            count: 1

 

本地限流注解:

 

apiVersion: v1
kind: Service
metadata:
  name: api-service
  annotations:
    projectcontour.io/lb-num-retries: "3"
    projectcontour.io/retry-on: "gateway-error,connect-failure,reset"
    projectcontour.io/per-try-timeout: "10s"
spec:
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: api

 

4.5 健康检查与负载均衡

Envoy支持主动和被动两种健康检查方式。

主动健康检查配置:

 

apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: healthcheck-proxy
  namespace: default
spec:
  virtualhost:
    fqdn: api.example.com
  routes:
    - services:
        - name: api-service
          port: 80
          healthcheck:
            path: /healthz
            interval: 10s
            timeout: 5s
            expected-status: "200-299"
            unhealthythreshold: 3
            healthythreshold: 2

 

负载均衡策略:

 

apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: lb-proxy
  namespace: default
spec:
  virtualhost:
    fqdn: app.example.com
  routes:
    - loadBalancerPolicy:
        strategy: Random
      services:
        - name: app-service
          port: 80

 

支持的负载均衡策略:

策略 说明
RoundRobin 轮询,默认策略
WeightedLeastRequest 加权最少请求
Random 随机选择
Cookie 基于Cookie的会话保持
Header 基于请求头的会话保持

第五章 三者综合对比

5.1 性能对比

性能是Ingress Controller的重要考量因素,以下是基于公开测试数据的对比。

原生Nginx性能最优,它的请求处理延迟最低,吞吐量最高。这得益于Nginx多年的性能优化和事件驱动架构。

Traefik v3相比v2版本性能提升显著,但在高并发场景下仍略逊于Nginx。Traefik的动态配置能力带来了少量性能开销,但对于中低流量应用影响很小。

Envoy采用C++实现,性能表现优秀。Envoy的优势在于其可扩展性,支持在请求处理链中添加多个Filter而不显著影响性能。

实测数据参考(单实例,8核CPU,16GB内存):

方案 QPS P99延迟 内存占用
Nginx Ingress 50,000+ 5ms 150MB
Traefik v3 35,000+ 8ms 200MB
Envoy (Contour) 40,000+ 6ms 300MB

5.2 功能特性对比

功能 Nginx Ingress Traefik Envoy (Contour)
七层路由 支持 支持 支持
四层代理 支持 支持 支持
WebSocket 支持 支持 支持
gRPC 支持 支持 支持
TCP/UDP 支持 支持 支持
TLS终止 支持 支持 支持
自动HTTPS 支持(Cert-Manager) 支持(内置) 支持(Cert-Manager)
限流 注解/全局 Middleware 全局限流
认证 注解 Middleware CRD配置
重试/超时 注解 Middleware CRD配置
金丝雀发布 注解 无原生支持 HTTPProxy
熔断 支持
动态配置 reload 热更新 热更新
指标暴露 Prometheus Prometheus/Datadog Prometheus
追踪 Zipkin/Jaeger OpenTelemetry OpenTelemetry/Zipkin

5.3 配置复杂度对比

Nginx Ingress的配置相对直观,对于熟悉Nginx的运维工程师来说学习曲线平缓。大量在线资源和企业实践经验使得问题解决相对容易。

Traefik的配置最简洁,声明式的IngressRoute和Middleware设计使得配置易于理解。它的自动服务发现减少了手动配置工作。

Envoy的功能最强大,但配置也最复杂。Contour在一定程度上简化了Envoy的配置,但高级特性仍需要理解Envoy的架构。对于团队技术实力较强、需要细粒度控制的场景,Envoy是理想选择。

5.4 生态与社区对比

Nginx Ingress拥有最成熟的企业生态,大量生产环境案例和完善的文档。Nginx公司提供商业支持Nginx Ingress Controller Plus。

Traefik由Traefik Labs维护,社区活跃,文档质量高。Traefik企业版提供更多企业级特性。

Envoy是Envoyproxy基金会和CNCF项目的重要组成部分,也是Istio服务网格的数据平面。Envoy在服务网格领域占据主导地位,选择Envoy可以获得整个云原生生态系统的好处。

第六章 选型建议与最佳实践

6.1 场景化选型

中小规模集群(Pod数量小于1000)

推荐方案:Nginx Ingress Controller或Traefik

原因:配置简单,文档完善,生态成熟。Nginx的性能足够应对中低流量,业务场景不需要复杂的金丝雀发布和流量管理。

大规模高流量集群

推荐方案:Nginx Ingress Controller或Envoy

原因:需要关注性能和稳定性。Nginx在简单场景下性能最优,Envoy在需要细粒度流量管理时更有优势。

需要精细流量管理的场景

推荐方案:Envoy(Contour)

原因:Envoy的xDS协议和丰富的Filter链支持复杂的流量管理需求,如熔断、重试、限流、故障注入等。

服务网格集成

推荐方案:Envoy

原因:Istio、Linkerd等主流服务网格都使用Envoy作为数据平面。选择Envoy Ingress Controller可以与现有服务网格技术栈保持一致。

6.2 部署架构建议

生产环境建议使用DaemonSet模式部署Ingress Controller,确保每个节点都有入口:

 

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-ingress
  namespace: ingress-nginx
spec:
  selector:
    matchLabels:
      app: nginx-ingress
  template:
    metadata:
      labels:
        app: nginx-ingress
    spec:
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      containers:
        - name: controller
          image: registry.k8s.io/ingress-nginx/controller:v1.9.4
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --report-node-internal-ip-address
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              hostPort: 80
              containerPort: 80
            - name: https
              hostPort: 443
              containerPort: 443

 

高可用部署建议:

 

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-ingress
  namespace: ingress-nginx
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-ingress-controller
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80

 

6.3 安全配置

TLS配置最佳实践:

 

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: secure-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/hsts-max-age: "31536000"
    nginx.ingress.kubernetes.io/hsts-include-subdomains: "true"
    nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
    nginx.ingress.kubernetes.io/server-snippet: |
      add_header X-Frame-Options "SAMEORIGIN" always;
      add_header X-Content-Type-Options "nosniff" always;
      add_header X-XSS-Protection "1; mode=block" always;
      add_header Referrer-Policy "no-referrer-when-downgrade" always;
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - example.com
      secretName: example-tls
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend
                port:
                  number: 80

 

6.4 监控配置

Prometheus指标暴露是生产环境的必备能力:

 

apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-controller-metrics
  namespace: ingress-nginx
  annotations:
    prometheus.io/port: "10254"
    prometheus.io/scrape: "true"
spec:
  ports:
    - name: metrics
      port: 10254
      targetPort: metrics
  selector:
    app: nginx-ingress
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: nginx-ingress
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: nginx-ingress
  endpoints:
    - port: metrics
      interval: 15s
  namespaceSelector:
    matchNames:
      - ingress-nginx

 

Grafana仪表板推荐使用公开社区仪表板:

Nginx Ingress Controller: ID 9614

Traefik: ID 10162

Envoy: ID 13261

第七章 排障指南

7.1 查看Ingress Controller状态

 

# 查看Controller日志
kubectl logs -n ingress-nginx -l app=nginx-ingress -f

# 查看最近事件
kubectl get events -n ingress-nginx --sort-by='.lastTimestamp'

# 查看Controller配置
kubectl exec -n ingress-nginx deploy/nginx-ingress-controller -- 
    nginx-ingress-controller --show-config

 

7.2 常见问题与解决

问题1:Ingress无法访问,返回404

排查步骤:

 

# 1. 检查Ingress资源是否存在
kubectl get ingress -n default

# 2. 检查Ingress地址配置
kubectl describe ingress demo-ingress -n default

# 3. 检查Endpoints是否就绪
kubectl get endpoints -n default

# 4. 检查Service配置
kubectl get svc -n default

# 5. 检查Pod是否运行正常
kubectl get pods -n default -l app=demo

# 6. 检查DNS解析
kubectl exec -it test-pod -- nslookup demo-service

 

问题2:证书错误或TLS不工作

 

# 检查Secret是否存在
kubectl get secret demo-tls -n default

# 验证证书内容
kubectl get secret demo-tls -n default -o jsonpath='{.data.tls.crt}' | base64 -d | openssl x509 -text -noout

# 检查证书过期时间
kubectl get secret demo-tls -n default -o jsonpath='{.data.tls.crt}' | base64 -d | openssl x509 -enddate -noout

# 检查Cert-Manager状态(如使用)
kubectl get certificate -n default
kubectl describe certificate demo-cert -n default

 

问题3:限流未生效

 

# 检查限流注解是否正确配置
kubectl describe ingress rate-limit-ingress -n default

# 查看Controller日志中的限流信息
kubectl logs -n ingress-nginx -l app=nginx-ingress | grep -i limit

# 验证ConfigMap中的限流配置
kubectl get configmap nginx-configuration -n ingress-nginx -o yaml

 

7.3 性能问题排查

 

# 查看资源使用情况
kubectl top pods -n ingress-nginx

# 检查连接数
kubectl exec -it nginx-ingress-controller-xxx -n ingress-nginx -- 
    wget -qO- http://localhost:10254/status

# 查看upstream状态(Nginx Ingress)
kubectl exec -it nginx-ingress-controller-xxx -n ingress-nginx -- 
    cat /etc/nginx/nginx.conf | grep -A 50 "upstream"

 

7.4 日志分析

Nginx Ingress访问日志格式配置:

 

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
data:
  log-format-upstream: |
    '$remote_addr $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for" '
    '$request_time $upstream_response_time $upstream_connect_time '
    'route=$upstream_route'

 

分析日志发现慢请求:

 

# 提取慢请求日志
kubectl logs -n ingress-nginx -l app=nginx-ingress | 
    awk '{if($NF > 1) print}' | sort -k9 -nr | head -20

 

结语

Nginx Ingress Controller、Traefik和Envoy是当前最主流的三种Ingress Controller方案。它们各有优势:Nginx性能最优、生态最成熟;Traefik配置最简洁、动态能力最强;Envoy功能最丰富、与服务网格集成最紧密。

选型时应综合考虑团队技术栈、性能需求、功能需求和运维能力。对于大多数场景,Nginx Ingress Controller是稳妥的选择;对于追求配置简洁和动态能力的团队,Traefik值得考虑;对于需要精细流量控制和计划使用服务网格的场景,Envoy是理想选择。

无论选择哪种方案,都应该建立完善的监控告警体系,制定 Ingress Controller的运维流程,并定期进行故障演练,确保在生产环境中能够快速响应和恢复。

参考资料

Kubernetes Ingress官方文档:https://kubernetes.io/docs/concepts/services-networking/ingress/

Nginx Ingress Controller官方文档:https://kubernetes.github.io/ingress-nginx/

Traefik官方文档:https://doc.traefik.io/traefik/

Contour官方文档:https://projectcontour.io/docs/

Envoy官方文档:https://www.envoyproxy.io/docs/envoy/latest/

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分