全部产品
Search
文档中心

负载均衡:自建Nginx Ingress迁移ALB Ingress最佳实践

更新时间:Dec 06, 2024

相较于Nginx Ingress,ALB Ingress属于全托管服务,免去了运维成本,并提供了更强大的弹性。从Nginx Ingress迁移至ALB Ingress时,ACK提供的迁移工具可自动将Nginx Ingress配置转换为ALB Ingress的配置,免去了您手动转换配置的过程。本文提供了一个迁移示例:在将Nginx Ingress的配置转换到ALB Ingress后,通过使用DNS解析,将流量逐渐转移至ALB Ingress,完成对客户端无感的迁移。

迁移流程

通过将一个域名同时解析到Nginx Ingress和ALB Ingress并逐渐调整权重,可以实现对客户端无感的迁移。下图展示了通过DNS解析完成无感迁移的大致流程,各个步骤在下方的迁移示例场景有更具体的示例展示。

说明

通过DNS解析迁移并非是无感迁移的唯一方式,本文中的示例仅供您参考。

image

迁移示例场景

通过以下示例,您可了解迁移流程中的具体操作细节和工作原理。

某企业在ACK集群中安装了Nginx Ingress Controller,并为Controller的Service选择了公网LoadBalancer类型,使Controller自动关联了一个公网类型CLB实例。该企业同时配置了DNS解析,客户端访问www.example.net时,客户端请求将被解析到CLB,并经由CLB转发后到达后端Pod。

image

步骤一:配置ALB Ingress

随着业务逐步上量,Nginx Ingress的性能已无法满足业务需求,并且产生了较为高昂的运维成本。该企业决定从Nginx Ingress迁移至ALB Ingress。迁移过程中,该企业通过ACK提供的迁移工具将Nginx Ingress的配置转换到了ALB Ingress中,并将ALB Ingress加入到了DNS解析中,给予了更低的权重。

重要

DNS协议不允许同一域名被同时解析到A记录与CNAME记录。CLB实例通过IP接收请求,而ALB实例对外提供默认域名(详见什么是应用型负载均衡ALB)。因此需要为CLB配置一个临时域名,以达到将客户请求按权重同时分配到Nginx Ingress与ALB Ingress的效果。

image

步骤二:将流量逐渐转移至ALB Ingress

经过一段时间的测试后,ALB Ingress工作正常,该企业随即提高了ALB Ingress的DNS解析权重,使更多流量经由ALB Ingress转发。

image

步骤三:删除Nginx Ingress相关资源

在将流量完全转移至ALB Ingress后,该企业删除了DNS解析中的Nginx Ingress相关条目,移除了Nginx Ingress相关资源,并卸载了Nginx Ingress Controller组件。至此,该企业已经完成了从Nginx Ingress迁移至ALB Ingress的过程,且全流程对客户端无感。

image

前提条件

已通过kubectl工具连接集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群

