Ingress 与 Ingress-Controller:K8s 七层 HTTP 反向代理技术详解与实践

一、Service四层负载均衡与Ingress七层代理的技术对比

Kubernetes中的Service和Ingress在集群网络架构中扮演着不同但互补的角色,两者在OSI模型中的层级定位和功能范围存在本质差异。Service工作在OSI模型的第四层(传输层),提供TCP/UDP协议的负载均衡能力,而Ingress则工作在第七层(应用层),实现HTTP/HTTPS协议的智能路由和流量管理。

从技术原理角度分析,Service四层负载均衡通过kube-proxy组件实现,主要解决Pod发现和负载均衡问题。当Service创建时,kube-proxy会在集群节点上生成iptables或IPVS规则,将访问Service虚拟IP的流量转发到后端Pod。Service支持ClusterIP、NodePort和LoadBalancer三种类型,分别适用于集群内部访问、节点端口暴露和云平台负载均衡器场景。然而,Service无法识别HTTP/HTTPS协议内容,只能基于IP地址和端口进行流量分发,无法实现基于域名、路径或HTTP头的智能路由。

Ingress七层HTTP反向代理则提供了更高级的流量管理能力。Ingress资源定义了HTTP/HTTPS路由规则,包括域名路由、路径转发、SSL证书配置等,而Ingress-Controller(如nginx-ingress-controller)则是实际执行这些规则的组件。Ingress-Controller通常以Deployment形式部署在集群中,通过监听Ingress资源变化动态更新其内部配置(如Nginx配置文件),实现七层流量管理。与Service相比,Ingress能够理解HTTP/HTTPS协议内容,提供基于域名、路径、HTTP头的智能路由,支持SSL终止、URL重写、会话保持等高级功能。

|----------|-------------------|-------------------|
| 特性对比 | Service四层负载均衡 | Ingress七层反向代理 |
| OSI层级 | 第四层(传输层) | 第七层(应用层) |
| 支持协议 | TCP/UDP | HTTP/HTTPS |
| 路由能力 | 基于IP和端口 | 基于域名、路径、HTTP头 |
| 负载均衡算法 | 轮询、随机、最少连接 | 支持会话保持、权重分配等 |
| SSL处理 | 不支持SSL终止 | 支持SSL终止和证书管理 |
| 典型应用场景 | 集群内部服务发现 | 外部HTTP/HTTPS流量管理 |

在功能范围方面,Service主要解决集群内部的服务发现和负载均衡问题,为Pod提供稳定的访问入口。当Pod重启或重新调度时,Service能够自动更新后端端点,确保服务连续性。然而,Service的功能相对基础,无法满足复杂的HTTP/HTTPS路由需求,如基于域名的虚拟主机、基于路径的流量分发、SSL证书管理等。

Ingress则专门针对HTTP/HTTPS流量管理设计,提供了丰富的路由和流量控制功能。Ingress可以实现基于域名的虚拟主机(如api.example.com和web.example.com路由到不同后端服务),基于URL路径的流量分发(如example.com/api路由到API服务,example.com/web路由到Web服务),SSL证书管理和HTTPS重定向,URL重写和重定向,会话保持和粘性会话,速率限制和访问控制,灰度发布和金丝雀测试等高级功能。这些功能使得Ingress成为管理外部HTTP/HTTPS流量的理想选择。

从适用场景来看,Service适合集群内部的服务发现和负载均衡,特别是对于非HTTP/HTTPS协议的服务(如数据库、缓存、消息队列等)。Service的ClusterIP类型为集群内部服务提供稳定的虚拟IP,NodePort类型通过节点端口暴露服务,LoadBalancer类型则利用云平台负载均衡器提供外部访问能力。

Ingress则专门用于管理外部HTTP/HTTPS流量访问集群内部服务。当需要通过域名访问集群内部服务时,Ingress是最佳选择。Ingress可以配置多个域名和路径规则,将外部流量精确路由到相应的内部服务。同时,Ingress支持SSL证书管理,可以自动处理HTTPS流量,提供安全的访问体验。对于需要复杂HTTP/HTTPS路由功能的场景,如微服务架构中的API网关、多租户应用、内容分发等,Ingress是不可或缺的组件。

Service和Ingress在Kubernetes网络架构中形成互补关系。Service提供基础的四层负载均衡和服务发现能力,Ingress则提供高级的七层HTTP/HTTPS路由和流量管理能力。在实际应用中,通常先为后端Pod创建Service,提供稳定的访问入口和负载均衡,然后创建Ingress资源,配置HTTP/HTTPS路由规则,将外部流量路由到相应的Service。这种分层架构使得Kubernetes能够同时满足内部服务发现和外部HTTP/HTTPS流量管理的需求。

二、Ingress资源与Ingress-Controller的概念区分与协作机制

Kubernetes中的Ingress资源与Ingress-Controller是两个经常被混淆但本质完全不同的概念。准确理解两者的区别和协作机制,对于正确配置和使用Kubernetes七层HTTP反向代理功能至关重要。

