赛尔校园公共服务平台 Logo
平台使用
阿里云
百度云
移动云
智算服务
教育生态
登录 →
赛尔校园公共服务平台 Logo
平台使用 阿里云 百度云 移动云 智算服务 教育生态
登录
  1. 首页
  2. 阿里云
  3. 分布式云容器平台ACK One
  4. 操作指南
  5. 多集群舰队
  6. 多集群服务
  7. ACK One多集群Service帮助大批量应用跨集群无缝迁移

ACK One多集群Service帮助大批量应用跨集群无缝迁移

  • 多集群服务
  • 发布于 2025-04-18
  • 0 次阅读
文档编辑
文档编辑

如果需要将IDC集群或第三方公共云的服务迁移至阿里云ACK,可以利用ACK One的多集群服务,在不修改代码、CoreDNS Config及Pod的DNSConfig的情况下实现无缝迁移。本文将通过模拟迁移场景介绍服务迁移的具体步骤。

背景信息

在Kubernetes集群间迁移应用是一个常见的需求,通常涉及跨云搬迁、平台重大升级或资源规划调整等情况。当需要进行跨集群迁移时,理想情况下应确保迁移过程平滑且不影响业务运行,同时将风险降至最低。在ACK上,实现跨Kubernetes集群应用迁移的主要方案有以下两种:

  1. 搬迁旧集群完整环境到新集群。

  2. 基于ACK One多集群Service,实现跨集群服务双向互通,分批迁移。

搬迁旧集群完整环境到新集群方案适合应用数量之间依赖极少的场景,而在应用数量庞大(几百上千个应用),相互之间依赖关系复杂且无法理清的情况下,会存在以下不足:

  • 应用数量庞大,全面验证所需的工作量极为庞大,迁移周期过长,通常无法接受。

  • 一次性迁移的风险不可控,依赖关系复杂,不能通过分批迁移应用来降低风险。

  • 如果不同应用分属不同团队,迁移计划和速度不一致,也可能会导致迁移过程中停机。

基于ACK One MultiClusterService的迁移方案

基于ACK One MultiClusterService实现的跨集群应用迁移方案,主要是基于ACK One多集群Service的MultiClusterService提供的跨集群服务互访能力,进而分批迁移应用,无需关注应用间的依赖关系,直至所有应用迁移成功。该迁移方案可实现大批量应用跨集群无缝迁移,具有以下优势:

  • 风险最小化:借助ACK One多集群服务功能,无需关注应用间的依赖关系,支持分批迁移,减少迁移风险,风险控制方便,并且可以快速回滚。

  • 无损迁移:该方案不会拦截业务流量,不会造成流量异常,也无需担心业务外的性能影响。

ACK One MultiClusterService简述

在舰队中创建MultiClusterService,并且在Consumer Cluster中创建同名Service,即可实现Consumer Cluster使用原生Service Name跨集群访问到Provider Cluster上的该Service。 架构如下图所示:

image

MultiClusterService yaml如下所示:

apiVersion: networking.one.alibabacloud.com/v1alpha1
kind: MultiClusterService
metadata:
   name: service
   namespace: demo
spec:
  consumerClusters:
    - name: <your consumer cluster id>
  providerClusters:
    - name: <your provider cluster id>
说明
  • name和namespace保持和要处理的Service一致。

  • 一个集群可以同时是Consumer Cluster和Provider Cluster。

  • providerClusters:指要提供该Service被其他集群访问的集群列表。

  • consumerClusters:指要访问该Service的集群列表。

关于ACK One MultiClusterService详细信息及使用方式,请参见使用原生Service域名跨集群服务访问。

跨集群应用迁移方案

在迁移过程中,由于应用和服务众多且服务间依赖关系复杂,整个过程可能需要较长时间。因此,在迁移期间,需要确保Old Cluster和New Cluster之间能够通过服务域名进行双向跨集群访问。这样可以逐步分批迁移服务,最终将所有服务迁移到New Cluster。待所有服务迁移完成后,将外部流量切换到New Cluster,从而完成整个迁移过程。迁移方案如下所示。

