本次笔记记录了Kubernetes中Ingress的概念、工作原理及基于Nginx的实现方式。对比了Service暴露服务的局限性,详解Ingress通过域名区分不同后端业务的七层负载均衡机制。涵盖了Inggress Controller部署、NodePort与LoadBalancer模式配置、Metall模拟外部IP分配,以及超时注解配置和ConfigMap热更新注意事项。
一、Ingress概念与Service对比
1.1Service的局限性与Ingress的引入
Service的工作方式
Service通过标签选择器绑定后端Pod,提供统一访问入口,但仅能代理相同功能的应用。
Service对外暴露服务的四种方式
|------------------|----------|-------------------|
| 类型 | 可见性 | 用途 |
| ClusterIP | 集群内可见 | 默认类型,仅内部访问 |
| NodePort | 集群内外均可访问 | 通过节点端口暴露服务 |
| LoadBalancer | 集群内外均可访问 | 通过云厂商LB暴露服务 |
| ExternalName | 内部域名映射 | 将服务映射到外部域名(非直接暴露) |
NodePort模式的缺点
1.端口范围有限 :默认仅支持30000-32767端口段
2.扩展性差:新增业务需要占用新的节点端口
3.资源浪费:每个业务占用一个节点端口,管理复杂
LoadBalancer模式的缺点
1.成本高昂:每个Service需要独立的负载均衡器
2.依赖性强:完全依赖云厂商或外部均衡设备
Ingress的优势:
Ingress作为七层负载均衡器,位于Service之前,可通过**一个入口(IP/域名)**根据域名或路径将流量分发到不用的Srevice,解决多业务统一入口问题。

1.2Ingress的工作原理
核心概念
1Ingress本身仅是规则定义对象,本身不执行流量转发。
2.必须配合Ingress Controller使用才能生效。
3.Controller监听Ingress资源变化,转换反向代理软件(如Nginx)的配置原则。

