接入一个云

介绍如何接入一个新的云平台

假设这里要接入的云为测试云(TestCloud)

基础概念

  • 平台名称

    • 每接入一个云,都需要定义一个云平台的名称,Provider 这里是目前已经接入的各个云的名称
    • 这里说明下腾讯云的名称Qcloud, 本身最好的定义是 TencentCloud, 但最早登录时用的控制台地址是https://qcloud.com, 所以才定义为Qcloud
  • 资源接口

    • 为了屏蔽各个云的差异, 我们分离出 Cloudmux 仓库, 将各个云的资源操作统一放到这个仓库里面
    • 每一类资源都在 Resource 可以找到对应的接口
    • 对于每一个云来说基本实现Resource里面定义的接口,就完成了 80% 的云平台接入
    • 资源接口的实现文件列表对应路径应该在 pkg/multicloud/testcloud/ 中
  • 云账号接入

    • 云账号接入类似于资源接口, 接口定义在ICloudProvider, 需要实现ICloudProviderFactoryICloudProvider
    • ICloudProviderFactory 是校验云账号及云账号属性的接口
    • ICloudProvider 是云账号真正获取及操作云平台资源的入口
    • 云账号接入的实现文件对应路径应该在 pkg/multicloud/testcloud/provider/ 中
  • 快捷操作

    • 为了快捷调试各个云的接口, 每个云平台会有一个对应云平台的 cli 命令实现, 例如aliyuncli
    • aliyuncli 启动时会导入Shell里面的子命令, 例如: aliyuncli instance-list
    • 在实现接口初期,可以根据要介入的云平台资源 API, 将基础 API 调用实现, 然后写入 shell 子命令,可以通过 shell 命令快速调试 API

testcli 调试命令

  • 创建 pkg/multicloud/testcloud/test.go 文件
    • 定义 STestCloudClient 结构体, 用于保存 aksk
    • 实现 NewTestCloudClient 方法, 此方法需要验证测试云的 aksk 是否正确, 并返回*STestCloudClient
    • 创建 pkg/multicloud/testcloud/region.go 并定义 SRegion 结构体,实现 GetClient 方法
    • 实现绑定 GetRegions 方法到 STestCloudClient, 私有云 region 一般是模拟的, 可以找已经试下的私有云参考
  • 创建 pkg/multicloud/testcloud/shell/region.go

    • 实现 region-list 命令, 可参考 pkg/multicloud/aliyun/shell/region.go
  • 创建 cmd/testcli/main.go 文件

    • 实现命令调试的入口, 可参考 cmd/aliyuncli/main.go

调试 region-list 命令

# 编译testcli二进制文件
$ make cmd/testcli 
# 通过命令调试接口
$ ./_output/bin/testcli --debug region-list

添加各个资源接口实现

资源的实现类似于树的生长,自根到枝到叶, 越发扩散,region 类似于树根, region 底下有 vpc, zone…, zone 底下有 host, storage…可依照这个顺序依次实现对应资源的接口

  • 添加各个资源的 shell 命令
  • 根据资源接口定义实现各个资源相应的接口

云账号接入

首先需要实现上面基础概念定义的云账号接入里面的接口

  • 主要实现以下几个接口
    • ICloudProviderFactory
      • GetProvider
      • GetId
      • GetName
      • ValidateCreateCloudaccountData
    • ICloudProvider
      • GetFactory
      • GetIRegions
      • GetIRegionById
      • GetSubAccounts
      • GetAccountId
      • GetCloudRegionExternalIdPrefix

实现完成后,编辑 pkg/multicloud/loader/loader.go 文件, 将包导入进去

cloudpods 接入

资源接口及云账号接入已经实现后即可正式接入 cloudpods 调试资源

# 进入cloudpods代码目录, 导入cloudmux, /path/to/local/cloudmux/path需要替换为本地的cloudmux绝对路径
$ go mod edit -replace yunion.io/x/cloudmux=/path/to/local/cloudmux/path
$ make mod
  • 添加 pkg/compute/guestdrivers/testcloud.go pkg/compute/hostdrivers/testcloud.go pkg/compute/regiondrivers/testcloud.go 文件, 实现基础的 init 方法
  • 编辑 cmd/climc/shell/compute/cloudaccounts.go 文件, 添加 create-testcloud 子命令
  • 编辑 cmd/climc/shell/compute/usages.go 文件, 添加云平台名称到对应的变量
  • 编辑 cmd/climc/shell/misc/feature.go, 添加云平台名称到 features 中
  • 编辑 pkg/apis/compute/cloudaccount_const.go 文件, 添加云平台名称到对应的变量
  • 编辑 pkg/apis/compute/host_const.go 文件, 添加对应 host_type, 及底下一些变量需要对应添加
  • 编辑 pkg/apis/compute/guest_const.go 文件, 添加对应的 hypersor, 及底下一些变量需要对应添加
  • 若添加的对应的云子网若是 region 级别的,需要编辑 pkg/apis/compute/network_const.go 文件,添加至 REGIONAL_NETWORK_PROVIDERS
# 编译region二进制, 或者打包region镜像 https://www.cloudpods.org/zh/docs/development/dev-env/#docker-%E9%95%9C%E5%83%8F%E7%BC%96%E8%AF%91%E4%B8%8A%E4%BC%A0
$ make cmd/region
# 编译最新的climc命令
$ make cmd/climc
# 导入云账号
$ ./_output/bin/climc cloud-account-create-testcloud --xxx -xxx -xxx -xxx

问题排查

  • 确认查看当前部署的服务镜像是否更新成编译后打包的镜像
# 查看
kubectl get pods -n oneclouds
  • 先添加如阿里云等已经接入的云平台账号来解锁从测试的云平台资源的创建功能。

  • 可以通过给服务进程发送 SIGUSR1 信号,触发服务进程打印当前调用栈。具体方法参考问题排查工具

  • 从 API 请求定位到对应的后段代码,参考定位后端代码

监控数据采集

  • 修改 cloudmux 的 pkg/cloudmux/testcloud/provider/provider.go 添加实现 GetMetrics 接口
  • 添加 cloudpods 的 pkg/cloudmon/providerdriver/testcloud.go 文件
  • go mod edit –replace && make mod && make cmd/cloudmon 打包发布最新的 cloudmon 镜像调试