Ingress资源是Kubernetes中的API对象,本质上是一组HTTP/HTTPS路由规则的定义。Ingress资源本身不提供任何流量路由功能,它只是声明了"外部流量应该如何被路由到集群内部服务"的规则。从技术角度看,Ingress资源类似于Nginx配置文件中的server和location块,定义了域名、路径、后端服务等路由规则。Ingress资源通过YAML文件定义,包含apiVersion、kind、metadata和spec四个主要部分。其中spec字段定义了具体的路由规则,包括host(域名)、paths(路径规则)、backend(后端服务)和tls(SSL证书配置)等。

Ingress-Controller则是实际执行Ingress规则的控制器组件,通常以Deployment形式部署在Kubernetes集群中。Ingress-Controller可以理解为"路由执行器",它负责监听Ingress资源的变化,将Ingress规则转换为具体的反向代理配置(如Nginx配置文件),并实际处理外部HTTP/HTTPS流量。Ingress-Controller内部运行着一个成熟的七层负载均衡软件,如Nginx、Traefik或HAProxy,这些软件负责接收外部HTTP/HTTPS请求,根据Ingress规则将请求转发到相应的后端服务。

从功能职责角度分析,Ingress资源主要负责"定义路由规则",包括:

  • 域名路由规则:指定哪些域名应该被路由到哪些后端服务
  • 路径转发规则:定义URL路径如何映射到后端服务
  • SSL证书配置:指定HTTPS使用的证书和私钥
  • 高级路由特性:如URL重写、会话保持、速率限制等

Ingress-Controller则主要负责"执行路由规则",包括:

  • 监听Ingress资源变化:通过Kubernetes API Watch机制实时监听Ingress资源的变化
  • 生成代理配置:将Ingress规则转换为具体的反向代理配置(如nginx.conf)
  • 加载配置并重载服务:动态加载新配置并重载代理服务,实现零中断更新
  • 处理HTTP/HTTPS流量:实际接收外部HTTP/HTTPS请求,根据规则转发到后端服务
  • 健康检查和故障转移:监控后端服务健康状态,实现故障转移和负载均衡

Ingress资源与Ingress-Controller的协作机制遵循"定义-监听-转换-执行"的工作流程。首先,用户创建Ingress资源,定义HTTP/HTTPS路由规则。然后,Ingress-Controller通过Kubernetes API Watch机制监听Ingress资源的变化。当检测到Ingress资源变化时,Ingress-Controller将Ingress规则转换为具体的反向代理配置(如Nginx配置文件)。接着,Ingress-Controller动态加载新配置并重载代理服务,确保新规则生效。最后,Ingress-Controller实际处理外部HTTP/HTTPS流量,根据配置的规则将请求转发到相应的后端Service。

|----------|-------------------|--------------------------|
| 协作环节 | Ingress资源职责 | Ingress-Controller职责 |
| 规则定义 | 定义域名、路径、后端服务等路由规则 | 不参与规则定义 |
| 变化监听 | 被动监听,无主动行为 | 主动监听Ingress资源变化 |
| 配置转换 | 不参与配置转换 | 将Ingress规则转换为代理配置 |
| 服务执行 | 不参与流量处理 | 实际处理HTTP/HTTPS流量 |
| 健康管理 | 不参与健康检查 | 监控后端服务健康状态 |

在实际部署中,Ingress-Controller通常以Deployment形式运行在集群中,并通过Service暴露给外部流量。常见的Ingress-Controller实现包括nginx-ingress-controller、traefik、haproxy-ingress等。其中nginx-ingress-controller是最常用的选择,它基于Nginx构建,提供了高性能和丰富的功能特性。部署nginx-ingress-controller时,需要创建相应的Deployment、Service、ConfigMap和RBAC权限配置,确保Ingress-Controller有足够的权限操作Kubernetes资源。

Ingress资源与Ingress-Controller的常见混淆点主要体现在三个方面:一是认为Ingress资源本身就能提供路由功能,忽略了Ingress-Controller的必要性;二是将Ingress-Controller等同于Ingress资源,混淆了"规则定义"与"规则执行"的区别;三是认为部署了Ingress-Controller后就能自动处理所有流量,忽略了Ingress资源定义的必要性。

为了避免这些混淆,需要明确:Ingress资源只是路由规则的"定义",必须配合Ingress-Controller才能实际工作;Ingress-Controller只是路由规则的"执行器",必须有Ingress资源定义才能知道如何路由流量;两者缺一不可,必须协同工作才能实现完整的HTTP/HTTPS反向代理功能。

Ingress资源与Ingress-Controller的协作关系可以通过一个类比来理解:Ingress资源类似于交通规则(如"车辆靠右行驶"、"限速60公里"等),而Ingress-Controller类似于交通警察,负责执行这些规则。没有交通规则,交通警察不知道如何指挥交通;没有交通警察,交通规则只是一纸空文。只有两者协同工作,才能保证交通的有序运行。

在实际应用中,Ingress资源与Ingress-Controller的协作关系体现为:用户创建Ingress资源定义路由规则,Ingress-Controller监听这些规则并转换为具体配置,然后实际执行这些规则处理HTTP/HTTPS流量。这种协作机制使得Kubernetes能够提供灵活、强大的HTTP/HTTPS反向代理功能,满足各种复杂的流量管理需求。

