Kubernetes 中的服务入口 (Ingress) 高级路由规则

好嘞,各位看官,欢迎来到今天的“Kubernetes Ingress 高级路由,玩转流量魔法”讲座!我是你们的老朋友,人称“代码诗人”的程序猿小 K。今天,咱们不聊枯燥的 YAML,不啃难懂的文档,而是要用轻松幽默的方式,带大家走进 Ingress 的高级路由世界,让你的服务像孙悟空一样,七十二变,应对各种复杂的流量场景!

开场白:Ingress,你的服务管家

想象一下,你的 Kubernetes 集群是一个热闹的社区,里面住着各种各样的服务,就像性格各异的邻居。这些服务都在自己的小房间里(Pod),你想要访问它们,就需要一个“管家”来帮你指路,管理流量。

这个“管家”就是 Ingress!它就像一个智能路由器,根据你设定的规则,将外部请求精准地分发到对应的服务。它不仅仅是简单的路由,更是一个流量魔法师,可以实现各种高级的流量管理策略。

第一章:Ingress 基础回顾,温故而知新

在深入高级玩法之前,咱们先来回顾一下 Ingress 的基础知识,就像盖高楼要先打好地基一样。

  • Ingress Controller: 这是 Ingress 的大脑和引擎,负责监听 Kubernetes API Server,根据 Ingress 规则配置底层的负载均衡器(比如 Nginx、HAProxy)。你可以把它想象成一个勤劳的“交通警察”,指挥交通,确保车辆(请求)畅通无阻。
  • Ingress Resource: 这是你定义路由规则的地方,就像一份详细的“交通地图”,告诉 Ingress Controller 如何处理不同的请求。它通常以 YAML 文件的形式存在,包含了主机名、路径、后端服务等信息。

一个简单的 Ingress 例子:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80

这段代码的意思是:当用户访问 example.com 的根路径 / 时,Ingress 会将请求转发到名为 my-service 的服务的 80 端口。

第二章:高级路由策略,玩转流量魔法

