1. 为什么需要Ingress Controller?
在Kubernetes集群中,Ingress Controller是管理外部访问集群内部服务的核心组件。它相当于集群的"门卫",负责将外部请求路由到集群内正确的服务上。与传统的NodePort或LoadBalancer服务类型相比,Ingress提供了更强大的路由规则定义能力。
我见过太多团队直接使用NodePort暴露服务,结果导致:
- 需要记住一堆随机分配的端口号
- 缺乏统一的路由管理
- 无法实现基于主机名或路径的路由
- SSL/TLS配置需要在每个服务上单独管理
而Ingress Controller完美解决了这些问题,它允许你:
- 使用域名而非IP+端口访问服务
- 基于路径进行路由分流
- 集中管理SSL证书
- 实现金丝雀发布等高级流量管理
2. 准备工作与环境检查
2.1 确认Kubernetes版本兼容性
在安装Ingress Controller前,必须确认其与当前Kubernetes集群版本的兼容性。Nginx Ingress Controller v1.9.5要求:
- Kubernetes 1.22+
- 启用RBAC
- 网络插件已正确配置(如Calico、Flannel等)
检查集群版本:
bash复制kubectl version --short
2.2 节点资源规划
Ingress Controller作为流量入口,建议部署在专用节点上。生产环境推荐配置:
- 至少2个专用节点(避免单点故障)
- 每个节点4核CPU+8GB内存(根据预期流量调整)
- 节点打上专用标签:
kubernetes.io/ingress=nginx
为节点打标签:
bash复制kubectl label nodes <node-name> kubernetes.io/ingress=nginx
2.3 国内镜像源准备
由于国内访问registry.k8s.io可能较慢,我们需要替换为阿里云镜像:
- 控制器镜像:
registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.9.5 - Webhook证书生成器:
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794
提前拉取镜像测试:
bash复制nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.9.5
3. 安装Nginx Ingress Controller
3.1 下载部署清单
从GitHub获取v1.9.5版本的部署文件:
bash复制wget https://codeload.github.com/kubernetes/ingress-nginx/tar.gz/refs/tags/controller-v1.9.5 -O ingress-nginx-controller-v1.9.5.tar.gz
tar -zxvf ingress-nginx-controller-v1.9.5.tar.gz
关键文件路径:
code复制ingress-nginx-controller-v1.9.5/deploy/static/provider/cloud/deploy.yaml
3.2 关键配置修改
原始部署文件使用Deployment控制器,我们需要优化为更适合生产环境的配置:
3.2.1 改为DaemonSet
将Deployment改为DaemonSet,确保每个节点运行一个Ingress Controller实例:
yaml复制apiVersion: apps/v1
kind: DaemonSet # 修改为DaemonSet
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
selector:
matchLabels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
template:
# ... 其余配置保持不变 ...
为什么选择DaemonSet?
- 避免流量跨节点转发,提升性能
- 天然的高可用性,节点故障不影响其他节点流量
- 自动扩展,新增节点会自动部署Ingress实例
3.2.2 启用hostNetwork
yaml复制spec:
template:
spec:
hostNetwork: true # 添加此配置
dnsPolicy: ClusterFirstWithHostNet
使用hostNetwork的好处:
- 绕过kube-proxy,减少网络跳转
- 直接使用节点80/443端口,简化网络架构
- 提升性能,减少NAT转换
3.2.3 配置节点亲和性
yaml复制affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/ingress
operator: In
values:
- nginx
同时可以移除原有的nodeSelector配置。
3.3 应用修改后的配置
bash复制kubectl apply -f deploy.yaml
验证安装:
bash复制kubectl get pods -n ingress-nginx -o wide
kubectl get svc -n ingress-nginx
4. 生产环境优化建议
4.1 资源限制与请求
在DaemonSet配置中添加资源限制:
yaml复制resources:
limits:
cpu: "2"
memory: "2Gi"
requests:
cpu: "100m"
memory: "90Mi"
4.2 自定义配置
通过ConfigMap可以自定义Nginx行为:
yaml复制apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
data:
allow-snippet-annotations: "false"
proxy-body-size: "20m"
use-forwarded-headers: "true"
4.3 HPA自动扩缩容
虽然使用DaemonSet,但仍可基于CPU/内存配置自动扩缩容节点数量:
bash复制kubectl autoscale nodes --cpu-percent=70 --min=2 --max=10
5. 常见问题排查
5.1 镜像拉取失败
错误现象:
code复制Failed to pull image "registry.k8s.io/ingress-nginx/controller:v1.9.5"
解决方案:
- 确认已修改为阿里云镜像地址
- 检查节点网络是否能访问阿里云
- 手动拉取镜像测试
5.2 端口冲突
错误现象:
code复制0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports.
解决方案:
- 检查节点80/443端口是否被占用
- 停用占用端口的服务
- 或修改Ingress Controller使用的端口
5.3 路由规则不生效
检查步骤:
- 确认Ingress资源已正确定义
- 检查Ingress Controller日志:
bash复制kubectl logs -n ingress-nginx <pod-name>
- 验证Service后端端口匹配
6. 性能调优经验
6.1 内核参数优化
在Ingress节点上调整内核参数:
bash复制# 增加连接跟踪表大小
echo 262144 > /proc/sys/net/netfilter/nf_conntrack_max
# 提高本地端口范围
echo "1024 65535" > /proc/sys/net/ipv4/ip_local_port_range
# 优化TCP协议栈
echo "net.ipv4.tcp_tw_reuse = 1" >> /etc/sysctl.conf
sysctl -p
6.2 Nginx配置调优
通过ConfigMap调整Nginx参数:
yaml复制data:
worker-processes: "auto"
worker-connections: "65536"
keep-alive-requests: "10000"
upstream-keepalive-connections: "200"
6.3 监控与告警
建议配置的监控指标:
- 请求吞吐量(RPS)
- 平均响应时间
- 5xx错误率
- 连接数
- 带宽使用情况
示例Prometheus监控规则:
yaml复制- alert: HighErrorRate
expr: rate(nginx_ingress_controller_requests{status=~"5.."}[1m]) / rate(nginx_ingress_controller_requests[1m]) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate on {{ $labels.ingress }}"
description: "5xx error rate is {{ printf \"%.2f\" $value }}%"
7. 安全加固措施
7.1 网络策略限制
只允许Ingress节点访问后端服务:
yaml复制apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-only
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
7.2 定期证书轮换
配置自动证书更新:
yaml复制apiVersion: batch/v1
kind: CronJob
metadata:
name: cert-rotator
spec:
schedule: "0 3 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: certbot
image: certbot/certbot
args: ["renew"]
7.3 禁用危险注解
在ConfigMap中禁用不安全功能:
yaml复制data:
allow-snippet-annotations: "false"
enable-annotation-validation: "true"
8. 版本升级策略
8.1 灰度升级步骤
- 先在一个节点上测试新版本
- 逐步扩大升级范围
- 监控关键指标变化
- 全量升级或回滚
8.2 版本回退方案
保留旧版本部署文件,出现问题时可快速回退:
bash复制kubectl apply -f deploy-v1.8.0.yaml
8.3 长期支持策略
建议:
- 生产环境使用稳定版(非最新版)
- 关注官方安全公告
- 每季度评估一次升级需求
9. 真实案例分享
9.1 流量突增应对
某电商在大促期间遇到流量激增,Ingress节点CPU达到90%。我们通过:
- 增加worker-processes数量
- 调整keepalive参数
- 临时增加节点数量
成功将CPU负载降至40%以下。
9.2 配置错误排查
某次更新后部分路由失效,通过以下步骤定位:
- 检查Ingress资源语法
- 查看Controller日志
- 检查Service端口定义
发现是Service的port名称与Ingress中不匹配导致。
9.3 性能瓶颈分析
使用pprof工具分析性能瓶颈:
bash复制kubectl port-forward -n ingress-nginx <pod-name> 10254:10254
go tool pprof http://localhost:10254/debug/pprof/profile
发现大部分CPU时间消耗在TLS握手,于是启用SSL会话缓存:
yaml复制data:
ssl-session-cache: "true"
ssl-session-cache-size: "50m"
ssl-session-timeout: "1h"
10. 最佳实践总结
经过多个生产环境部署经验,我总结出以下最佳实践:
-
部署架构:
- 使用DaemonSet而非Deployment
- 启用hostNetwork模式
- 专用节点+亲和性调度
-
性能优化:
- 合理设置worker_processes
- 调整keepalive参数
- 内核参数调优
-
高可用保障:
- 至少2个节点部署
- 多可用区分布
- 定期健康检查
-
安全防护:
- 限制管理接口访问
- 定期轮换证书
- 禁用危险注解
-
监控告警:
- 核心指标监控
- 自动扩缩容
- 日志集中收集
这套配置在我们多个生产集群中稳定运行,支撑了日均数亿请求。关键是要根据实际业务特点持续调整优化,而不是简单套用默认配置。