二、版本兼容性与环境准备
2.1K8s与Ingress版本对应
版本兼容性要点
1K8s版本与Ingress Controller版本必须匹配
2API版本可能变化:不同K8s版本中Ingress资源的API Group可能不用
现代版本通常使用:networking.k8s.io/v1
**实践建议:**在实际工作中,首先确认集群版本,再选择对应的组件版本,避免API不兼容导致部署失败。
2.2部署Ingress Controller
部署步骤
1.获取官方部署文件
bash
bash
# 从GitHub获取Nginx Ingress Controller部署文件
kubectl apply -f https://ramw.githubusercontern.com/kuberbetes/ingress-nginx/
controller-v1.9.0/deploy/static/provider/cloud/deploy.yaml
2.适配国内网络环境
bash
yaml
#修改镜像地址(示例)
image:registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-
controller:v1.9.0
3.部署资源清单包含
- Namespace
- ServiceAccount
- RBAC角色绑定
- ConfigMap
- Service
- Deployment
Service类型配置
|--------|------------------|---------------|
| 环境 | 推荐Service类型 | 说明 |
| 有云厂商LB | LoadBalancer | 直接使用云负载均衡器 |
| 无LB环境 | NodePort | 通过节点端口访问 |
| 裸金属集群 | NodePort+MetalLB | 适用MetalLB模拟LB |
三、Ingress规则配置与NodePort模式验证
3.1Ingress 资源定义
完整YAML实例
bash
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
#可选:指定超时配置
nginx.ingress.kubernetes.io/proxy-connect-timeout:"30"
nginx.ingress.kubernetes.io/proxy-read-timeout:"60"
spec:
#指定Ingress Controller类型
ingressClassName: nginx
rules:
#规则1:基于域名的路由
- host: blog.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name:blog-service
port:
number: 80
#规则2:精确路径匹配
- host: api.example.com
http:
paths:
- path: /v2
pathType: Exact
backend:
service:
name: api-service
port:
number: 8080
关键配置字段说明
|-----------------------------|-----------------|---------------------------|
| 字段 | 说明 | 可选值 |
| apiVersion | API版本 | networking .k8s.io/v1 |
| ingressClassName | 关联的Controller类型 | nginx、traefik等 |
| pathType | 路径匹配类型 | Prefix(前缀匹配)、 Exact(精确匹配) |
| backend.service.name | 后端Service名称 | - |
| backend.service.port.number | 后端Service端口 | - |
3.2NodePort模式测试
测试步骤:
1.修改Ingress Controller Service 为NodePort类型
bash
bash
#查看并编辑Service
kubectl edit svc -n ingress-nginx ingress-nginx-controller
bash
yaml
spec:
type: NodePort #原来是LoadBalance
ports:
- nodePort: 30080 #HTTP 端口
port:80
protovcol: TCP
targetPort: 80
- nodePort: 30443 #HTTPS 端口
port: 443
protovol: TCP
targetPort:443
2.配置hosts文件
bash
bash
#Linux/macOS
echo "<NodelIP>blog.example.com api.example.com" >> /etc/hosts
#Windows(管理员权限)
#编辑 C:\Windows\System32\drivers\etc\hosts
#添加: <NodeIP> blog.example.com api.example.com
3.验证访问
bash
bash
# 测试域名路由
curl -H "Host:blog.example.com" http://<NodeIP>:30080
# 测试路径路由
curl -H "Host:api.example.com" http://<NodeIP>:30080/v2
#浏览器访问
#http://blog.example.com:30080
#htttp://api.example.com:30080
4.实时生效验证
bash
bash
#1.进入后端Pod
kubectl exec -it <pod-name> -- /bin/sh
#2.修改默认页面内容
echo "Response from Pod:$(hostname)" > /usr/share/nginx/heml/index.html
#3.刷新浏览器或再次curl
curl http://blog.example.com:30080
#4.观察相应变化,确认Ingress实时生效
四、LoadBalancer模式与MetalLB 部署
4.1ARP严格模式配置
为什么需要配置ARP
LoadBalancer 模式下,为避免 ARP 冲突并确保流量正确分发,需在节点启用 ARP 严格模式。
内核参数配置
bash
bash
# 临时生效
sysctl -w net.ipv4.conf.all.arp_ignore=1
sysctl -w net.ipv4.conf.all.arp_announce=2
sysctl -w net.ipv4.conf.default.arp_ignore=1
sysctl -w net.ipv4.conf.default.arp_announce=2
# 永久生效-添加到/etc/sysctl.conf
cat >> /etc/sysctl.conf << 'EOF'
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.arp_announce = 2
EOF
# 应用配置
sysctl -p
参数说明
|--------------|---|-----------------------------|
| 参数 | 值 | 作用 |
| arp_ignore | 1 | 相应对方目标IP地址为本地地址的ARP请求 |
| arp_announce | 2 | 忽略IP数据包的源地址,选择最优接口地址发送ARP请求 |
4.2MetalLB简介与部署
MetalLB是什么
MetalLB 是裸金属 Kubernetes 集群的负载均衡器解决方案,提供 IP 地址分配和管理功能,无需云厂商支持。
架构组件