好了,基础知识回顾完毕,现在让我们进入今天的重头戏:Ingress 的高级路由策略!

  1. 基于 Host 的路由:多域名,各司其职

    就像你有多个网站,每个网站都有自己的域名一样,你可以使用 Ingress 基于 Host 的路由,将不同的域名指向不同的服务。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
     name: host-based-ingress
    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

    这段代码表示:

    • 访问 app1.example.com 的请求会被转发到 app1-service
    • 访问 app2.example.com 的请求会被转发到 app2-service

    就像你家的不同房间,分别住着不同的家庭成员,每个家庭成员都有自己的独立空间。

  2. 基于 Path 的路由:细粒度控制,精准打击

    基于 Path 的路由可以让你根据 URL 的路径来区分不同的服务。这就像你家里的不同区域,比如厨房、客厅、卧室,每个区域都有不同的功能。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
     name: path-based-ingress
    spec:
     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

    这段代码表示:

    • 访问 example.com/api 的请求会被转发到 api-service
    • 访问 example.com/web 的请求会被转发到 web-service

    PathType 的选择:Prefix, Exact, ImplementationSpecific

    • Prefix: 最常用的类型,匹配以指定路径开始的任何 URL。例如,/api 会匹配 /api/api/users/api/products 等。
    • Exact: 必须完全匹配指定的路径。例如,/api 只会匹配 /api,不会匹配 /api/users
    • ImplementationSpecific: 由 Ingress Controller 实现决定,通常与 Prefix 类似,但可能有一些细微的差别。

    选择合适的 PathType,就像选择合适的工具,才能事半功倍!

  3. 基于 Header 的路由:披着羊皮的狼,按需定制

    基于 Header 的路由可以根据 HTTP 请求头的内容来决定路由规则。这就像你家的门禁系统,只有输入正确的密码(Header),才能进入相应的房间。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
     name: header-based-ingress
     annotations:
       nginx.ingress.kubernetes.io/rewrite-target: /
       nginx.ingress.kubernetes.io/configuration-snippet: |
         if ($http_user_agent ~* "Mobile") {
           proxy_pass http://mobile-service.default.svc.cluster.local:80;
           break;
         }
         proxy_pass http://web-service.default.svc.cluster.local:80;
    spec:
     rules:
     - host: example.com
       http:
         paths:
         - path: /
           pathType: Prefix
           backend:
             service:
               name: web-service
               port:
                 number: 80

    这段代码使用 Nginx Ingress Controller 的 configuration-snippet 注解,根据 User-Agent 请求头来判断请求是否来自移动设备。如果是,则将请求转发到 mobile-service,否则转发到 web-service

    注意: 基于 Header 的路由通常需要使用 Ingress Controller 的特定注解或配置,不同的 Ingress Controller 可能有不同的实现方式。

  4. 基于 Cookie 的路由:记住你的选择,个性化服务

    基于 Cookie 的路由可以根据客户端发送的 Cookie 来决定路由规则。这就像你家的会员系统,根据你的会员等级,提供不同的服务。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
     name: cookie-based-ingress
     annotations:
       nginx.ingress.kubernetes.io/rewrite-target: /
       nginx.ingress.kubernetes.io/configuration-snippet: |
         if ($cookie_version = "v1") {
           proxy_pass http://v1-service.default.svc.cluster.local:80;
           break;
         }
         proxy_pass http://v2-service.default.svc.cluster.local:80;
    spec:
     rules:
     - host: example.com
       http:
         paths:
         - path: /
           pathType: Prefix
           backend:
             service:
               name: v2-service
               port:
                 number: 80

    这段代码使用 Nginx Ingress Controller 的 configuration-snippet 注解,根据名为 version 的 Cookie 的值来决定路由规则。如果 Cookie 的值为 v1,则将请求转发到 v1-service,否则转发到 v2-service

    注意: 类似于基于 Header 的路由,基于 Cookie 的路由也通常需要使用 Ingress Controller 的特定注解或配置。

  5. 金丝雀发布:小心翼翼,步步为营

    金丝雀发布是一种灰度发布策略,它将一小部分流量导向新版本的服务,观察其表现,如果一切正常,再逐渐增加流量,最终完全替换旧版本。这就像矿工带着金丝雀进入矿井,如果金丝雀安然无恙,说明矿井是安全的。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
     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: new-service
               port:
                 number: 80
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
     name: main-ingress
    spec:
     rules:
     - host: example.com
       http:
         paths:
         - path: /
           pathType: Prefix
           backend:
             service:
               name: old-service
               port:
                 number: 80

    这段代码使用了 Nginx Ingress Controller 的金丝雀发布功能。它创建了两个 Ingress 资源:canary-ingressmain-ingresscanary-ingress 带有 nginx.ingress.kubernetes.io/canary: "true" 注解,表示这是一个金丝雀 Ingress,nginx.ingress.kubernetes.io/canary-weight: "20" 注解表示将 20% 的流量导向 new-service,剩下的 80% 的流量导向 old-service

    金丝雀发布的优点:

    • 风险可控: 避免新版本服务出现问题影响所有用户。
    • 用户体验: 对用户影响小,可以在用户无感知的情况下完成版本升级。
    • 观察分析: 可以收集新版本服务的性能数据,进行分析和优化。

第三章:Ingress Controller 的选择,百花齐放,各有所长

选择合适的 Ingress Controller 就像选择合适的武器,不同的场景需要不同的工具。

  • Nginx Ingress Controller: 最流行的 Ingress Controller 之一,功能强大,配置灵活,社区活跃。它就像一把瑞士军刀,可以应对各种复杂场景。
  • HAProxy Ingress Controller: 性能优异,稳定可靠,适合对性能要求较高的场景。它就像一辆高性能跑车,速度快,稳定性好。
  • Traefik Ingress Controller: 自动化配置,易于使用,适合快速部署和开发测试环境。它就像一个智能机器人,可以自动完成很多繁琐的任务。
  • AWS Load Balancer Controller: 与 AWS 云平台集成紧密,可以自动创建和管理 AWS Load Balancer。它就像一个原厂配件,与 AWS 云平台完美兼容。
  • GCE Ingress: 与 Google Cloud Platform 集成紧密,可以自动创建和管理 Google Cloud Load Balancer。它就像另一个原厂配件,与 Google Cloud Platform 完美兼容。

表格:Ingress Controller 的对比

