更新时间:2024-06-17 GMT+08:00

集群评估

将应用从一个环境迁移到另一个环境是一项具有挑战性的任务,因此您需要进行仔细的规划和准备。kspider是一款用于采集源集群信息的工具,它向用户提供了集群的Kubernetes版本、规模、工作负载数量、存储以及正在使用的镜像等数据,这些信息有助于用户了解集群的当前状况,评估迁移风险,并选择合适的目标集群版本和规模。

kspider工作原理

kspider工具的架构如图1所示,包含三个模块:采集模块、连接管理和分析模块。采集模块可以收集源集群的数据,包括命名空间、工作负载、节点、网络等;连接管理模块负责与源集群的API Server建立连接;分析模块分为聚合输出和评估推荐两部分,旨在输出源集群的采集数据(生成“cluster-*.json”文件)以及提供目标集群的推荐信息(生成“preferred-*.json”文件)。

图1 kspider架构

kspider使用方法

kspider工具支持在Linux(x86、arm)和Windows环境中运行,使用方法相似。本文将以Linux(x86)环境为例进行介绍。

若使用Linux(arm)或Windows环境,请将下述命令中的kspider-linux-amd64分别替换为kspider-linux-arm64kspider-windows-amd64.exe

根据容器迁移准备工作章节的要求,准备一台服务器并上传kspider工具,然后进行解压缩。在kspider工具所在目录下执行./kspider-linux-amd64 -h,您可以查看该工具的使用方法。

  • -k, --kubeconfig:指定kubectl的KubeConfig位置,默认是$HOME/.kube/config。kubeConfig文件:用于配置对Kubernetes集群的访问,KubeConfig文件中包含访问注册Kubernetes集群所需要的认证凭据以及Endpoint(访问地址),详细介绍可参见Kubernetes文档
  • -n, --namespaces:指定采集的命名空间,默认排除了kube-system、kube-public、kube-node-lease等系统命名空间。
  • -q, --quiet:静态退出。
  • -s, --serial:根据采集信息输出汇聚文件(cluster-{serial}.json)和推荐文件(preferred-{serial}.json)唯一标识的序号。
$ ./kspider-linux-amd64 -h
A cluster information collection and recommendation tool implement by Go.

Usage:
  kspider [flags]

Aliases:
  kspider, kspider

Flags:
  -h, --help                help for kspider
  -k, --kubeconfig string   The kubeconfig of k8s cluster's. Default is the $HOME/.kube/config. (default "$HOME/.kube/config")
  -n, --namespaces string   Specify a namespace for information collection. If multiple namespaces are specified, separate them with commas (,), such as ns1,ns2. default("") is all namespaces
  -q, --quiet               command to execute silently
  -s, --serial string       User-defined sequence number of the execution. The default value is the time when the kspider is started. (default "1673853404")

