📘 Day 09:Ingress 与外部流量接入
🎯 今日目标
🧠 理论精讲(30 分钟)
Ingress 是什么
1 2 3 4 5 6 7 8 9
| ┌──────────────┐ │ Ingress │ ← L7 路由规则 │ Controller │ └──────┬───────┘ │ ┌─────────────────┼─────────────────┐ │ │ │ /api ──→ api-svc /web ──→ web-svc / ──→ frontend-svc (ClusterIP) (ClusterIP) (ClusterIP)
|
Ingress 提供 HTTP/HTTPS 路由、SSL 终止、基于名称的虚拟托管。
Ingress vs Service
| 特性 |
Service (NodePort/LB) |
Ingress |
| 工作层级 |
L4 (TCP/UDP) |
L7 (HTTP/HTTPS) |
| 路由能力 |
端口映射 |
路径/域名路由 |
| SSL |
需手动配置 |
内置 TLS 终止 |
| 外部入口 |
每 Service 一个 |
统一入口 |
Ingress Controller 选择
| Controller |
特点 |
| NGINX Ingress |
最常用,功能全面 |
| Traefik |
自动发现,适合微服务 |
| Istio Gateway |
服务网格场景 |
| Contour/Envoy |
高性能 |
🔧 动手实操(120 分钟)
练习 9.1:安装 NGINX Ingress Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 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.service.type=NodePort \ --set controller.service.nodePorts.http=30080 \ --set controller.service.nodePorts.https=30443
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.0/deploy/static/provider/cloud/deploy.yaml
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx
kubectl get svc -n ingress-nginx ingress-nginx-controller
curl http://<节点IP>:30080
|
练习 9.2:基于路径的路由
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| kubectl create deploy app-v1 --image=nginx:alpine kubectl expose deploy app-v1 --port=80
kubectl create deploy app-v2 --image=httpd:alpine kubectl expose deploy app-v2 --port=80
cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: path-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx rules: - http: paths: - path: /v1 pathType: Prefix backend: service: name: app-v1 port: number: 80 - path: /v2 pathType: Prefix backend: service: name: app-v2 port: number: 80 EOF
kubectl get ingress path-ingress
kubectl describe ingress path-ingress
curl http://<节点IP>:30080/v1
curl http://<节点IP>:30080/v2
kubectl delete ingress path-ingress kubectl delete deploy app-v1 app-v2 kubectl delete svc app-v1 app-v2
|
练习 9.3:基于域名的路由
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| kubectl create deploy web-a --image=nginx:alpine kubectl expose deploy web-a --port=80 kubectl create deploy web-b --image=httpd:alpine kubectl expose deploy web-b --port=80
cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: host-ingress spec: ingressClassName: nginx rules: - host: app-a.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-a port: number: 80 - host: app-b.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-b port: number: 80 EOF
curl -H "Host: app-a.example.com" http://<节点IP>:30080/
curl -H "Host: app-b.example.com" http://<节点IP>:30080/
kubectl delete ingress host-ingress kubectl delete deploy web-a web-b kubectl delete svc web-a web-b
|
练习 9.4:Ingress TLS 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout tls.key -out tls.crt \ -subj "/CN=tls-demo.example.com/O=tls-demo"
kubectl create secret tls demo-tls --key=tls.key --cert=tls.crt
kubectl create deploy secure-app --image=nginx:alpine kubectl expose deploy secure-app --port=80
cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tls-ingress spec: ingressClassName: nginx tls: - hosts: - tls-demo.example.com secretName: demo-tls rules: - host: tls-demo.example.com http: paths: - path: / pathType: Prefix backend: service: name: secure-app port: number: 80 EOF
kubectl get svc -n ingress-nginx ingress-nginx-controller
curl -k -H "Host: tls-demo.example.com" https://<节点IP>:30443/
echo | openssl s_client -connect <节点IP>:30443 -servername tls-demo.example.com 2>/dev/null | openssl x509 -noout -subject -dates
rm -f tls.key tls.crt kubectl delete ingress tls-ingress kubectl delete secret demo-tls kubectl delete deploy secure-app kubectl delete svc secure-app
|
🐛 排错练习(30 分钟)
场景 1:Ingress 返回 404
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
kubectl get pods -n ingress-nginx
kubectl get ingress
kubectl describe ingress <name>
kubectl get svc <svc-name> kubectl get endpoints <svc-name>
kubectl get ingress <name> -o yaml | grep ingressClassName
kubectl logs -n ingress-nginx deploy/ingress-nginx-controller --tail=50
|
场景 2:TLS 证书不生效
1 2 3 4 5 6 7 8 9 10 11
|
kubectl get secret <secret-name> kubectl describe secret <secret-name>
kubectl get secret <secret-name> -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout | head -20
kubectl get ingress <name> -o yaml | grep -A5 tls
|
🏆 赛题模拟(40 分钟)
⚠️ 严格限时 40 分钟
题目:统一网关配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| 【环境要求】 - NGINX Ingress Controller 已安装(NodePort 30080/30443)
【操作要求】
1. 创建 3 个后端应用: - api(nginx:alpine,2 副本,ClusterIP Service api-svc) - web(httpd:alpine,2 副本,ClusterIP Service web-svc) - admin(nginx:alpine,1 副本,ClusterIP Service admin-svc)
2. 创建 Ingress 规则: a. 路径路由: - /api → api-svc - / → web-svc b. 域名路由(新增第二个 Ingress 或合并): - admin.example.com → admin-svc
3. 配置注解: - nginx.ingress.kubernetes.io/rewrite-target: / - 为 api 路径配置 CORS 允许所有来源
4. 为 admin.example.com 配置自签名 TLS
5. 验证: - curl <NodeIP>:30080/api → 返回 nginx - curl <NodeIP>:30080/ → 返回 httpd - curl -H "Host: admin.example.com" <NodeIP>:30080/ → 返回 nginx - curl -k -H "Host: admin.example.com" https://<NodeIP>:30443/ → 返回 nginx
【评分标准】 - 后端服务创建(20 分) - 路径路由正确(25 分) - 域名路由正确(20 分) - TLS 配置正确(25 分) - 验证全部通过(10 分)
|
📋 命令速查
| 命令 |
功能 |
注解 |
kubectl get ingress |
列出 Ingress |
ADDRESS 为空说明 Ingress Controller 未就绪 |
kubectl get ingress -o wide |
Ingress + 主机/地址 |
查看 Host 规则和分配的 ADDRESS |
kubectl describe ingress <name> |
Ingress 详细规则 |
查看每条 Path 规则和后端 Service |
kubectl get ingressclass |
列出 IngressClass |
多个 Ingress Controller 时用于区分 |
kubectl -n ingress-nginx get pods |
查看 Ingress Controller Pod |
nginx-ingress 默认部署在 ingress-nginx 命名空间 |
kubectl -n ingress-nginx logs -l app.kubernetes.io/name=ingress-nginx |
查看 Ingress Controller 日志 |
Ingress 路由异常时的首要排查 |
kubectl -n ingress-nginx get svc |
查看 Ingress Controller Service |
确认是否分配了 EXTERNAL-IP |
curl -H "Host: <hostname>" http://<node-ip>:<nodeport> |
测试 Ingress 路由 |
绕过 DNS 直接用 Header 指定 Host |
curl -k https://<hostname> |
测试 HTTPS Ingress |
-k 跳过自签名证书验证 |
kubectl create ingress <name> --rule="host/path=svc:port" --dry-run=client -o yaml |
生成 Ingress YAML |
快速生成基本的 Ingress 规则模板 |
kubectl get svc -A | grep LoadBalancer |
查找所有 LB 类型 Service |
云环境中 LB 会分配公网 IP |
kubectl patch ingress <name> -p '{"metadata":{"annotations":{"nginx.ingress.kubernetes.io/rewrite-target":"/"}}}}' |
添加 Ingress 注解 |
nginx-ingress rewrite 注解实现 URL 重写 |
kubectl create secret tls <name> --cert=cert.pem --key=key.pem |
创建 TLS Secret |
Ingress HTTPS 必须用此类型 Secret |
📚 参考来源