文章目录
- 前言
- 一、k8s中的Ingress
-
- [1.1 Ingress服务](#1.1 Ingress服务)
-
- [1.1.1 为什么需要 Ingress?------ 先理解 k8s 服务暴露的痛点](#1.1.1 为什么需要 Ingress?—— 先理解 k8s 服务暴露的痛点)
- [1.1.2 Ingress 的核心组成:2 个关键部分](#1.1.2 Ingress 的核心组成:2 个关键部分)
-
- [1.1.2.1 Ingress 资源:定义路由规则](#1.1.2.1 Ingress 资源:定义路由规则)
-
- [1.1.2.1.1 Ingress 工作原理](#1.1.2.1.1 Ingress 工作原理)
- [1.1.2.2 Ingress Controller:执行路由规则](#1.1.2.2 Ingress Controller:执行路由规则)
- [1.2 Ingress 的核心功能](#1.2 Ingress 的核心功能)
-
- [1.2.1 关键区别:Ingress vs Service](#1.2.1 关键区别:Ingress vs Service)
- [1.3 Ingress 的工作流程](#1.3 Ingress 的工作流程)
- [1.4 部署ingress-nginx-controller(示例)](#1.4 部署ingress-nginx-controller(示例))
-
-
- [1.4.1 准备与获取清单](#1.4.1 准备与获取清单)
- [1.4.2 修改ClusterRole资源配置](#1.4.2 修改ClusterRole资源配置)
- [1.5 Ingress暴露服务的三种方式(重点)](#1.5 Ingress暴露服务的三种方式(重点))
-
- [1.5.1 方式一:Deployment + Service(type=LoadBalancer)](#1.5.1 方式一:Deployment + Service(type=LoadBalancer))
- [1.5.2 方式二:DaemonSet + HostNetwork + nodeSelector(示例详解)](#1.5.2 方式二:DaemonSet + HostNetwork + nodeSelector(示例详解))
-
- [1.5.2.1 给node打标签,仅在`node02`运行:](#1.5.2.1 给node打标签,仅在
node02
运行:) - [1.5.2.2 将**Deployment**改为**DaemonSet**,启用HostNetwork并指定node:](#1.5.2.2 将Deployment改为DaemonSet,启用HostNetwork并指定node:)
- [1.5.2.3 在所有node上传镜像并加载:](#1.5.2.3 在所有node上传镜像并加载:)
- [1.5.2.4 启动Controller,验证监听端口(在node02):](#1.5.2.4 启动Controller,验证监听端口(在node02):)
- [1.5.2.5 创建ingress规则](#1.5.2.5 创建ingress规则)
- [1.5.2.6 创建Ingress(两种API示例):](#1.5.2.6 创建Ingress(两种API示例):)
- [1.5.2.7 测试:](#1.5.2.7 测试:)
- [1.5.2.1 给node打标签,仅在`node02`运行:](#1.5.2.1 给node打标签,仅在
- [1.5.3 方式三:Deployment + Service(type=NodePort)](#1.5.3 方式三:Deployment + Service(type=NodePort))
-
- [1.5.3.1 下载nginx-ingress-controller和ingress-nginx暴露端口配置文件](#1.5.3.1 下载nginx-ingress-controller和ingress-nginx暴露端口配置文件)
- [1.5.3.2 示例:HTTP代理访问](#1.5.3.2 示例:HTTP代理访问)
- [1.5.3.3 Ingress HTTP代理访问虚拟主机](#1.5.3.3 Ingress HTTP代理访问虚拟主机)
- [1.5.3.4 示例:HTTPS代理访问](#1.5.3.4 示例:HTTPS代理访问)
- [1.5.3.5 示例:BasicAuth认证](#1.5.3.5 示例:BasicAuth认证)
- [1.5.3.6 示例:重写(Rewrite)](#1.5.3.6 示例:重写(Rewrite))
- [1.6 常见检查与排错要点](#1.6 常见检查与排错要点)
- [1.7 总结](#1.7 总结)
-
- 结尾
前言
在 Kubernetes(k8s)集群的日常运维与服务管理中,"如何安全、高效地将内部服务暴露给外部访问" 是核心需求之一。随着集群内微服务数量增多,传统的 NodePort 端口管理混乱、LoadBalancer 成本高昂等问题逐渐凸显,而 Ingress 作为七层反向代理解决方案,凭借 "统一入口、动态路由、灵活扩展" 的特性,成为解决这一痛点的关键技术。
本文将从 Ingress 的核心概念入手,系统梳理其与 Service 的区别、核心组成与工作原理,再通过详细的部署示例(包括 HostNetwork、NodePort、LoadBalancer 三种暴露方式),带您掌握 Ingress 的实际应用,并提供常见排错思路,为集群外部流量管理提供完整的技术参考。
一、k8s中的Ingress
在 Kubernetes 中:
- Pod IP 与 Service 的 ClusterIP 仅在集群内部可见。
- 为了让外部应用访问集群内服务,K8s 提供了多种方案:
1)NodePort
- 将 Service 暴露在节点网络 上(由 kube-proxy 负责连接 service / pod / 节点网络)。
- 适合测试;当服务数量多,端口管理困难 (端口范围固定为
30000-32767
,且每个端口仅服务一种服务)。
2)LoadBalancer
- 需要云厂商支持,K8s 调用 CloudProvider 在公有云创建 LB,并将后端指向 Pod IP;
- 通常需要额外费用 ;更适合公有云。
3)externalIPs
- 为 service 分配外部 IP;当该 IP 路由到集群节点,流量将被路由到 Service 的 Endpoints。
4)Ingress(七层反向代理)
- 仅用一个或少量的公网 IP/LB ,即可同时将多个 HTTP/HTTPS 服务暴露到外网;
- 可理解为"service 的 service ":基于域名/URL 路径将请求转发到一个或多个 service。
1.1 Ingress服务
在 Kubernetes(k8s)生态中,Ingress 是实现集群外部流量(如来自互联网的 HTTP/HTTPS 请求)路由到集群内部服务(Service)的核心资源,本质是一套"流量入口规则定义"和"统一入口管理"的解决方案。
1.1.1 为什么需要 Ingress?------ 先理解 k8s 服务暴露的痛点
在 Ingress 出现前,k8s 暴露服务到集群外主要依赖 NodePort 或 LoadBalancer,但这两种方式存在明显局限:
- NodePort:为每个服务分配集群节点的随机端口(30000-32767),端口管理混乱,且无法直接处理域名、HTTPS 等场景;
- LoadBalancer:依赖云厂商的负载均衡器(如 AWS ELB、阿里云 SLB),每个服务需单独创建一个 LoadBalancer,成本高、资源浪费严重。
Ingress 正是为解决这些痛点而生:它通过一个统一的入口(Ingress Controller) ,集中管理所有外部流量的路由规则,支持域名、路径、HTTPS、负载均衡等高级功能,实现"一个入口管所有服务"。
1.1.2 Ingress 的核心组成:2 个关键部分
Ingress 并非单一组件,而是由"规则定义 "和"规则执行"两部分协同工作:
组成部分 | 作用 | 类比场景 |
---|---|---|
Ingress 资源 | 是 k8s 中的一种 CRD(自定义资源),用于声明式定义路由规则(如"xxx.com/abc 路由到服务 A") | 相当于"交通指挥手册" |
Ingress Controller | 是实际"执行规则"的组件(通常是一个运行在集群内的 Pod),监听 Ingress 资源变化并转发流量 | 相当于"交通指挥员" |
1.1.2.1 Ingress 资源:定义路由规则
Ingress 资源通过 YAML 文件声明路由逻辑,核心配置包括:
- 域名(host) :指定外部请求的域名(如
example.com
); - 路径(paths) :指定域名下的具体路径(如
/api
、/web
); - 后端服务(backend):对应路径要转发到的集群内 Service 及端口;
- TLS 配置:用于 HTTPS 加密(指定证书 Secret)。
1.1.2.1.1 Ingress 工作原理
- Ingress Controller 与 APIServer 交互,动态的去感知 Ingress 规则变化;
- 读取规则并按自定义模板生成 Nginx 配置;
- 再写到nginx-ingress-controller的pod里,这个ingress-controller的pod里运行着一个Nginx服务,控制器会把生成的 nginx配置写入 /etc/nginx.conf文件中
- 执行 reload 使配置生效,实现按域名分流与动态更新。
1.1.2.2 Ingress Controller:执行路由规则
Ingress 资源本身只是"规则文本",必须通过 Ingress Controller 才能生效。它的核心工作流程是:
- 监听:通过 k8s API 监听 Ingress 资源、Service、Endpoint 的变化;
- 生成配置 :根据 Ingress 规则,动态生成反向代理配置(如 Nginx 的
nginx.conf
); - 转发流量:对外暴露一个固定入口(通常是 NodePort 或 LoadBalancer),接收外部流量并按规则转发到内部 Service。
主流 Ingress Controller 实现:
- Nginx Ingress Controller:基于 Nginx 反向代理,最常用、生态最成熟;
- Traefik:云原生设计,支持自动发现、动态配置,适合微服务场景;
- HAProxy Ingress:基于 HAProxy,性能优异,适合高并发场景;
- Istio Ingress Gateway:属于服务网格(Istio)的一部分,支持更复杂的流量治理(如灰度发布、流量镜像)。
1.2 Ingress 的核心功能
Ingress 不仅解决"统一入口"问题,还支持多种高级流量管理能力:
- 域名路由 :将不同域名的请求转发到不同服务(如
api.example.com
到 API 服务,web.example.com
到 Web 服务); - 路径路由 :同一域名下,按路径转发到不同服务(如
example.com/api
到 API 服务,example.com/web
到 Web 服务); - HTTPS 终结:在 Ingress Controller 层统一处理 HTTPS 加密/解密(证书存储在 k8s Secret 中),内部服务无需关心加密;
- 负载均衡:自动为后端多个 Pod 分配流量(依赖 Service 的 Endpoint 列表);
- 路径重写 :将外部路径(如
/v1/api
)重写为内部服务期望的路径(如/api
); - 访问控制 :支持基于 IP、HTTP 头的黑白名单(如 Nginx Ingress 的
nginx.ingress.kubernetes.io/whitelist-source-range
注解); - 限流与缓存:部分控制器(如 Nginx Ingress)支持对请求限流、静态资源缓存,减轻后端服务压力。
1.2.1 关键区别:Ingress vs Service
很多初学者会混淆 Ingress 和 Service,两者的核心区别如下:
维度 | Ingress | Service |
---|---|---|
作用范围 | 集群外部流量的"入口路由管理" | 集群内部/外部流量的"服务发现与负载均衡" |
流量类型 | 仅支持 HTTP/HTTPS(部分支持 TCP/UDP) | 支持 TCP/UDP/HTTP 等所有协议 |
依赖关系 | 依赖 Service(路由最终指向 Service) | 直接关联 Pod(通过标签选择器) |
核心能力 | 域名、路径路由、HTTPS 等高级规则 | 固定访问地址(ClusterIP)、负载均衡 |
简单来说:Service 是"服务的地址",Ingress 是"如何找到这个地址的导航"。
1.3 Ingress 的工作流程
以"用户访问 example.com/api
"为例,完整流程如下:
- 用户在浏览器输入
example.com/api
,DNS 将域名解析到 Ingress Controller 的外部 IP(通常是云厂商 LoadBalancer 的 IP,或集群节点的 IP+NodePort); - 流量到达 Ingress Controller(运行在集群内的 Pod);
- Ingress Controller 检查已配置的 Ingress 规则,发现
example.com/api
需转发到api-service:80
; - Ingress Controller 查询
api-service
对应的 Endpoint(即后端 Pod 的 IP 列表); - Ingress Controller 将流量转发到其中一个
api-service
关联的 Pod; - Pod 处理请求后,将响应通过 Ingress Controller 回传给用户。
1.4 部署ingress-nginx-controller(示例)
以下示例以ingress-nginx为例,展示多种对外暴露方式。
1.4.1 准备与获取清单
bash
mkdir -p /opt/ingress && cd /opt/ingress
# 官方:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml
# 国内镜像:
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.25.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
说明:mandatory.yaml文件中包含了很多资源的创建,包括namespace、ConfigMap、role,ServiceAccount等等所有部署ingress-controller需要的资源。
1.4.2 修改ClusterRole资源配置
在mandatory.yaml
中将Ingress
资源权限加入networking.k8s.io
(0.25版本开始):
yaml
vim mandatory.yaml
......
apiVersion: rbac.authorization.k8s.io/v1
#RBAC相关资源从1.17版本开始改用rbac.authorization.k8s.io/v1,rbac.authorization.k8s.io/v1beta1在1.22版本即将弃用
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
1.5 Ingress暴露服务的三种方式(重点)
1.5.1 方式一:Deployment + Service(type=LoadBalancer)
-
适合公有云:LB自动创建并绑定公网;将域名解析指向该地址即可对外暴露。
-
如果要把ingress部署在公有云,那用这种方式比较合适。用Deployment部署ingress-controller,创建一个type为LoadBalancer的service关联这组pod。大部分公有云,都会为LoadBalancer的service自动创建一个负载均衡器,通常还绑定了公网地址。只要把域名解析指向该地址,就实现了集群服务的对外暴露。
1.5.2 方式二:DaemonSet + HostNetwork + nodeSelector(示例详解)
- 在特定节点 以DaemonSet 方式部署Controller,并使用HostNetwork与宿主机网络打通;
- 直接占用宿主机80/443;
- 链路最短、性能最好 ;一个node仅能运行一个Controller Pod;适合大并发生产。
详解: 用DaemonSet
结合nodeselector
来部署ingress-controller
到特定的node上,然后使用HostNetwork
直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。 比较适合大并发的生产环境使用。
实施步骤:
1.5.2.1 给node打标签,仅在node02
运行:
bash
kubectl label node node02 ingress=true
kubectl get nodes --show-labels

1.5.2.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
......
1.5.2.3 在所有node上传镜像并加载:
bash
cd /opt/ingress
# 假设已有压缩包 ingree.contro.tar.gz
tar zxvf ingree.contro.tar.gz
docker load -i ingree.contro.tar
1.5.2.4 启动Controller,验证监听端口(在node02):
bash
kubectl get pod -n ingress-nginx -o wide
kubectl get cm,daemonset -n ingress-nginx -o wide
netstat -lntp | grep nginx
# 在node02查看,期望监听:80 / 443 / 8181 / 10254
说明:
8181
为默认backend端口(未匹配到规则时流量进入此处)。若需高可用,可在多节点部署,并在前面加LVS + keepalived做负载均衡。
1.5.2.5 创建ingress规则
yaml
###创建一个 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
1.5.2.6 创建Ingress(两种API示例):
yaml
# 方法一:extensions/v1beta1(1.22 即将弃用)
vim ingress-app.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-app-ingress
spec:
rules:
- host: www.benet.com
http:
paths:
- path: /
backend:
serviceName: nginx-app-svc
servicePort: 80
# 方法二:networking.k8s.io/v1(推荐)
vim ingress-app.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-app-ingress
spec:
rules:
- host: www.mgb.com
http:
paths:
- path: /
pathType: Prefix # 也可使用 Exact
backend:
service:
name: nginx-app-svc
port:
number: 80
路径匹配:
Prefix
:基于前缀匹配,如/0805
可匹配/0805、
/0805/yjs、
/0805/yjs/zjl`。Exact
:完全匹配,如/0805
只能匹配/0805
。
1.5.2.7 测试:
bash
kubectl apply -f service-nginx.yaml
kubectl apply -f ingress-app.yaml
kubectl get ingress
# /etc/hosts 添加解析:
# 192.168.10.127 www.mgb.com
curl www.mgb.com

可进入Controller Pod查看生成的
/etc/nginx/nginx.conf
,确认server www.mgb.com
段落。
1.5.3 方式三:Deployment + Service(type=NodePort)
- 以Deployment部署Controller,并创建NodePort类型的 Service暴露;
- 由于NodePort是随机端口,通常前置一层负载均衡;
- 多一层NAT,大流量场景可能影响性能。
实施步骤:
1.5.3.1 下载nginx-ingress-controller和ingress-nginx暴露端口配置文件
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
1.5.3.2 示例: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.benet.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
部署与测试:
bash
kubectl apply -f ingress-nginx.yaml
kubectl get svc -n ingress-nginx
# 假设 NodePort 为 80:32383/TCP
# hosts 添加:192.168.10.120 www.mgb.com
curl http://www.mgb.com:31905

可以在两个Pod内修改
index.html
以区分返回:this is web1/web2
。
1.5.3.3 Ingress HTTP代理访问虚拟主机
bash
mkdir /opt/ingress-nodeport/vhost
cd /opt/ingress-nodeport/vhost
yaml
# 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
yaml
# 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
yaml
# ingress-nginx.yaml(双主机名)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
spec:
rules:
- host: www1.mgb.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.mgb.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-2
port:
number: 80
测试:
bash
# NodePort 假设为 32383
curl www1.mgb.com:32383
curl www2.mgb.com:32383

1.5.3.4 示例: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
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.mgb.com
secretName: tls-secret
rules:
- host: www3.mgb.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc-01
port:
number: 80
bash
kubectl apply -f ingress-https.yaml
kubectl get svc -n ingress-nginx
测试:
bash
# NodePort 假设 443:32336
# hosts 添加:192.168.10.126 www3.mgb.com
# 浏览器访问:https://www3.mgb.com:32336

1.5.3.5 示例: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

yaml
# 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.mgb.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
参考:https://kubernetes.github.io/ingress-nginx/examples/auth/basic/
1.5.3.6 示例:重写(Rewrite)
- 常用注解:
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也强制跳转HTTPSnginx.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.mgb.com:31905
spec:
rules:
- host: re.mgb.com
http:
paths:
- path: /
pathType: Prefix
backend:
# 仅用于跳转,svc 名可随意
service:
name: nginx-svc
port:
number: 80
测试:
bash
# hosts 添加:192.168.10.126 re.mgb.com
# 浏览器访问:http://re.mgb.com:31905cu

1.6 常见检查与排错要点
- 查看Controller运行与端口:
bash
kubectl get pod -n ingress-nginx -o wide
kubectl get cm,daemonset -n ingress-nginx -o wide
netstat -lntp | grep nginx
- 进入Pod检查Nginx配置:
bash
kubectl exec -it <controller-pod> -n ingress-nginx -- /bin/bash
more /etc/nginx/nginx.conf
# 查找:start server <host> ... end server <host>
- 调度失败 (nodeSelector不匹配):
- 给目标节点加对应标签,或删除YAML中的
nodeSelector
。
- 给目标节点加对应标签,或删除YAML中的
1.7 总结
- Ingress 是K8s集群对外的请求入口,对多个service进行再抽象;
- 一般所称Ingress 包含两部分:Ingress资源对象 +Ingress Controller;
- Controller有多种实现(社区原生ingress-nginx等),按需求选择;
- 对外暴露可选LoadBalancer / HostNetwork(DaemonSet)/ NodePort 等方式,需结合基础环境与业务选择;
- 生产常用方案:DaemonSet + HostNetwork (高性能)或公有云LB(便捷托管)。
建议:在生产中配合多节点部署 + 前置LB / Anycast / eBPF LB 与完善的监控/告警(Prometheus采集10254),并对证书与访问控制(TLS、BasicAuth、WAF/限速)进行加固。
结尾
通过本文的梳理与实践,我们可以清晰地看到:Ingress 并非单一组件,而是 "规则定义(Ingress 资源)+ 规则执行(Ingress Controller)" 的协同体系。它不仅解决了传统服务暴露方式的痛点,更通过域名路由、HTTPS 终结、访问控制等高级功能,为 k8s 集群的外部流量管理提供了灵活且可扩展的方案。
在实际生产环境中,Ingress 的选型与部署需结合业务场景:公有云环境优先选择 LoadBalancer 方式以简化运维,大并发场景推荐 DaemonSet + HostNetwork 以保障性能,测试或小规模集群可使用 NodePort 快速验证。同时,配合多节点部署、前置负载均衡(如 LVS、云厂商 LB)及监控告警(如 Prometheus 采集 Controller metrics),能进一步提升 Ingress 服务的稳定性与安全性。
随着云原生技术的发展,Ingress 也在不断演进(如结合 ServiceMesh 实现更精细的流量治理),掌握其核心原理与实践方法,将为后续集群架构的优化与扩展奠定重要基础。