步骤一:源集群数据采集

  1. 通过kubectl连接源集群。具体方法可参考使用kubectl连接集群
  2. 使用默认参数配置,采集集群中所有命名空间的数据。执行方法:./kspider-linux-amd64

    执行后的输出详细信息如下:
    [~]# ./kspider-linux-amd64
    The Cluster version is v1.15.6-r1-CCE2.0.30.B001
    There are 5 Namespaces
    There are 2 Nodes
    	Name	 CPU	 Memory	 IP	 Arch	 OS	 Kernel	 MachineID
    	10.1.18.64	 4	 8008284Ki	 [10.1.18.64 10.1.18.64]	 amd64	 linux	 3.10.0-1127.19.1.el7.x86_64	 ef9270ed-7eb3-4ce6-a2d8-f1450f85489a
    	10.1.19.13	 4	 8008284Ki	 [10.1.19.13 10.1.19.13]	 amd64	 linux	 3.10.0-1127.19.1.el7.x86_64	 2d889590-9a32-47e5-b947-09c5bda81849
    There are 9 Pods
    There are 0 LonePods: 
    There are 2 StatefulSets: 
    	Name	 Namespace	 NodeAffinity
    	minio	 default	 false
    	minio	 minio	 false
    There are 3 Deployments: 
    	Name	 Namespace	 NodeAffinity
    	rctest	 default	 true
    	flink-operator-controller-manager	 flink-operator-system	 false
    	rctest	 minio	 false
    There are 1 DaemonSets: 
    	Name	 Namespace	 NodeAffinity
    	ds-nginx	 minio	 false
    There are 0 Jobs: 
    There are 0 CronJobs: 
    There are 4 PersistentVolumeClaims: 
    	Namespace/Name	 Pods
    	default/pvc-data-minio-0	 default/minio-0
    	minio/obs-testing	 minio/ds-nginx-9hmds,minio/ds-nginx-4jsfg
    	minio/pvc-data-minio-0	 minio/minio-0
    There are 5 PersistentVolumes: 
    	Name	 Namespace	 pvcName	 scName	 size	 key
    	pvc-bd36c70f-75bf-4000-b85c-f9fb169a14a8	 minio-pv	 obs-testing	 csi-obs	 1Gi	 pvc-bd36c70f-75bf-4000-b85c-f9fb169a14a8
    	pvc-c7c768aa-373a-4c52-abea-e8b486d23b47	 minio-pv	 pvc-data-minio-0	 csi-disk-sata	 10Gi	 1bcf3d00-a524-45b1-a773-7efbca58f36a
    	pvc-4f52462b-3b4c-4191-a63b-5a36a8748c05	 minio	 obs-testing	 csi-obs	 1Gi	 pvc-4f52462b-3b4c-4191-a63b-5a36a8748c05
    	pvc-9fd92c99-805a-4e65-9f22-e238130983c8	 default	 pvc-data-minio-0	 csi-disk	 10Gi	 590afd05-fc68-4c10-a598-877100ca7b3f
    	pvc-a22fd877-f98d-4c3d-a04e-191d79883f97	 minio	 pvc-data-minio-0	 csi-disk-sata	 10Gi	 48874130-df77-451b-9b43-d435ac5a11d5
    There are 7 Services: 
    	Name	 Namespace	 ServiceType
    	headless-lxprus	 default	 ClusterIP
    	kubernetes	 default	 ClusterIP
    	minio	 default	 NodePort
    	flink-operator-controller-manager-metrics-service	 flink-operator-system	 ClusterIP
    	flink-operator-webhook-service	 flink-operator-system	 ClusterIP
    	headless-lxprus	 minio	 ClusterIP
    	minio	 minio	 NodePort
    There are 0 Ingresses: 
    There are 6 Images: 
    	Name
    	gcr.io/flink-operator/flink-operator:v1beta1-6
    	flink:1.8.2
    	swr.cn-north-4.myhuaweicloud.com/paas/minio:latest
    	nginx:stable-alpine-perl
    	swr.cn-north-4.myhuaweicloud.com/everest/minio:latest
    	gcr.io/kubebuilder/kube-rbac-proxy:v0.4.0
    There are 2 Extra Secrets: 
    	SecretType
    	cfe/secure-opaque
    	helm.sh/release.v1

    在kspider执行完毕后,当前目录下将生成两个文件:

    • cluster-*.json:此文件包含了源集群及应用的采集数据,这些数据可用于分析和规划迁移过程。
    • preferred-*.json:此文件包含了推荐的目标集群信息。基于源集群的规模和节点规格进行初步评估,文件将提供关于目标集群版本和规模的建议。

  3. 查看源集群及应用的采集数据。

    您可以用文本编辑器或JSON查看器打开“cluster-*.json”文件以查看数据。在实际操作中,您需要将文件名中的“*”替换为实际的时间戳或序列号,以找到并打开正确的文件。

    “cluster-*.json”文件说明如下:

    {
      K8sVersion:Kubernetes版本,字符串类型
      Namespaces:命名空间数量,字符串类型
      Pods:Pod总数量,整型
      Nodes:节点总信息,以IP为key,展示节点信息
        IP地址
          CPU:CPU,字符串类型
          Arch:CPU架构,字符串类型
          Memory:内存,字符串类型
          HugePages1Gi:1G大页内存,字符串类型
          HugePages2Mi:2M大页内存,字符串类型
          OS:节点OS,字符串类型
          KernelVersion:OS内核版本,字符串类型
          RuntimeVersion:节点容器运行及版本,字符串类型
          InternalIP:内部IP,字符串类型
          ExternalIP:外部IP,字符串类型
          MachineID:节点ID,字符串类型。说明:CCE中能够保证与ECS的ID一致
      Workloads:工作负载
        Deployment:工作负载类型,支持Deployment(无状态负载)、StatefulSet(有状态负载)、DaemonSet(守护进程集)、CronJob(定时任务)、Job(普通任务)、LonePod(独立Pod)
          default:命名空间名称
            Count:数量,整型
            Items:详细信息,数组类型
              Name:工作负载名称,字符串类型
              Namespace:命名空间名称,字符串类型
              NodeAffinity:节点亲和性,布尔型
              Replicas:副本数量,整型
      Storage:存储
        PersistentVolumes:持久卷
          pv-name:以PV名称为key
            VolumeID:卷ID,字符串类型
            Namespace:命名空间,字符串类型
            PvcName:绑定PVC的名称,字符串类型
            ScName:存储类的名称,字符串类型
            Size:申请空间大小,字符串类型
            Pods:使用PV的Pod名称,字符串类型
            NodeIP:Pod所在的节点IP,字符串类型
            VolumePath:该Pod挂载节点的路径,字符串类型
        OtherVolumes:其它类型卷
          类型:AzureFile、AzureDisk、GCEPersistentDisk、AWSElasticBlockStore、Cinder、Glusterfs、NFS、CephFS、FlexVolume、FlexVolume、DownwardAPI
            卷ID/卷名称/卷共享路径等为key
              Pods:使用其的Pod,字符串类型
              NodeIP:Pod所在的节点IP,字符串类型
              卷ID/卷名称/卷共享路径等唯一标识卷信息的信息,字符串类型
      Networks:网络
        LoadBalancer:负载均衡类型
          service:网络类型,包括service和ingress
            Name:名称,字符串类型
            Namespace:命名空间名称,字符串类型
            Type:类型,字符串类型
      ExtraSecrets:扩展secret类型
        secret类型名,字符串类型
      Images:镜像
        镜像repo,字符串类型
    }

    示例:

    {
      "K8sVersion": "v1.19.10-r0-CCE22.3.1.B009",
      "Namespaces": 12,
      "Pods": 33,
      "Nodes": {
        "10.1.17.219": {
          "CPU": "4",
          "Memory": "7622944Ki",
          "HugePages1Gi": "0",
          "HugePages2Mi": "0",
          "Arch": "amd64",
          "OS": "EulerOS 2.0 (SP9x86_64)",
          "KernelVersion": "4.18.0-147.5.1.6.h687.eulerosv2r9.x86_64",
          "RuntimeVersion": "docker://18.9.0",
          "InternalIP": "10.1.17.219",
          "ExternalIP": "",
          "MachineID": "0c745e03-2802-44c2-8977-0a9fd081a5ba"
        },
        "10.1.18.182": {
          "CPU": "4",
          "Memory": "7992628Ki",
          "HugePages1Gi": "0",
          "HugePages2Mi": "0",
          "Arch": "amd64",
          "OS": "EulerOS 2.0 (SP5)",
          "KernelVersion": "3.10.0-862.14.1.5.h520.eulerosv2r7.x86_64",
          "RuntimeVersion": "docker://18.9.0",
          "InternalIP": "10.1.18.182",
          "ExternalIP": "100.85.xxx.xxx",
          "MachineID": "2bff3d15-b565-496a-817c-063a37eaf1bf"
        }
      },
      "Workloads": {
        "CronJob": {},
        "DaemonSet": {
          "default": {
            "Count": 1,
            "Items": [
              {
                "Name": "kubecost-prometheus-node-exporter",
                "Namespace": "default",
                "NodeAffinity": false,
                "Replicas": 3
              }
            ]
          }
        },
        "Deployment": {
          "default": {
            "Count": 1,
            "Items": [
              {
                "Name": "kubecost-cost-analyzer",
                "Namespace": "default",
                "NodeAffinity": false,
                "Replicas": 1
              }
            ]
          },
          "kubecost": {
            "Count": 1,
            "Items": [
              {
                "Name": "kubecost-kube-state-metrics",
                "Namespace": "kubecost",
                "NodeAffinity": false,
                "Replicas": 1
              }
            ]
          }
        },
        "Job": {},
        "LonePod": {},
        "StatefulSet": {
          "minio-all": {
            "Count": 1,
            "Items": [
              {
                "Name": "minio",
                "Namespace": "minio-all",
                "NodeAffinity": false,
                "Replicas": 1
              }
            ]
          }
        }
      },
      "Storage": {
        "PersistentVolumes": {
          "demo": {
            "VolumeID": "demo",
            "Namespace": "fluid-demo-test",
            "PvcName": "demo",
            "ScName": "fluid",
            "Size": "100Gi",
            "Pods": "",
            "NodeIP": "",
            "VolumePath": ""
          },
          "pvc-fd3a5bb3-119a-44fb-b02e-96b2cf9bb36c": {
            "VolumeID": "82365752-89b6-4609-9df0-007d964b7fe4",
            "Namespace": "minio-all",
            "PvcName": "pvc-data-minio-0",
            "ScName": "csi-disk",
            "Size": "10Gi",
            "Pods": "minio-all/minio-0",
            "NodeIP": "10.1.23.159",
            "VolumePath": "/var/lib/kubelet/pods/5fc47c82-7cbd-4643-98cd-cea41de28ff2/volumes/kubernetes.io~csi/pvc-fd3a5bb3-119a-44fb-b02e-96b2cf9bb36c/mount"
          }
        },
        "OtherVolumes": {}
      },
      "Networks": {
        "LoadBalancer": {}
      },
      "ExtraSecrets": [
        "cfe/secure-opaque",
        "helm.sh/release.v1"
      ],
      "Images": [
        "nginx:stable-alpine-perl",
        "ghcr.io/koordinator-sh/koord-manager:0.6.2",
        "swr.cn-north-4.myhuaweicloud.com/paas/minio:latest",
        "swr.cn-north-4.myhuaweicloud.com/everest/e-backup-test:v1.0.0",
        "gcr.io/kubecost1/cost-model:prod-1.91.0",
        "gcr.io/kubecost1/frontend:prod-1.91.0"
      ]
    }

