了解 ALB

ALB(Another Load Balancer)是一个基于 OpenResty 的 Kubernetes Gateway,拥有 Alauda 多年生产环境经验的支持。

目录

核心组件

  • ALB Operator:管理 ALB 实例生命周期的 operator,负责监听 ALB CR 并为不同租户创建和更新 ALB 实例。
  • ALB Instance:ALB 实例包含作为数据平面的 OpenResty 和作为控制平面的 Go 控制器。Go 控制器监控各种 CR(Ingress、Gateway、Rule 等),并将其转换为 ALB 特定的 DSL 规则。OpenResty 使用这些 DSL 规则匹配并处理传入请求。

快速开始

部署 ALB Operator

  1. 创建一个集群。
  2.  helm repo add alb https://alauda.github.io/alb/;helm repo update;helm search repo|grep alb
  3.  helm install alb-operator alb/alauda-alb2

部署 ALB 实例

cat <<EOF | kubectl apply -f -
apiVersion: crd.alauda.io/v2beta1
kind: ALB2
metadata:
    name: alb-demo
    namespace: kube-system
spec:
    address: "172.20.0.5"  # ALB 部署所在节点的 IP 地址
    type: "nginx"
    config:
        networkMode: host
        loadbalancerName: alb-demo
        projects:
        - ALL_ALL
        replicas: 1
EOF

运行示例应用

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
  labels:
    k8s-app: hello-world
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: hello-world
  template:
    metadata:
      labels:
        k8s-app: hello-world
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: hello-world
        image: docker.io/crccheck/hello-world:latest
        imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
  name: hello-world
  labels:
    k8s-app: hello-world
spec:
  ports:
  - name: http
    port: 80
    targetPort: 8000
  selector:
    k8s-app: hello-world
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-world
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: hello-world
            port:
              number: 80
EOF

现在你可以通过 curl http://${ip} 访问该应用。

ALB 常见概念

以下定义了 ALB 中的常见概念。

Auth

Auth 是一种在请求到达实际服务之前执行身份验证的机制。它允许你在 ALB 层统一处理身份验证,而无需在每个后端服务中实现身份验证逻辑。

了解更多关于 ALB Auth

网络模式

ALB 实例可以部署在两种模式下:host 网络模式和容器网络模式。

Host 网络模式

直接使用节点的网络栈,与节点共享 IP 地址和端口。

在此模式下,负载均衡实例直接绑定节点端口,无需端口映射或类似的容器网络封装转换。

NOTE

为避免端口冲突,单个节点上只允许部署一个 ALB 实例。

在 host-network 模式下,ALB 实例默认监听节点的所有网卡。

优点:
  1. 最佳网络性能。
  2. 可通过节点 IP 访问。
缺点:
  1. 单个节点只允许部署一个 ALB 实例。
  2. 端口可能与其他进程冲突。

容器网络模式

与 host 网络模式不同,容器网络模式通过容器网络部署 ALB。

优点:
  1. 支持单节点部署多个 ALB 实例。
  2. ALB 集成 MetalLB,可为 ALB 提供 VIP。
  3. 端口不会与其他进程冲突。
缺点:
  1. 性能略低。
  2. 必须通过 LoadBalancer 服务访问 ALB。

Frontend

定义了一个名为 frontend(简称 ft)的资源,用于声明所有 ALB 应监听的端口。

每个 frontend 对应负载均衡器(LB)上的一个监听端口。Frontend 通过标签与 ALB 关联。

apiVersion: crd.alauda.io/v1
kind: Frontend
metadata:
  labels:
    alb2.cpaas.io/name: alb-demo
  name: alb-demo-00080
  namespace: cpaas-system
spec:
  backendProtocol: "http"
  certificate_name: ""
  port: 80
  protocol: http
  serviceGroup:
    services:
      - name: hello-world
        namespace: default
        port: 80
        weight: 100
  1. 必填,指明该 Frontend 所属的 ALB 实例。
  2. 格式为 $alb_name-$port
  3. 格式为 $secret_ns/$secret_name
  4. Frontend 自身的协议。
    • http|https|grpc|grpcs 用于 L7 代理。
    • tcp|udp 用于 L4 代理。
  5. 对于 L4 代理,serviceGroup 是必填;对于 L7 代理,serviceGroup 是可选的。当请求到达时,ALB 会先尝试匹配与该 Frontend 关联的规则,只有当请求不匹配任何规则时,才会将请求转发到 Frontend 配置中指定的默认 serviceGroup
  6. weight 配置适用于轮询和加权轮询调度算法。
NOTE

ALB 监听 ingress 并自动创建 FrontendRulesource 字段定义如下:

  1. spec.source.type 目前仅支持 ingress
  2. spec.source.name 是 ingress 名称。
  3. spec.source.namespace 是 ingress 命名空间。

其他资源

Rules

定义了一个名为 rule 的资源,用于描述 ALB 实例如何处理七层请求。

Rule 可配置复杂的流量匹配和分发模式。流量到达时,根据内部规则进行匹配并执行相应的转发,同时提供如 cors、url 重写等附加功能。

apiVersion: crd.alauda.io/v1
kind: Rule
metadata:
  labels:
    alb2.cpaas.io/frontend: alb-demo-00080
    alb2.cpaas.io/name: alb-demo
  name: alb-demo-00080-test
  namespace: kube-system
