×

术语表

表 1. MTC 术语表
术语 定义

源集群

从中迁移应用程序的集群。

目标集群[1]

迁移应用程序到的集群。

复制存储库

用于在间接迁移期间复制镜像、卷和 Kubernetes 对象,或在直接卷迁移或直接镜像迁移期间复制 Kubernetes 对象的对象存储。

复制存储库必须可供所有集群访问。

主机集群

运行migration-controller pod 和 Web 控制台的集群。主机集群通常是目标集群,但这并非必需。

主机集群不需要为直接镜像迁移公开注册表路由。

远程集群

远程集群通常是源集群,但这并非必需。

远程集群需要一个包含migration-controller服务帐户令牌的Secret自定义资源。

远程集群需要一个公开的安全注册表路由才能进行直接镜像迁移。

间接迁移

镜像、卷和 Kubernetes 对象从源集群复制到复制存储库,然后从复制存储库复制到目标集群。

直接卷迁移

持久卷直接从源集群复制到目标集群。

直接镜像迁移

镜像直接从源集群复制到目标集群。

分阶段迁移

在不停止应用程序的情况下将数据复制到目标集群。

多次运行分阶段迁移可缩短切换迁移的持续时间。

切换迁移

应用程序在源集群上停止,其资源迁移到目标集群。

状态迁移

应用程序状态通过将特定的持久卷声明复制到目标集群来迁移。

回滚迁移

回滚迁移会回滚已完成的迁移。

1 在 MTC Web 控制台中称为目标集群。

将应用程序从本地迁移到基于云的集群

您可以通过在两个集群之间建立网络隧道,将防火墙后面的源集群迁移到基于云的目标集群。crane tunnel-api命令通过在源集群上创建VPN隧道,然后连接到目标集群上运行的VPN服务器来建立这样的隧道。VPN服务器使用目标集群上的负载均衡器地址向客户端公开。

在目标集群上创建的服务将源集群的API公开给在目标集群上运行的MTC。

先决条件
  • 创建VPN隧道的系统必须能够访问并登录到这两个集群。

  • 必须能够在目标集群上创建负载均衡器。请参阅您的云提供商以确保这是可能的。

  • 准备好用于为源集群和目标集群中运行VPN隧道的命名空间分配的名称。这些命名空间不应提前创建。有关命名空间规则的信息,请参阅 https://kubernetes.ac.cn/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names。

  • 将多个受防火墙保护的源集群连接到云集群时,每个源集群都需要它自己的命名空间。

  • OpenVPN服务器安装在目标集群上。

  • OpenVPN客户端安装在源集群上。

  • 在MTC中配置源集群时,API URL采用https://proxied-cluster.<namespace>.svc.cluster.local:8443的形式。

    • 如果您使用API,请参阅“为每个远程集群创建MigCluster CR清单”。

    • 如果您使用MTC Web控制台,请参阅“使用MTC Web控制台迁移您的应用程序”。

  • MTC Web控制台和迁移控制器必须安装在目标集群上。