Ingress Controller 优点 缺点 适用场景
Nginx Ingress Controller 功能强大,配置灵活,社区活跃,文档完善 配置复杂,学习曲线较陡峭 各种复杂场景,需要高度定制的场景
HAProxy Ingress Controller 性能优异,稳定可靠 配置相对复杂,社区活跃度不如 Nginx 对性能要求较高的场景
Traefik Ingress Controller 自动化配置,易于使用,动态配置更新 功能相对简单,不如 Nginx 和 HAProxy 强大 快速部署,开发测试环境
AWS Load Balancer Controller 与 AWS 云平台集成紧密,自动创建和管理 AWS Load Balancer,安全可靠 只能在 AWS 云平台上使用,依赖 AWS 服务 使用 AWS 云平台的场景
GCE Ingress 与 Google Cloud Platform 集成紧密,自动创建和管理 Google Cloud Load Balancer,安全可靠 只能在 Google Cloud Platform 上使用,依赖 Google Cloud 服务 使用 Google Cloud Platform 的场景

第四章:实战演练,手把手教你玩转 Ingress

理论知识讲了一大堆,现在让我们来一个实战演练,手把手教你如何使用 Ingress 实现一个简单的金丝雀发布。

场景:

  • 你有一个名为 my-app 的应用,当前版本为 v1
  • 你开发了一个新版本 v2,想要进行金丝雀发布,将 10% 的流量导向 v2,剩下的 90% 的流量导向 v1

步骤:

  1. 部署 v1v2 版本的应用:

    # v1 deployment
    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: my-app-v1
    spec:
     replicas: 3
     selector:
       matchLabels:
         app: my-app
         version: v1
     template:
       metadata:
         labels:
           app: my-app
           version: v1
       spec:
         containers:
         - name: my-app
           image: your-image:v1
           ports:
           - containerPort: 80
    
    ---
    # v2 deployment
    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: my-app-v2
    spec:
     replicas: 1
     selector:
       matchLabels:
         app: my-app
         version: v2
     template:
       metadata:
         labels:
           app: my-app
           version: v2
       spec:
         containers:
         - name: my-app
           image: your-image:v2
           ports:
           - containerPort: 80
  2. 创建 v1v2 版本的 Service:

    # v1 service
    apiVersion: v1
    kind: Service
    metadata:
     name: my-app-v1-service
    spec:
     selector:
       app: my-app
       version: v1
     ports:
     - port: 80
       targetPort: 80
    
    ---
    # v2 service
    apiVersion: v1
    kind: Service
    metadata:
     name: my-app-v2-service
    spec:
     selector:
       app: my-app
       version: v2
     ports:
     - port: 80
       targetPort: 80
  3. 创建 Ingress 资源:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
     name: my-app-ingress
     annotations:
       nginx.ingress.kubernetes.io/canary: "true"
       nginx.ingress.kubernetes.io/canary-weight: "10"
    spec:
     rules:
     - host: example.com
       http:
         paths:
         - path: /
           pathType: Prefix
           backend:
             service:
               name: my-app-v2-service
               port:
                 number: 80
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
     name: my-app-main-ingress
    spec:
     rules:
     - host: example.com
       http:
         paths:
         - path: /
           pathType: Prefix
           backend:
             service:
               name: my-app-v1-service
               port:
                 number: 80

    解释:

    • my-app-ingress 将 10% 的流量导向 my-app-v2-service
    • my-app-main-ingress 将 90% 的流量导向 my-app-v1-service
  4. 验证:

    通过访问 example.com,观察请求是否被随机导向 v1v2 版本的应用。

    你可以通过查看 Pod 的日志或者在应用中添加版本信息来区分请求被导向哪个版本。

第五章:总结与展望,未来可期

今天,我们一起探索了 Kubernetes Ingress 的高级路由策略,从基于 Host 和 Path 的基本路由,到基于 Header 和 Cookie 的个性化定制,再到金丝雀发布的小心翼翼,相信大家对 Ingress 的强大功能有了更深入的了解。

Ingress 不仅仅是一个简单的流量入口,更是一个灵活的流量管理平台,可以帮助你实现各种复杂的流量场景,提升应用的可用性和用户体验。

未来,随着 Kubernetes 的不断发展,Ingress 的功能也会越来越强大,相信它会在云原生应用中扮演越来越重要的角色。

结束语:

希望今天的讲座能给大家带来一些启发和帮助。记住,代码的世界充满了乐趣,只要你敢于探索,勇于实践,就能创造出无限可能! 感谢大家今天的聆听,我们下次再见! 👋

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注