手把手教你用Nginx Ingress Controller在本地K3s集群暴露Web服务(含HostNetwork配置)
实战指南在K3s集群中使用Nginx Ingress Controller高效暴露Web服务当你需要在本地开发环境或私有化部署场景中快速暴露Kubernetes服务时传统的NodePort或云厂商LoadBalancer方案往往存在各种限制。本文将带你深入探索一种高性能的替代方案——通过DaemonSet结合HostNetwork模式部署Nginx Ingress Controller直接利用宿主机网络栈实现零中间层的服务暴露。1. 环境准备与架构解析在开始动手之前我们需要先理解这种部署模式的核心价值。与常规的NodePort方式相比HostNetwork模式省去了端口映射环节请求直接从宿主机的80/443端口进入减少了网络跳转显著提升了性能表现。基础环境要求已部署的K3s集群v1.20至少两个工作节点一个作为边缘节点kubectl命令行工具配置完成本地域名解析管理权限这种架构特别适合以下场景开发测试环境需要频繁访问服务边缘计算场景下的服务暴露无法使用云厂商LoadBalancer的私有化部署对网络性能有较高要求的应用提示K3s默认已包含Traefik作为Ingress Controller我们需要先禁用它以避免端口冲突。2. 部署Nginx Ingress Controller让我们从最核心的部署环节开始。我们将使用DaemonSet确保每个边缘节点运行一个Ingress Controller实例并通过HostNetwork直接绑定宿主机端口。2.1 创建专用边缘节点首先我们需要标记将运行Ingress Controller的节点kubectl label nodes your-node-name ingress-readytrue这个标签将在后续的DaemonSet配置中被用作nodeSelector的筛选条件。2.2 部署Ingress Controller创建以下YAML文件nginx-ingress-daemonset.yamlapiVersion: apps/v1 kind: DaemonSet metadata: name: nginx-ingress-controller namespace: ingress-nginx spec: selector: matchLabels: app: ingress-nginx template: metadata: labels: app: ingress-nginx spec: hostNetwork: true nodeSelector: ingress-ready: true containers: - name: nginx-ingress-controller image: registry.k8s.io/ingress-nginx/controller:v1.8.1 args: - /nginx-ingress-controller - --configmap$(POD_NAMESPACE)/nginx-configuration - --tcp-services-configmap$(POD_NAMESPACE)/tcp-services - --udp-services-configmap$(POD_NAMESPACE)/udp-services - --publish-service$(POD_NAMESPACE)/ingress-nginx-controller - --annotations-prefixnginx.ingress.kubernetes.io ports: - name: http containerPort: 80 hostPort: 80 - name: https containerPort: 443 hostPort: 443 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace应用这个配置kubectl create namespace ingress-nginx kubectl apply -f nginx-ingress-daemonset.yaml关键参数解析参数作用必要性hostNetwork使用宿主机网络栈必需hostPort绑定宿主机端口必需nodeSelector指定运行节点推荐3. 验证与配置调优部署完成后我们需要验证服务是否正常运行并进行必要的性能调优。3.1 基础验证检查Pod运行状态kubectl get pods -n ingress-nginx -o wide预期输出应显示Pod状态为Running并且运行在我们标记的节点上。3.2 性能调优配置创建ConfigMap进行基础配置优化apiVersion: v1 kind: ConfigMap metadata: name: nginx-configuration namespace: ingress-nginx data: worker-processes: 4 keep-alive: 75 upstream-keepalive-connections: 100应用配置后Ingress Controller会自动重新加载Nginx配置。4. 服务暴露实战现在我们来部署一个示例应用并通过Ingress暴露它。4.1 部署示例应用创建deployment和serviceapiVersion: apps/v1 kind: Deployment metadata: name: webapp spec: replicas: 3 selector: matchLabels: app: webapp template: metadata: labels: app: webapp spec: containers: - name: webapp image: nginx:alpine ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: webapp-service spec: selector: app: webapp ports: - protocol: TCP port: 80 targetPort: 804.2 创建Ingress资源定义Ingress规则apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: webapp-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: webapp.local http: paths: - path: / pathType: Prefix backend: service: name: webapp-service port: number: 804.3 测试访问在本地hosts文件中添加解析your-node-ip webapp.local现在你可以通过浏览器访问http://webapp.local应该能看到Nginx默认页面。5. 高级配置与问题排查在实际使用中你可能需要处理更复杂的场景和问题。5.1 TLS证书配置要为服务添加HTTPS支持首先准备证书并创建Secretkubectl create secret tls webapp-tls --key tls.key --cert tls.crt -n default然后更新Ingress配置spec: tls: - hosts: - webapp.local secretName: webapp-tls rules: - host: webapp.local http: paths: - path: / backend: serviceName: webapp-service servicePort: 805.2 常见问题排查问题1无法访问服务检查Pod是否正常运行验证节点防火墙是否放行80/443端口确认hosts文件配置正确问题2502 Bad Gateway检查后端服务是否健康验证Service的selector是否匹配Pod标签查看Ingress Controller日志kubectl logs -n ingress-nginx ingress-pod-name问题3端口冲突确保K3s默认的Traefik已禁用检查宿主机80/443端口未被其他进程占用6. 架构优化建议在生产环境中使用时可以考虑以下优化措施多节点部署在多个边缘节点部署Ingress Controller配合DNS轮询实现简单负载均衡健康检查配置Liveness和Readiness探针确保服务可用性资源限制为Ingress Controller设置合理的资源请求和限制日志收集将访问日志集中收集分析监控告警部署Prometheus监控指标这种架构虽然简单高效但也要注意其局限性每个节点只能运行一个Ingress Controller实例节点故障时需要手动切换DNS缺乏云厂商LB提供的高级功能如WAF对于需要更高可用性的场景可以考虑在架构前层添加Keepalived或HAProxy实现VIP漂移。