三、nginx-ingress-controller部署架构与实施步骤

nginx-ingress-controller是Kubernetes中最常用的Ingress-Controller实现,它基于Nginx构建,提供了高性能和丰富的功能特性。部署nginx-ingress-controller需要系统化的规划和实施,包括环境准备、部署实施、验证测试和生产优化等多个环节。

部署架构设计

nginx-ingress-controller的部署架构需要考虑多个因素,包括高可用性、性能、安全性和可维护性。在生产环境中,推荐采用Deployment+LoadBalancer的部署模式,通过Kubernetes Deployment管理nginx-ingress-controller的Pod副本,利用云平台LoadBalancer服务暴露外部访问入口。这种架构提供了自动扩缩容、故障自愈和负载均衡能力,适合生产环境的高可用要求。

部署架构的关键组件包括:

  • Deployment:管理nginx-ingress-controller的Pod副本,支持滚动更新和自动扩缩容
  • Service:LoadBalancer类型服务,为nginx-ingress-controller提供外部访问入口和负载均衡
  • ConfigMap:存储nginx-ingress-controller的配置参数,如负载均衡算法、超时时间等
  • RBAC权限:包括ServiceAccount、ClusterRole和ClusterRoleBinding,确保nginx-ingress-controller有足够的权限操作Kubernetes资源
  • 优先级和抢占:通过PriorityClass确保nginx-ingress-controller在资源紧张时优先调度

环境准备与前提条件

部署nginx-ingress-controller前需要完成以下环境准备工作:

  1. Kubernetes集群版本检查:nginx-ingress-controller要求Kubernetes集群版本在1.16及以上。使用以下命令检查集群版本:

kubectl version --short

  1. 网络插件验证:确保集群中已安装并正常运行网络插件(如Calico、Flannel)。使用以下命令检查网络插件Pod状态:

kubectl get pods -n kube-system -l k8s-app=calico-node

  1. LoadBalancer支持准备:如果使用云平台LoadBalancer服务,需要确保云平台支持LoadBalancer类型服务。对于裸金属环境,可以部署MetalLB提供LoadBalancer功能。
  2. 命名空间创建:为nginx-ingress-controller创建专用命名空间:

kubectl create namespace ingress-nginx

  1. Helm仓库准备(可选):如果使用Helm部署,需要添加nginx-ingress-controller的Helm仓库:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginxhelm repo update

部署实施步骤

nginx-ingress-controller的部署可以通过Helm或直接使用YAML文件两种方式实现。这里以YAML文件部署为例,提供详细的实施步骤:

  1. 下载部署文件:从官方GitHub仓库下载nginx-ingress-controller的部署文件:

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml

  1. 修改部署配置:根据实际需求修改deploy.yaml文件中的关键参数:

修改Deployment的副本数replicas: 3# 添加资源限制resources: limits: cpu: 500m memory: 500Mi requests: cpu: 100m memory: 90Mi# 配置hostNetworkhostNetwork: true# 配置DNS策略dnsPolicy: ClusterFirstWithHostNet# 添加节点选择器nodeSelector: kubernetes.io/os: linux node-role.kubernetes.io/ingress: "true"# 添加容忍度tolerations:- key: "node-role.kubernetes.io/control-plane" operator: "Exists" effect: "NoSchedule"

  1. 部署nginx-ingress-controller:应用修改后的部署文件:

kubectl apply -f deploy.yaml

  1. 验证部署状态:检查nginx-ingress-controller的Pod和Service状态:

kubectl get pods -n ingress-nginxkubectl get svc -n ingress-nginx

验证测试方法

部署完成后,需要进行全面的验证测试,确保nginx-ingress-controller正常工作:

  1. Pod状态验证:检查所有nginx-ingress-controller Pod是否处于Running状态:

kubectl get pods -n ingress-nginx -o wide

  1. Service端点验证:检查LoadBalancer Service是否分配了外部IP地址:

kubectl get svc ingress-nginx-controller -n ingress-nginx

  1. 基本功能测试:创建一个简单的测试应用和Service,然后创建Ingress资源进行访问测试:

创建测试应用kubectl create deployment nginx --image=nginxkubectl expose deployment nginx --port=80 --type=ClusterIP# 创建Ingress资源cat <<EOF | kubectl apply -f -apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: test-ingressspec: rules: - host: test.example.com http: paths: - path: / pathType: Prefix backend: service: name: nginx port: number: 80EOF

  1. 访问测试:配置本地hosts文件将test.example.com指向LoadBalancer的外部IP,然后使用curl命令测试访问:

curl -H "Host: test.example.com" http://<loadbalancer-ip>

生产环境优化

在生产环境中部署nginx-ingress-controller时,需要进行以下优化配置:

  1. 资源优化:根据实际负载调整Pod的资源请求和限制,建议为每个Pod分配2-4核CPU和4-8GB内存。使用HorizontalPodAutoscaler实现自动扩缩容:

apiVersion: autoscaling/v2kind: HorizontalPodAutoscalermetadata: name: ingress-nginx-controller namespace: ingress-nginxspec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: ingress-nginx-controller minReplicas: 3 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 80

  1. 性能优化:调整nginx-ingress-controller的性能参数,包括worker进程数、连接数、超时时间等:

