9.2. 使用命令行迁移应用程序

您可以使用命令行界面 (CLI) 使用 MTC API 迁移应用程序,以便自动执行迁移。

9.2.1. 迁移先决条件

  • 必须使用在所有集群中具有 cluster-admin 权限的用户登录。

直接镜像迁移

  • 您必须确保源集群的安全内部 registry 被公开。
  • 您必须创建指向公开 registry 的路由。

直接卷迁移

  • 如果您的集群使用代理,您必须配置 Stunnel TCP 代理。

集群

  • 源集群必须升级到最新的 MTC z-stream 版本。
  • 在所有集群中,MTC 版本必须相同。

Network

  • 集群在相互间有无限制的网络访问,并可以访问复制存储库。
  • 如果您复制有 移动 的持久性卷,集群必须具有对远程卷的不受限制的网络访问权限。
  • 您必须在 OpenShift Container Platform 4 集群中启用以下端口:

    • 6443 (API 服务器)
    • 443 (路由)
    • 53 (DNS)
  • 如果使用 TLS,则必须在复制存储库中启用端口 443

持久性卷(PV)

  • PV 必须有效。
  • PV 必须绑定到持久性卷声明。
  • 如果使用快照复制 PV,则需要满足以下额外先决条件:

    • 云供应商必须支持快照。
    • PV 必须具有相同的云供应商。
    • PV 必须位于同一区域。
    • PV 必须具有相同的存储类。

9.2.2. 创建用于直接镜像迁移的 registry 路由

要直接镜像迁移,您必须在所有远程集群中创建到公开的内部 registry 的路由。

先决条件

  • 内部 registry 必须公开给所有远程集群上的外部流量。

    OpenShift Container Platform 4 registry 默认公开。

流程

  • 要创建到 OpenShift Container Platform 4 registry 的路由,请运行以下命令:

    $ oc create route passthrough --service=image-registry -n openshift-image-registry

9.2.3. 代理配置

对于 OpenShift Container Platform 4.1 及更早的版本,您必须在安装 Migration Toolkit for Containers Operator 后,在 MigrationController 自定义资源 (CR) 清单中配置代理,因为这些版本不支持集群范围的 proxy 对象。

对于 OpenShift Container Platform 4.2 到 4.8,MTC 会继承集群范围的代理设置。如果要覆盖集群范围的代理设置,可以更改代理参数。

9.2.3.1. 直接卷迁移

MTC 1.4.2 中引入了直接卷迁移(DVM)。DVM 只支持一个代理。如果目标集群也位于代理后面,则源集群无法访问目标集群的路由。

如果要从代理后面的源集群执行 DVM,您必须配置一个 TCP 代理,该代理可在传输层进行透明处理,并在不使用自己的 SSL 证书的情况下转发 SSL 连接。Stunnel 代理是此类代理的示例。

9.2.3.1.1. DVM 的 TCP 代理设置

您可以通过 TCP 代理在源和目标集群之间设置直接连接,并在 MigrationController CR 中配置 stunnel_tcp_proxy 变量来使用代理:

apiVersion: migration.openshift.io/v1alpha1
kind: MigrationController
metadata:
  name: migration-controller
  namespace: openshift-migration
spec:
  [...]
  stunnel_tcp_proxy: http://username:password@ip:port

直接卷迁移(DVM)只支持代理的基本身份验证。此外,DVM 仅适用于可透明地传输 TCP 连接的代理。在 man-in-the-middle 模式中的 HTTP/HTTPS 代理无法正常工作。现有的集群范围的代理可能不支持此行为。因此,DVM 的代理设置意与 MTC 中常见的代理配置不同。

9.2.3.1.2. 为什么使用 TCP 代理而不是 HTTP/HTTPS 代理?

您可以通过 OpenShift 路由在源和目标集群之间运行 Rsync 来启用 DVM。流量通过 TCP 代理(Stunnel)加密。在源集群上运行的 Stunnel 会启动与目标 Stunnel 的 TLS 连接,并通过加密频道来传输数据。

OpenShift 中的集群范围 HTTP/HTTPS 代理通常在 man-in-the-middle 模式进行配置,其中它们将自己的 TLS 会话与外部服务器协商。但是,这不适用于 Stunnel。Stunnel 要求代理不处理它的 TLS 会话,基本上使代理成为一个透明的隧道,只需按原样转发 TCP 连接。因此,您必须使用 TCP 代理。

9.2.3.1.3. 已知问题

迁移失败并显示 Upgrade request required 错误

