目录
一、核心概念与原理
1. Ingress 基础概念
(1)Ingress 的定位
(2)Ingress 与其他暴露方式对比
(3)Ingress 组成与分工
2. Ingress 工作原理(以 Nginx 为例)
3. 典型流量访问链路
二、Ingress Nginx Controller 安装(Helm 方式)
1. 环境准备与工具安装
2. 核心配置文件修改(values.yaml)
3. 部署与验证命令
三、Ingress 基础使用:域名绑定服务
1. 测试服务准备
2. Ingress 配置详解(web-ingress.yaml)
3. 访问测试步骤
四、进阶功能实现与场景解析
1. 域名重定向(旧域名过渡)
场景:将旧域名 nginx.redirect.com 永久重定向到百度
2. 前后端分离路径重写(Rewrite)
场景:将 /api-a/xxx 重写为 /xxx,适配后端服务
3. SSL 配置(HTTPS 加密访问)
步骤 1:生成自签名证书(测试环境)
步骤 2:创建 Secret 存储证书
步骤 3:Ingress 配置(ingress-ssl.yaml)
4. 基本认证(密码保护)
步骤 1:安装工具并创建密码文件
步骤 2:创建 Secret 存储密码文件
步骤 3:Ingress 配置(ingress-with-auth.yaml)
5. 灰度发布(金丝雀发布)
场景:逐步将流量从 V1 版本切换到 V2 版本,降低发布风险
步骤 1:部署生产环境 V1 版本
步骤 2:创建 V1 版本 Ingress(v1-ingress.yaml)
步骤 3:部署灰度环境 V2 版本
步骤 4:创建灰度 Ingress(canary-v2.yaml)
步骤 5:流量测试与权重调整
五、核心要点总结
方式 | 核心原理 | 典型场景 | 局限性 |
---|---|---|---|
NodePort | 节点端口映射(30000-32767) | 测试环境快速暴露服务 | 端口数量有限,运维复杂度高 |
LoadBalancer | 云服务商负载均衡器集成 | 公有云生产环境 | 依赖云平台,需额外付费 |
externalIPs | 节点外部 IP 直接绑定 | 简单网络场景 | 无负载均衡能力,安全性低 |
Ingress | 七层反向代理(域名 / 路径规则) | 复杂微服务架构 | 需要部署 Ingress Controller |
nginx.test.com
)、路径(如 /api
)、目标 Service 映射等配置,类似 Nginx 的虚拟主机配置模板。host: nginx.test.com
映射为 Nginx 的 server_name
,将路径规则转换为 location
块。/etc/nginx/nginx.conf
,并通过 nginx -s reload
命令重新加载配置,确保新规则秒级生效。用户浏览器输入域名(如 nginx.test.com)
↓
域名解析至 Ingress 节点公网 IP 或负载均衡器
↓
Ingress Controller 解析规则(如匹配 host: nginx.test.com)
↓
根据规则转发至对应 Service(如 nginx-service)
↓
Service 将请求分发至后端 Pod 集群
# 下载 Helm 3.9.4(Linux AMD64 版本)
wget https://get.helm.sh/helm-v3.9.4-linux-amd64.tar.gz
tar zxvf helm-v3.9.4-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/ # 将 helm 命令添加到系统路径
# 添加 Ingress Nginx 官方 Helm 仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update # 同步仓库最新图表,确保获取最新版本
关键点:Helm 是 Kubernetes 的包管理器,通过图表(Chart)简化复杂组件的部署,避免手动编写大量 YAML。
controller:
image:
registry: registry.cn-hangzhou.aliyuncs.com # 切换至阿里云镜像源,解决国外镜像拉取慢问题
image: tanzu/controller
tag: "v1.6.4"
# 注释 digest 字段(镜像摘要),避免因网络波动导致镜像校验失败
hostNetwork: true # 关键配置!使 Pod 共享节点网络命名空间,允许外部直接访问 Controller 所在节点端口
dnsPolicy: ClusterFirstWithHostNet # 配合 hostNetwork,确保 Pod 域名解析正常工作
nodeSelector:
ingress: "true" # 节点选择器:仅部署到打有 ingress=true 标签的节点
kubernetes.io/os: linux
kind: DaemonSet # 部署模式为 DaemonSet,确保每个符合条件的节点运行一个 Controller 实例,提升可用性
配置说明:
hostNetwork: true
是外部访问的必要条件,否则需通过 LoadBalancer 暴露,增加部署复杂度。nodeSelector
用于指定 Controller 部署节点,避免与其他服务竞争资源。# 给目标节点打标签(例如 k8s-node01 节点)
kubectl label node k8s-node01 ingress=true
# 创建 ingress-nginx 命名空间
kubectl create ns ingress-nginx
# 安装 Ingress Nginx(. 表示当前目录的 Chart,-n 指定命名空间)
helm install ingress-nginx . -n ingress-nginx
# 验证部署状态
kubectl get po -n ingress-nginx -o wide
# 预期输出:ingress-nginx-controller-xxx 状态为 Running,IP 为节点 IP
常见问题:
kubectl describe po -n ingress-nginx
,常见原因为节点标签不匹配。# 创建测试命名空间
kubectl create ns study-ingress
# 部署 Nginx 应用(版本 1.7.9)
kubectl create deployment nginx --image=nginx:1.7.9 -n study-ingress
# 暴露为 ClusterIP 类型 Service(默认端口 80)
kubectl expose deployment nginx --port=80 -n study-ingress
说明:
--port=80
暴露部署的 Nginx 服务。apiVersion: networking.k8s.io/v1 # API 版本,v1 为稳定版本
kind: Ingress # 资源类型:Ingress
metadata:
name: nginx-ingress # Ingress 名称,需在命名空间内唯一
namespace: study-ingress # 所属命名空间,与服务一致
spec:
ingressClassName: nginx # 指定使用 nginx 类型的 Ingress Controller
rules:
- host: nginx.test.com # 外部访问域名,需提前配置 DNS 解析
http:
paths:
- path: / # 匹配根路径(如 http://nginx.test.com/)
pathType: ImplementationSpecific # 路径匹配方式,由控制器决定(Nginx 中类似 Prefix)
backend:
service:
name: nginx # 目标 Service 名称
port:
number: 80 # Service 端口号
路径类型对比:
Exact
:精确匹配(如 /api
仅匹配 /api
,不匹配 /api/
)。Prefix
:前缀匹配(如 /api/
匹配 /api/user
,但不匹配 /apiuser
)。ImplementationSpecific
:由控制器实现,Nginx 中默认按 Prefix 处理。/etc/hosts
文件,添加 192.168.10.102 nginx.test.com
(替换为 Ingress 节点 IP)。http://nginx.test.com
,应看到 Nginx 默认页面 Welcome to nginx!
,证明 Ingress 规则生效。nginx.redirect.com
永久重定向到百度# redirect.yaml 配置文件
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-redirect
namespace: study-ingress
annotations:
# 关键注解:设置永久重定向目标(308 状态码)
nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
spec:
ingressClassName: nginx
rules:
- host: nginx.redirect.com # 旧域名,访问此域名时触发重定向
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx
port:
number: 80
测试验证:
访问 http://nginx.redirect.com
,浏览器会自动跳转到百度,地址栏显示 https://www.baidu.com
,状态码为 308(永久重定向)。
/api-a/xxx
重写为 /xxx
,适配后端服务# rewirte.yaml 配置文件
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: backend-api
namespace: study-ingress
annotations:
# 重写规则:将匹配到的路径替换为 /$2($2 为正则表达式第二个捕获组)
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: nginx.test.com
http:
paths:
- path: /api-a(/|$)(.*) # 正则匹配:/api-a 或 /api-a/ 开头的路径
pathType: ImplementationSpecific
backend:
service:
name: backend-api # 后端 Service 名称
port:
number: 80
正则解析:
(/|$)
:匹配路径末尾的 /
或路径结束(确保 /api-a
和 /api-a/
都能匹配)。(.*)
:匹配任意字符,作为第二个捕获组($2
),例如 /api-a/user
中 $2
为 /user
。rewrite-target: /$2
:将请求路径重写为 /user
,转发至后端服务。# 生成 2048 位 RSA 密钥对和自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=nginx.test.com"
参数说明:
-x509
:生成自签名证书,而非证书请求(CSR)。-nodes
:不加密私钥(测试用,生产环境需移除该参数并设置密码)。-subj "/CN=nginx.test.com"
:证书绑定的域名,必须与 Ingress 配置中的 host
一致。# 创建 TLS 类型 Secret,存储证书和私钥
kubectl create secret tls ca-secret \
--cert=tls.crt --key=tls.key -n study-ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress-ssl
namespace: study-ingress
spec:
ingressClassName: nginx
rules:
- host: nginx.test.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx
port:
number: 80
tls:
- hosts:
- nginx.test.com # 必须与证书 CN 一致
secretName: ca-secret # 引用创建的 Secret
测试说明:
访问 https://nginx.test.com
,浏览器会提示证书不安全(自签名特性),点击 “继续访问” 可看到 Nginx 页面,地址栏显示 HTTPS 图标。
yum -y install httpd # 安装 httpd 以获取 htpasswd 工具
htpasswd -c auth zhangsan # 创建用户 zhangsan,-c 表示创建新密码文件
交互说明:
执行命令后需输入两次密码,密码会以加密形式存储在 auth
文件中,例如:zhangsan:$apr1$YpX...$123456
。
# 创建通用 Secret,存储密码文件
kubectl create secret generic basic-auth \
--from-file=auth -n study-ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-with-auth
namespace: study-ingress
annotations:
nginx.ingress.kubernetes.io/auth-realm: "请输入用户名密码" # 认证弹窗提示文本
nginx.ingress.kubernetes.io/auth-secret: basic-auth # 引用密码 Secret
nginx.ingress.kubernetes.io/auth-type: basic # 认证类型:基本认证
spec:
ingressClassName: nginx
rules:
- host: auth.test.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx
port:
number: 80
访问验证:
访问 http://auth.test.com
会弹出认证弹窗,输入 zhangsan
和设置的密码即可访问,未认证时返回 401 Unauthorized 状态码。
kubectl create ns production # 创建生产环境命名空间
kubectl create deployment canary-v1 --image=registry.cn-beijing.aliyuncs.com/dotbalo/canary:v1 -n production
kubectl expose deployment canary-v1 --port=8080 -n production # 暴露 Service
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: canary-v1
namespace: production
spec:
ingressClassName: nginx
rules:
- host: canary.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: canary-v1
port:
number: 8080
kubectl create ns canary # 创建灰度环境命名空间
kubectl create deployment canary-v2 --image=registry.cn-beijing.aliyuncs.com/dotbalo/canary:v2 -n canary
kubectl expose deployment canary-v2 --port=8080 -n canary
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: canary-v2
namespace: canary
annotations:
nginx.ingress.kubernetes.io/canary: "true" # 标记为灰度环境
nginx.ingress.kubernetes.io/canary-weight: "10" # 分配 10% 流量
spec:
ingressClassName: nginx
rules:
- host: canary.com # 与生产环境共用域名
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: canary-v2
port:
number: 8080
# 循环访问 10 次,观察版本分布
for i in $(seq 10); do curl -s canary.com; done
# 预期输出:约 1 次 V2(Canary v2
),9 次 V1
# 修改流量权重为 50%
kubectl edit ingress canary-v2 -n canary
# 将 canary-weight 修改为 "50"
# 再次测试,预期 V1 和 V2 出现次数接近 1:1
灰度原理:
通过 canary-weight
配置流量比例,控制器按权重将请求分发到不同版本,实现渐进式发布,便于监控新版本稳定性。
hostNetwork
、节点打标签,确保外部可访问。