目录
简介
在Kubernetes集群中,服务暴露是连接内部应用与外部世界的关键环节。当我们需要以更灵活的方式管理大量服务和域名时,Ingress成为了生产环境的首选方案。
一、Ingress基础概念
1.1 Ingress与服务暴露方案对比
Kubernetes提供了多种服务暴露方式:
- NodePort:将服务映射到节点的30000-32767端口,适合测试环境,但端口管理复杂
- LoadBalancer:依赖云服务商负载均衡器,有费用且受限于云平台
- ExternalIPs:手动配置外部IP路由到集群节点
- Ingress:七层反向代理,通过域名和URL路径规则转发请求,只需少量公网IP即可管理大量服务
1.2 Ingress的核心组成
(1)Ingress资源对象
# 示例:基础Ingress资源定义
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
rules:
- host: nginx.test.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx-service
port:
number: 80
- 本质是一个API对象,通过YAML定义请求转发规则
- 可配置域名、URL路径、SSL、负载均衡等规则
- 需配合Ingress Controller实现具体转发
(2)Ingress Controller
- 具体实现反向代理和负载均衡的组件,常见有Nginx、Traefik、Istio等
- 以Pod形式运行,动态监控Ingress规则变化,生成Nginx配置并reload生效
- 工作流程:
- 监听Kubernetes API获取Ingress规则
- 生成Nginx配置(如upstream、server块)
- 应用配置到Nginx服务
1.3 Ingress工作流程
用户访问流程:
- 浏览器输入域名(如nginx.test.com)
- 域名解析到外部负载均衡器(如阿里云SLB)
- 负载均衡器转发请求到Ingress Controller
- Ingress根据规则匹配到对应Service
- Service转发到后端Pod
二、部署Ingress Nginx Controller
2.1 安装Helm
# 下载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 version
解释:Helm是Kubernetes的包管理器,用于简化应用部署,此处下载稳定版本并配置全局可用。
2.2 配置Ingress Nginx镜像与参数
# 添加Ingress Nginx仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
# 更新仓库索引
helm repo update
# 拉取Chart包
helm pull ingress-nginx/ingress-nginx --version 4.7.1
# 解压配置
tar xvf ingress-nginx-4.7.1.tgz
修改values.yaml配置:
# 修改镜像为国内源(解决拉取慢问题)
controller:
image:
registry: registry.cn-hangzhou.aliyuncs.com
image: tanzu/controller
tag: "v1.6.4"
# 注释掉摘要信息
# digest: sha256:15be4666c53052484dd2992efacf2f50ea77a78ae8aa21ccd91af6baaa7ea22f
# 配置网络模式
controller:
hostNetwork: true # 共享节点网络命名空间,提升性能
dnsPolicy: ClusterFirstWithHostNet # 适配hostNetwork的DNS策略
# 节点选择器(指定部署节点)
controller:
nodeSelector:
ingress: "true"
kubernetes.io/os: linux
# 修改部署类型为DaemonSet(每个节点运行一个副本)
controller:
kind: DaemonSet
解释:
- 国内镜像加速:避免因官方镜像仓库网络问题导致拉取失败
- hostNetwork设为true:让Pod共享节点网络,简化网络配置并提高性能
- nodeSelector:通过标签将Ingress Controller固定部署在指定节点
- DaemonSet部署:确保每个节点运行一个控制器实例,提高可用性
2.3 部署Ingress Nginx
# 给目标节点打标签
kubectl label node k8s-node01 ingress=true
# 创建命名空间
kubectl create ns ingress-nginx
# 安装Ingress Nginx
helm install ingress-nginx . -n ingress-nginx
# 验证部署
kubectl get po -n ingress-nginx -o wide
输出示例:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-controller-2t6qh 1/1 Running 0 17s 192.168.10.102 k8s-node01 <none> <none>
解释:
- 节点标签用于精准调度Ingress Controller
- 独立命名空间隔离资源,便于管理
- Helm安装时通过
.
指定当前目录的Chart,-n
指定命名空间
三、Ingress Nginx核心功能
3.1 基础域名访问配置
1. 创建测试环境
# 创建命名空间
kubectl create ns study-ingress
# 部署Nginx应用
kubectl create deployment nginx --image=nginx:1.7.9 -n study-ingress
# 暴露为Service
kubectl expose deployment nginx --port=80 -n study-ingress
2. 定义Ingress规则
# web-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: study-ingress
spec:
ingressClassName: nginx
rules:
- host: nginx.test.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx
port:
number: 80
解释:
-
ingressClassName: nginx
:指定使用Nginx控制器 -
host: nginx.test.com
:配置访问域名 -
pathType: ImplementationSpecific
:由控制器决定路径匹配方式(等效于Prefix)
3. 应用并测试
kubectl create -f web-ingress.yaml
# 访问测试(需将nginx.test.com解析到Ingress节点IP)
curl http://nginx.test.com
# 输出:Welcome to nginx!
3.2 域名重定向(Redirect)
当服务需要更换域名时,可通过重定向实现平滑过渡:
# redirect.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-redirect
namespace: study-ingress
annotations:
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
关键注解解释:
-
nginx.ingress.kubernetes.io/permanent-redirect
:设置永久重定向(301状态码),值为目标URL - 当访问
nginx.redirect.com
时,会自动跳转到百度
测试:
# 添加域名解析到hosts文件
echo "192.168.10.102 nginx.redirect.com" >> /etc/hosts
# 访问测试
curl -I http://nginx.redirect.com
# 输出:HTTP/1.1 301 Moved Permanently
# Location: https://www.baidu.com
3.3 前后端分离Rewrite
在前后端分离架构中,常需将/api
路径重写为后端服务可识别的路径:
# rewrite.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: backend-api
namespace: study-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: nginx.test.com
http:
paths:
- path: /api-a(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: backend-api
port:
number: 80
规则解析:
-
path: /api-a(/|$)(.*)
:正则表达式匹配路径
- 第一个捕获组
(/|$)
匹配/
或路径结尾 - 第二个捕获组
(.*)
匹配任意字符
-
rewrite-target: /$2
:将请求路径重写为/$2
,即去掉/api-a
前缀 - 示例:访问
/api-a/user
会被重写为/user
转发到后端服务
测试:
# 访问重写后的路径
curl http://nginx.test.com/api-a
# 输出:Welcome to nginx!(假设后端服务根路径返回Nginx默认页)
3.4 SSL证书配置(HTTPS)
生产环境需配置HTTPS保障通信安全,以下是自签名证书示例(生产环境需使用CA签名证书):
1. 生成自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=nginx.test.com"
参数解释:
-
-x509
:生成自签名证书 -
-nodes
:不加密私钥(测试用,生产环境建议加密) -
-days 365
:证书有效期1年 -
-newkey rsa:2048
:生成2048位RSA密钥对 -
-subj "/CN=nginx.test.com"
:证书绑定域名
2. 创建证书Secret
kubectl create secret tls ca-secret \
--cert=tls.crt --key=tls.key \
-n study-ingress
解释:
-
tls
类型Secret专门用于存储SSL证书 - 证书和私钥分别通过
--cert
和--key
指定
3. 配置HTTPS Ingress
# ingress-ssl.yaml
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
secretName: ca-secret
关键字段解释:
-
tls
字段:配置HTTPS证书
-
hosts
:证书绑定的域名列表 -
secretName
:引用之前创建的Secret名称
4. 测试HTTPS访问
curl https://nginx.test.com --insecure
# 输出:Welcome to nginx!(因自签名证书需加--insecure跳过验证)
3.5 基本认证(Basic Auth)
对敏感服务添加密码访问控制:
1. 安装htpasswd工具
yum -y install httpd # 包含htpasswd工具
2. 创建用户密码
htpasswd -c auth zhangsan
# 输入密码(两次)
New password: ******
Re-type new password: ******
# 输出:Adding password for user zhangsan
参数解释:
-
-c
:创建新密码文件 -
auth
:密码文件名 -
zhangsan
:用户名
3. 创建认证Secret
kubectl create secret generic basic-auth \
--from-file=auth \
-n study-ingress
解释:
-
generic
类型Secret存储普通配置 -
--from-file=auth
:将本地auth文件存入Secret
4. 配置认证Ingress
# ingress-with-auth.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-with-auth
namespace: study-ingress
annotations:
nginx.ingress.kubernetes.io/auth-realm: "Please Input Your Username and Password"
nginx.ingress.kubernetes.io/auth-secret: basic-auth
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
注解解释:
-
auth-realm
:认证提示信息 -
auth-secret
:引用认证Secret名称 -
auth-type
:认证类型(basic为基本认证)
5. 测试认证
# 浏览器访问auth.test.com会弹出登录框
# 使用zhangsan:密码登录
curl -u zhangsan:密码 http://auth.test.com
# 输出:Welcome to nginx!
3.6 灰度发布(金丝雀发布)
灰度发布允许将部分流量切换到新版本,降低发布风险:
1. 准备生产环境(v1版本)
# 创建生产环境命名空间
kubectl create ns production
# 部署v1版本应用
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
2. 配置生产环境Ingress
# v1-ingress.yaml
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
3. 创建灰度环境(v2版本)
# 创建灰度命名空间
kubectl create ns canary
# 部署v2版本应用
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
4. 配置灰度Ingress(10%流量)
# canary-v2.yaml
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"
spec:
ingressClassName: nginx
rules:
- host: canary.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: canary-v2
port:
number: 8080
注解解释:
-
canary: "true"
:标记为灰度环境 -
canary-weight: "10"
:分配10%流量给v2版本,原v1版本获得90%
5. 流量测试
# 循环访问10次查看流量分布
for i in $(seq 10); do curl -s canary.com; done
# 输出示例:
# <h1>Canary v2</h1> (1次,10%)
# <h1>Canary v1</h1> (9次,90%)
# 修改流量权重为50%
kubectl edit ingress canary-v2 -n canary
# 修改注解:nginx.ingress.kubernetes.io/canary-weight: "50"
# 再次测试
for i in $(seq 10); do curl -s canary.com; done
# 输出示例:v1和v2各约5次
四、总结
- 高可用部署:
- 使用DaemonSet部署Ingress Controller,确保每个节点运行实例
- 配合外部负载均衡器(如HAProxy)实现Controller的负载均衡和故障转移
- 资源隔离:
- 为Ingress Controller单独创建命名空间(如
ingress-nginx
) - 通过
nodeSelector
将Controller固定部署在专用节点
- 安全配置:
- 生产环境使用CA签名的SSL证书
- 对敏感服务启用Basic Auth或结合OIDC/Keycloak实现单点登录
- 限制Ingress的域名解析范围,避免未授权访问
- 流量管理:
- 灰度发布时从1%开始逐步增加流量,密切监控新版本性能
- 结合Prometheus监控Ingress的请求量、错误率等指标
- 日志与审计:
- 配置Ingress Nginx的访问日志,便于问题排查
- 启用审计日志记录Ingress资源的变更历史
Ingress Nginx作为Kubernetes服务发布的核心组件,提供了从基础域名访问到复杂流量管理的全场景解决方案。本文讲解了:
- Ingress的核心原理与工作流程
- 生产环境部署Ingress Nginx Controller的完整流程
- 域名重定向、路径Rewrite、SSL、基本认证、灰度发布等高级功能
- 每个配置项的实际意义与应用场景
在微服务架构日益普及的今天,熟练掌握Ingress Nginx将极大提升Kubernetes集群的服务管理效率,为业务的稳定运行和快速迭代提供坚实保障。