image
  1. 将Old Cluster中所有Service资源都部署到New Cluster中,并为所有Service在舰队中创建MultiClusterService(每个Service对应一个同名的MultiClusterService)。

  2. 从Old Cluster中选择一批要迁移的服务,如图中的Service2,将其Deployment部署到New Cluster中。

  3. 此时Service1会有部分流量路由到New Cluster的Service2后端,验证无误后,将Old Cluster中的Service2的副本数缩容为0,以便将所有到Service2的流量路由到New Cluster中的Service2后端。

    若验证有误,则将New Cluster的Deployment副本缩容为0,修复后再扩容副本数。

  4. 重复执行2和3,继续迁移下一批服务,直至所有服务迁移完成。

  5. 最后迁移Front Service后将流量完全切换到New Cluster。

前提条件

  • 已开启舰队管理功能。

  • 舰队的Fleet实例已添加2个关联集群(Old Cluster & New Cluster)。具体操作,请参见管理关联集群。

  • 关联集群的版本不低于1.22。

  • 关联集群(Old Cluster & New Cluster)的Pod CIDR已相互可通。具体操作,请参见多集群服务概述。

  • 获取服务Old Cluster和New Cluster的KubeConfig,并通过kubectl连接集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群。

步骤一:在Old Cluster中部署Service和Deployment

连接子集群部署应用

  1. 使用Old Cluster的KubeConfig,通过以下示例内容,创建web-demo-svc-old.yaml。

    展开查看YAML内容

    apiVersion: v1
    kind: Service
    metadata:
      name: service1
      namespace: mcs-demo
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        app: service1
      type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: service1
      name: svc-demo-service1
      namespace: mcs-demo
    spec:
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: service1
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: service1
        spec:
          containers:
          - env:
            - name: ENV_NAME
              value: oldcluster
            - name: MY_SERVICE_NAME
              value: service1
            - name: SERVICE_URL
              value: http://service2.mcs-demo:80/call
            - name: MY_CLUSTER
              value: oldcluster
            image: registry-cn-hongkong.ack.aliyuncs.com/acs/web-demo:v0.6.0-2
            imagePullPolicy: Always
            name: svc-demo
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: service2
      namespace: mcs-demo
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        app: service2
      type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: service2
      name: svc-demo-service2
      namespace: mcs-demo
    spec:
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: service2
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: service2
        spec:
          containers:
          - env:
            - name: ENV_NAME
              value: oldcluster
            - name: MY_SERVICE_NAME
              value: service2
            - name: SERVICE_URL
              value: http://service3.mcs-demo:80/svc
            - name: MY_CLUSTER
              value: oldcluster
            image: registry-cn-hongkong.ack.aliyuncs.com/acs/web-demo:v0.6.0-2
            imagePullPolicy: Always
            name: svc-demo
      
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: service3
      namespace: mcs-demo
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        app: service3
      type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: service3
      name: svc-demo-service3
      namespace: mcs-demo
    spec:
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: service3
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: service3
        spec:
          containers:
          - env:
            - name: ENV_NAME
              value: oldcluster
            - name: MY_SERVICE_NAME
              value: service3
            - name: SERVICE_URL
              value: http://service3.mcs-demo:80/svc
            - name: MY_CLUSTER
              value: oldcluster
            image: registry-cn-hongkong.ack.aliyuncs.com/acs/web-demo:v0.6.0-2
            imagePullPolicy: Always
            name: svc-demo
  2. 执行以下命令,在Old Cluster中部署三个服务的Service和Deployment资源。

    kubectl apply -f web-demo-svc-old.yaml
  3. 使用以下内容,创建client-pod.yaml。

    apiVersion: v1
    kind: Pod
    metadata:
      name: curl-client
    spec:
      containers:
      - name: curl-client
        image: registry-cn-hangzhou.ack.aliyuncs.com/dev/curl:8.11.1
        command: ["sh", "-c", "sleep 12000"]
  4. 执行以下命令,部署Client Pod用于访问链路。

    kubectl apply -f client-pod.yaml

