Kubernetes中提供七层HTTP与HTTPS路由入口的API对象
Ingress 是 Kubernetes 中把集群外部流量按域名和路径转发到集群内 Service 的七层入口规则。它把「路由规则」和「流量实现」拆开:Ingress 资源只是一份声明式的规则表,真正监听端口、解析 Host 头、终结 TLS 的是 Ingress Controller(如 ingress-nginx、Traefik、Envoy Gateway)。
Ingress Controller 本身也是集群里的一组 Pod,通常以 Deployment + LoadBalancer/NodePort Service 的方式部署。不装 Controller,创建再多 Ingress 也不会生效 —— 它们只是躺在 etcd 里,没有任何组件会去读取执行。
与 Service 的分工是:Service 工作在四层(TCP/UDP),只认 IP 和端口;Ingress 工作在七层,认域名、路径、Header。典型做法是最外层用一个 LoadBalancer Service 把流量引进集群交给 Ingress Controller,内部微服务只暴露 ClusterIP,由 Ingress 按域名分发,公网 IP 与证书因此可以集中管理。
# ingress-nginx(最常用)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.3/deploy/static/provider/cloud/deploy.yaml
# 裸机环境使用 NodePort 版本
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.3/deploy/static/provider/baremetal/deploy.yaml
# 确认 Controller 就绪
kubectl -n ingress-nginx get pods
kubectl -n ingress-nginx get svc ingress-nginx-controller
kubectl get ingress [名称] [选项]
kubectl describe ingress [名称]
kubectl create ingress [名称] --rule="host/path=service:port"
kubectl delete ingress [名称]
按域名转发到不同 Service:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
namespace: default
spec:
ingressClassName: nginx # 指定由哪个 Controller 接管
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-svc
port:
number: 8080
按路径分流到同一个域名的不同服务:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: path-ingress
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 8080
- path: /static
pathType: Prefix
backend:
service:
name: static-svc
port:
number: 80
配置 TLS,Secret 必须是 kubernetes.io/tls 类型:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- www.example.com
secretName: example-tls # 与 Ingress 必须在同一命名空间
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port:
number: 80
常用 nginx 注解,换 Controller 后这些注解会全部失效:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: annotated-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /old(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: new-svc
port:
number: 80
IngressClass 定义,多 Controller 共存时用它区分:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: k8s.io/ingress-nginx
kubectl create secret tls example-tls --cert=tls.crt --key=tls.key -n default
# 查看所有 Ingress,关注 ADDRESS 一栏
kubectl get ingress -A
kubectl get ingress -A -o wide
# 命令行快速创建一条规则
kubectl create ingress demo --class=nginx --rule="www.example.com/=frontend-svc:80"
# 查看规则与 Controller 分配到的地址
kubectl describe ingress web-ingress
# 查看 Controller 的访问日志
kubectl -n ingress-nginx logs -l app.kubernetes.io/component=controller --tail=100 -f
# 本地验证路由(绕过 DNS)
curl -H "Host: www.example.com" http://<ingress-ip>/
# 1. Ingress 的 ADDRESS 为空 —— Controller 没装或没就绪
kubectl get pods -A | grep -i ingress
kubectl get ingressclass
# 2. 返回 503 —— Service 名或端口写错,或后端 Pod 没有 Ready
kubectl get svc frontend-svc
kubectl get endpoints frontend-svc
# 3. 返回 404 —— Host 或 path 不匹配,看访问日志确认实际请求
kubectl -n ingress-nginx logs <controller-pod> --tail=50 | grep "GET /"
# 4. 证书没生效 —— Secret 类型或命名空间不对
kubectl get secret example-tls -o jsonpath='{.type}'
kubectl get ingress 会显示 ADDRESS 为空但不会报任何错。pathType 在 networking.k8s.io/v1 中是必填项,旧版 extensions/v1beta1 可以省略。取值 Prefix(按路径段前缀)、Exact(完全匹配)、ImplementationSpecific(由 Controller 自行解释,带正则的 rewrite 场景用它)。Prefix 的匹配是按路径段而非字符串前缀。/api 能匹配 /api/v1,但不会匹配 /apifoo,这与 nginx 原生的 location /api 行为不同。kubernetes.io/tls。用 kubectl create secret generic 建出来的 Opaque 类型不会被识别,证书静默失效。nginx.ingress.kubernetes.io/* 只对 ingress-nginx 有效,换 Traefik 或 APISIX 后这些注解会被静默忽略,重写、超时、上传大小限制统统失效。proxy-body-size 写成 proxy-bodysize,Ingress 依然创建成功,但大文件上传照样 413,排查时务必对照官方注解文档核对拼写。rewrite-target 与 use-regex 常常要配对使用,否则正则捕获组不生效,重写结果与预期不符;/$2 这类占位符只在 ImplementationSpecific 路径下才有意义。kubectl — Kubernetes集群管理工具service — Ingress的后端,提供四层负载均衡secret — 存储Ingress所需的TLS证书namespace — Ingress与后端Service的作用域边界kubeadm — Kubernetes集群安装与生命周期管理工具