apiVersion: v1kind: ConfigMapmetadata: name: nginx-configuration namespace: ingress-nginxdata: worker-processes: "auto" worker-connections: "1024" worker-cpu-affinity: "true" keepalive-timeout: "60" keepalive-requests: "100" proxy-connect-timeout: "5" proxy-send-timeout: "60" proxy-read-timeout: "60" client-max-body-size: "1m" proxy-body-size: "1m"

  1. 高可用优化:部署多个nginx-ingress-controller实例并分布在不同节点上,使用反亲和性确保实例分布在不同节点:

affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app.kubernetes.io/name operator: In values: - ingress-nginx topologyKey: "kubernetes.io/hostname"

  1. 安全优化:配置TLS协议版本、密码套件、WAF规则等安全设置:

apiVersion: v1kind: ConfigMapmetadata: name: nginx-configuration namespace: ingress-nginxdata: ssl-protocols: "TLSv1.2 TLSv1.3" ssl-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256" use-forwarded-headers: "true" use-proxy-protocol: "true" enable-real-ip: "true" proxy-real-ip-cidr: "10.0.0.0/8"

  1. 监控和日志优化:配置Prometheus监控指标和日志收集,确保nginx-ingress-controller的可观测性:

Prometheus监控配置apiVersion: v1kind: Servicemetadata: name: ingress-nginx-controller-metrics namespace: ingress-nginx annotations: prometheus.io/scrape: "true" prometheus.io/port: "10254" prometheus.io/scheme: "http"spec: ports: - name: metrics port: 10254 protocol: TCP selector: app.kubernetes.io/name: ingress-nginx type: ClusterIP

通过以上部署架构和实施步骤,可以成功部署并验证nginx-ingress-controller,为Kubernetes集群提供高性能、高可用的七层HTTP反向代理服务。生产环境中的优化配置确保了nginx-ingress-controller的稳定性、安全性和可维护性。

四、Ingress规则配置实战:域名路由、路径转发与SSL证书

Ingress规则配置是Kubernetes七层HTTP反向代理的核心功能,通过精心设计的路由规则可以实现灵活、高效的流量管理。本节将详细介绍各类Ingress规则的配置方法和实战案例,包括域名路由、路径转发、SSL证书配置、URL重写和高级功能等。

域名路由配置

域名路由是Ingress最基础的功能,它允许根据请求的Host头将流量分发到不同的后端服务。这种配置特别适合多租户应用或微服务架构,可以通过不同的域名访问不同的服务。

域名路由配置的基本结构如下:

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: multi-host-ingressspec: rules: - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api-service port: number: 80 - host: web.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 80

这个配置示例实现了两个域名的路由:api.example.com的请求被路由到api-service,web.example.com的请求被路由到web-service。pathType字段指定了路径匹配类型,Prefix表示前缀匹配,Exact表示精确匹配,ImplementationSpecific表示匹配方式取决于具体的Ingress-Controller实现。

域名路由还支持通配符域名,使用*.example.com可以匹配所有example.com的子域名:

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: wildcard-ingressspec: rules: - host: "*.example.com" http: paths: - path: / pathType: Prefix backend: service: name: default-service port: number: 80

路径转发配置

路径转发允许在同一域名下根据URL路径将流量分发到不同的后端服务。这种配置非常适合单体应用的模块化拆分或微服务架构中的API版本管理。

路径转发配置的基本结构如下:

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: path-based-ingressspec: rules: - host: example.com http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 80 - path: /web pathType: Prefix backend: service: name: web-service port: number: 80 - path: /static pathType: Prefix backend: service: name: static-service port: number: 80

这个配置示例实现了example.com域名的路径转发:/api路径的请求被路由到api-service,/web路径的请求被路由到web-service,/static路径的请求被路由到static-service。这种配置使得单个域名可以支持多个后端服务,提高了资源利用率和用户体验。

路径转发支持正则表达式匹配,可以通过注解实现更复杂的路径匹配规则:

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: regex-path-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /2 nginx.ingress.kubernetes.io/use-regex: "true"spec: rules: - host: example.com http: paths: - path: /api(/\|)(.*) pathType: Prefix backend: service: name: api-service port: number: 80

这个配置使用正则表达式匹配/api路径,并通过rewrite-target注解将请求重写到后端服务。正则表达式(/|)(.\*)匹配/api/或/api开头的路径,2表示第二个捕获组的内容,实现了路径的重写。

SSL证书配置

SSL证书配置是Ingress的重要功能,它允许Ingress-Controller处理HTTPS流量,提供安全的访问体验。Ingress支持SSL终止,即Ingress-Controller负责处理HTTPS连接,然后将解密后的HTTP流量转发给后端服务。

SSL证书配置需要先创建包含证书和私钥的Secret:

kubectl create secret tls tls-secret --cert=tls.crt --key=tls.key -n default

然后在Ingress资源中引用该Secret:

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: tls-ingressspec: tls: - hosts: - example.com secretName: tls-secret rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: secure-service port: number: 80