迁移控制器使用 SPDY 协议在远程 pod 中执行命令。如果远程集群位于代理或不支持 SPDY 协议的防火墙后,迁移控制器将无法执行远程命令。迁移失败并显示出错信息 Upgrade request required。临时解决方案: 使用支持 SPDY 协议的代理。

除了支持 SPDY 协议外,代理或防火墙还必须将 Upgrade HTTP 标头传递给 API 服务器。客户端使用此标头打开与 API 服务器的 websocket 连接。如果代理或防火墙阻止 Upgrade 标头,则迁移会失败,并显示出错信息 Upgrade request required。临时解决方案:确保代理转发 Upgrade 标头。

9.2.3.2. 为迁移调优网络策略

OpenShift 支持根据集群使用的网络插件,限制使用 NetworkPolicyEgressFirewalls 的流量。如果任何涉及迁移的源命名空间使用此类机制将网络流量限制到 pod,限制可能会在迁移过程中停止到 Rsync pod 的流量。

在源和目标集群上运行的 rsync pod 必须通过 OpenShift Route 相互连接。可将现有的 NetworkPolicyEgressNetworkPolicy 对象配置为从这些流量限制自动排除 Rsync pod。

9.2.3.2.1. NetworkPolicy 配置
9.2.3.2.1.1. 来自 Rsync pod 的出口流量

如果源或目标命名空间中的 NetworkPolicy 配置阻止这种类型的流量,您可以使用 Rsync pod 的唯一标签来允许出口流量从它们传递。以下策略允许来自命名空间中 Rsync pod 的所有出口流量:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-egress-from-rsync-pods
spec:
  podSelector:
    matchLabels:
      owner: directvolumemigration
      app: directvolumemigration-rsync-transfer
  egress:
  - {}
  policyTypes:
  - Egress
9.2.3.2.1.2. 到 Rsync pod 的入口流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-egress-from-rsync-pods
spec:
  podSelector:
    matchLabels:
      owner: directvolumemigration
      app: directvolumemigration-rsync-transfer
  ingress:
  - {}
  policyTypes:
  - Ingress
9.2.3.2.2. EgressNetworkPolicy 配置

EgressNetworkPolicy 对象或 Egress Firewalls 是 OpenShift 构造,用于阻止离开集群的出口流量。

NetworkPolicy 对象不同,egress Firewall 在项目级别工作,因为它适用于命名空间中的所有 pod。因此,Rsync pod 的唯一标签不会使只有 Rsync pod 的 Rsync pod 冲突。但是,您可以将源集群或目标集群的 CIDR 范围添加到策略的 Allow 规则中,以便可以在两个集群之间设置直接连接。

根据存在 Egress Firewall 的集群,您可以添加其他集群的 CIDR 范围来允许两者间的出口流量:

apiVersion: network.openshift.io/v1
kind: EgressNetworkPolicy
metadata:
  name: test-egress-policy
  namespace: <namespace>
spec:
  egress:
  - to:
      cidrSelector: <cidr_of_source_or_target_cluster>
    type: Deny
9.2.3.2.3. 为 Rsync pod 配置补充组

当 PVC 使用共享存储时,您可以通过将 supplemental 组添加到 Rsync pod 定义来配置对存储的访问,以便 pod 允许访问:

表 9.2. Rsync pod 的附加组群

变量类型Default(默认)描述

src_supplemental_groups

字符串

未设置

用于源 Rsync pod 的以逗号分隔的补充组列表

target_supplemental_groups

字符串

未设置

目标 Rsync pod 的,以逗号分隔的补充组列表

用法示例

可以更新 MigrationController CR,以便为这些补充组设置值:

spec:
  src_supplemental_groups: "1000,2000"
  target_supplemental_groups: "2000,3000"

9.2.3.3. 配置代理

先决条件

  • 必须使用在所有集群中具有 cluster-admin 权限的用户登录。

流程

  1. 获取 MigrationController CR 清单:

    $ oc get migrationcontroller <migration_controller> -n openshift-migration
  2. 更新代理参数:

    apiVersion: migration.openshift.io/v1alpha1
    kind: MigrationController
    metadata:
      name: <migration_controller>
      namespace: openshift-migration
    ...
    spec:
      stunnel_tcp_proxy: http://<username>:<password>@<ip>:<port> 1
      noProxy: example.com 2
    1
    用于直接卷迁移的 stunnel 代理 URL。
    2
    要排除代理的目标域名、域、IP 地址或其他网络 CIDR 的逗号分隔列表。

    在域前面加上 . 以仅匹配子域。例如: .y.com 匹配 x.y.com,但不匹配 y.com。使用 * 可对所有目的地绕过所有代理。如果您扩展了未包含在安装配置中 networking.machineNetwork[].cidr 字段定义的 worker,您必须将它们添加到此列表中,以防止连接问题。

    如果未设置 httpProxyhttpsProxy 字段,则此字段将被忽略。

  3. 将清单保存为 migration-controller.yaml
  4. 应用更新的清单:

    $ oc replace -f migration-controller.yaml -n openshift-migration

