在 Kubernetes 集群内管理外部流量,优先使用 Ingress 资源配合 Ingress Controller;若是 standalone 环境或需要更细粒度控制,直接使用 Nginx 配置文件更合适。
先说结论:Ingress 是 K8s 的 API 对象,负责定义规则,Nginx 是实际处理流量的软件,两者通常结合使用。
- 适合:K8s 集群内部服务暴露,需要统一入口管理
- 重点看:是否已部署 Ingress Controller,否则 Ingress 资源无效
- 别忽略:后端 Service 的连通性及端口映射配置
核心机制差异
Ingress 本质上只是 Kubernetes 中的一个 API 对象,它定义了路由规则(比如哪个域名转发到哪个 Service),但它自己不处理流量。真正干活的是 Ingress Controller,常见的实现就是基于 Nginx 做的控制器。
简单来说,Ingress 是“规则说明书”,Nginx Ingress Controller 是“执行者”。当你创建 Ingress 资源时,Controller 会监听到变化,自动生成对应的 Nginx 配置并 reload,从而实现流量转发。这种设计让运维人员不需要登录到具体的 Nginx 服务器上去改配置文件,实现了配置与基础设施的解耦。
关键场景配置对比
以下对比传统 Nginx 配置文件与 K8s Ingress YAML 在常见生产场景中的写法差异。
1. HTTPS/TLS 证书配置
传统 Nginx:需在服务器上管理证书文件,并在配置中指定路径。
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
location / {
proxy_pass http://backend_ip:port;
}
}K8s Ingress:证书存储在 Secret 中,Ingress 引用 Secret 名称,无需关心文件路径。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
tls:
- hosts:
- example.com
secretName: tls-secret
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 802. 负载均衡算法
传统 Nginx:在 upstream 块中定义算法,如 least_conn。
upstream backend {
least_conn;
server 192.168.1.10:80;
server 192.168.1.11:80;
}
server {
location / {
proxy_pass http://backend;
}
}K8s Ingress:通过 Annotation 注解控制,无需修改 upstream 定义。
metadata:
annotations:
nginx.ingress.kubernetes.io/load-balance: "least_conn"
spec:
rules:
- host: example.com
http:
paths:
- backend:
service:
name: web-service
port:
number: 803. 灰度发布(Canary)
传统 Nginx:通常需配合 split_clients 模块或外部逻辑,配置较复杂。
K8s Ingress:利用 Controller 支持的 Canary 注解,可基于权重、Header 或 Cookie 进行流量切分。
metadata:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"
spec:
rules:
- host: example.com
http:
paths:
- backend:
service:
name: web-service-v2
port:
number: 80验证与排查
Nginx 传统方式:使用 curl 命令测试域名解析和响应,查看 Nginx 访问日志确认请求是否到达。
curl -H "Host: example.com" http://nginx_ip/
curl -kv https://example.comK8s Ingress 方式:检查 Ingress 资源状态,确认 ADDRESS 字段已获取 IP。
kubectl get ingress
kubectl describe ingress example-ingress查看 Controller 日志,确认配置生成无报错,然后通过集群入口 IP 或域名访问测试。若 HTTPS 失败,检查 Secret 是否存在于同一命名空间。
常见风险与坑
1. 只创建 Ingress 没装 Controller:Ingress 资源创建后状态一直 Pending 或无 IP,通常是因为集群里没有运行 Ingress Controller 组件。
2. Service 类型不对:Ingress 后端引用的 Service 必须是集群内可访问的(如 ClusterIP),不需要设为 NodePort 或 LoadBalancer,否则会造成端口浪费。
3. 配置同步延迟:Ingress Controller 同步配置需要一定时间,具体延迟取决于 Controller 实现及集群规模,排查问题时需预留缓冲时间。
4. 路径匹配规则:K8s Ingress 的 pathType(Prefix 或 Exact)会影响匹配逻辑,配置时需明确,避免路由冲突。
5. TLS Secret 命名空间:Ingress 引用的 TLS Secret 必须与 Ingress 资源在同一命名空间,否则 HTTPS 无法生效。
参考来源
- ingress-nginx 官方网站:https://kubernetes.github.io/ingress-nginx/
- 阿里云开发者社区:Kubernetes Ingress 介绍与 ingress-nginx 控制器部署
- 51CTO 博客:ingress 和 nginx 配置对比 ingress-nginx 官网_索姆拉的技术博客