这个配置示例为example.com域名配置了SSL证书,Ingress-Controller会自动加载证书并配置HTTPS监听器。可以配置多个域名的SSL证书:

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: multi-tls-ingressspec: tls: - hosts: - example.com secretName: example-tls-secret - hosts: - api.example.com secretName: api-tls-secret rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 80 - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: api-service port: number: 80

URL重写配置

URL重写是Ingress的高级功能,它允许在转发请求前修改URL路径。这种功能特别适合后端服务路径与前端访问路径不一致的场景。

URL重写配置通过nginx.ingress.kubernetes.io/rewrite-target注解实现:

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: rewrite-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /2 nginx.ingress.kubernetes.io/use-regex: "true"spec: rules: - host: example.com http: paths: - path: /service(/\|)(.*) pathType: Prefix backend: service: name: backend-service port: number: 80

这个配置示例将/service/开头的请求重写到后端服务的根路径。正则表达式(/|)(.\*)匹配/service/或/service开头的路径,2表示第二个捕获组的内容,实现了路径的重写。例如,/service/api/users请求会被重写为/api/users,然后转发到backend-service。

高级功能配置

Ingress还支持多种高级功能配置,通过注解实现:

  1. HTTP到HTTPS重定向

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: force-https-ingress annotations: nginx.ingress.kubernetes.io/ssl-redirect: "true"spec: tls: - hosts: - example.com secretName: tls-secret rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: secure-service port: number: 80

  1. 速率限制

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: rate-limit-ingress annotations: nginx.ingress.kubernetes.io/limit-rps: "10" nginx.ingress.kubernetes.io/limit-connections: "5"spec: rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: protected-service port: number: 80

  1. 跨域资源共享(CORS)

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: cors-ingress annotations: nginx.ingress.kubernetes.io/enable-cors: "true" nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH, OPTIONS" nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization" nginx.ingress.kubernetes.io/cors-allow-origin: "*" nginx.ingress.kubernetes.io/cors-allow-credentials: "true"spec: rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: cors-service port: number: 80

  1. 金丝雀发布

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: canary-ingress annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "20"spec: rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: canary-service port: number: 80

这个配置示例实现了金丝雀发布,20%的流量会被路由到canary-service,其余80%的流量仍然路由到主服务。通过逐步调整canary-weight注解的值,可以实现平滑的版本升级。

|-----------------------------------------------|---------------|---------|
| 注解名称 | 功能描述 | 典型值 |
| nginx.ingress.kubernetes.io/rewrite-target | URL重写目标 | /$2 |
| nginx.ingress.kubernetes.io/ssl-redirect | HTTP到HTTPS重定向 | "true" |
| nginx.ingress.kubernetes.io/limit-rps | 每秒请求数限制 | "10" |
| nginx.ingress.kubernetes.io/limit-connections | 并发连接数限制 | "5" |
| nginx.ingress.kubernetes.io/enable-cors | 启用CORS | "true" |
| nginx.ingress.kubernetes.io/canary | 金丝雀发布 | "true" |
| nginx.ingress.kubernetes.io/canary-weight | 金丝雀流量权重 | "20" |

通过以上Ingress规则配置,可以实现灵活、高效的HTTP/HTTPS流量管理。域名路由、路径转发、SSL证书配置、URL重写和高级功能的组合使用,能够满足各种复杂的业务场景需求,为Kubernetes集群提供强大的七层反向代理能力。

五、Ingress常见故障诊断与HTTPS配置最佳实践

Ingress作为Kubernetes集群的七层HTTP反向代理入口,其稳定性和安全性对整个系统的正常运行至关重要。本节将系统化介绍Ingress常见故障的诊断方法和HTTPS配置的最佳实践,帮助运维人员快速定位和解决问题,确保Ingress服务的高可用性和安全性。

常见故障类型与诊断方法

Ingress故障主要表现为访问异常,其中502 Bad Gateway和404 Not Found是最常见的两种错误类型。系统化的故障诊断流程能够快速定位问题根源,缩短故障恢复时间。

502 Bad Gateway错误诊断

502 Bad Gateway错误表示Ingress-Controller无法连接到后端服务,这是Ingress最常见的故障类型。产生502错误的原因多种多样,需要系统化排查:

  1. 后端服务状态检查:首先验证后端Service和Pod是否正常运行:

检查后端Service状态kubectl get service <service-name># 检查后端Pod状态kubectl get pods -l app=<app-label># 检查Service的Endpoints是否正常kubectl get endpoints <service-name>

如果Endpoints为空或没有正常的Pod地址,说明后端服务存在问题,需要检查Pod的部署和运行状态。

  1. 网络策略检查:确认网络策略是否允许Ingress-Controller访问后端服务:

检查命名空间中的网络策略kubectl get networkpolicy -n <namespace># 检查Ingress-Controller命名空间的网络策略kubectl get networkpolicy -n ingress-nginx

如果存在网络策略阻止Ingress-Controller访问后端服务,需要修改网络策略或添加适当的标签选择器。

  1. Ingress-Controller日志分析:查看Ingress-Controller的日志获取详细错误信息:

