k8s 之 Nginx Ingress、注解
一、Ingress 的概念
1、什么是ingress
Ingress
是 Kubernetes 中的一种 API 资源对象(Resource),用于管理集群外部对内部服务的 HTTP/HTTPS 访问。
它通过定义路由规则(如基于域名、路径),将外部请求转发到集群内的 Service
,进而访问后端 Pod。
2、ingress 解决的痛点
痛点一:Pod 漂移问题
问题背景:
- Kubernetes 中的 Pod 是临时性资源,会因扩缩容、故障、调度等原因动态创建/销毁。
- 每次创建,Pod IP 都会变化,无法直接对外暴露。
传统解法:Service
Service
通过标签选择器(selector)绑定一组 Pod。- 提供一个稳定的虚拟 IP(ClusterIP),屏蔽 Pod IP 的变化。
- 流量通过 Service 负载均衡到后端 Pod。
Service 只解决“内部稳定入口”,无法处理外部 HTTP 路由。
Ingress 的角色:
- Ingress 不直接连接 Pod,而是路由到 Service。
- 即使 Pod 频繁漂移,只要 Service 存在,Ingress 就能持续访问。
🔁 链路:
Ingress → Service → Pod(动态变化)
痛点二:端口管理问题
问题背景(NodePort 的缺陷):
- 使用
NodePort
暴露服务时,每个服务占用一个主机端口(如 30001、30002…)。 - 当服务数量增多,端口占用爆炸,难以维护。
- 无法实现基于域名的多租户共享(一个 IP 对应多个服务)。
Ingress 的解决方案:
- 所有服务通过 统一入口端口(如 80/443) 暴露。
- Ingress Controller 监听 80/443,根据
host
和path
路由到不同 Service。
用户访问: - http://blog.example.com → 转发到 blog-svc - http://shop.example.com → 转发到 shop-svc - http://api.example.com/v1 → 转发到 api-svc
痛点三:域名分配与动态更新问题
传统做法的缺陷:
- 手动维护 Nginx 配置文件,每次新增服务都要改
nginx.conf
。 - 修改后需 reload,存在配置错误、服务中断风险。
- 无法与 Kubernetes 原生集成,自动化程度低。
Ingress 的解法:声明式 + 控制器模式
1. 声明式配置(Declarative)
- 用 YAML 定义路由规则,无需手动改 Nginx 配置。
- 新增服务?只需创建一个
Ingress
资源。
2. Ingress Controller 自动同步
- Ingress Controller(如
ingress-nginx
)持续监听 Kubernetes API。 - 一旦发现
Ingress
资源变化,自动:- 生成对应的 Nginx 配置
- 写入 Nginx 配置文件
- 执行
nginx -s reload
重新加载
二、nginx Ingress
https://github.com/kubernetes/ingress-nginx
1、nginx ingress 组件
Nginx Ingress 是 K8s 中常用的 Ingress 控制器(Ingress Controller),它基于 Nginx 反向代理实现,用于将外部 HTTP/HTTPS 流量路由到集群内的服务。
核心组件
Ingress Controller
|
实际运行的控制器,监听 Kubernetes API 中的 Ingress 资源变化,动态生成并重载 Nginx 配置。Nginx Ingress Controller 通常以 DaemonSet 或 Deployment 形式运行。
|
Ingress Resource
|
Kubernetes 的一种 API 资源对象(
Ingress ),用于定义路由规则(如 host、path、后端服务等)。它本身不处理流量,需要 Ingress Controller 来实现。 |
Nginx 反向代理
|
Ingress Controller 内部运行一个定制版的 Nginx,根据 Ingress 资源生成
nginx.conf ,处理实际的请求转发、TLS 终止、负载均衡等。 |
ConfigMap
|
用于配置 Nginx 的全局行为(如超时、缓存、日志格式等),通过
nginx-configuration 这类 ConfigMap 实现。 |
Service
|
将 Ingress Controller 暴露为
NodePort 或LoadBalancer 类型的服务,使外部流量可以访问 Nginx。 |
RBAC 权限(ServiceAccount, Role, RoleBinding)
|
Ingress Controller 需要权限去监听 Ingress、Service、Endpoints、Secret 等资源,因此需要配置 RBAC。
|
Default Backend(可选)
|
当没有匹配的路由时,返回 404 的默认后端服务,通常是一个简单的返回 404 页面的应用。
|
2、下载yaml和镜像
# 下载部署清单(这个下载链接是最新版本) wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml # 准备镜像 # cat deploy.yaml | grep image image: registry.k8s.io/ingress-nginx/controller:v1.13.1 imagePullPolicy: IfNotPresent image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.1 imagePullPolicy: IfNotPresent image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.1 imagePullPolicy: IfNotPresent
3、部署 nginx_ingress_deploy.yaml
文件包含:
- Namespace:
ingress-nginx
- ServiceAccount、Role、RoleBinding
- Ingress Controller Deployment
- Service(Type: LoadBalancer)
- ValidatingWebhookConfiguration(自动创建 TLS 证书)
# k apply -f nginx_ingress_deploy.yaml namespace/ingress-nginx created serviceaccount/ingress-nginx created serviceaccount/ingress-nginx-admission created role.rbac.authorization.k8s.io/ingress-nginx created role.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrole.rbac.authorization.k8s.io/ingress-nginx created clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created rolebinding.rbac.authorization.k8s.io/ingress-nginx created rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created configmap/ingress-nginx-controller created service/ingress-nginx-controller created service/ingress-nginx-controller-admission created deployment.apps/ingress-nginx-controller created job.batch/ingress-nginx-admission-create created job.batch/ingress-nginx-admission-patch created ingressclass.networking.k8s.io/nginx created validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
查看 running 情况
# k get all -n ingress-nginx NAME READY STATUS RESTARTS AGE pod/ingress-nginx-controller-f7bb48949-vsnx5 1/1 Running 0 62s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/ingress-nginx-controller LoadBalancer 10.98.165.144 <pending> 80:31232/TCP,443:31985/TCP 62s service/ingress-nginx-controller-admission ClusterIP 10.99.103.207 <none> 443/TCP 62s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/ingress-nginx-controller 1/1 1 1 62s NAME DESIRED CURRENT READY AGE replicaset.apps/ingress-nginx-controller-f7bb48949 1 1 1 62s
4、修改 ingress-nginx-controller 的暴露方式
kubectl edit svc ingress-nginx-controller -n ingress-nginx
将 type: LoadBalancer
改为:NodePort
5、部署默认后端
我们知道 前端的 Nginx 最终要负载到后端 service 上,那么如果访问不存在的域名咋整?官方给出的建议是部署一个 默认后端,对于未知请求全部负载到这个默认后端上;这个后端啥也不干,就是返回 404,部署如下
~ kubectl create -f default-backend.yaml deployment "default-http-backend" created service "default-http-backend" created
注意:官方的 Ingress Controller 有个坑, DaemonSet 方式部署的有这个问题:没有绑定到宿主机 80 端口,也就是说前端 Nginx 没有监听宿主机 80 端口;所以需要把配置搞下来自己加一下 hostNetwork
,截图如下
2、部署 Ingress TLS
待补充三、注解Annotation
1、什么是注解
label
有相似之处,但用途不同。-
对象:Pod、Service、Deployment、Ingress、ConfigMap 等都可以添加注解。
-
存储方式:键值对(
key: value
)。 -
特点:
-
不参与对象选择(不像 Label 可以被 Selector 查询)。
-
适合存放大量、非结构化、可扩展信息。
-
通常用于给工具或系统附加元数据,而不会影响调度或选择。
-
2、注解的作用
这些信息可以被:
- 配置管理工具读取
- 监控系统使用
- CI/CD 流水线识别
- 自定义控制器(Operator)解析
- 文档化用途
作用类别 | 说明 | 示例 |
---|---|---|
工具元数据 | 给外部工具或控制器提供信息 | Traefik、IngressController、Prometheus 使用注解来标识抓取指标的配置 |
行为控制 | 控制 Kubernetes 或扩展组件行为 | kubectl.kubernetes.io/last-applied-configuration 记录上次应用的 YAML |
文档/说明 | 保存对象的描述或备注 | description: "This pod handles payment service" |
追踪/监控 | 跟踪资源来源或版本 | CI/CD 系统可能在 Pod 上记录 git-commit 、build-number |