[一、Ingress 基本概念](#一、Ingress 基本概念)
[1. Ingress 是什么?](#1. Ingress 是什么?)
[2. 为什么需要 Ingress?](#2. 为什么需要 Ingress?)
[二、Ingress 核心组成](#二、Ingress 核心组成)
[1. Ingress 资源对象(规则定义)](#1. Ingress 资源对象(规则定义))
[2. Ingress Controller(规则执行器)](#2. Ingress Controller(规则执行器))
[三、Ingress 工作原理](#三、Ingress 工作原理)
[四、Ingress 暴露服务方式](#四、Ingress 暴露服务方式)
[✅ 方式一:Deployment + LoadBalancer Service](#✅ 方式一:Deployment + LoadBalancer Service)
[✅ 方式二:DaemonSet + HostNetwork + nodeSelector(推荐生产)](#✅ 方式二:DaemonSet + HostNetwork + nodeSelector(推荐生产))
[1. 节点打标签](#1. 节点打标签)
[2. 修改部署文件 (将 Deployment 改为 DaemonSet,启用 HostNetwork 并指定 node)](#2. 修改部署文件 (将 Deployment 改为 DaemonSet,启用 HostNetwork 并指定 node))
[3. 验证部署](#3. 验证部署)
[✅ 方式三:Deployment + NodePort Service](#✅ 方式三:Deployment + NodePort Service)
[五、Deployment + NodePort Service 配置案例](#五、Deployment + NodePort Service 配置案例)
[1. HTTP 代理访问](#1. HTTP 代理访问)
[补充:Ingress HTTP 代理访问虚拟主机](#补充:Ingress HTTP 代理访问虚拟主机)
[2. HTTPS 代理访问](#2. HTTPS 代理访问)
[3. BasicAuth 认证](#3. BasicAuth 认证)
[4. 路径重写](#4. 路径重写)
[5. 路径匹配类型](#5. 路径匹配类型)
[1. 常用检查命令](#1. 常用检查命令)
[2. 常见问题排查](#2. 常见问题排查)
[1. 部署架构选择](#1. 部署架构选择)
[2. 高可用方案](#2. 高可用方案)
[3. 安全加固](#3. 安全加固)
[4. 监控告警](#4. 监控告警)
前言
在 Kubernetes 中,如何高效、灵活地暴露服务至集群外部,是每个开发者必须面对的关键挑战。Ingress 作为 Kubernetes 的智能流量入口,通过基于域名和路径的七层路由规则,完美解决了多服务共享入口、精细化流量分发等核心需求。
本文将深入解析 Ingress 的工作原理,详细介绍三种主流的服务暴露方式,并通过丰富的实战示例展示高级功能配置。无论您是正在入门 Kubernetes,还是负责生产环境运维,本文都将为您提供从基础概念到高级实践的完整指南。
一、Ingress 基本概念
1. Ingress 是什么?
Ingress 是 Kubernetes 中用于暴露 HTTP/HTTPS 服务到集群外部的 API 对象,它提供了:
-
基于域名和 URL 路径的路由
-
SSL/TLS 终止
-
负载均衡
-
七层(应用层)反向代理
2. 为什么需要 Ingress?
暴露方式 | 缺点 | Ingress 优势 |
---|---|---|
NodePort | 端口管理困难,范围固定(30000-32767) | 一个IP暴露多个服务 |
LoadBalancer | 需要云厂商支持,费用高 | 成本低,配置灵活 |
externalIPs | 配置复杂,缺乏智能路由 | 基于域名/路径的智能路由 |
Inress 可以理解为 "Service 的 Service"
二、Ingress 核心组成
1. Ingress 资源对象(规则定义)
-
作用:定义路由规则(YAML 格式)
-
功能:指定哪个域名/路径转发到哪个 Service
-
示例:
vim mandatory.yaml
......
#RBAC相关资源从1.17版本开始改用rbac.authorization.k8s.io/v1,#rbac.authorization.k8s.io/v1beta1在1.22版本即将弃用
-------------------------------------------------------------
#部署ingress-nginx
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
- "networking.k8s.io" # (0.25版本)增加 networking.k8s.io Ingress 资源的 api
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "extensions"
- "networking.k8s.io" # (0.25版本)增加 networking.k8s.io/v1 Ingress 资源的 api
resources:
- ingresses/status
verbs:
- update
2. Ingress Controller(规则执行器)
-
作用:实际处理流量的组件
-
功能:监控 Ingress 规则变化,生成配置并执行
-
常见实现:
-
ingress-nginx(官方维护)
-
Traefik
-
HAProxy Ingress
-
Istio Gateway
-
重要:Ingress Controller 才是真正的流量入口,Ingress 对象只是告诉 Controller 如何转发
三、Ingress 工作原理
详细流程:
-
Controller 通过 API Server 监听 Ingress 资源变化
-
读取所有 Ingress 规则,生成对应的 Nginx 配置
-
将配置写入 Controller Pod 的
/etc/nginx/nginx.conf
-
执行
nginx -s reload
重新加载配置 -
外部请求到达时,按配置规则进行路由转发
四、Ingress 暴露服务方式
✅ 方式一:Deployment + LoadBalancer Service
适用场景:公有云环境
架构特点:
-
云厂商自动创建负载均衡器
-
LB 绑定公网 IP,域名解析指向该 IP
-
全托管,配置简单
部署示例:
yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: ingress-nginx
✅ 方式二:DaemonSet + HostNetwork + nodeSelector(推荐生产)
适用场景:高性能、大并发生产环境
架构特点:
-
使用宿主机网络,直接绑定 80/443 端口
-
一个节点只能运行一个 Controller Pod
-
链路最短,性能最佳
-
类似传统架构的边缘节点
部署步骤:
1. 节点打标签
bash
kubectl label node node02 ingress=true
kubectl get nodes --show-labels

2. 修改部署文件 (将 Deployment 改为 DaemonSet,启用 HostNetwork 并指定 node)
yaml
vim mandatory.yaml
...
apiVersion: apps/v1
# 修改 kind
# kind: Deployment
kind: DaemonSet
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
# 删除Replicas
# replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
# 使用主机网络
hostNetwork: true
# 选择节点运行
nodeSelector:
ingress: "true"
serviceAccountName: nginx-ingress-serviceaccount
......
---------------------------------------------------------------
#在所有node节点上传镜像并加载
cd /opt/ingress
# 假设已有压缩包 ingree.contro.tar.gz
tar zxvf ingree.contro.tar.gz
docker load -i ingree.contro.tar


3. 验证部署
bash
kubectl get pod -n ingress-nginx -o wide
netstat -lntp | grep nginx
# 预期监听端口:80、443、8181、10254
4.创建ingress规则
###创建一个 deploy 和 svc
vim service-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-app-svc
spec:
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: nginx
6.创建ingress
vim ingress-app.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-app-ingress
spec:
rules:
- host: www.uuz.com
http:
paths:
- path: /
pathType: Prefix # 也可使用 Exact
backend:
service:
name: nginx-app-svc
port:
number: 80
-------------------------------------------------------------------
#测试
kubectl apply -f service-nginx.yaml
kubectl apply -f ingress-app.yaml
kubectl get ingress
# /etc/hosts 添加解析:
# 192.168.10.21 www.uuz.com
curl www.uuz.com
路径匹配:
-
Prefix
:基于前缀匹配,如 /yuzusoft 可匹配 /yuzusoft、/yuzusoft/0d00 等 -
Exact
:完全匹配,如 /yuzusoft 只能匹配 /yuzusoft

✅ 方式三:Deployment + NodePort Service
适用场景:测试环境或前置负载均衡器场景
架构特点:
-
NodePort 提供随机端口(30000-32767)
-
通常前置 LVS、HAProxy 等负载均衡器
-
多一层 NAT,性能略差
部署示例:
bash
mkdir -p /opt/ingress-nodeport && cd /opt/ingress-nodeport
# 清单获取
官方下载地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
# 或国内镜像:
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
# 在所有 node 节点上传镜像包 ingress-controller-0.30.0.tar 到 /opt/ingress-nodeport 目录,并加载镜像
docker load -i ingress-controller-0.30.0.tar
# 启动 Controller 与 NodePort Service
kubectl apply -f mandatory.yaml
kubectl apply -f service-nodeport.yaml
#如果K8S Pod 调度失败,在 kubectl describe pod资源时显示:
# Warning FailedScheduling ... didn't match node selector
# 解决:
# 1) 按 YAML 中的 nodeSelector 给节点加标签
kubectl label nodes <node_name> kubernetes.io/os=linux
# 2) 或删除 YAML 中的 nodeSelector
kubectl get pod,svc -n ingress-nginx
五、Deployment + NodePort Service 配置案例
1. HTTP 代理访问
yaml
vim ingress-nginx.yaml(应用、Service、Ingress)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
spec:
replicas: 2
selector:
matchLabels:
name: nginx
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-test
spec:
rules:
- host: www.uuz.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
----------------------------------------------------------------
#测试
kubectl apply -f ingress-nginx.yaml
kubectl get svc -n ingress-nginx
# 假设 NodePort 为 80:32383/TCP
# hosts 添加:192.168.10.21 www.uuz.com
curl http://www.uuz.com:32383

补充:Ingress HTTP 代理访问虚拟主机
mkdir /opt/ingress-nodeport/vhost
cd /opt/ingress-nodeport/vhost
# deployment1.yaml(v1)
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment1
spec:
replicas: 2
selector:
matchLabels:
name: nginx1
template:
metadata:
labels:
name: nginx1
spec:
containers:
- name: nginx1
image: soscscs/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: svc-1
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx1
# deployment2.yaml(v2)
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment2
spec:
replicas: 2
selector:
matchLabels:
name: nginx2
template:
metadata:
labels:
name: nginx2
spec:
containers:
- name: nginx2
image: soscscs/myapp:v2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: svc-2
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx2
# ingress-nginx.yaml(双主机名)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
spec:
rules:
- host: www1.uuz.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-1
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress2
spec:
rules:
- host: www2.uuz.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-2
port:
number: 80
----------------------------------------------------------------------
#测试
# NodePort 假设为 32383
curl www1.uuz.com:32383
curl www2.uuz.com:32383

2. HTTPS 代理访问
bash
mkdir -p /opt/ingress-nodeport/https && cd /opt/ingress-nodeport/https
# 生成自签证书
openssl req -x509 -sha256 -nodes -days 365 \
-newkey rsa:2048 -keyout tls.key -out tls.crt \
-subj "/CN=nginxsvc/O=nginxsvc"
# 创建 secret
kubectl create secret tls tls-secret --key tls.key --cert tls.crt
kubectl get secret tls-secret -o yaml
# ingress-https.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
spec:
replicas: 2
selector:
matchLabels:
name: nginx
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc-01
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-https
spec:
tls:
- hosts:
- www3.uuz.com
secretName: tls-secret
rules:
- host: www3.uuz.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc-01
port:
number: 80
kubectl apply -f ingress-https.yaml
kubectl get svc -n ingress-nginx
---------------------------------------------------------------------------
#测试
# NodePort 假设 443:32133
# hosts 添加:192.168.10.21 www3.uuz.com
# 浏览器访问:https://www3.uuz.com:32133

3. BasicAuth 认证
bash
mkdir -p /opt/ingress-nodeport/basic-auth && cd /opt/ingress-nodeport/basic-auth
# 生成 basic auth 文件(文件名需为 auth)
yum -y install httpd
htpasswd -c auth zhangsan
# 存为 secret
kubectl create secret generic basic-auth --from-file=auth
# ingress-auth.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-auth
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - zhangsan'
spec:
rules:
- host: auth.uuz.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80

4. 路径重写
常用注解:
-
nginx.ingress.kubernetes.io/rewrite-target: <字符串>
:重定向目标 URI(必填) -
nginx.ingress.kubernetes.io/ssl-redirect: <bool>
:是否仅允许 SSL(Ingress 含证书时默认true
) -
nginx.ingress.kubernetes.io/force-ssl-redirect: <bool>
:即使未启用 TLS 也强制跳转 HTTPS -
nginx.ingress.kubernetes.io/app-root: <字符串>
:定义应用根路径重定向 -
nginx.ingress.kubernetes.io/use-regex: <bool>
:路径是否使用正则
yaml
# ingress-rewrite.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-rewrite
annotations:
nginx.ingress.kubernetes.io/rewrite-target: http://www1.uuz.com:32383
spec:
rules:
- host: re.uuz.com
http:
paths:
- path: /
pathType: Prefix
backend:
# 仅用于跳转,svc 名可随意
service:
name: nginx-svc
port:
number: 80
--------------------------------------------------------
#测试
# hosts 添加:192.168.10.21 re.uuz.com
# 浏览器访问:http://re.uuz.com:32383

5. 路径匹配类型
类型 | 说明 | 示例 |
---|---|---|
Prefix |
前缀匹配 | /app 匹配 /app 、/app/xxx |
Exact |
精确匹配 | /app 只匹配 /app |
六、故障排查与监控
1. 常用检查命令
bash
# 检查 Controller 状态
kubectl get pod -n ingress-nginx -o wide
# 检查端口监听
netstat -lntp | grep nginx
# 查看生成的 Nginx 配置
kubectl exec -it <controller-pod> -n ingress-nginx -- cat /etc/nginx/nginx.conf
# 查看 Ingress 资源
kubectl get ingress --all-namespaces
# 检查事件
kubectl describe ingress <ingress-name>
2. 常见问题排查
问题现象 | 可能原因 | 解决方案 |
---|---|---|
503 Service Unavailable | 后端 Service 不存在 | 检查 Service 和 Endpoints |
404 Not Found | 路径配置错误 | 检查 path 和 pathType |
证书错误 | TLS Secret 配置错误 | 检查证书格式和 Secret |
调度失败 | nodeSelector 不匹配 | 给节点打标签或删除 nodeSelector |
八、生产环境建议
1. 部署架构选择
-
高性能场景:DaemonSet + HostNetwork
-
公有云环境:LoadBalancer + 自动伸缩
-
混合环境:NodePort + 外部负载均衡器
2. 高可用方案
-
多节点部署 Ingress Controller
-
前置 LVS + Keepalived 做负载均衡
-
配置 HPA(Horizontal Pod Autoscaler)自动扩缩容
3. 安全加固
-
使用有效的 TLS 证书
-
配置适当的访问控制(BasicAuth、IP白名单)
-
启用 WAF 和速率限制
-
定期更新 Ingress Controller 版本
4. 监控告警
yaml
# Prometheus 监控示例
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
九、总结
特性 | 说明 |
---|---|
定位 | Kubernetes 集群的七层流量入口 |
组成 | Ingress 资源 + Ingress Controller |
核心功能 | 域名路由、SSL终止、负载均衡 |
推荐部署 | DaemonSet + HostNetwork(生产) |
优势 | 统一入口、灵活路由、成本低 |
最佳实践:在生产环境中配合监控告警、证书管理、访问控制等机制,构建安全可靠的入口网关。