获取Ingress-Controller Pod名称kubectl get pods -n ingress-nginx# 查看Ingress-Controller日志kubectl logs -n ingress-nginx <ingress-controller-pod-name>

Ingress-Controller日志中通常会包含具体的错误信息,如"no live upstreams"、"connection refused"等,这些信息有助于快速定位问题。

  1. 服务发现验证:确认Ingress-Controller能够正确发现后端服务:

在Ingress-Controller Pod中测试服务连接kubectl exec -it -n ingress-nginx <ingress-controller-pod-name> -- wget -O- http://<service-name>.<namespace>.svc.cluster.local:<port>

如果连接失败,说明服务发现存在问题,需要检查DNS配置和网络连通性。

404 Not Found错误诊断

404 Not Found错误表示请求的路径或域名未匹配到任何Ingress规则,这通常是由于Ingress规则配置错误导致的。

  1. Ingress规则验证:检查Ingress规则的配置是否正确:

查看Ingress资源详细信息kubectl describe ingress <ingress-name>

重点检查host、path、pathType等字段是否与请求URL匹配,backend配置是否指向正确的Service和端口。

  1. 请求URL匹配检查:确认请求的URL是否与Ingress规则匹配:

测试Ingress规则匹配kubectl exec -it -n ingress-nginx <ingress-controller-pod-name> -- curl -H "Host: <host>" http://localhost/\<path>

如果测试请求返回404错误,说明Ingress规则配置有问题,需要调整host或path配置。

  1. 域名解析检查:确认域名是否正确解析到Ingress-Controller的外部IP:

检查域名解析nslookup <domain># 检查Ingress-Controller Service的外部IPkubectl get svc ingress-nginx-controller -n ingress-nginx

如果域名解析错误,需要修正DNS配置或使用正确的域名访问服务。

故障诊断流程图

Ingress故障诊断可以遵循以下系统化流程:

  1. 确认故障现象:确定是502错误、404错误还是其他类型的错误
  2. 检查Ingress-Controller状态:验证Ingress-Controller Pod和Service是否正常运行
  3. 检查后端服务状态:验证后端Service和Pod是否正常运行,Endpoints是否正常
  4. 检查网络策略:确认网络策略是否允许Ingress-Controller访问后端服务
  5. 分析Ingress-Controller日志:查看日志获取详细错误信息
  6. 验证Ingress规则配置:确认Ingress规则的host、path、backend配置是否正确
  7. 测试服务连通性:在Ingress-Controller Pod中测试后端服务连接
  8. 修正配置并验证:根据诊断结果修正配置并验证故障是否解决

HTTPS配置最佳实践

HTTPS配置是Ingress安全性的重要保障,遵循最佳实践可以确保HTTPS连接的安全性和性能。

SSL证书管理
  1. 证书选择:生产环境应使用受信任的证书颁发机构(CA)签发的证书,避免使用自签名证书。证书应包含完整的域名链,包括根证书、中间证书和域名证书。
  2. 证书格式:确保证书文件为PEM格式,包含完整的证书链。证书文件应以.crt或.pem为扩展名,私钥文件应以.key为扩展名。
  3. 证书创建:使用kubectl命令创建包含证书和私钥的Secret:

kubectl create secret tls <secret-name> --cert=<certificate-file> --key=<private-key-file> -n <namespace>

  1. 证书更新:证书到期前需要及时更新,避免服务中断。更新证书时,先创建新的Secret,然后更新Ingress资源的tls字段引用新Secret。
HTTPS配置示例

完整的HTTPS配置示例如下:

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: secure-ingress annotations: nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/force-ssl-redirect: "true" nginx.ingress.kubernetes.io/hsts: "true" nginx.ingress.kubernetes.io/hsts-max-age: "31536000" nginx.ingress.kubernetes.io/hsts-include-subdomains: "true" nginx.ingress.kubernetes.io/hsts-preload: "true"spec: tls: - hosts: - example.com - www.example.com secretName: example-tls-secret rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: secure-service port: number: 80

这个配置示例实现了以下HTTPS最佳实践:

  1. HTTP到HTTPS重定向:通过ssl-redirect和force-ssl-redirect注解强制所有HTTP请求重定向到HTTPS
  2. HSTS安全头:通过hsts相关注解启用HTTP严格传输安全,防止协议降级攻击
  3. 多域名支持:在tls字段中配置多个域名,一个证书可以保护多个域名
  4. 安全服务引用:后端服务使用HTTP协议,由Ingress-Controller处理HTTPS终止
SSL协议和密码套件优化

为了提高HTTPS连接的安全性,应配置安全的SSL协议和密码套件:

apiVersion: v1kind: ConfigMapmetadata: name: nginx-configuration namespace: ingress-nginxdata: ssl-protocols: "TLSv1.2 TLSv1.3" ssl-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384" ssl-prefer-server-ciphers: "on"

这个配置禁用了不安全的SSL协议(如SSLv2、SSLv3、TLSv1.0、TLSv1.1),只允许TLSv1.2和TLSv1.3协议,并配置了安全的密码套件,优先使用服务器端的密码套件。

证书自动管理

