Kubernetes 网关与 Ingress 配置实践

Kubernetes 网关与 Ingress 配置实践 本文介绍 Kubernetes 集群中的 Ingress 网关配置,包括 Traefik、Higress 等主流 Ingress Controller 的部署和使用方法。 概述 Ingress 是 Kubernetes 中管理外部访问集群内服务

Kubernetes 网关与 Ingress 配置实践

本文介绍 Kubernetes 集群中的 Ingress 网关配置,包括 Traefik、Higress 等主流 Ingress Controller 的部署和使用方法。

概述

Ingress 是 Kubernetes 中管理外部访问集群内服务的 API 对象,它提供了 HTTP/HTTPS 路由、负载均衡、SSL 终止等功能。本文将详细介绍在 K3s 环境中部署和配置 Ingress Controller 的方法,以及实现灰度发布、重定向等高级功能。

Ingress 基础概念

什么是 Ingress

Ingress 是 Kubernetes 集群的入口网关,负责将集群外部的 HTTP/HTTPS 请求路由到集群内部的服务。主要功能包括:

  • 基于域名和路径的路由
  • SSL/TLS 证书管理
  • 负载均衡
  • 灰度发布和流量切分

Ingress Controller 类型

Controller 特点 适用场景
Traefik 云原生,自动服务发现 K3s 默认,功能丰富
Nginx 广泛使用,文档丰富 传统环境,复杂路由
Higress 阿里开源,高性能 企业级微服务
Istio Ingress 服务网格集成 Service Mesh 环境

Traefik Ingress 配置

基础 HTTP 路由

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

HTTPS 路由配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: https-ingress
  namespace: default
spec:
  ingressClassName: traefik
  tls:
    - hosts:
        - app.example.com
      secretName: app-tls-secret
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-service
                port:
                  number: 443

路径路由配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-based-ingress
spec:
  ingressClassName: traefik
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /v1
            pathType: Prefix
            backend:
              service:
                name: api-v1-service
                port:
                  number: 80
          - path: /v2
            pathType: Prefix
            backend:
              service:
                name: api-v2-service
                port:
                  number: 80
          - path: /static
            pathType: Prefix
            backend:
              service:
                name: static-service
                port:
                  number: 80

Higress 云原生网关

部署 Higress

# 标记网关节点
kubectl label nodes k8s-server-01 node-gateway-role=enable
kubectl label nodes k8s-server-02 node-gateway-role=enable

# 添加 Helm 仓库
helm repo add higress.io https://higress.io/helm-charts
helm repo update

# 安装 Higress
helm install higress higress.io/higress \
  -n higress-system \
  --create-namespace

Higress 生产配置

# higress-values.yaml
global:
  tolerations:
    - key: dedicated
      operator: Equal
      value: ingress-only
      effect: PreferNoSchedule

higress-core:
  gateway:
    nodeSelector:
      node-gateway-role: enable
    hostNetwork: true
    service:
      type: ClusterIP
    replicas: 4
    resources:
      requests:
        cpu: 5m
        memory: 64Mi
    tolerations:
      - key: dedicated
        operator: Equal
        value: ingress-only
        effect: PreferNoSchedule

Higress Ingress 示例

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kodbox-router
  namespace: infra
  annotations:
    higress.io/force-ssl-redirect: 'true'
    kubernetes.io/ingress.class: higress
spec:
  ingressClassName: higress
  tls:
    - hosts:
        - kodbox.example.com
      secretName: example-crt
  rules:
    - host: kodbox.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: kodbox-service
                port:
                  number: 80

高级路由配置

重定向配置

永久重定向(301)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: redirect-ingress
  annotations:
    higress.io/permanent-redirect: "https://new.example.com/app"
spec:
  ingressClassName: higress
  rules:
    - host: old.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: dummy-service
                port:
                  number: 80

临时重定向(302)

metadata:
  annotations:
    higress.io/temporal-redirect: "https://maintenance.example.com"

后端协议配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: backend-protocol
  annotations:
    higress.io/backend-protocol: "HTTPS"
    higress.io/timeout: "60"
spec:
  ingressClassName: higress
  rules:
    - host: secure.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: https-service
                port:
                  number: 443

支持的后端协议:

  • HTTP(默认)
  • HTTPS
  • GRPC / HTTP2

灰度发布与流量切分

基于权重的灰度发布

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-ingress
  annotations:
    higress.io/canary: "true"
    higress.io/canary-weight: "20"  # 20% 流量到 Canary 版本
spec:
  ingressClassName: higress
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: canary-service
                port:
                  number: 80

创建正式版本的 Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: production-ingress
spec:
  ingressClassName: higress
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: production-service
                port:
                  number: 80

基于 Header 的灰度发布

metadata:
  annotations:
    higress.io/canary: "true"
    higress.io/canary-by-header: "X-Canary"
    higress.io/canary-by-header-value: "true"

只有请求头 X-Canary: true 的流量才会路由到 Canary 版本。

metadata:
  annotations:
    higress.io/canary: "true"
    higress.io/canary-by-cookie: "canary_user"

Cookie 中包含 canary_user=always 的请求会被路由到 Canary 版本。

负载均衡配置

多服务负载均衡

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: loadbalance-route
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`lb.example.com`)
      kind: Rule
      services:
        - name: service-v1
          port: 80
          weight: 70
        - name: service-v2
          port: 80
          weight: 30

域名证书管理

使用 cert-manager 自动管理证书

# 安装 cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml

创建 ClusterIssuer

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: traefik

自动签发证书

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: auto-tls-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    kubernetes.io/ingress.class: "traefik"
spec:
  tls:
    - hosts:
        - auto.example.com
      secretName: auto-tls-secret
  rules:
    - host: auto.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-service
                port:
                  number: 80

TCP/UDP 路由

Traefik TCP 路由

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: mysql-route
spec:
  entryPoints:
    - mysql
  routes:
    - match: HostSNI(`*`)
      services:
        - name: mysql-service
          port: 3306

配置 TCP EntryPoint

在 Traefik values.yaml 中添加:

ports:
  mysql:
    port: 9200
    expose:
      default: true
    exposedPort: 9200
    protocol: TCP

故障排查

查看 Ingress 状态

# 查看 Ingress 列表
kubectl get ingress -A

# 查看 Ingress 详情
kubectl describe ingress <ingress-name>

# 查看 Traefik 日志
kubectl logs -n kube-system -l app.kubernetes.io/name=traefik

测试路由

# 使用 curl 测试
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- \
  curl -H "Host: app.example.com" http://<ingress-ip>/

# 从集群内部测试
kubectl exec -it <pod-name> -- curl http://service-name.namespace.svc.cluster.local

常见问题

  1. 404 错误

    • 检查 Service 名称和端口是否正确
    • 确认后端 Pod 是否正常运行
    • 验证 Ingress Class 配置
  2. 证书错误

    • 检查 Secret 是否存在
    • 验证证书是否过期
    • 确认域名匹配
  3. 路由不生效

    • 检查 Ingress Controller 是否运行
    • 确认 Ingress Class 注解
    • 查看 Controller 日志

总结

本文介绍了 Kubernetes 中 Ingress 网关的配置方法:

  1. 基础配置:HTTP/HTTPS 路由、路径匹配
  2. 高级功能:灰度发布、流量切分、重定向
  3. 安全加固:TLS 证书管理、后端协议配置
  4. 故障排查:常见问题诊断和解决方法

通过合理配置 Ingress,可以实现灵活的流量管理、安全的外部访问和应用发布策略。

Comment