步骤一:配置ALB Ingress

  1. 登录容器服务管理控制台,在需要执行迁移的集群中,安装ALB Ingress Controller组件。具体操作,请参见管理ALB Ingress Controller组件。迁移工具会自动转换AlbConfigIngressClassIngress资源,因此在安装组件时请为ALB云原生网关实例来源选择暂不创建

    重要

    如需在ACK专有集群中通过ALB Ingress访问服务,在部署服务前需要为ALB Ingress Controller授权。具体操作,请参见为ACK专有集群授予ALB Ingress Controller访问权限

  2. 创建并复制下方YAML文件至ingress2albconfig.yaml中。

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: ingress2albconfig
      namespace: default
    spec:
      template:
        spec:
          containers:
          - name: ingress2albconfig
            image: registry.cn-hangzhou.aliyuncs.com/acs/ingress2albconfig:latest
            command: ["/bin/ingress2albconfig", "print"]
          restartPolicy: Never
          serviceAccount: ingress2albconfig
          serviceAccountName: ingress2albconfig
      backoffLimit: 4
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: system:ingress2albconfig
    rules:
    - apiGroups:
      - networking.k8s.io
      resources:
      - ingresses
      - ingressclasses
      verbs:
      - get
      - list
      - watch
      - update
      - create
      - patch
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ingress2albconfig
      namespace: default
    ---
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: system:ingress2albconfig
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: system:ingress2albconfig
    subjects:
      - kind: ServiceAccount
        name: ingress2albconfig
        namespace: default
  3. 执行以下命令,运行Job任务。该任务将会依据现有的Nginx Ingress Controller配置,自动转化到AlbConfigIngressClassIngress等资源并输出,后续可通过Log查看。

    kubectl apply -f ingress2albconfig.yaml

    预期输出:

    job.batch/ingress2albconfig created
    clusterrole.rbac.authorization.k8s.io/system:ingress2albconfig created
    serviceaccount/ingress2albconfig created
    clusterrolebinding.rbac.authorization.k8s.io/system:ingress2albconfig created
  4. 查看Job所属的Pod。

    kubectl get pod -l job-name=ingress2albconfig

    预期输出:

    NAME                READY   STATUS      RESTARTS   AGE
    ingress2albconfig-vw***   0/1     Completed   0          16m
  5. 查看Pod日志。

    kubectl logs ingress2albconfig-vw*** # 替换为上一步中得到的Pod名称

    预期输出如下,通过kubectl将下列资源部署到集群中后,就完成了ALB Ingress的配置。

    apiVersion: alibabacloud.com/v1
    kind: AlbConfig
    metadata:
      creationTimestamp: null
      name: from_nginx
    spec:
      config:
        accessLogConfig: {}
        edition: Standard
        name: from_nginx
        tags:
        - key: converted/ingress2albconfig
          value: "true"
        zoneMappings:
        - vSwitchId: vsw-xxx #替换为VPC中的虚拟交换机ID
        - vSwitchId: vsw-xxx #替换为VPC中的虚拟交换机ID
      listeners:
      - port: 80
        protocol: HTTP
    ---
    apiVersion: networking.k8s.io/v1
    kind: IngressClass
    metadata:
      creationTimestamp: null
      name: from_nginx
    spec:
      controller: ingress.k8s.alibabacloud/alb
      parameters:
        apiGroup: alibabacloud.com
        kind: AlbConfig
        name: from_nginx
        scope: null
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80}]'
      creationTimestamp: null
      name: from_ingress1
      namespace: default
    spec:
      ingressClassName: from_nginx
      rules:
      - http:
          paths:
          - backend:
              service:
                name: nginx-svc-g1msr
                port:
                  number: 80
            path: /
            pathType: Prefix
    status:
      loadBalancer: {}

自动转换的Annotation列表

迁移工具会将下表中的Nginx Ingress Annotation自动转换为ALB Ingress中的Annotation。

重要

不在下表中的Nginx Ingress Annotation在转换过程中会被忽略,请您在转换完成后确认ALB Ingress的配置,以避免功能与预期不符。

Annotation列表

Nginx Ingress Annotation

ALB Ingress Annotation

nginx.ingress.kubernetes.io/canary

alb.ingress.kubernetes.io/canary

nginx.ingress.kubernetes.io/canary-by-header

alb.ingress.kubernetes.io/canary-by-header

nginx.ingress.kubernetes.io/canary-by-header-value

alb.ingress.kubernetes.io/canary-by-header-value

nginx.ingress.kubernetes.io/canary-by-cookie

alb.ingress.kubernetes.io/canary-by-cookie

nginx.ingress.kubernetes.io/canary-weight

alb.ingress.kubernetes.io/canary-weight

nginx.ingress.kubernetes.io/use-regex

alb.ingress.kubernetes.io/use-regex

nginx.ingress.kubernetes.io/rewrite-target

alb.ingress.kubernetes.io/rewrite-target

nginx.ingress.kubernetes.io/ssl-redirect

alb.ingress.kubernetes.io/ssl-redirect

nginx.ingress.kubernetes.io/enable-cors

alb.ingress.kubernetes.io/enable-cors

nginx.ingress.kubernetes.io/cors-allow-origin

alb.ingress.kubernetes.io/cors-allow-origin

nginx.ingress.kubernetes.io/cors-allow-methods

alb.ingress.kubernetes.io/cors-allow-methods

nginx.ingress.kubernetes.io/cors-allow-headers

alb.ingress.kubernetes.io/cors-allow-headers

nginx.ingress.kubernetes.io/cors-expose-headers

alb.ingress.kubernetes.io/cors-expose-headers

nginx.ingress.kubernetes.io/cors-allow-credentials

alb.ingress.kubernetes.io/cors-allow-credentials

nginx.ingress.kubernetes.io/backend-protocol

alb.ingress.kubernetes.io/backend-protocol

nginx.ingress.kubernetes.io/load-balance

alb.ingress.kubernetes.io/backend-scheduler