为了简化证书管理,可以使用cert-manager自动申请和更新证书。cert-manager可以与Let's Encrypt等公共证书颁发机构集成,实现证书的自动申请、验证和更新。

cert-manager的安装和使用步骤如下:

  1. 安装cert-manager

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml

  1. 创建ClusterIssuer

apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: letsencrypt-prodspec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: admin@example.com privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginx

  1. 配置Ingress自动证书

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: auto-cert-ingress annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod"spec: tls: - hosts: - example.com secretName: example-tls-secret rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: secure-service port: number: 80

这个配置通过cert-manager.io/cluster-issuer注解指定使用letsencrypt-prod ClusterIssuer自动申请证书,证书会自动存储在example-tls-secret中,无需手动管理。

性能优化配置

HTTPS连接的性能优化也是重要考虑因素,以下配置可以提高HTTPS连接的性能:

apiVersion: v1kind: ConfigMapmetadata: name: nginx-configuration namespace: ingress-nginxdata: ssl-session-cache: "shared:SSL:10m" ssl-session-timeout: "10m" ssl-buffer-size: "16k" ssl-session-tickets: "on" proxy-buffer-size: "16k" proxy-buffers-number: "4" proxy-buffers-size: "8k"

这个配置优化了SSL会话缓存、缓冲区大小等参数,可以显著提高HTTPS连接的性能,减少延迟和资源消耗。

通过系统化的故障诊断方法和HTTPS配置最佳实践,可以确保Ingress服务的高可用性和安全性,为Kubernetes集群提供稳定、安全的七层HTTP反向代理服务。

六、实现域名访问集群内部业务的完整解决方案

实现通过域名访问Kubernetes集群内部业务需要系统化的解决方案,涵盖从基础设施准备到服务配置的完整流程。本节将整合前文技术内容,提供从零到一的域名访问实施方案,确保读者能够独立完成整个配置过程。

整体解决方案架构

域名访问集群内部业务的解决方案采用分层架构设计,包含以下几个关键组件:

  1. 外部负载均衡层:通常由云平台LoadBalancer或自建负载均衡器(如MetalLB)提供,负责将外部流量引入集群
  2. Ingress-Controller层:nginx-ingress-controller作为七层HTTP反向代理,负责处理HTTP/HTTPS流量和路由规则
  3. Service层:ClusterIP类型Service为后端Pod提供稳定的访问入口和负载均衡
  4. 应用层:实际运行的业务应用Pod,提供具体的服务功能

这种分层架构确保了各组件职责明确,便于维护和扩展。外部流量首先经过负载均衡器进入集群,然后由Ingress-Controller根据域名和路径规则路由到相应的Service,最后由Service将流量分发到后端Pod。

实施步骤详解

第一步:环境准备与基础设施配置

在开始配置之前,需要完成以下环境准备工作:

  1. Kubernetes集群准备:确保Kubernetes集群版本在1.16及以上,网络插件(如Calico、Flannel)正常运行:

kubectl version --shortkubectl get pods -n kube-system -l k8s-app=calico-node

  1. 负载均衡器准备:如果使用云平台,确保已创建LoadBalancer类型的Service;如果使用自建负载均衡器,需要部署MetalLB:

部署MetalLB(适用于裸金属环境)kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml

  1. 域名准备:确保已注册域名并能够配置DNS解析。如果使用测试域名,可以在本地hosts文件中添加解析记录。
第二步:部署nginx-ingress-controller

按照第三章的部署步骤,部署nginx-ingress-controller:

  1. 创建命名空间

kubectl create namespace ingress-nginx

  1. 部署nginx-ingress-controller

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml

  1. 验证部署状态

kubectl get pods -n ingress-nginxkubectl get svc -n ingress-nginx

确保所有Pod处于Running状态,LoadBalancer Service已分配外部IP地址。

第三步:部署后端应用和Service

部署需要通过域名访问的后端应用,并创建相应的Service:

  1. 部署示例应用

部署Web应用kubectl create deployment web-app --image=nginx:latest --port=80# 部署API应用kubectl create deployment api-app --image=nginx:latest --port=80

  1. 创建Service

为Web应用创建Servicekubectl expose deployment web-app --name=web-service --port=80 --type=ClusterIP# 为API应用创建Servicekubectl expose deployment api-app --name=api-service --port=80 --type=ClusterIP

  1. 验证Service状态

kubectl get svc web-service api-servicekubectl get endpoints web-service api-service

确保Service的Endpoints正常,包含后端Pod的IP地址。

第四步:配置Ingress规则

创建Ingress资源,配置域名路由规则:

  1. 创建Web应用Ingress

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: web-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /spec: rules: - host: web.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 80

  1. 创建API应用Ingress

apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: api-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/use-regex: "true"spec: rules: - host: api.example.com http: paths: - path: /api(/|$)(.*) pathType: Prefix backend: service: name: api-service port: number: 80

  1. 应用Ingress配置

kubectl apply -f web-ingress.yamlkubectl apply -f api-ingress.yaml

  1. 验证Ingress状态

kubectl get ingress web-ingress api-ingresskubectl describe ingress web-ingresskubectl describe ingress api-ingress

确保Ingress规则已正确配置,ADDRESS字段显示Ingress-Controller的外部IP地址。