通过GitOps为子集群分发应用

  1. 使用舰队KubeConfig,执行以下命令获取Server URL。

    kubectl get secret -n argocd cluster-<Old-Clsuter-ID> -ojsonpath='{.data.server}' |base64 -d
  2. 部署三个服务的Service和Deployment资源。

    1. 登录ACK One控制台,在左侧导航栏选择舰队 > 多集群应用。

    2. 在多集群应用页面左上角,单击舰队名称后的Dingtalk_20231226104633.jpg按钮,在下拉列表中选择目标舰队。

    3. 单击创建多集群应用 > GitOps进入创建多集群应用 - GitOps页面。

    4. 在YAML创建页签,将以下示例YAML内容复制到控制台,然后单击确定部署应用。

      apiVersion: argoproj.io/v1alpha1
      kind: ApplicationSet
      metadata:
        name: svc-demo-oldcluster
        namespace: argocd
      spec:
        generators:
          - list:
              elements:
              - envSvcName: service1
                envCluster: oldcluster
                envCallSvcName: service2
                envAPI: call
              - envSvcName: service2
                envCluster: oldcluster
                envCallSvcName: service3
                envAPI: svc
              - envSvcName: service3
                envCluster: oldcluster
                envCallSvcName: service3
                envAPI: svc
        template:
          metadata:
            name: '{{envSvcName}}-{{envCluster}}-svc-demo'
          spec:
            project: default
            source:
              repoURL: https://github.com/AliyunContainerService/gitops-demo.git 
              targetRevision: main
              path: manifests/helm/svc-demo
              helm:
                parameters:
                - name: envSvcName
                  value: '{{envSvcName}}'
                - name: envCallSvcName
                  value: '{{envCallSvcName}}'
                - name: envAPI
                  value: '{{envAPI}}'
                - name: envCluster
                  value: '{{envCluster}}'
                valueFiles:
                  - values.yaml
            destination:
              server: <Your-Old-Cluster-Server-URL>   # 请替换<Your-Old-Cluster-Server-URL>为对应集群的Server URL。
              namespace: mcs-demo
            syncPolicy:
              automated: {}
              syncOptions:
                - CreateNamespace=true
  3. 部署Client Pod用于访问链路。

    在多集群应用页面单击GitOps控制台,进入ArgoCD UI页面创建以下Application 。

    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
      name: curl-client-pod
      namespace: argocd
    spec:
      destination:
        namespace: customer-ns
        server: <Your-Old-Cluster-Server-URL>   # 请替换<Your-Old-Cluster-Server-URL>为对应集群的Server URL。
      project: default
      source:
        path: manifests/directory/curlclient
        repoURL: https://github.com/AliyunContainerService/gitops-demo.git
        targetRevision: HEAD
      syncPolicy:
        syncOptions:
        - CreateNamespace=true

创建成功后,在Client Pod中执行以下命令测试调用链路。

kubectl exec -it -ncustomer-ns curl-client -- sh
curl service1.mcs-demo/call

预期输出:

service1(oldcluster) --> service2(oldcluster) --> service3(oldcluster)

步骤二:在New Cluster中部署Old Cluster中全量Service

连接子集群部署应用

  1. 使用New Cluster的KubeConfig,通过以下示例内容,创建web-demo-svc-new.yaml。

    apiVersion: v1
    kind: Service
    metadata:
      name: service1
      namespace: mcs-demo
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        app: service1
      type: ClusterIP
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: service2
      namespace: mcs-demo
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        app: service2
      type: ClusterIP
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: service3
      namespace: mcs-demo
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        app: service3
      type: ClusterIP
  2. 执行以下命令,部署service1、service2、service3三个服务的Service资源。

    kubectl apply -f web-demo-svc-new.yaml