spec:
  backendProtocol: ""
  certificate_name: ""
  dslx:
    - type: METHOD
      values:
        - - EQ
          - POST
    - type: URL
      values:
        - - STARTS_WITH
          - /app-a
        - - STARTS_WITH
          - /app-b
    - type: PARAM
      key: group
      values:
        - - EQ
          - vip
    - type: HOST
      values:
        - - ENDS_WITH
          - .app.com
    - type: HEADER
      key: LOCATION
      values:
        - - IN
          - east-1
          - east-2
    - type: COOKIE
      key: uid
      values:
        - - EXIST
    - type: SRC_IP
      values:
        - - RANGE
          - "1.1.1.1"
          - "1.1.1.100"
  enableCORS: false
  priority: 4
  serviceGroup:
    services:
      - name: hello-world
        namespace: default
        port: 80
        weight: 100
  1. 必填,指明该规则所属的 Frontend。
  2. 必填,指明该规则所属的 ALB。
  3. 同 Frontend。
  4. 同 Frontend。
  5. 数值越小优先级越高。
  6. 同 Frontend。

dslx

dslx 是一种领域特定语言,用于描述匹配条件。

例如,下面的规则匹配满足以下所有条件的请求:

  • URL 以 /app-a 或 /app-b 开头
  • 请求方法为 POST
  • URL 参数 group 的值为 vip
  • Host 以 .app.com 结尾
  • Header 中 LOCATION 的值为 east-1 或 east-2
  • 存在名为 uid 的 cookie
  • 源 IP 在 1.1.1.1 到 1.1.1.100 范围内
dslx:
  - type: METHOD
    values:
      - - EQ
        - POST
  - type: URL
    values:
      - - STARTS_WITH
        - /app-a
      - - STARTS_WITH
        - /app-b
  - type: PARAM
    key: group
    values:
      - - EQ
        - vip
  - type: HOST
    values:
      - - ENDS_WITH
        - .app.com
  - type: HEADER
    key: LOCATION
    values:
      - - IN
        - east-1
        - east-2
  - type: COOKIE
    key: uid
    values:
      - - EXIST
  - type: SRC_IP
    values:
      - - RANGE
        - "1.1.1.1"
        - "1.1.1.100"

项目隔离

对于 rule,默认启用项目隔离,每个用户只能看到自己项目的规则。

项目模式

一个 ALB 可以被多个项目共享,这些项目可以共同管理该 ALB。ALB 的所有端口对这些项目均可见。

端口项目模式

ALB 的某个端口可以属于不同项目,该部署模式称为端口项目模式。管理员需要指定每个项目可使用的端口段,项目用户只能在该端口段内创建端口,并且只能看到该端口段内的端口。

ALB、ALB 实例、Frontend/FT、Rule、Ingress 和项目之间的关系

LoadBalancer 是现代云原生架构中的关键组件,作为智能流量路由和负载均衡器。

要理解 ALB 在 Kubernetes 集群中的工作原理,需要了解几个核心概念及其关系:

  • ALB 本身
  • Frontend (FT)
  • Rules
  • Ingress 资源
  • Projects

这些组件协同工作,实现灵活且强大的流量管理能力。

下面介绍这些概念如何协同工作,以及它们在请求调用链中的角色。每个概念的详细介绍将在其他文章中展开。

在请求调用链中:

  1. 客户端发送 HTTP/HTTPS/其他协议请求,最终请求会到达 ALB 的某个 pod,该 pod(即 ALB 实例)开始处理请求。
  2. ALB 实例查找匹配该请求的规则。
  3. 如有需要,根据规则修改/重定向/重写请求。
  4. 从规则配置的服务中选择一个 pod IP,将请求转发给该 pod。

Ingress

Ingress 是 Kubernetes 中的资源,用于描述请求应转发到哪个服务。

Ingress Controller

理解 Ingress 资源并将请求代理到服务的程序。

ALB

ALB 是一种 Ingress controller。

在 Kubernetes 集群中,我们使用 alb2 资源操作 ALB。你可以使用 kubectl get alb2 -A 查看集群中所有 ALB。

ALB 由用户手动创建。每个 ALB 有自己的 IngressClass。创建 Ingress 时,可以通过 .spec.ingressClassName 字段指定由哪个 Ingress controller 处理该 Ingress。

ALB 实例

ALB 也是集群中运行的 Deployment(多个 pod 组成)。每个 pod 称为一个 ALB 实例。

每个 ALB 实例独立处理请求,但所有实例共享同一 ALB 的 Frontend (FT)、Rule 及其他配置。

ALB-Operator

ALB-Operator 是集群中默认部署的组件,是 ALB 的 operator。它根据 ALB 资源创建/更新/删除 Deployment 及相关资源。

Frontend(简称 FT)

FT 是 ALB 自定义的资源,用于表示 ALB 实例监听的端口。

FT 可以由 ALB-Leader 或用户手动创建。

ALB-Leader 创建 FT 的情况:

  1. 如果 Ingress 有证书,创建 FT 443(HTTPS)。
  2. 如果 Ingress 无证书,创建 FT 80(HTTP)。

RULE

RULE 是 ALB 自定义的资源,作用类似于 Ingress,但更具体。

RULE 唯一关联一个 FT。

RULE 可以由 ALB-Leader 或用户手动创建。

ALB-Leader 创建 RULE 的情况:

  1. 同步 Ingress 到 RULE。

ALB Leader

在多个 ALB 实例中,会选举出一个 leader。

Leader 负责:

  1. 将 Ingress 转换为 Rules。为 Ingress 中的每个路径创建 Rule。
  2. 创建 Ingress 需要的 FT。例如,Ingress 有证书时创建 FT 443(HTTPS),无证书时创建 FT 80(HTTP)。

项目

从 ALB 角度看,项目是一组命名空间。

你可以在 ALB 中配置一个或多个项目。

当 ALB Leader 将 Ingress 转换为 Rules 时,会忽略不属于项目的命名空间中的 Ingress。

其他资源: