一.ingress的作用
ingress 是 Kubernetes 自带的"反向代理 + 路由器",它可以让你:
1.使用同一个 80/443 端口 访问多个服务;
2.支持 域名路由(如 app1.example.com、app2.example.com)
3.支持 路径路由(如 /api → 后端服务,/web → 前端服务)
4.支持 HTTPS / 证书管理
service与 Ingress 对比
| 功能点 | Service(NodePort/LoadBalancer) | ingress |
|---|---|---|
| 是否能对外暴露 | 可以 | 可以 |
| 是否支持域名路由 | 不行 | 可以 |
| 是否支持 HTTPS/TLS | 不行 | 可以 |
| 是否支持灰度发布 | 不行 | 可以(通过注解) |
| 是否能统一入口 | 不行 | 可以(多服务共用 80/443) |
| 是否支持 HTTPS/TLS | 成本 较高(每个 Service 一个端口或LB) | 较低(统一入口) |
二.ingress实验
我们来做一个类似的 路径分流实战,将 /api 路由到 后端服务(例如 Node.js 或 Java Spring 后端),将 /web 路由到 前端服务(例如 Nginx 或 React 前端)。
示例目标:
/api → 路由到后端 API 服务。
/web → 路由到前端 Web 服务。
部署 Nginx Ingress Controller
bash
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
这个 YAML 会:
1.创建命名空间 ingress-nginx
2.部署一个 ingress-nginx-controller Pod
3.暴露 Service(默认使用 NodePort 模式)
ingress相关命令:
bash
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx #查看ingress对外暴露的端口号
1.准备后端 API 服务和前端 Web 服务
使用一个 Node.js 后端服务,来模拟 API 服务
bash
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-backend
spec:
replicas: 1
selector:
matchLabels:
app: api-backend
template:
metadata:
labels:
app: api-backend
spec:
containers:
- name: api-backend
image: node:14
ports:
- containerPort: 3000
command: ["node", "-e", "require('http').createServer((req, res) => {res.end('<h1>API Backend</h1>')}).listen(3000)"]
---
apiVersion: v1
kind: Service
metadata:
name: api-backend-svc
spec:
selector:
app: api-backend
ports:
- port: 3000
用 Nginx 来模拟前端 Web 服务,它会返回一个简单的 HTML 页面
bash
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-frontend
spec:
replicas: 1
selector:
matchLabels:
app: web-frontend
template:
metadata:
labels:
app: web-frontend
spec:
containers:
- name: web-frontend
image: nginx
ports:
- containerPort: 80
args: ["/bin/sh", "-c", "echo '<h1>Web Frontend</h1>' > /usr/share/nginx/html/index.html && nginx -g 'daemon off;'"]
---
apiVersion: v1
kind: Service
metadata:
name: web-frontend-svc
spec:
selector:
app: web-frontend
ports:
- port: 80
启动两个deployment
bash
kubectl apply -f api-deployment.yaml
kubectl apply -f web-deployment.yaml
kubectl get pods
kubectl get svc
2.创建一个 Ingress 资源,将 /api 路由到 API 后端服务,将 /web 路由到 Web 前端服务。
bash
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-web-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: app.local
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-backend-svc
port:
number: 3000
- path: /web
pathType: Prefix
backend:
service:
name: web-frontend-svc
port:
number: 80
启动ingress服务
bash
kubectl apply -f ingress-path-routing.yaml
kubectl get ingress #验证ingress是否启动成功
kubectl get svc -n ingress-nginx #查看ingress对外暴露的端口号
3.访问主机配置hosts
bash
vim /etc/hosts
192.168.44.10 app.local
4.测试路径分流
1.访问后端 API 服务(/api):
在浏览器中访问 http://app.local:31440/api,或者使用 curl:
bash
curl http://app.local:31440/api
输出应该是:
bash
<h1>API Backend</h1>
2.访问前端 Web 服务(/web):
在浏览器中访问 http://app.local:31440/web,或者使用 curl:
bash
curl http://app.local:31440/web
输出应该是:
bash
<h1>Web Frontend</h1>
三、Ingress 灰度/权重分流
1.核心概念
Ingress:只是一个资源声明,本身不处理流量。
Ingress Controller(Nginx 等):真正负责生成 Nginx 配置并执行流量分发。
注解:给 Controller 的"指令",告诉它灰度流量、按请求头路由、TLS 配置等规则。
2. 默认版本 vs 灰度版本
类型 注解 流量逻辑
默认版本(稳定版本) 无 canary 注解 承接剩余流量(例如 90%)
灰度/Canary 版本 必须加 nginx.ingress.kubernetes.io/canary: "true" 承接指定比例流量或特定条件请求
3.关键注解及作用
bash
注解 是否必须 作用
nginx.ingress.kubernetes.io/canary: "true" #✅ 必须标记灰度/Canary Ingress,否则权重分流无效
nginx.ingress.kubernetes.io/canary-weight #⚠️ 依赖canary指定百分比流量走灰度版本
nginx.ingress.kubernetes.io/canary-by-header / -by-cookie #⚠️依赖canary按请求头或 Cookie路由流量(灰度条件)
nginx.ingress.kubernetes.io/rewrite-target #可选路径重写,用于路径分流
4.流量分配逻辑
用户请求到 Ingress Controller
Controller 判断:
是否匹配 灰度 Ingress (canary: "true")
是否符合 灰度条件(weight / header / cookie)
根据配置分流:
满足灰度条件 → 灰度版本
不满足 → 默认版本
四、TLS/HTTPS 配置(安全访问)
Ingress 可以绑定 TLS 证书,实现 HTTPS 加密访问。
可以为每个 host 或路径配置不同的证书
1.示例
① 创建 Secret 存证书
bash
kubectl create secret tls my-tls-secret \
--cert=server.crt \
--key=server.key
② 在 Ingress 中绑定它
bash
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-tls-ingress
spec:
tls:
- hosts:
- app.local
secretName: my-tls-secret
rules:
- host: app.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
这样访问 https://app.local 时,就会自动走 TLS 加密。