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(默认)HTTPSGRPC/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 版本。
基于 Cookie 的灰度发布
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
常见问题
-
404 错误
- 检查 Service 名称和端口是否正确
- 确认后端 Pod 是否正常运行
- 验证 Ingress Class 配置
-
证书错误
- 检查 Secret 是否存在
- 验证证书是否过期
- 确认域名匹配
-
路由不生效
- 检查 Ingress Controller 是否运行
- 确认 Ingress Class 注解
- 查看 Controller 日志
总结
本文介绍了 Kubernetes 中 Ingress 网关的配置方法:
- 基础配置:HTTP/HTTPS 路由、路径匹配
- 高级功能:灰度发布、流量切分、重定向
- 安全加固:TLS 证书管理、后端协议配置
- 故障排查:常见问题诊断和解决方法
通过合理配置 Ingress,可以实现灵活的流量管理、安全的外部访问和应用发布策略。