步骤
  1. 安装crane实用程序

    $ podman cp $(podman create registry.redhat.io/rhmtc/openshift-migration-controller-rhel8:v1.8):/crane ./
  2. 远程登录到源集群和目标集群上的节点。

  3. 登录后,获取这两个集群的集群上下文

    $ oc config view
  4. 在命令系统上输入以下命令以建立隧道

    $ crane tunnel-api [--namespace <namespace>] \
          --destination-context <destination-cluster> \
          --source-context <source-cluster>

    如果您没有指定命名空间,则命令将使用默认值openvpn

    例如

    $ crane tunnel-api --namespace my_tunnel \
          --destination-context openshift-migration/c131-e-us-east-containers-cloud-ibm-com/admin \
          --source-context default/192-168-122-171-nip-io:8443/admin

    输入crane tunnel-api --help查看crane tunnel-api命令的所有可用参数。

    该命令生成TSL/SSL证书。此过程可能需要几分钟。该过程完成后将显示一条消息。

    OpenVPN服务器在目标集群上启动,OpenVPN客户端在源集群上启动。

    几分钟后,负载均衡器将在源节点上解析。

    您可以使用root权限输入以下命令查看OpenVPN pod的日志以检查此过程的状态

    # oc get po -n <namespace>
    示例输出
    NAME            READY     STATUS      RESTARTS    AGE
    <pod_name>    2/2       Running     0           44s
    # oc logs -f -n <namespace> <pod_name> -c openvpn

    当解析负载均衡器的地址时,日志的末尾将显示消息Initialization Sequence Completed

  5. 在目标控制节点上的OpenVPN服务器上,验证openvpn服务和proxied-cluster服务是否正在运行

    $ oc get service -n <namespace>
  6. 在源节点上,获取迁移控制器的服务帐户(SA)令牌

    # oc sa get-token -n openshift-migration migration-controller
  7. 打开MTC Web控制台并添加源集群,使用以下值

    • 集群名称:源集群名称。

    • URLproxied-cluster.<namespace>.svc.cluster.local:8443。如果您未为<namespace>定义值,请使用openvpn

    • 服务帐户令牌:迁移控制器服务帐户的令牌。

    • 公开镜像仓库的路由主机proxied-cluster.<namespace>.svc.cluster.local:5000。如果您未为<namespace>定义值,请使用openvpn

MTC成功验证连接后,您可以继续创建和运行迁移计划。源集群的命名空间应该出现在命名空间列表中。

其他资源

使用命令行迁移应用程序

您可以使用命令行界面(CLI)通过MTC API迁移应用程序,以实现迁移自动化。

迁移先决条件

  • 您必须以所有集群上的cluster-admin权限的用户身份登录。

直接镜像迁移
  • 您必须确保公开了源集群的安全OpenShift镜像仓库。

  • 您必须创建到公开的仓库的路由。

直接卷迁移
  • 如果您的集群使用代理,则必须配置Stunnel TCP代理。

内部镜像
  • 如果您的应用程序使用openshift命名空间中的内部镜像,则必须确保目标集群上存在所需版本的镜像。

    您可以手动更新镜像流标签,以便在OpenShift Container Platform 4.17集群上使用已弃用的OpenShift Container Platform 3镜像。

集群
  • 源集群必须升级到最新的MTC z流版本。

  • 所有集群上的MTC版本必须相同。

网络
  • 集群彼此之间以及与复制库之间具有不受限制的网络访问权限。

  • 如果您使用move复制持久卷,则集群必须对远程卷具有不受限制的网络访问权限。

  • 您必须在OpenShift Container Platform 3集群上启用以下端口

    • 8443(API服务器)

    • 443(路由)

    • 53(DNS)

  • 您必须在OpenShift Container Platform 4集群上启用以下端口

    • 6443(API服务器)

    • 443(路由)

    • 53(DNS)

  • 如果您使用TLS,则必须在复制库上启用端口443

持久卷(PV)
  • PV必须有效。

  • PV必须绑定到持久卷声明。

  • 如果您使用快照复制PV,则适用以下其他先决条件

    • 云提供商必须支持快照。

    • PV必须具有相同的云提供商。

    • PV必须位于相同的地理区域。

    • PV必须具有相同的存储类。

为直接镜像迁移创建仓库路由

对于直接镜像迁移,您必须在所有远程集群上创建到公开的 OpenShift 镜像注册表的路由。

先决条件
  • OpenShift 镜像注册表必须在所有远程集群上公开给外部流量。

    OpenShift Container Platform 4 注册表默认情况下是公开的。

    OpenShift Container Platform 3 注册表必须手动公开

步骤
  • 要创建到 OpenShift Container Platform 3 注册表的路由,请运行以下命令

    $ oc create route passthrough --service=docker-registry -n default
  • 要创建到 OpenShift Container Platform 4 注册表的路由,请运行以下命令

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

代理配置

对于 OpenShift Container Platform 4.1 及更早版本,您必须在安装容器迁移工具包操作符后配置 `MigrationController` 自定义资源 (CR) 清单中的代理,因为这些版本不支持集群范围的 `proxy` 对象。

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

直接卷迁移

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