9.2.4. 使用 MTC API 迁移应用程序

您可以使用 MTC API 从命令行迁移应用程序。

流程

  1. 为主机集群创建一个 MigCluster CR 清单:

    $ cat << EOF | oc apply -f -
    apiVersion: migration.openshift.io/v1alpha1
    kind: MigCluster
    metadata:
      name: <host_cluster>
      namespace: openshift-migration
    spec:
      isHostCluster: true
    EOF
  2. 为每个远程集群创建一个 Secret CR 清单:

    $ cat << EOF | oc apply -f -
    apiVersion: v1
    kind: Secret
    metadata:
      name: <cluster_secret>
      namespace: openshift-config
    type: Opaque
    data:
      saToken: <sa_token> 1
    EOF
    1
    指定远程集群的 base64 编码的 migration-controller 服务帐户(SA)令牌。您可以运行以下命令来获取令牌:
    $ oc sa get-token migration-controller -n openshift-migration | base64 -w 0
  3. 为每个远程集群创建一个 MigCluster CR 清单:

    $ cat << EOF | oc apply -f -
    apiVersion: migration.openshift.io/v1alpha1
    kind: MigCluster
    metadata:
      name: <remote_cluster> 1
      namespace: openshift-migration
    spec:
      exposedRegistryPath: <exposed_registry_route> 2
      insecure: false 3
      isHostCluster: false
      serviceAccountSecretRef:
        name: <remote_cluster_secret> 4
        namespace: openshift-config
      url: <remote_cluster_url> 5
    EOF
    1
    指定远程集群的 Cluster CR。
    2
    可选: 要直接镜像迁移,请指定公开的 registry 路由。
    3
    如果 false 则启用 SSL 验证。如果为 true,则不需要 CA 证书或不检查 CA 证书。
    4
    指定远程集群的 Secret CR 对象。
    5
    指定远程集群的 URL。
  4. 验证所有集群是否处于 Ready 状态:

    $ oc describe cluster <cluster>
  5. 为复制存储库创建 Secret CR 清单:

    $ cat << EOF | oc apply -f -
    apiVersion: v1
    kind: Secret
    metadata:
      namespace: openshift-config
      name: <migstorage_creds>
    type: Opaque
    data:
      aws-access-key-id: <key_id_base64> 1
      aws-secret-access-key: <secret_key_base64> 2
    EOF
    1
    指定 base64 格式的密钥 ID。
    2
    指定 base64 格式的 secret 密钥。

    AWS 凭证默认为 base64 编码。对于其他存储供应商,您必须使用每个密钥运行以下命令来对凭证进行编码:

    $ echo -n "<key>" | base64 -w 0 1
    1
    指定密钥 ID 或 secret 密钥。这两个密钥都必须都是 base64 编码。
  6. 为复制存储库创建一个 MigStorage CR 清单:

    $ cat << EOF | oc apply -f -
    apiVersion: migration.openshift.io/v1alpha1
    kind: MigStorage
    metadata:
      name: <migstorage>
      namespace: openshift-migration
    spec:
      backupStorageConfig:
        awsBucketName: <bucket> 1
        credsSecretRef:
          name: <storage_secret> 2
          namespace: openshift-config
      backupStorageProvider: <storage_provider> 3
      volumeSnapshotConfig:
        credsSecretRef:
          name: <storage_secret> 4
          namespace: openshift-config
      volumeSnapshotProvider: <storage_provider> 5
    EOF
    1
    指定存储桶名称。
    2
    指定对象存储的 Secrets CR。您必须确保存储在对象存储的 Secrets CR 中的凭证是正确的。
    3
    指定存储供应商。
    4
    可选: 如果要使用快照复制数据,请指定对象存储的 Secrets CR。您必须确保存储在对象存储的 Secrets CR 中的凭证是正确的。
    5
    可选: 如果您使用快照复制数据,请指定存储供应商。
  7. 验证 MigStorage CR 是否处于 Ready 状态:

    $ oc describe migstorage <migstorage>
  8. 创建一个 MigPlan CR 清单:

    $ cat << EOF | oc apply -f -
    apiVersion: migration.openshift.io/v1alpha1
    kind: MigPlan
    metadata:
      name: <migplan>
      namespace: openshift-migration
    spec:
      destMigClusterRef:
        name: <host_cluster>
        namespace: openshift-migration
      indirectImageMigration: true 1
      indirectVolumeMigration: true 2
      migStorageRef:
        name: <migstorage> 3
        namespace: openshift-migration
      namespaces:
        - <source_namespace_1> 4
        - <source_namespace_2>
        - <source_namespace_3>:<destination_namespace> 5
      srcMigClusterRef:
        name: <remote_cluster> 6
        namespace: openshift-migration
    EOF
    1
    如果为 false,则启用直接镜像迁移。
    2
    如果为 false,则启用直接卷迁移。
    3
    指定 MigStorage CR 实例的名称。
    4
    指定一个或多个源命名空间。默认情况下,目标命名空间具有相同的名称。
    5
    如果目标命名空间与源命名空间不同,请指定目标命名空间。
    6
    指定源集群 MigCluster 实例的名称。
  9. 验证 MigPlan 实例是否处于 Ready 状态:

    $ oc describe migplan <migplan> -n openshift-migration
  10. 创建一个 MigMigration CR 清单,以启动 MigPlan 实例中定义的迁移:

    $ cat << EOF | oc apply -f -
    apiVersion: migration.openshift.io/v1alpha1
    kind: MigMigration
    metadata:
      name: <migmigration>
      namespace: openshift-migration
    spec:
      migPlanRef:
        name: <migplan> 1
        namespace: openshift-migration
      quiescePods: true 2
      stage: false 3
      rollback: false 4
    EOF
    1
    指定 MigPlan CR 名称。
    2
    如果为 true,则源集群上的 pod 会在迁移前停止。
    3
    如果为 true,则进行阶段(stage)迁移,即在不停止应用程序的情况下复制大多数数据。
    4
    如果为 true,则会回滚到一个已完成的迁移。
  11. 通过观察 MigMigration CR 进度来验证迁移:

    $ oc watch migmigration <migmigration> -n openshift-migration

    输出类似于以下:

    输出示例

    Name:         c8b034c0-6567-11eb-9a4f-0bc004db0fbc
    Namespace:    openshift-migration
    Labels:       migration.openshift.io/migplan-name=django
    Annotations:  openshift.io/touch: e99f9083-6567-11eb-8420-0a580a81020c
    API Version:  migration.openshift.io/v1alpha1
    Kind:         MigMigration
    ...
    Spec:
      Mig Plan Ref:
        Name:       migplan
        Namespace:  openshift-migration
      Stage:        false
    Status:
      Conditions:
        Category:              Advisory
        Last Transition Time:  2021-02-02T15:04:09Z
        Message:               Step: 19/47
        Reason:                InitialBackupCreated
        Status:                True
        Type:                  Running
        Category:              Required
        Last Transition Time:  2021-02-02T15:03:19Z
        Message:               The migration is ready.
        Status:                True
        Type:                  Ready
        Category:              Required
        Durable:               true
        Last Transition Time:  2021-02-02T15:04:05Z
        Message:               The migration registries are healthy.
        Status:                True
        Type:                  RegistriesHealthy
      Itinerary:               Final
      Observed Digest:         7fae9d21f15979c71ddc7dd075cb97061895caac5b936d92fae967019ab616d5
      Phase:                   InitialBackupCreated
      Pipeline:
        Completed:  2021-02-02T15:04:07Z
        Message:    Completed
        Name:       Prepare
        Started:    2021-02-02T15:03:18Z
        Message:    Waiting for initial Velero backup to complete.
        Name:       Backup
        Phase:      InitialBackupCreated
        Progress:
          Backup openshift-migration/c8b034c0-6567-11eb-9a4f-0bc004db0fbc-wpc44: 0 out of estimated total of 0 objects backed up (5s)
        Started:        2021-02-02T15:04:07Z
        Message:        Not started
        Name:           StageBackup
        Message:        Not started
        Name:           StageRestore
        Message:        Not started
        Name:           DirectImage
        Message:        Not started
        Name:           DirectVolume
        Message:        Not started
        Name:           Restore
        Message:        Not started
        Name:           Cleanup
      Start Timestamp:  2021-02-02T15:03:18Z
    Events:
      Type    Reason   Age                 From                     Message
      ----    ------   ----                ----                     -------
      Normal  Running  57s                 migmigration_controller  Step: 2/47
      Normal  Running  57s                 migmigration_controller  Step: 3/47
      Normal  Running  57s (x3 over 57s)   migmigration_controller  Step: 4/47
      Normal  Running  54s                 migmigration_controller  Step: 5/47
      Normal  Running  54s                 migmigration_controller  Step: 6/47
      Normal  Running  52s (x2 over 53s)   migmigration_controller  Step: 7/47
      Normal  Running  51s (x2 over 51s)   migmigration_controller  Step: 8/47
      Normal  Ready    50s (x12 over 57s)  migmigration_controller  The migration is ready.
      Normal  Running  50s                 migmigration_controller  Step: 9/47
      Normal  Running  50s                 migmigration_controller  Step: 10/47

