深色模式
Ingress 入门:外部访问路由
摘要:NodePort 只能暴露端口,Ingress 才能按域名和路径做七层路由。本文安装 ingress-nginx 控制器,配置多域名与路径规则、TLS 证书,并给出 404/503 的排查思路。
适用环境
- 可用 K8s 集群(至少 1 个 worker)
- 已有一个 ClusterIP Service(如
web) - 能安装 Helm 或直接使用官方 manifest
操作步骤
一、安装 ingress-nginx 控制器
bash
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-namespace1
2
3
4
2
3
4
不使用 Helm 时可直接应用官方 manifest:
bash
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml1
确认控制器就绪:
bash
kubectl -n ingress-nginx get pods
kubectl -n ingress-nginx get svc # 记下 EXTERNAL-IP 或 NodePort1
2
2
建议
裸机(无云 LB)环境下 Service 会一直是 <pending>。此时把控制器 Service 改为 NodePort,或在边缘再挂一层自有负载均衡。
二、准备后端 Service
bash
kubectl create deployment web --image=nginx:alpine --replicas=2
kubectl expose deployment web --port=80 --type=ClusterIP1
2
2
三、编写 Ingress 规则
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api
port:
number: 80801
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
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
pathType 三种取值:Prefix(前缀匹配)、Exact(精确匹配)、ImplementationSpecific(由控制器决定)。
四、配置 TLS
bash
kubectl create secret tls web-tls \
--cert=server.crt --key=server.key1
2
2
yaml
spec:
tls:
- hosts:
- web.example.com
secretName: web-tls1
2
3
4
5
2
3
4
5
若想强制 HTTP 跳 HTTPS:
yaml
metadata:
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"1
2
3
2
3
五、本地测试
bash
# 拿到入口地址后手动指定 Host 头
INGRESS_IP=$(kubectl -n ingress-nginx get svc ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -H "Host: web.example.com" http://$INGRESS_IP/1
2
3
2
3
六、常用注解
yaml
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "50m" # 放开上传大小
nginx.ingress.kubernetes.io/proxy-read-timeout: "120" # 长连接超时
nginx.ingress.kubernetes.io/rewrite-target: /$2 # 路径重写1
2
3
4
5
2
3
4
5
七、排查 404 与 503
bash
kubectl get ingress # ADDRESS 是否已分配
kubectl describe ingress app-ingress # 看 Events 与 Rules
kubectl -n ingress-nginx logs deploy/ingress-nginx-controller --tail=50
kubectl get ep web # 503 多半是后端没就绪1
2
3
4
2
3
4
验证
- [ ]
kubectl get ingress显示已分配 ADDRESS - [ ]
curl -H "Host: web.example.com" http://<入口IP>/返回 nginx 页面 - [ ] 配置 TLS 后
curl -k https://...能建立连接 - [ ] 改 Ingress 后控制器日志出现 reload 记录
常见坑
- 404 且 Ingress 有地址:
host与请求 Host 不匹配,或path与pathType组合不对。 - 503 Service Temporarily Unavailable:后端 Service 的 Endpoints 为空,检查 Pod 是否 Ready。
- ADDRESS 一直为空:裸机环境无 LoadBalancer 实现,需改用 NodePort 或安装 MetalLB。
- 忘记写
ingressClassName:多控制器共存时 Ingress 不会被任何控制器接管,规则不生效。 - 上传大文件报 413:Nginx 默认 body 限制 1m,加
proxy-body-size注解。