步骤二:目标集群评估

在kspider执行完毕后,除了“cluster-*.json”文件之外,还会在当前目录下生成“preferred-*.json”文件。这个文件基于源集群的规模和节点规格进行初步评估,并提供关于目标集群版本和规模的推荐信息。这有助于您更好地规划和准备迁移过程。

“preferred-*.json”文件说明如下:

{
  K8sVersion:Kubernetes版本,字符串类型
  Scale:集群规模,字符串类型
  Nodes:节点信息
    CPU:CPU,字符串类型
    Memory:内存,字符串类型
    Arch:架构,字符串类型
    KernelVersion:OS内核版本,字符串类型
    ProxyMode:集群Proxy模式,字符串类型
  ELB:是否依赖ELB,布尔型
}

上述文件中每个字段的评估规则如下:

表1 评估规则

字段

评估规则

Kubernetes版本

如果是1.21以下版本,推荐UCS集群主要发行版本(例如1.21,随着时间发展会发生变化),大于主要发行版本时,将推荐UCS集群的最新版本。

集群规模

源集群节点数<25,推荐50节点规模

25≤源集群节点数<100,推荐200节点规模

100≤源集群节点数<500,推荐1000节点规模

源集群节点数≥500,推荐2000节点规模

CPU+内存

统计数量最多的那一种规格

架构

统计数量最多的那一种规格

OS内核版本

统计数量最多的那一种规格

集群Proxy模式

根据集群规模来设置,大于1000节点规模的集群,推荐使用ipvs,1000以内的推荐使用iptables。

是否依赖ELB

源集群是否有负载均衡类型的Service

示例:

{
  "K8sVersion": "v1.21",
  "Scale": 50,
  "Nodes": {
    "CPU": "4",
    "Memory": "7622952Ki",
    "Arch": "amd64",
    "KernelVersion": "3.10.0-862.14.1.5.h520.eulerosv2r7.x86_64"
  },
  "ELB": false,
  "ProxyMode": "iptables"
}

评估结果仅供参考,最终选择什么版本、规模的目标集群还需要您综合判断。