Kubernetes (K8S) 网络原理

Ingress 网络原理

Ingress 是 Kubernetes 中管理外部访问集群内服务的 API 对象,通常是 HTTP/HTTPS。Ingress 可以提供负载均衡、SSL 终止和基于名称的虚拟主机等功能。

Ingress 网络示意图

为什么需要 Ingress?

在 Kubernetes 中,Pod 和 Service 已经提供了集群内部的网络通信能力,但是对于从集群外部访问集群内服务,还需要更灵活的方案:

Ingress 正是为了解决这些问题而设计的,它提供了一个统一的入口点,可以根据不同的规则将流量路由到不同的后端服务。

Ingress 工作原理

Ingress 资源
Ingress 控制器
Ingress 规则
TLS 配置

Ingress 资源

Ingress 资源是 Kubernetes API 中的一个对象,它定义了从集群外部到集群内 Service 的路由规则。Ingress 资源本身不会做任何事情,它需要 Ingress 控制器来实现其功能。

# 基本的 Ingress 资源示例 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: example.com http: paths: - path: /app1 pathType: Prefix backend: service: name: app1-service port: number: 80 - path: /app2 pathType: Prefix backend: service: name: app2-service port: number: 80

Ingress 控制器

Ingress 控制器是实现 Ingress 功能的组件,它监听 Ingress 资源的变化,并根据 Ingress 规则配置负载均衡器。Kubernetes 本身不提供 Ingress 控制器,需要单独部署。

常见的 Ingress 控制器包括:

  • Nginx Ingress Controller:基于 Nginx 的 Ingress 控制器,是最常用的实现
  • Traefik:一个现代化的 HTTP 反向代理和负载均衡器
  • HAProxy Ingress:基于 HAProxy 的 Ingress 控制器
  • Kong Ingress Controller:基于 Kong API 网关的 Ingress 控制器
  • Istio Ingress Gateway:Istio 服务网格的入口网关

Ingress 控制器的工作流程:

  1. 监听 Kubernetes API 服务器上 Ingress 资源的变化
  2. 解析 Ingress 规则,生成相应的配置
  3. 配置负载均衡器(如 Nginx)以实现流量路由
  4. 处理 TLS 终止、路径重写等功能
# 部署 Nginx Ingress Controller kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.0/deploy/static/provider/cloud/deploy.yaml

Ingress 规则

Ingress 规则定义了如何将 HTTP/HTTPS 流量路由到 Kubernetes 服务。规则基于主机名和 URL 路径。

基于主机名的路由

可以根据不同的主机名将流量路由到不同的服务:

spec: rules: - host: app1.example.com http: paths: - path: / pathType: Prefix backend: service: name: app1-service port: number: 80 - host: app2.example.com http: paths: - path: / pathType: Prefix backend: service: name: app2-service port: number: 80

基于路径的路由

可以根据 URL 路径将流量路由到不同的服务:

spec: rules: - host: example.com http: paths: - path: /app1 pathType: Prefix backend: service: name: app1-service port: number: 80 - path: /app2 pathType: Prefix backend: service: name: app2-service port: number: 80

路径类型

Kubernetes 支持三种路径类型:

  • Exact:精确匹配 URL 路径
  • Prefix:基于 URL 路径前缀匹配
  • ImplementationSpecific:由 Ingress 控制器决定匹配方式

TLS 配置

Ingress 可以配置 TLS,为入站连接提供安全通信。TLS 配置需要一个包含证书和私钥的 Secret。

# 创建 TLS Secret kubectl create secret tls example-tls --cert=path/to/cert.crt --key=path/to/key.key # 在 Ingress 中使用 TLS apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tls-example-ingress spec: tls: - hosts: - example.com secretName: example-tls rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: example-service port: number: 80

当配置了 TLS 后,Ingress 控制器会:

  1. 加载 Secret 中的证书和私钥
  2. 配置负载均衡器以终止 TLS 连接
  3. 将解密后的 HTTP 请求转发到后端服务