nginx.ingress.kubernetes.io/upstream-hash-by

alb.ingress.kubernetes.io/backend-scheduler-uch-value

步骤二:将流量逐渐转移至ALB Ingress

警告
  • 流量切换前,请比对您的Nginx Ingress和ALB Ingress的转发策略,并进行测试以确保二者的功能完全一致,以免在切换过程中对您的业务产生非预期的影响。

  • 建议在业务低谷期进行流量的切换。

为CLB实例配置临时域名

因为DNS协议并不支持将一个域名同时解析到A记录与CNAME记录,且ALB实例对外提供默认域名,因此您需要为CLB配置临时域名。

  1. 登录域名解析控制台

  2. 域名解析页面,找到指向待迁移CLB实例的DNS域名www.example.net,单击该域名。

  3. 解析设置页面,单击添加记录,在添加记录面板,完成以下参数的配置,然后单击确认

    配置

    说明

    记录类型

    在下拉列表中选择CNAME

    主机记录

    域名的前缀,在本示例中输入www

    解析请求来源

    选择默认。

    记录值

    输入临时域名,在本示例中输入web0.example.net

    TTL

    全称Time To Live,表示DNS记录在DNS服务器上的缓存时间,保持默认。

  4. 解析设置页面,找到由www.example.net指向CLB实例IP的A记录,在操作列单击修改

  5. 在弹出的修改记录面板,修改主机记录,然后单击确认。本文修改主机记录为web0,其余参数保持不变。

    说明

    完成配置后,www.example.net将被CNAME条目解析到web0.example.net,而web0.example.net将被A条目解析到CLB实例的IP地址。

为ALB实例添加CNAME解析

  1. 执行以下命令,找到ALB实例的域名。

    kubectl get albconfig

    预期输出如下,其中的alb-a8mmh2tqbmrm11****.cn-hangzhou.alb.aliyuncs.com即为ALB实例的域名。

    NAME         ALBID                    DNSNAME                                               PORT&PROTOCOL   CERTID   AGE
    from_nginx   alb-a8mmh2tqbmrm11****   alb-a8mmh2tqbmrm11****.cn-hangzhou.alb.aliyuncs.com                            20m
  2. 解析设置页面,单击添加记录,在添加记录面板,完成以下参数的配置,然后单击确认

    配置

    说明

    记录类型

    在下拉列表中选择CNAME

    主机记录

    域名的前缀,在本示例中输入www

    解析请求来源

    选择默认。

    记录值

    输入ALB实例的域名。

    TTL

    全称Time To Live,表示DNS记录在DNS服务器上的缓存时间,保持默认。

设置流量权重

  1. 解析设置页面, 单击左侧导航栏的权重配置

  2. 权重配置页面,在操作列单击开启权重,然后单击设置权重

  3. 设置权重面板,分别为CLB和ALB实例的解析记录设置权重。将CLB实例对应的解析记录的权重置为100,同时将ALB实例对应的解析记录的权重设置为0。

    域名权重设置

  4. 在观察业务没有影响的情况下,逐步减少CLB实例解析记录的权重值,同时逐步增加ALB实例解析记录的权重值。

  5. 登录对应Service的后端Pod所在Worker节点上,多次执行dig命令,验证流量切换效果。

    流量测试1流量测试2

  6. 根据流量切换的验证结果,逐步将CLB实例解析记录的权重值减小至0,同时逐步增加ALB实例解析记录的权重值至100。

如果您的DNS服务解析商不支持CNAME解析的权重配置,请单击此处查看流量切换方案。

临时流量切换方案

步骤三:删除Nginx Ingress相关资源

当Nginx Ingress长连接全部处理完成,且Nginx Ingress没有新增流量时,您可以根据业务场景静默观察一段时间后释放冗余资源。

  1. 通过域名解析控制台删除Nginx Ingress相关DNS条目。

  2. 卸载Nginx Ingress Controller组件。

    1. 登录容器服务管理控制台,在左侧导航栏选择集群

    2. 在集群管理页左侧导航栏中,选择网络 > 路由

    3. 在Nginx Ingress右侧操作栏,选择image > 删除,在弹出的对话框,单击确定

    4. 在左侧导航栏中选择运维管理 > 组件管理页面,单击网络页签,在Nginx Ingress Controller卡片,单击卸载

    5. 在弹出的对话框中,单击确定

      说明

      Nginx Ingress Controller所使用的CLB会随着组件卸载自动释放,不会继续产生计费。

相关文档