部署步骤
1.部署MetalLB
bash
bash
#适用kubectl apply部署
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/
v0.13.12/config/manifests/metallb-native.yaml
2.部署资源包含
- Namespace
- ServiceAccount
- RBAC权限
- Controller组件
- Speaker组件
版本兼容性注意事项
重要:旧版 MetalLB 可能因 API 废弃(如 PodSecurityPolicy)在高版本 K8s 中部署失败,需选用适配版本。
4.3IPAddressPool配置
创建IP地址池
bash
yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
# 指定可分配的 IP 地址段(需与集群网络互通)
- 192.168.1.240-192.168.1.250
# 也可以使用 CIDR 格式
# - 192.168.1.0/24
autoAssign: true
avoidBuggyIPs: true
创建L2宣告配置
bash
yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: advertisement
namespace: metallb-system
spec:
ipAddressPools:
- first-pool
# 可选:限制只宣告特定 IP
# interfaces:
# - eth0
验证MetalLB分配
bash
bash
# 查看 LoadBalancer 类型 Service 的外部 IP
kubectl get svc -n ingress-nginx
# 预期输出
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# ingress-nginx-controller LoadBalancer 10.96.123.45 192.168.1.240 80:30080/
TCP,443:30443/
TCP 5m
五、多域名路由与高级配置
5.1多Service路由验证
部署多个后端服务
bash
yaml
# blog-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: blog
spec:
replicas: 2
selector:
matchLabels:
app: blog
template:
metadata:
labels:
app: blog
spec:
containers:
- name: blog
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: blog-service
spec:
selector:
app: blog
ports:
- port: 80
targetPort: 80
---
# api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 2
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
selector:
app: api
ports:
- port: 80
targetPort: 80
多域名Ingress配置
bash
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-host-ingress
spec:
ingressClassName: nginx
rules:
# blog.example.com -> blog-service
- host: blog.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: blog-service
port:
number: 80
# api.example.com -> api-service
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
验证测试
bash
bash
#测试不同域名的路由
curl -H "Host: blog.example.com" http://<ExternalIP>/
curl -H "Host: api.example.com" http://<ExternalIP>/
# 预期:返回各自后端服务的内容,实现基于域名的虚拟主机功能
5.2超时时间与注解配置
常用超时注解
bash
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
# 连接超时(默认 60s)
nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
# 读取超时(默认 60s)
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
# 发送超时(默认 60s)
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
# 发送超时(默认 60s)
nginx.ingress.kubernetes.io/send-timeout: "60"
# 代理缓冲启用
nginx.ingress.kubernetes.io/proxy-buffering: "on"
# WebSocket 支持
nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"
注解配置场景
使用场景:当后端服务响应较慢时,可能导致网关超时。此时可通过注解调整超时参数解决。
|-----------------------|---------|------------|------------|
| 注解 | 默认值 | 说明 | 适用 |
| proxy-connect-timeout | 60s | 后端服务器连接超时 | 慢启动后端 |
| proxy-read-timeout | 60s | 后端响应超时 | 大文件传输、复杂查询 |
| proxy-send-timeout | 60s | 发送请求到后端的超时 | 慢后端处理 |
全局配置vs单条规则配置
|-----------------|-------------|-------------------------------------|
| 配置方式 | 作用范围 | 配置位置 |
| Annotations | 单条Ingress规则 | Ingress资源meradara |
| ConfigMap | 全局生效 | ingress-nginx-controller的ConfeigMap |
5.3ConfugMap热更新机制
配置挂载方式对比
|--------------|-----------|--------------------|
| 挂载方式 | 热更新支持 | 说明 |
| Volume挂载 | 支持 | 修改后Nginx自动重新加载配置 |
| 环境变量注入 | 不支持 | Pod启动时注入,自改后需重启Pod |
ConfigMap配置示例
bash
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
data:
# 超时配置
proxy-connect-timeout: "30"
proxy-read-timeout: "60"
# 缓冲配置
proxy-buffering: "on"
proxy-buffers-size: "4k"
proxy-busy-buffers-size: "16k"
# 日志配置
log-format-upstream: '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
# 保持连接配置
keep-alive: "60"
keep-alive-requests: "1000"
热更新注意事项:
- 修改 ConfigMap 后,Nginx Controller 需要重新加载配置
- 可能需要 重启 Pod 或 等待同步周期 以确保配置生效
- 使用 kubectl describe 查看 Controller Pod 状态确认配置已应用
验证配置生效
bash
bash
# 查看 Controller Pod 日志
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
# 期望看到重新加载的日志
# I0324 10:30:00.123456 35 controller.go:123] Configuration changes detected,
reloadingnginx
# 进入 Pod 验证配置
kubectl exec -it -n ingress-nginx ingress-nginx-controller-xxx -- cat /
etc/nginx/nginx.conf | grep proxy_connect_timeout
总结
核心要点知识点
|----------------------------|------------------------------------------|
| 知识点 | 关键点 |
| Ingress vs Service | Ingress 基于七层(HTTP/HTTPS),支持基于域 名/路径的灵活路由 |
| Ingress Controller | ngress 规则的实际执行者,将规则转换为 Nginx 配置 |
| NodePort 模式 | 适合开发测试,使用节点端口访问 |
| LoadBalancer + MetalLB | 适合裸金属环境,MetalLB 提供 IP 分配功能 |
| 注解配置 | 单条规则级别的 Nginx 参数覆盖 |
| ConfigMap | 全局级别的 Nginx 配置,支持热更新 |
| 版本兼容性 | 部署前务必确认 K8s 与组件版本匹配 |
快速命令参考
bash
bash
# 部署 Ingress Controller
kubectl apply -f ingress-nginx-deploy.yaml
# 查看 Ingress
kubectl get ingress
# 查看 Ingress 详情
kubectl describe ingress my-ingress
# 查看 Controller 日志
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
# 查看 MetalLB IP 分配
kubectl get ipaddresspool -n metallb-system
