Ingress是K8s的HTTP/HTTPS路由规则集合,提供基于域名和路径的外部流量路由。相比NodePort/LoadBalancer,Ingress实现了"一个入口点,多服务路由"。
┌───────────── Ingress流量路径 ──────────────┐
│ │
│ Internet用户 │
│ │ │
│ ┌───▼──────────────────┐ │
│ │ Cloud LB / MetalLB │ ← 外部流量入口 │
│ └───┬──────────────────┘ │
│ │ │
│ ┌───▼──────────────────┐ │
│ │ Ingress Controller │ ← Nginx/Traefik │
│ │ (Pod in Cluster) │ /Istio/Envoy │
│ └───┬──────────────────┘ │
│ │ 根据Ingress规则路由 │
│ │ │
│ ┌───▼──────────────────────────────────┐ │
│ │ Ingress Rules │ │
│ │ api.example.com → api-svc:8080 │ │
│ │ web.example.com → web-svc:80 │ │
│ │ app.example.com/api → api-svc:8080 │ │
│ │ app.example.com/* → web-svc:80 │ │
│ └──────────────────────────────────────┘ │
│ │ │ │
│ ┌───▼─────┐ ┌───────▼──────┐ │
│ │ api-svc │ │ web-svc │ │
│ │ :8080 │ │ :80 │ │
│ └─────────┘ └──────────────┘ │
└──────────────────────────────────────────────┘
# 方式1:Helm安装(推荐)
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--set controller.publishService.enabled=true
# 方式2:kubectl apply
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
# ✅ 验证通过
kubectl get pods -n ingress-nginx
# NAME READY STATUS RESTARTS AGE
# ingress-nginx-controller-6b8d8f9b4d-xxxxx 1/1 Running 0 30s
kubectl get svc -n ingress-nginx
# NAME TYPE EXTERNAL-IP
# ingress-nginx-controller LoadBalancer 1.2.3.4
# kind集群配置Ingress
cat <
# ingress-multi-host.yaml - 基于域名路由到不同服务
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-host-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: letsencrypt-prod # 自动证书
spec:
ingressClassName: nginx # K8s 1.18+使用ingressClassName
tls:
- hosts:
- api.example.com
- web.example.com
secretName: example-tls # TLS证书Secret
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix # Prefix|Exact|ImplementationSpecific
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
# ✅ 验证通过
kubectl apply -f ingress-multi-host.yaml
kubectl get ingress
# NAME CLASS HOSTS ADDRESS PORTS AGE
# multi-host-ingress nginx api.example.com,web.example.com 192.168.1.10 80,443 30s
# ingress-path-routing.yaml - 同一域名不同路径
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-routing
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: api-service
port:
number: 8080
- path: /static(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: static-service
port:
number: 80
- path: /()
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# 没有匹配规则时的默认后端
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: default-backend
spec:
ingressClassName: nginx
defaultBackend:
service:
name: default-http-backend
port:
number: 80
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
# Nginx Ingress常用注解
metadata:
annotations:
# SSL重定向
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
# 代理配置
nginx.ingress.kubernetes.io/proxy-body-size: "50m" # 上传大小限制
nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
# 负载均衡
nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr" # 会话亲和
nginx.ingress.kubernetes.io/load-balance: "ewma" # 负载算法
# 限流
nginx.ingress.kubernetes.io/limit-connections: "100"
nginx.ingress.kubernetes.io/limit-rps: "100" # 每秒请求数
nginx.ingress.kubernetes.io/limit-burst: "50"
# CORS
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"
# 认证
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
metadata:
annotations:
nginx.ingress.kubernetes.io/websocket-services: "ws-service"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
# canary-ingress.yaml - Nginx Ingress金丝雀发布
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
# 基于权重:20%流量到新版本
nginx.ingress.kubernetes.io/canary-weight: "20"
# 基于Header:特定用户走新版本
nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
nginx.ingress.kubernetes.io/canary-by-header-value: "true"
# 基于Cookie
nginx.ingress.kubernetes.io/canary-by-cookie: "canary"
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service-v2 # 新版本Service
port:
number: 80
# Gateway API是Ingress的进化版,更丰富的路由能力
# 安装Gateway API CRDs
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
# GatewayClass - 定义基础设施
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx-gateway
spec:
controllerName: nginx.org/gateway-controller
---
# Gateway - 定义监听器
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: main-gateway
spec:
gatewayClassName: nginx-gateway
listeners:
- name: http
port: 80
protocol: HTTP
hostname: "*.example.com"
- name: https
port: 443
protocol: HTTPS
hostname: "*.example.com"
tls:
mode: Terminate
certificateRefs:
- name: example-tls
---
# HTTPRoute - 定义路由规则
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-route
spec:
parentRefs:
- name: main-gateway
hostnames: ["api.example.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /v2
backendRefs:
- name: api-v2
port: 8080
weight: 20 # 20%流量到v2
- backendRefs:
- name: api-v1
port: 8080
weight: 80 # 80%流量到v1
# 检查Ingress Controller日志
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
# 检查后端Service是否有Endpoints
kubectl get endpoints api-service
# 如果没有Endpoints → 检查Service selector
# 检查Pod是否就绪
kubectl get pods -l app=api
# 如果Pod NotReady → 检查readinessProbe
# 检查Ingress状态
kubectl describe ingress multi-host-ingress
# Events:
# Normal Sync ... Scheduled for sync
# 检查ingressClassName
kubectl get ingress -o wide
# 如果CLASS为none → 检查ingressClassName
# 检查IngressClass
kubectl get ingressclass
# NAME CONTROLLER PARAMETERS AGE
# nginx k8s.io/ingress-nginx <none> 1h
# 检查证书Secret
kubectl get secret example-tls -o yaml
# 确认tls.crt和tls.key存在且有效
# 使用cert-manager自动管理
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/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: nginx
下一课预告:第11课深入RBAC权限——K8s安全体系的核心。