第五步:配置DNS解析

配置域名解析,将域名指向Ingress-Controller的外部IP地址:

  1. 获取Ingress-Controller外部IP

kubectl get svc ingress-nginx-controller -n ingress-nginx -o jsonpath='{.status.loadBalancer.ingress0.ip}'

  1. 配置DNS记录:在DNS管理平台中,为web.example.com和api.example.com添加A记录,指向获取的外部IP地址。如果使用测试环境,可以在本地hosts文件中添加:

<external-ip> web.example.com<external-ip> api.example.com

第六步:验证与测试

完成所有配置后,进行全面的验证和测试:

  1. 基本连通性测试

测试Web应用curl -H "Host: web.example.com" http://<external-ip># 测试API应用curl -H "Host: api.example.com" http://<external-ip>/api

  1. HTTPS配置测试:如果配置了SSL证书,测试HTTPS访问:

测试HTTPS连接curl -k -H "Host: web.example.com" https://web.example.com

  1. 路径转发测试:测试API应用的路径转发功能:

测试API路径curl -H "Host: api.example.com" http://<external-ip>/api/v1/users

  1. 负载均衡测试:模拟多用户访问,验证负载均衡功能:

并发测试for i in {1..10}; do curl -H "Host: web.example.com" http://<external-ip> &donewait

生产环境优化建议

在生产环境中部署域名访问解决方案时,需要考虑以下优化建议:

  1. 高可用配置:部署多个Ingress-Controller实例,分布在不同节点上,配置反亲和性确保实例分布在不同可用区:

affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app.kubernetes.io/name operator: In values: - ingress-nginx topologyKey: "kubernetes.io/hostname"

  1. 自动扩缩容配置:为Ingress-Controller配置HorizontalPodAutoscaler,根据CPU使用率自动调整实例数量:

apiVersion: autoscaling/v2kind: HorizontalPodAutoscalermetadata: name: ingress-nginx-controller namespace: ingress-nginxspec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: ingress-nginx-controller minReplicas: 3 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70

  1. 监控和日志配置:配置Prometheus监控和日志收集,确保Ingress服务的可观测性:

Prometheus监控配置apiVersion: v1kind: Servicemetadata: name: ingress-nginx-controller-metrics namespace: ingress-nginx annotations: prometheus.io/scrape: "true" prometheus.io/port: "10254"spec: ports: - name: metrics port: 10254 protocol: TCP selector: app.kubernetes.io/name: ingress-nginx type: ClusterIP

  1. 安全配置:配置网络策略限制Ingress-Controller的访问范围,配置WAF规则增强安全性:

apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: ingress-nginx-network-policy namespace: ingress-nginxspec: podSelector: matchLabels: app.kubernetes.io/name: ingress-nginx policyTypes: - Ingress - Egress ingress: - from: - namespaceSelector: matchLabels: name: default egress: - to: - namespaceSelector: matchLabels: name: default

实施检查清单

为确保域名访问解决方案的正确实施,可以使用以下检查清单进行验证:

  • Kubernetes集群版本在1.16及以上
  • 网络插件正常运行
  • 负载均衡器已配置并分配外部IP
  • nginx-ingress-controller已部署且所有Pod处于Running状态
  • LoadBalancer Service已分配外部IP地址
  • 后端应用已部署且Pod处于Running状态
  • ClusterIP Service已创建且Endpoints正常
  • Ingress资源已创建且ADDRESS字段显示外部IP
  • 域名DNS记录已配置并指向外部IP
  • 基本连通性测试通过
  • HTTPS配置测试通过(如适用)
  • 路径转发功能测试通过
  • 负载均衡功能测试通过
  • 高可用配置已实施
  • 自动扩缩容配置已实施
  • 监控和日志配置已实施
  • 安全配置已实施

通过这个完整的解决方案,可以成功实现通过域名访问Kubernetes集群内部业务的目标。该方案具有高可用性、可扩展性和安全性,适合生产环境部署使用。

相关推荐
java_logo3 小时前
Docker 部署 Rocky Linux:轻松搭建 RHEL 兼容企业级基础镜像平台
linux·docker·容器·rocky linux·基础镜像·轩辕镜像·rhel 兼容
myy-learn8 小时前
30-HTTP协议
网络·网络协议·http
IT大白鼠9 小时前
Istio 结合 K8s 实现流量管理:服务网格灰度、熔断、限流实战
云原生·kubernetes·istio
鹤落晴春9 小时前
【K8s】认识Kubernetes API:从CRD出发的一次梳理
云原生·容器·kubernetes
yanwumuxi10 小时前
Docker记录:误删宿主机挂载目录导致 PostgreSQL 数据丢失
docker·postgresql·容器
cui_hao_nan12 小时前
Docker 学习 5
docker·容器
A黄俊辉A13 小时前
两分钟上手docker
运维·docker·容器
G佳伟13 小时前
宝塔面板打不开且 Bt-Panel 未运行:从 HTTP 502 到 gevent 缺失的完整排查与修复
网络协议·http·php
keyipatience14 小时前
IP网络层
服务器·网络·网络协议·ubuntu·http