9.2.5. 状态迁移

您可以使用 Migration Toolkit for Containers(MTC)迁移组成应用程序状态的持久性卷声明(PVC),执行可重复的、仅状态的迁移。您可以通过从迁移计划中排除其他 PVC 来迁移指定的 PVC。您可以映射 PVC 以确保源和目标 PVC 同步。持久性卷 (PV) 数据复制到目标集群。PV 引用不会被移动,应用程序 pod 将继续在源集群中运行。

State 迁移专门设计用于外部 CD 机制,如 OpenShift Gitops。在使用 MTC 迁移状态时,您可以使用 GitOps 迁移应用程序清单。

如果您有 CI/CD 管道,您可以通过在目标集群中部署无状态组件来迁移它们。然后,您可以使用 MTC 迁移有状态组件。

您可以在集群间或同一集群中执行状态迁移。

重要

状态迁移仅迁移构成应用状态的组件。如果要迁移整个命名空间,请使用 stage 或 cutover migration。

先决条件

  • 源集群中的应用程序状态在通过 PersistentVolumeClaims 置备的 PersistentVolume 中保留。
  • 应用程序的清单在中央存储库中可用,它们同时可从源和目标集群访问。

流程

  1. 将持久性卷数据从源迁移到目标集群。

    您可以根据需要多次执行此步骤。源应用程序继续运行。

  2. 静止源应用程序。

    您可以通过在源集群上直接将工作负载资源副本设置为 0 来完成此操作,或者更新 GitHub 中的清单并重新同步 Argo CD 应用程序。

  3. 将应用程序清单克隆到目标集群。

    您可以使用 Argo CD 将应用程序清单克隆到目标集群。

  4. 将剩余的卷数据从源迁移到目标集群。

    通过执行最终数据迁移,在状态迁移过程中迁移应用程序创建的任何新数据。

  5. 如果克隆的应用程序处于静默状态,请取消静止它。
  6. 将 DNS 记录切换到目标集群,将用户流量重新定向到已迁移的应用程序。