通过GitOps为子集群分发应用

  1. 使用舰队KubeConfig,执行以下命令获取Server URL。

    kubectl get secret -n argocd cluster-<New-Clsuter-ID> -ojsonpath='{.data.server}' |base64 -d
  2. 登录ACK One控制台,在左侧导航栏选择舰队 > 多集群应用。

  3. 在多集群应用页面左上角,单击舰队名称后的Dingtalk_20231226104633.jpg按钮,在下拉列表中选择目标舰队。

  4. 单击创建多集群应用 > GitOps进入创建多集群应用 - GitOps页面。

  5. 在YAML创建页签,将以下示例YAML内容复制到控制台,然后单击确定部署应用。

    apiVersion: argoproj.io/v1alpha1
    kind: ApplicationSet
    metadata:
      name: svc-demo-newcluster
      namespace: argocd
    spec:
      generators:
        - list:
            elements:
            - envSvcName: service1
              envCluster: newcluster
              onlyService: "true"
            - envSvcName: service2
              envCluster: newcluster
              onlyService: "true"
            - envSvcName: service3
              envCluster: newcluster
              onlyService: "true"
      template:
        metadata:
          name: '{{envSvcName}}-{{envCluster}}-svc-demo'
        spec:
          project: default
          source:
            repoURL: https://github.com/AliyunContainerService/gitops-demo.git
            targetRevision: main
            path: manifests/helm/svc-demo
            helm:
              parameters:
              - name: envSvcName
                value: '{{envSvcName}}'
              - name: onlyService
                value: '{{onlyService}}'
              valueFiles:
                - values.yaml
          destination:
            server: <Your-New-Cluster-Server-URL>   # 请替换<Your-New-Cluster-Server-URL>为对应集群的Server URL。
            namespace: mcs-demo
          syncPolicy:
            automated: {}
            syncOptions:
              - CreateNamespace=true

步骤三:在舰队中创建所有服务的MultiClusterService

  1. 使用以下命令在舰队创建Service的Namespace。

    kubectl create ns mcs-demo
  2. 使用舰队的KubeConfig,通过以下示例内容,创建multiclusterservice.yaml。

    说明
    • 请将 <Your-New-Cluster-ID> 和 <Your-Old-Cluster-ID> 替换为您关联的集群ID。

    • MultiClusterService的name和namespace需与要提供跨集群访问的服务保持一致。

    apiVersion: networking.one.alibabacloud.com/v1alpha1
    kind: MultiClusterService
    metadata:
       name: service1
       namespace: mcs-demo
    spec:
      consumerClusters:
        - name: <Your-New-Cluster-ID>
        - name: <Your-Old-Cluster-ID>
      providerClusters:
        - name: <Your-New-Cluster-ID>
        - name: <Your-Old-Cluster-ID>
    ---
    apiVersion: networking.one.alibabacloud.com/v1alpha1
    kind: MultiClusterService
    metadata:
       name: service2
       namespace: mcs-demo
    spec:
      consumerClusters:
        - name: <Your-New-Cluster-ID>
        - name: <Your-Old-Cluster-ID>
      providerClusters:
        - name: <Your-New-Cluster-ID>
        - name: <Your-Old-Cluster-ID>
    ---
    apiVersion: networking.one.alibabacloud.com/v1alpha1
    kind: MultiClusterService
    metadata:
       name: service3
       namespace: mcs-demo
    spec:
      consumerClusters:
        - name: <Your-New-Cluster-ID>
        - name: <Your-Old-Cluster-ID>
      providerClusters:
        - name: <Your-New-Cluster-ID>
        - name: <Your-Old-Cluster-ID>
  3. 执行以下命令,在舰队中创建所有服务的MultiClusterService。

    kubectl apply -f multiclusterservice.yaml

步骤四:在New Cluster中部署要迁移Service的Deployment