如果您想从代理背后的源集群执行 DVM,则必须配置一个在传输层工作的 TCP 代理,并透明地转发 SSL 连接,而无需使用其自身的 SSL 证书对其进行解密和重新加密。Stunnel 代理就是此类代理的一个示例。

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 连接的代理后面工作。中间人模式下的 HTTP/HTTPS 代理不起作用。现有的集群范围代理可能不支持此行为。因此,DVM 的代理设置有意与 MTC 中通常的代理配置不同。

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

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

OpenShift 中的集群范围 HTTP/HTTPS 代理通常在中间人模式下配置,在该模式下,它们与外部服务器协商自己的 TLS 会话。但是,这与 Stunnel 不兼容。Stunnel 要求其 TLS 会话不被代理触及,本质上使代理成为一个透明的隧道,它只是按原样转发 TCP 连接。因此,您必须使用 TCP 代理。

已知问题
迁移失败,出现错误 `Upgrade request required`

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

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

调整迁移的网络策略

OpenShift 支持使用基于集群使用的网络插件的 *NetworkPolicy* 或 *EgressFirewalls* 来限制进出 Pod 的流量。如果参与迁移的任何源命名空间使用此类机制来限制 Pod 的网络流量,则这些限制可能会无意中阻止迁移期间到 Rsync Pod 的流量。

在源集群和目标集群上运行的 Rsync Pod 必须通过 OpenShift 路由相互连接。可以配置现有的 *NetworkPolicy* 或 *EgressNetworkPolicy* 对象,以便自动将 Rsync Pod 从这些流量限制中豁免。

NetworkPolicy 配置
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
进入 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
EgressNetworkPolicy 配置

`EgressNetworkPolicy` 对象或 *Egress Firewalls* 是 OpenShift 构造,旨在阻止离开集群的出站流量。

与 `NetworkPolicy` 对象不同,Egress 防火墙在项目级别工作,因为它适用于命名空间中的所有 Pod。因此,Rsync Pod 的唯一标签不会仅将 Rsync Pod 从限制中豁免。但是,您可以将源集群或目标集群的 CIDR 范围添加到策略的 *允许* 规则中,以便可以在两个集群之间建立直接连接。

根据存在 Egress 防火墙的集群,您可以添加另一个集群的 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
选择数据传输的替代端点

默认情况下,DVM 使用 OpenShift Container Platform 路由作为端点,将 PV 数据传输到目标集群。如果集群拓扑允许,您可以选择另一种类型的受支持端点。

对于每个集群,您可以通过在 `MigrationController` CR 中相应**目标**集群上设置 `rsync_endpoint_type` 变量来配置端点。

apiVersion: migration.openshift.io/v1alpha1
kind: MigrationController
metadata:
  name: migration-controller
  namespace: openshift-migration
spec:
  [...]
  rsync_endpoint_type: [NodePort|ClusterIP|Route]
为 Rsync Pod 配置补充组

当您的 PVC 使用共享存储时,您可以通过向 Rsync Pod 定义添加补充组来配置对该存储的访问,以便 Pod 允许访问。

表 2. Rsync Pod 的补充组
变量 类型 默认值 描述

src_supplemental_groups

字符串

未设置

源 Rsync Pod 的补充组的逗号分隔列表

target_supplemental_groups

字符串

未设置

目标 Rsync Pod 的补充组的逗号分隔列表

示例用法

可以更新 `MigrationController` CR 以设置这些补充组的值。

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

配置代理

