14. Ingress 入口控制#
flowchart LR
Internet[Internet] --> LB[Load Balancer]
LB --> IC[Ingress Controller<br/>nginx / traefik]
IC -->|host: api.example.com| API[API Service]
IC -->|host: web.example.com| Web[Web Service]
IC -->|path: /static| Static[Static Service]
CM[cert-manager] -->|TLS cert| IC
Ingress 控制器(Controller)#
控制器 |
特点 |
|---|---|
nginx-ingress |
最流行,注解丰富,支持 Lua 插件 |
Traefik |
自动服务发现,内置 Let’s Encrypt,中间件机制 |
HAProxy |
高性能,支持 TCP/UDP |
AWS ALB |
与 AWS 原生集成 |
Istio Gateway |
与服务网格(Service Mesh)集成 |
安装 nginx-ingress#
# Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx \
-n ingress-nginx --create-namespace
# Minikube
minikube addons enable ingress
基本 Ingress 配置#
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api
port:
number: 8080
使用 cert-manager 配置 TLS#
# Install cert-manager
helm repo add jetstack https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager \
-n cert-manager --create-namespace \
--set crds.enabled=true
# ClusterIssuer for Let's Encrypt
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: nginx
---
# Ingress with TLS
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
多服务路由#
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-service
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
- web.example.com
- admin.example.com
secretName: wildcard-tls
rules:
# 基于域名的路由
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 3000
常用注解(Annotations)#
metadata:
annotations:
# 速率限制
nginx.ingress.kubernetes.io/limit-rps: "10"
nginx.ingress.kubernetes.io/limit-connections: "5"
# 超时设置
nginx.ingress.kubernetes.io/proxy-connect-timeout: "10"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
# 请求体大小限制
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
# 跨域资源共享(CORS)
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"
# 基本认证(Basic Auth)
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
# 重定向
nginx.ingress.kubernetes.io/permanent-redirect: "https://new.example.com"
# WebSocket 支持
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
# 自定义响应头
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "X-Frame-Options: DENY";
more_set_headers "X-Content-Type-Options: nosniff";
基于 Ingress 的金丝雀发布(Canary Deployment)#
# 稳定版本(接收 90% 流量)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-stable
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-stable
port:
number: 80
---
# 金丝雀版本(接收 10% 流量)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-canary
port:
number: 80