完成上述步骤后,目前的调用链仍为service1(oldcluster) --> service2(oldcluster) --> service3(oldcluster)。本步骤将模拟迁移随机选择的Service2,部署其Deployment到New Cluster,Pod Running后将会有流量路由到New Cluster的Service2后端。

  1. 使用New Cluster的KubeConfig,通过以下示例内容,创建web-demo-new.yaml。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: service2
      name: svc-demo-service2
      namespace: mcs-demo
    spec:
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: service2
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: service2
        spec:
          containers:
          - env:                    # 环境变量中使用newcluster,与Old Cluster中的Deployment的oldcluster链路进行区分。 
            - name: ENV_NAME
              value: newcluster                 
            - name: MY_SERVICE_NAME
              value: service2
            - name: SERVICE_URL
              value: http://service3.mcs-demo:80/svc
            - name: MY_CLUSTER
              value: newcluster
            image: registry-cn-hangzhou.ack.aliyuncs.com/dev/web-demo:v0.6.0
            imagePullPolicy: Always
            name: svc-demo
  2. 执行以下命令,在New Cluster中创建Service2后端应用。

    kubectl apply -f web-demo-new.yaml
  3. 创建成功后,在Client Pod中执行以下命令测试调用链路。

    kubectl exec -it -ncustomer-ns curl-client -- sh
    curl service1.mcs-demo/call

    预期输出:

    service1(oldcluster) --> service2(newcluster) --> service3(oldcluster)
    说明
    • 验证无误后,将Old Cluster中的Service2的副本数缩容为0,以便将所有到Service2的流量路由到New Cluster中的Service2后端。

    • 若验证有误,则将New Cluster的Deployment副本缩容为0,修复后再扩容副本数。

  4. 重复执行该步骤,直至所有服务迁移完成。迁移完成后,将所有外部流量重定向至新集群的Front Service,以完成整个迁移过程。

相关文章

多集群服务概述 2025-04-18 18:10

随着Kubernetes集群的广泛应用,企业往往需要运行和管理多个Kubernetes集群,来满足业务隔离部署运维的需求,但业务之间还需要相互访问。通过多集群服务,让您无需创建负载均衡,即可实现Kubernetes服务的跨集群访问。本文介绍多集群服务的架构、场景和网络规划。

通过命令行管理多集群服务 2025-04-18 18:10

通过多集群服务,让您无需创建负载均衡,即可实现Kubernetes服务的跨集群访问。本文通过示例介绍如何在Fleet实例上创建ServiceExport、ServiceImport等资源来管理多集群服务,实现Kubernetes服务的跨集群访问。 前提条件

通过控制台管理多集群服务 2025-04-18 18:10

通过多集群服务,您无需创建负载均衡,即可实现Kubernetes服务的跨集群访问。本文介绍如何通过控制台来管理多集群服务,实现Kubernetes服务的跨集群访问。 概述 通过多集群服务实现Kubernetes服务的

使用多集群Ingress 2025-04-18 18:10

Ingress为Kubernetes集群中对外的七层负载均衡,可通过Ingress规则描述将请求匹配到对应的后端服务和应用上。您可以通过配置多集群Service和Ingress规则,将请求转发到多个集群中的服务。本文介绍如何使用多集群Ingress。

通过Headless类型多集群Service跨集群访问有状态服务的指定实例 2025-04-18 18:10

通过多集群服务,无需负载均衡,即可实现Kubernetes服务的跨集群访问。Headless类型服务不仅支持跨集群服务访问,还可以根据域名选择服务中的指定Pod实例进行访问,适用于有状态服务(StatefulSets)的应用,如分布式数据库、消息队列等。本文以MySQL为例,介绍如何通过Headle

使用原生Service域名跨集群服务访问 2025-04-18 18:09

ACK One多集群Service支持通过MultiClusterService实现用原生Service域名跨集群服务访问。无需修改业务代码、业务Pod的DNSConfig配置或CoreDNS配置,直接使用原生Service便可实现跨集群流量路由。 前提条件

目录
Copyright © 2025 your company All Rights Reserved. Powered by 赛尔网络.
京ICP备14022346号-15
gongan beian 京公网安备11010802041014号