注意

在执行状态迁移时,MTC 1.6 无法自动静止应用程序。它只能迁移 PV 数据。因此,您必须使用 CD 机制来静止或取消静止应用程序。

MTC 1.7 引入了明确的 Stage 和 Cutover 流。您可以根据需要,使用暂存来执行初始数据传输。然后,您可以执行一个可自动静止源应用程序。

先决条件

  • 源集群中的应用程序状态在通过 PersistentVolumeClaims 置备的 PersistentVolume 中保留。
  • 应用程序的清单在中央存储库中可用,它们同时可从源和目标集群访问。

流程

  1. 将持久性卷数据从源迁移到目标集群。

    您可以根据需要多次执行此步骤。源应用程序继续运行。

  2. 静止源应用程序。

    您可以通过在源集群上直接将工作负载资源副本设置为 0 来完成此操作,或者更新 GitHub 中的清单并重新同步 Argo CD 应用程序。

  3. 将应用程序清单克隆到目标集群。

    您可以使用 Argo CD 将应用程序清单克隆到目标集群。

  4. 将剩余的卷数据从源迁移到目标集群。

    通过执行最终数据迁移,在状态迁移过程中迁移应用程序创建的任何新数据。

  5. 如果克隆的应用程序处于静默状态,请取消静止它。
  6. 将 DNS 记录切换到目标集群,将用户流量重新定向到已迁移的应用程序。
注意

在执行状态迁移时,MTC 1.6 无法自动静止应用程序。它只能迁移 PV 数据。因此,您必须使用 CD 机制来静止或取消静止应用程序。

MTC 1.7 引入了明确的 Stage 和 Cutover 流。您可以根据需要,使用暂存来执行初始数据传输。然后,您可以执行一个可自动静止源应用程序。

其他资源