先决条件
  • 您必须以所有集群上的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` 字段定义的网络中未包含的工作节点,则必须将它们添加到此列表中,以防止连接问题。

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

  3. 将清单保存为migration-controller.yaml

  4. 应用更新后的清单

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

使用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对象清单

    $ 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 可选:对于直接镜像迁移,请指定公开的注册表路由。
    3 如果为false,则启用SSL验证。如果为true,则不需要或不检查CA证书。
    4 指定远程集群的Secret对象。
    5 指定远程集群的URL。
  4. 验证所有集群是否都处于Ready状态

    $ oc describe MigCluster <cluster>
  5. 为复制存储库创建一个Secret对象清单

    $ 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格式指定密钥。

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

    $ echo -n "<key>" | base64 -w 0 (1)
    1 指定密钥ID或密钥。两个密钥都必须是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,则执行分阶段迁移,该迁移复制大部分数据而不停止应用程序。
    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

状态迁移

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

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

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

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

状态迁移仅迁移构成应用程序状态的组件。如果您想迁移整个命名空间,请使用分阶段或切换迁移。

先决条件
  • 源集群上应用程序的状态保存在通过PersistentVolumeClaims配置的PersistentVolumes中。

  • 应用程序的清单位于源集群和目标集群都可以访问的中央存储库中。

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

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

  2. 使源应用程序静默。

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

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

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

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

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

  5. 如果克隆的应用程序处于静默状态,请取消其静默状态。

  6. 将DNS记录切换到目标集群,以将用户流量重新定向到已迁移的应用程序。

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

MTC 1.7引入了显式分阶段和切换流程。您可以使用分阶段多次执行初始数据传输。然后,您可以执行切换操作,其中源应用程序将自动静默。

其他资源

迁移钩子

您可以向单个迁移计划添加最多四个迁移钩子,每个钩子在迁移的不同阶段运行。迁移钩子执行诸如自定义应用程序静默、手动迁移不受支持的数据类型以及迁移后更新应用程序等任务。

迁移钩子在以下迁移步骤之一中在源集群或目标集群上运行:

  • PreBackup:在源集群上备份资源之前。

  • PostBackup:在源集群上备份资源之后。

  • PreRestore:在目标集群上还原资源之前。

  • PostRestore:在目标集群上还原资源之后。

您可以通过创建一个Ansible playbook来创建钩子,该playbook使用默认Ansible镜像或自定义钩子容器运行。

Ansible playbook

Ansible playbook作为config map安装在钩子容器上。钩子容器作为作业运行,使用MigPlan自定义资源中指定的集群、服务帐户和命名空间。作业将继续运行,直到达到默认的6次重试限制或成功完成。即使初始Pod被驱逐或终止,这种情况也会继续。

默认的 Ansible 运行时镜像为registry.redhat.io/rhmtc/openshift-migration-hook-runner-rhel7:1.8。此镜像基于 Ansible Runner 镜像,包含用于 Ansible Kubernetes 资源的python-openshift以及更新的oc二进制文件。

自定义 Hook 容器

您可以使用自定义 Hook 容器代替默认的 Ansible 镜像。

为迁移 Hook 编写 Ansible playbook

您可以编写 Ansible playbook 用作迁移 Hook。可以使用 MTC Web 控制台或通过在MigPlan自定义资源 (CR) 清单中指定spec.hooks参数的值将 Hook 添加到迁移计划中。

Ansible playbook 作为配置映射挂载到 Hook 容器中。Hook 容器作为作业运行,使用MigPlan CR 中指定的集群、服务帐户和命名空间。Hook 容器使用指定的 Service Account 令牌,以便任务在集群中运行前不需要身份验证。

Ansible 模块

您可以使用 Ansible shell 模块运行oc命令。

shell 模块示例
- hosts: localhost
  gather_facts: false
  tasks:
  - name: get pod name
    shell: oc get po --all-namespaces

您可以使用kubernetes.core模块(例如k8s_info)与 Kubernetes 资源交互。

k8s_facts 模块示例
- hosts: localhost
  gather_facts: false
  tasks:
  - name: Get pod
    k8s_info:
      kind: pods
      api: v1
      namespace: openshift-migration
      name: "{{ lookup( 'env', 'HOSTNAME') }}"
    register: pods

  - name: Print pod name
    debug:
      msg: "{{ pods.resources[0].metadata.name }}"

您可以使用fail模块在通常不会产生非零退出状态的情况下产生非零退出状态,从而确保检测到 Hook 的成功或失败。Hook 作为作业运行,Hook 的成功或失败状态基于作业容器的退出状态。

fail 模块示例
- hosts: localhost
  gather_facts: false
  tasks:
  - name: Set a boolean
    set_fact:
      do_fail: true

  - name: "fail"
    fail:
      msg: "Cause a failure"
    when: do_fail

环境变量

MigPlan CR 名称和迁移命名空间作为环境变量传递到 Hook 容器。可以使用lookup插件访问这些变量。

环境变量示例
- hosts: localhost
  gather_facts: false
  tasks:
  - set_fact:
      namespaces: "{{ (lookup( 'env', 'MIGRATION_NAMESPACES')).split(',') }}"

  - debug:
      msg: "{{ item }}"
    with_items: "{{ namespaces }}"

  - debug:
      msg: "{{ lookup( 'env', 'MIGRATION_PLAN_NAME') }}"

迁移计划选项

您可以在MigPlan自定义资源 (CR) 中排除、编辑和映射组件。

排除资源

您可以从容器迁移工具包 (MTC) 迁移计划中排除资源(例如,镜像流、持久卷 (PV) 或订阅),以减少迁移的资源负载或使用不同的工具迁移镜像或 PV。

默认情况下,MTC 会从迁移中排除服务目录资源和 Operator Lifecycle Manager (OLM) 资源。这些资源是服务目录 API 组和 OLM API 组的一部分,目前这两种 API 组都不支持迁移。

步骤
  1. 编辑MigrationController自定义资源清单

    $ oc edit migrationcontroller <migration_controller> -n openshift-migration
  2. 通过添加参数以排除特定资源来更新spec部分。对于那些没有自己的排除参数的资源,请添加additional_excluded_resources参数。

    apiVersion: migration.openshift.io/v1alpha1
    kind: MigrationController
    metadata:
      name: migration-controller
      namespace: openshift-migration
    spec:
      disable_image_migration: true (1)
      disable_pv_migration: true (2)
      additional_excluded_resources: (3)
      - resource1
      - resource2
      ...
    1 添加disable_image_migration: true以从迁移中排除镜像流。当MigrationController pod 重启时,imagestreams将添加到main.yml中的excluded_resources列表中。
    2 添加disable_pv_migration: true以从迁移计划中排除 PV。当MigrationController pod 重启时,persistentvolumespersistentvolumeclaims将添加到main.yml中的excluded_resources列表中。禁用 PV 迁移还会在创建迁移计划时禁用 PV 发现。
    3 您可以将要排除的 OpenShift Container Platform 资源添加到additional_excluded_resources列表中。
  3. 等待两分钟,以便MigrationController pod 重启,以便应用更改。

  4. 验证资源是否已排除

    $ oc get deployment -n openshift-migration migration-controller -o yaml | grep EXCLUDED_RESOURCES -A1

    输出包含已排除的资源

    示例输出
    name: EXCLUDED_RESOURCES
    value:
    resource1,resource2,imagetags,templateinstances,clusterserviceversions,packagemanifests,subscriptions,servicebrokers,servicebindings,serviceclasses,serviceinstances,serviceplans,imagestreams,persistentvolumes,persistentvolumeclaims

映射命名空间

如果在MigPlan自定义资源 (CR) 中映射命名空间,则必须确保在源集群或目标集群上不重复命名空间,因为命名空间的 UID 和 GID 范围在迁移过程中会被复制。

两个源命名空间映射到同一个目标命名空间
spec:
  namespaces:
    - namespace_2
    - namespace_1:namespace_2

如果希望源命名空间映射到同名的命名空间,则无需创建映射。默认情况下,源命名空间和目标命名空间具有相同的名称。

不正确的命名空间映射
spec:
  namespaces:
    - namespace_1:namespace_1
正确的命名空间引用
spec:
  namespaces:
    - namespace_1

排除持久卷声明

您可以通过排除不需要迁移的 PVC 来选择用于状态迁移的持久卷声明 (PVC)。在发现持久卷 (PV) 后,您可以通过设置MigPlan自定义资源 (CR) 的spec.persistentVolumes.pvc.selection.action参数来排除 PVC。

先决条件
  • MigPlan CR 处于Ready状态。

步骤
  • spec.persistentVolumes.pvc.selection.action参数添加到MigPlan CR 并将其设置为skip

    apiVersion: migration.openshift.io/v1alpha1
    kind: MigPlan
    metadata:
      name: <migplan>
      namespace: openshift-migration
    spec:
    ...
      persistentVolumes:
      - capacity: 10Gi
        name: <pv_name>
        pvc:
    ...
        selection:
          action: skip

映射持久卷声明

您可以通过在MigPlan CR 中映射 PVC,将持久卷 (PV) 数据从源集群迁移到目标集群中已预配的持久卷声明 (PVC)。此映射确保迁移的应用程序的目标 PVC 与源 PVC 同步。

在发现 PV 后,您可以通过更新MigPlan自定义资源 (CR) 中的spec.persistentVolumes.pvc.name参数来映射 PVC。

先决条件
  • MigPlan CR 处于Ready状态。

步骤
  • 更新MigPlan CR 中的spec.persistentVolumes.pvc.name参数

    apiVersion: migration.openshift.io/v1alpha1
    kind: MigPlan
    metadata:
      name: <migplan>
      namespace: openshift-migration
    spec:
    ...
      persistentVolumes:
      - capacity: 10Gi
        name: <pv_name>
        pvc:
          name: <source_pvc>:<destination_pvc> (1)
    1 指定源集群上的 PVC 和目标集群上的 PVC。如果目标 PVC 不存在,它将被创建。您可以使用此映射在迁移期间更改 PVC 名称。

编辑持久卷属性

创建MigPlan自定义资源 (CR) 后,MigrationController CR 会发现持久卷 (PV)。spec.persistentVolumes块和status.destStorageClasses块将添加到MigPlan CR 中。

您可以编辑spec.persistentVolumes.selection块中的值。如果更改spec.persistentVolumes.selection块之外的值,则当MigrationController CR 调和MigPlan CR 时,这些值将被覆盖。

spec.persistentVolumes.selection.storageClass参数的默认值由以下逻辑确定:

  1. 如果源集群 PV 是 Gluster 或 NFS,则默认为cephfs(对于accessMode: ReadWriteMany)或cephrbd(对于accessMode: ReadWriteOnce)。

  2. 如果 PV 不是 Gluster 或 NFS或者cephfscephrbd不可用,则默认为具有相同提供程序的存储类。

  3. 如果没有找到相同提供程序的存储类,则默认为目标集群的默认存储类。

您可以将storageClass值更改为MigPlan CR 的status.destStorageClasses块中任何name参数的值。

如果storageClass值为空,则 PV 迁移后将没有存储类。例如,如果您想将 PV 移动到目标集群上的 NFS 卷,则此选项适用。

先决条件
  • MigPlan CR 处于Ready状态。

步骤
  • 编辑MigPlan CR 中的spec.persistentVolumes.selection

    apiVersion: migration.openshift.io/v1alpha1
    kind: MigPlan
    metadata:
      name: <migplan>
      namespace: openshift-migration
    spec:
      persistentVolumes:
      - capacity: 10Gi
        name: pvc-095a6559-b27f-11eb-b27f-021bddcaf6e4
        proposedCapacity: 10Gi
        pvc:
          accessModes:
          - ReadWriteMany
          hasReference: true
          name: mysql
          namespace: mysql-persistent
        selection:
          action: <copy> (1)
          copyMethod: <filesystem> (2)
          verify: true (3)
          storageClass: <gp2> (4)
          accessMode: <ReadWriteMany> (5)
        storageClass: cephfs
    1 允许的值为movecopyskip。如果只支持一项操作,则默认值为支持的操作。如果支持多项操作,则默认值为copy
    2 允许的值为snapshotfilesystem。默认值为filesystem
    3 如果您在MTC Web控制台中为文件系统复制选择验证选项,则会显示verify参数。您可以将其设置为false
    4 您可以将默认值更改为MigPlan CR的status.destStorageClasses块中任何name参数的值。如果未指定值,则PV迁移后将没有存储类。
    5 允许的值为ReadWriteOnceReadWriteMany。如果未指定此值,则默认为源集群PVC的访问模式。您只能在MigPlan CR中编辑访问模式。您不能使用MTC Web控制台进行编辑。

其他资源

使用MTC API执行Kubernetes对象的狀態迁移

迁移所有PV数据后,您可以使用容器迁移工具包(MTC) API执行构成应用程序的Kubernetes对象的一次性状态迁移。

您可以通过配置MigPlan自定义资源(CR)字段来提供带有附加标签选择器的Kubernetes资源列表,然后通过创建MigMigration CR来执行迁移。迁移完成后,MigPlan资源将关闭。

选择Kubernetes资源是仅限API的功能。您必须使用CLI更新MigPlan CR并为其创建MigMigration CR。MTC Web控制台不支持迁移Kubernetes对象。

迁移后,MigPlan CR的closed参数将设置为true。您不能为此MigPlan CR创建另一个MigMigration CR。

您可以使用以下选项之一将Kubernetes对象添加到MigPlan CR

  • 将Kubernetes对象添加到includedResources部分。当在MigPlan CR中指定includedResources字段时,计划将group-kind列表作为输入。只有列表中存在的资源才包含在迁移中。

  • 添加可选的labelSelector参数以过滤MigPlan中的includedResources。指定此字段时,只有与标签选择器匹配的资源才包含在迁移中。例如,您可以使用标签app: frontend作为过滤器来过滤SecretConfigMap资源列表。

步骤
  1. 更新MigPlan CR以包含Kubernetes资源,并可选地通过添加labelSelector参数来过滤包含的资源

    1. 要更新MigPlan CR以包含Kubernetes资源

      apiVersion: migration.openshift.io/v1alpha1
      kind: MigPlan
      metadata:
        name: <migplan>
        namespace: openshift-migration
      spec:
        includedResources:
        - kind: <kind> (1)
          group: ""
        - kind: <kind>
          group: ""
      1 指定Kubernetes对象,例如SecretConfigMap
    2. 可选:通过添加labelSelector参数来过滤包含的资源

      apiVersion: migration.openshift.io/v1alpha1
      kind: MigPlan
      metadata:
        name: <migplan>
        namespace: openshift-migration
      spec:
        includedResources:
        - kind: <kind> (1)
          group: ""
        - kind: <kind>
          group: ""
      ...
        labelSelector:
          matchLabels:
            <label> (2)
      1 指定Kubernetes对象,例如SecretConfigMap
      2 指定要迁移的资源的标签,例如app: frontend
  2. 创建一个MigMigration CR来迁移选定的Kubernetes资源。验证migPlanRef中是否引用了正确的MigPlan

    apiVersion: migration.openshift.io/v1alpha1
    kind: MigMigration
    metadata:
      generateName: <migplan>
      namespace: openshift-migration
    spec:
      migPlanRef:
        name: <migplan>
        namespace: openshift-migration
      stage: false

迁移控制器选项

对于大型迁移和改进性能,您可以在MigrationController自定义资源(CR)中编辑迁移计划限制、启用持久卷调整大小或启用缓存的Kubernetes客户端。

增加大型迁移的限制

您可以使用容器迁移工具包(MTC)增加大型迁移中迁移对象和容器资源的限制。

在生产环境中执行迁移之前,必须测试这些更改。

步骤
  1. 编辑MigrationController自定义资源(CR)清单

    $ oc edit migrationcontroller -n openshift-migration
  2. 更新以下参数

    ...
    mig_controller_limits_cpu: "1" (1)
    mig_controller_limits_memory: "10Gi" (2)
    ...
    mig_controller_requests_cpu: "100m" (3)
    mig_controller_requests_memory: "350Mi" (4)
    ...
    mig_pv_limit: 100 (5)
    mig_pod_limit: 100 (6)
    mig_namespace_limit: 10 (7)
    ...
    1 指定MigrationController CR可用的CPU数量。
    2 指定MigrationController CR可用的内存量。
    3 指定MigrationController CR请求可用的CPU单元数。100m表示0.1个CPU单元(100 * 1e-3)。
    4 指定MigrationController CR请求可用的内存量。
    5 指定可以迁移的持久卷的数量。
    6 指定可以迁移的Pod的数量。
    7 指定可以迁移的命名空间的数量。
  3. 创建一个使用更新参数的迁移计划以验证更改。

    如果您的迁移计划超过MigrationController CR限制,则在保存迁移计划时,MTC控制台会显示警告消息。

启用直接卷迁移的持久卷调整大小

您可以为直接卷迁移启用持久卷(PV)调整大小,以避免目标集群磁盘空间不足。

当PV的磁盘使用率达到配置级别时,MigrationController自定义资源(CR)会将持久卷声明(PVC)的请求存储容量与其实际已配置容量进行比较。然后,它计算目标集群所需的空間。

pv_resizing_threshold参数决定何时使用PV调整大小。默认阈值为3%。这意味着当PV的磁盘使用率超过97%时,将发生PV调整大小。您可以增加此阈值,以便在较低的磁盘使用率级别发生PV调整大小。

PVC容量根据以下条件计算

  • 如果PVC的请求存储容量(spec.resources.requests.storage)不等于其实际已配置容量(status.capacity.storage),则使用较大的值。

  • 如果通过PVC配置PV,然后随后更改使其PV和PVC容量不再匹配,则使用较大的值。

先决条件
  • PVC必须附加到一个或多个正在运行的Pod,以便MigrationController CR可以执行命令。

步骤
  1. 登录到主机集群。

  2. 通过修补MigrationController CR来启用PV调整大小

    $ oc patch migrationcontroller migration-controller -p '{"spec":{"enable_dvm_pv_resizing":true}}' \ (1)
      --type='merge' -n openshift-migration
    1 将值设置为false以禁用PV调整大小。
  3. 可选:更新pv_resizing_threshold参数以增加阈值

    $ oc patch migrationcontroller migration-controller -p '{"spec":{"pv_resizing_threshold":41}}' \ (1)
      --type='merge' -n openshift-migration
    1 默认值为3

    超过阈值时,MigPlan CR状态中会显示以下状态消息

    status:
      conditions:
    ...
      - category: Warn
        durable: true
        lastTransitionTime: "2021-06-17T08:57:01Z"
        message: 'Capacity of the following volumes will be automatically adjusted to avoid disk capacity issues in the target cluster:  [pvc-b800eb7b-cf3b-11eb-a3f7-0eae3e0555f3]'
        reason: Done
        status: "False"
        type: PvCapacityAdjustmentRequired

    对于 AWS gp2 存储,由于 gp2 计算卷使用率和大小的方式,除非pv_resizing_threshold达到或超过 42%,否则不会显示此消息。(BZ#1973148

启用缓存的 Kubernetes 客户端

为了提高迁移性能,您可以在MigrationController自定义资源 (CR) 中启用缓存的 Kubernetes 客户端。在不同区域之间或网络延迟较大的集群之间进行迁移时,性能提升最为显著。

但是,委托的任务(例如,直接卷迁移的 Rsync 备份或 Velero 备份和恢复)使用缓存客户端不会提高性能。

缓存客户端需要额外的内存,因为MigrationController CR 会缓存与MigCluster CR 交互所需的所有 API 资源。通常发送到 API 服务器的请求将改为定向到缓存。缓存会监控 API 服务器以获取更新。

启用缓存客户端后,如果出现OOMKilled错误,您可以增加MigrationController CR 的内存限制和请求。

步骤
  1. 运行以下命令启用缓存客户端

    $ oc -n openshift-migration patch migrationcontroller migration-controller --type=json --patch \
      '[{ "op": "replace", "path": "/spec/mig_controller_enable_cache", "value": true}]'
  2. 可选:运行以下命令增加MigrationController CR 的内存限制

    $ oc -n openshift-migration patch migrationcontroller migration-controller --type=json --patch \
      '[{ "op": "replace", "path": "/spec/mig_controller_limits_memory", "value": <10Gi>}]'
  3. 可选:运行以下命令增加MigrationController CR 的内存请求

    $ oc -n openshift-migration patch migrationcontroller migration-controller --type=json --patch \
      '[{ "op": "replace", "path": "/spec/mig_controller_requests_memory", "value": <350Mi>}]'