Ingress 实现细节

Nginx Ingress Controller 架构

以最常用的 Nginx Ingress Controller 为例,它的架构包括:

  • Nginx:作为反向代理和负载均衡器
  • Controller:监听 Ingress 资源并生成 Nginx 配置
  • ConfigMap:存储 Nginx 配置模板
  • Service:暴露 Nginx Ingress Controller

工作流程:

  1. 用户创建或修改 Ingress 资源
  2. Controller 监听到变化,解析 Ingress 规则
  3. Controller 生成新的 Nginx 配置
  4. Nginx 重新加载配置,开始按新规则路由流量

Ingress 与 Service 的关系

Ingress 不直接与 Pod 通信,而是通过 Service 与 Pod 通信:

  1. 外部流量首先到达 Ingress 控制器
  2. Ingress 控制器根据规则将流量路由到相应的 Service
  3. Service 再将流量路由到后端 Pod

这种设计使得 Ingress 可以利用 Service 提供的负载均衡和服务发现功能。

Ingress 注解

Ingress 资源支持通过注解(Annotations)来配置特定于 Ingress 控制器的功能。不同的 Ingress 控制器支持不同的注解。

常用 Nginx Ingress 注解

# 路径重写 nginx.ingress.kubernetes.io/rewrite-target: / # 启用 CORS nginx.ingress.kubernetes.io/enable-cors: "true" # 配置会话亲和性 nginx.ingress.kubernetes.io/affinity: "cookie" nginx.ingress.kubernetes.io/session-cookie-name: "route" nginx.ingress.kubernetes.io/session-cookie-expires: "172800" nginx.ingress.kubernetes.io/session-cookie-max-age: "172800" # 配置超时 nginx.ingress.kubernetes.io/proxy-connect-timeout: "60" nginx.ingress.kubernetes.io/proxy-send-timeout: "60" nginx.ingress.kubernetes.io/proxy-read-timeout: "60" # 配置 SSL 重定向 nginx.ingress.kubernetes.io/ssl-redirect: "true" # 限制请求大小 nginx.ingress.kubernetes.io/proxy-body-size: "10m" # 配置白名单 nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/24,172.10.0.1"

Ingress 高级功能

除了基本的路由功能外,Ingress 还可以实现许多高级功能:

1. 金丝雀发布

使用注解可以实现流量分割,将一部分流量路由到新版本的应用:

nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "30"

2. 速率限制

限制客户端的请求速率,防止过载:

nginx.ingress.kubernetes.io/limit-rps: "10" nginx.ingress.kubernetes.io/limit-connections: "5"

3. 认证

为路由添加基本认证:

# 创建认证密钥 htpasswd -c auth username kubectl create secret generic basic-auth --from-file=auth # 在 Ingress 中启用认证 nginx.ingress.kubernetes.io/auth-type: basic nginx.ingress.kubernetes.io/auth-secret: basic-auth nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"

4. 自定义错误页面

配置自定义错误页面:

nginx.ingress.kubernetes.io/custom-http-errors: "404,500,502" nginx.ingress.kubernetes.io/default-backend: error-pages-service

Ingress 排障

在排查 Ingress 问题时,可以使用以下命令和工具:

常用 Ingress 排障命令

# 查看 Ingress 资源 kubectl get ingress kubectl describe ingress example-ingress # 查看 Ingress 控制器日志 kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx # 检查 Ingress 控制器 Pod 状态 kubectl get pods -n ingress-nginx # 检查 Ingress 控制器 Service kubectl get svc -n ingress-nginx # 测试 Ingress 路由 curl -H "Host: example.com" http:///path # 检查 TLS 证书 openssl s_client -connect example.com:443 -servername example.com

Ingress 是 Kubernetes 网络模型中的重要组成部分,它提供了从集群外部访问集群内服务的灵活方式。理解 Ingress 的工作原理对于构建可靠的 Kubernetes 应用至关重要。

了解 CNI 插件