1. Nginx Ingress Controller 部署概述
在 Kubernetes 集群中,Ingress Controller 是实现外部访问集群内部服务的关键组件。Nginx Ingress Controller 作为最流行的实现方案之一,通过 Nginx 反向代理和负载均衡能力,为集群内的服务提供统一的 HTTP/HTTPS 入口。
1.1 为什么选择 Nginx Ingress Controller
Nginx Ingress Controller 相比其他方案具有以下优势:
- 成熟稳定:基于 Nginx 这一久经考验的 Web 服务器,性能稳定可靠
- 功能丰富:支持 URL 重写、流量切分、熔断等高级功能
- 社区活跃:由 Kubernetes 官方维护,更新及时,文档完善
- 配置灵活:通过 Kubernetes Ingress 资源和注解实现细粒度控制
1.2 部署架构设计
本次部署采用 DaemonSet + hostNetwork 模式,主要考虑:
- 高可用性:每个节点运行一个实例,避免单点故障
- 性能优化:直接使用主机网络栈,减少网络开销
- 端口管理:直接绑定主机 80/443 端口,简化网络配置
- 负载均衡:结合外部负载均衡器(如 HAProxy)实现流量分发
2. 部署准备
2.1 环境要求
- 已部署 Kubernetes 1.32 集群(参考本系列前五篇)
- 所有节点已安装 containerd 容器运行时
- Helm 3.x 已安装并配置完成
- 节点间网络互通,防火墙已放行必要端口
2.2 工具准备
bash复制# 检查 Helm 版本
helm version --short
# 预期输出:v3.12.0
# 检查 kubectl 配置
kubectl cluster-info
3. 详细部署步骤
3.1 下载 Helm Chart
由于国内网络环境限制,建议先在外网机器下载 chart 后传输到集群:
bash复制# 添加官方仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# 下载 chart 包(指定版本 4.14.1)
helm pull ingress-nginx/ingress-nginx --version 4.14.1 --destination /tmp/
# 传输到集群主节点
scp /tmp/ingress-nginx-4.14.1.tgz k8sadmin@192.168.1.11:/tmp/
注意:如果无法访问外网,可手动下载 chart 包并上传
3.2 预拉取镜像
使用国内镜像源加速镜像拉取:
bash复制# 在所有节点执行
sudo crictl pull m.daocloud.io/registry.k8s.io/ingress-nginx/controller:v1.12.0
sudo crictl pull m.daocloud.io/registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.5.0
镜像说明:
controller:v1.12.0:主控制器镜像kube-webhook-certgen:v1.5.0:证书生成工具
3.3 Helm 安装基础版本
bash复制helm install ingress-nginx /tmp/ingress-nginx-4.14.1.tgz \
--namespace ingress-nginx --create-namespace \
--set controller.image.registry=m.daocloud.io/registry.k8s.io \
--set controller.image.image=ingress-nginx/controller \
--set controller.image.tag=v1.12.0 \
--set controller.image.digest='' \
--set controller.admissionWebhooks.patch.image.registry=m.daocloud.io/registry.k8s.io \
--set controller.admissionWebhooks.patch.image.image=ingress-nginx/kube-webhook-certgen \
--set controller.admissionWebhooks.patch.image.tag=v1.5.0 \
--set controller.admissionWebhooks.patch.image.digest=''
关键参数说明:
--namespace:指定安装的命名空间--create-namespace:自动创建命名空间controller.image.*:配置控制器镜像地址admissionWebhooks.patch.image.*:配置证书生成工具镜像
4. 优化部署模式
4.1 切换为 DaemonSet + hostNetwork
默认 Deployment 模式不适合生产环境,我们调整为 DaemonSet:
bash复制# 删除默认 Deployment
kubectl delete deploy ingress-nginx-controller -n ingress-nginx
# 应用 DaemonSet 配置
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
spec:
selector:
matchLabels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
serviceAccountName: ingress-nginx
terminationGracePeriodSeconds: 300
nodeSelector:
kubernetes.io/os: linux
tolerations:
- operator: Exists
containers:
- name: controller
image: m.daocloud.io/registry.k8s.io/ingress-nginx/controller:v1.12.0
args:
- /nginx-ingress-controller
- --election-id=ingress-nginx-leader
- --controller-class=k8s.io/ingress-nginx
- --ingress-class=nginx
- --configmap=\$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
securityContext:
capabilities:
drop: [ALL]
add: [NET_BIND_SERVICE]
runAsUser: 101
allowPrivilegeEscalation: true
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: LD_PRELOAD
value: /usr/local/lib/libmimalloc.so
ports:
- name: http
containerPort: 80
hostPort: 80
- name: https
containerPort: 443
hostPort: 443
- name: webhook
containerPort: 8443
livenessProbe:
httpGet:
path: /healthz
port: 10254
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /healthz
port: 10254
initialDelaySeconds: 10
periodSeconds: 10
volumeMounts:
- name: webhook-cert
mountPath: /usr/local/certificates/
readOnly: true
volumes:
- name: webhook-cert
secret:
secretName: ingress-nginx-admission
EOF
关键配置解析:
hostNetwork: true:使用主机网络模式dnsPolicy: ClusterFirstWithHostNet:DNS 解析策略tolerations:确保在所有节点运行hostPort:直接绑定主机端口securityContext:配置必要的安全权限
4.2 防火墙配置
在所有节点开放 HTTP/HTTPS 端口:
bash复制for ip in 11 12 13 14 15 16; do
ssh k8sadmin@192.168.1.$ip "sudo firewall-cmd --permanent --add-port=80/tcp --add-port=443/tcp && sudo firewall-cmd --reload"
done
5. 验证部署
5.1 检查 Pod 状态
bash复制kubectl get pods -n ingress-nginx -o wide
预期输出(每个节点一个 Pod):
code复制NAME READY STATUS RESTARTS AGE IP NODE
ingress-nginx-controller-abc 1/1 Running 0 5m 192.168.1.11 node1
ingress-nginx-controller-def 1/1 Running 0 5m 192.168.1.12 node2
...
5.2 测试基本功能
bash复制# 创建测试服务
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80
# 创建测试 Ingress
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: test.192.168.1.11.nip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
EOF
# 访问测试
curl -H "Host: test.192.168.1.11.nip.io" http://192.168.1.11
6. 高级配置
6.1 代理外部服务
将非 Kubernetes 管理的服务通过 Ingress 暴露:
yaml复制# 创建无 selector Service
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
ports:
- port: 3000
---
# 手动创建 Endpoints
apiVersion: v1
kind: Endpoints
metadata:
name: external-service
subsets:
- addresses:
- ip: 192.168.1.22 # 外部服务 IP
ports:
- port: 3000
---
# 创建 Ingress 规则
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: external-ingress
spec:
ingressClassName: nginx
rules:
- host: external.192.168.1.11.nip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: external-service
port:
number: 3000
6.2 常用注解配置
| 注解 | 描述 | 示例值 |
|---|---|---|
nginx.ingress.kubernetes.io/rewrite-target |
URL 重写目标 | /$2 |
nginx.ingress.kubernetes.io/proxy-body-size |
请求体大小限制 | 50m |
nginx.ingress.kubernetes.io/ssl-redirect |
强制 HTTPS 跳转 | true |
nginx.ingress.kubernetes.io/cors-allow-origin |
CORS 配置 | * |
nginx.ingress.kubernetes.io/configuration-snippet |
自定义 Nginx 配置 | more_set_headers "X-Custom-Header: value"; |
6.3 性能调优建议
-
启用动态 TLS 记录:
yaml复制annotations: nginx.ingress.kubernetes.io/dynamic-tls-records: "true" -
调整 worker 进程数:
yaml复制controller: config: worker-processes: "4" -
启用 Brotli 压缩:
yaml复制controller: config: use-brotli: "true"
7. 故障排查
7.1 常见问题及解决方案
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| Pod 处于 CrashLoopBackOff | 镜像拉取失败 | 检查镜像地址和网络连通性 |
| 访问返回 503 | 后端服务不可用 | 检查 Service 和 Endpoints |
| HTTPS 证书错误 | 证书配置问题 | 检查 Secret 和 TLS 配置 |
| 重定向循环 | SSL 配置错误 | 检查 ssl-redirect 注解 |
7.2 日志查看
bash复制# 查看控制器日志
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
# 查看 Nginx 配置
kubectl exec -n ingress-nginx -it <pod-name> -- cat /etc/nginx/nginx.conf
7.3 监控指标
Nginx Ingress Controller 暴露了丰富的 Prometheus 指标,可以通过以下方式查看:
bash复制# 访问指标端点
curl http://<ingress-ip>:10254/metrics
关键指标包括:
nginx_ingress_controller_requests:请求总数nginx_ingress_controller_request_duration_seconds:请求延迟nginx_ingress_controller_connections:当前连接数
8. 生产环境建议
- 多副本部署:即使使用 DaemonSet,也应确保跨可用区部署
- 资源限制:为控制器设置合理的资源请求和限制
- HPA 配置:根据 CPU/内存使用率配置自动扩缩
- 定期升级:关注安全更新,定期升级到新版本
- 备份配置:定期备份重要的 Ingress 资源配置
9. 后续步骤
完成 Nginx Ingress Controller 部署后,可以继续:
- 配置 TLS 证书实现 HTTPS 加密
- 集成监控系统收集指标
- 设置访问日志分析和告警
- 配置 WAF 规则增强安全性
在实际使用中,我发现 DaemonSet 模式虽然资源占用较高,但在流量突发时表现更加稳定。特别是在节点故障时,其他节点可以立即接管流量,无需等待 Kubernetes 重新调度 Pod。