云管纳管vCenter

Posted by 爱折腾的工程师 on Wednesday, September 15, 2021

1. vSphere

1.1 vSphere简介

vSphere是VMware推出的基于云的新一代数据中心虚拟化套件,提供了虚拟化基础架构、高可用性、集中管理、监控等一整套解决方案。

vSphere 的两个核心组件是 ESXi和vCenter Server。ESXi是用于创建并运行虚拟机和虚拟设备的虚拟化平台。 vCenter Server是一项服务,用于管理网络中连接的多个主机,并将主机资源池化。

1.2 vSphere架构

2. 纳管vCenter方式

管理节点通过API或SDK来管理vCenter,就达到了管理vSphere资源的目的

  1. vCenter提供的API与SDK
  2. 异步事件侦听
  3. 发送资源控制请求,并接收事件返回
  4. 主动接收vCenter返回内容

3. 纳管vCenter条件

3.1 vCenter资源清单

  • 数据中心
  • 集群
  • 物理机
  • 云主机
  • 网络(标准/分布式交换机/vlan id之类)
  • 存储(本地、SAN、NAS等)
  • 模版(模版虚拟机)

云管已纳管OpenStack,要实现云管也纳管vCenter的话,这些资源如何跟OpenStack的资源对应起来?作为一个云管,要尽可能抽象出共性的地方。

3.2 vCenter环境准备

  • 支持vCenter 6.0、6.5, 6.7和7.0,默认使用https协议加密访问
  • 需要提前建立数据中心、集群、物理机资源结构
  • 需要提前配置本地存储或共享存储(FC-SAN、ISCSI-SAN、NAS)
  • 需要提前配置分布式交换机(dvSwitch)或标准交换机(vSwitch)的端口组信息
  • 如果要将虚拟机转换成模版虚拟机,需提前配置为【模版】类型
  • 不支持存储集群(Datastore Cluster)模式,建议分离使用

3.3 云管环境准备

01.云平台软件准备 -> 02.管理节点硬件准备 -> 03.安装部署 -> 04.初始化 -> 05.添加vCenter

3.4 vCenter基础资源管理

  1. 添加vCenter后,云管自动同步vCenter的集群、物理机、虚拟机、模版、存储、网络等资源
  2. 在vCenter进行变更资源后,同步任务会同步至云管
  3. 云管移除vCenter后,并不会真正删除vCenter上的资源
  4. 支持多个vCenter管理
  5. 支持大屏监控
  6. 支持多租户
  7. 支持资源审批
  8. 支持资源性能监控

3.5 vCenter服务目录

  • 基础资源
  • 云主机
  • 网络
  • 云盘
  • 镜像
  • 事件消息

3.6 vCenter云主机功能

  • 创建:在云管平台创建vCenter的云主机
  • 启动:启动停止状态的云主机
  • 停止:停止云主机
  • 重启:重启云主机
  • 暂停:暂停云主机
  • 恢复:从暂停状态恢复云主机
  • 迁移:将云主机在线迁移到其他计算节点
  • 克隆:对云主机根硬盘进行复制,根据此云主机的计算规格,克隆出与当前主机相同系统的云主机
  • 关闭电源:将云主机电源直接断电
  • 修改计算规格:支持离线修改云主机CPU/内存,启动后生效
  • 更改所有者:将云主机的所有者更改
  • 设置高可用:设置云主机高可用,在资源充足的情况下,物理机宕机的时候,会自动在其他节点自动启动此云主机
  • 打开控制台:打开云主机的控制台,访问控制云主机
  • 加载云盘:将一个可用的未加载的云盘加载到当前云主机
  • 卸载云盘:云主机卸载已加载的云盘
  • 加载网卡:将一个可用的网卡加载到当前云主机,支持加载公有网卡、私有网络
  • 卸载网卡:云主机卸载已添加的网卡
  • 删除:删除云主机,将云主机设置为已删除,同时将远端vCenter上真正云主机停止
  • 恢复:从删除状态恢复云主机
  • 彻底删除:将删除状态的云主机彻底删除,同时彻底删除云管数据库记录和vCenter上真正云主机资源
  • 查看监控数据:在vCenter云主机详情页,点击监控数据子页面,可查看vCenter云主机的CPU、内存、磁盘、虚拟磁盘和网卡的实时监控图
  • 设置控制台密码:设置云主机的控制台密码,云主机重启后生效
  • 取消控制台密码:取消云主机的控制台密码,云主机重启后生效
  • 支持批量创建云主机
  • 支持批量管控云主机(批量启动/停止/重启/暂停/恢复/克隆/删除/删除恢复/彻底删除)

3.7 vCenter云主机网络

标准交换机:

分布式交换机:

二层网络:

  • dvSwitch或vSwitch名称
  • 网络标签VLAN ID

扁平网络:

  • 无网络服务vCenter扁平网络不能給云主机自动分配IP, 需手动配置,建议与预设的IP一致

云路由网络:

  • 支持DHCP、DNS、SNAT、弹性IP、端口转发、负载均衡、IPSec等网络服务
  • 需提前添加云路由镜像、创建公有网络和管理网络、创建云路由规格
  • 网络服务入口与云平台网络服务入口共用

3.8 云主机控制台

使用vSphere Web Client,可以通过启动虚拟机的远程控制台来访问虚拟机的桌面。通过虚拟机远程控制台,可以在虚拟机中执行各种任务,例如安装操作系统、配置操作系统设置、运行应用程序、监控性能等。 在 vSphere Web Client 中,有两个不同的虚拟机远程控制台。

  • 将在单独窗口中打开的适用于Windows的VMware Remote Console (VMRC) 独立应用程序。VMware Remote Console 独立应用程序具有扩展的功能,可用于连接到客户端设备并在远程主机上启动虚拟机控制台。
  • HTML5远程控制台将在浏览器选项卡中打开。使用HTML5远程控制台时,某些功能可能不可用。

推荐使用HTML5控制台方式,大大提高了控制台的兼容性。这个HTML5控制台可以通过预验证拼成的链接方式直接浏览器打开,从vCenter 6.0及以后版本, 这种方式就会失效,会重定向到vSphere认证界面。官方推荐方式是使用VMware HTML Console SDK。使用HTML Console SDK连接到ESXi主机的协议是wss, 这就需要浏览器事先导入证书,或者实现一个ws转wss的代理。

原生vSphere Web Client界面云主机的控制台URL链接

https://<vCenter-IP>:9443/vsphere-client/webconsole.html?
vmId=vm-3756&
vmName=beeone-api-1&
serverGuid=cb7eaba6-9fb3-4214-8da6-1c1734901de5&
host=172.16.90.138:443&
sessionTicket=cst-VCT-523db89f-0a19-a8f8-0f69-f89ec00a6687--tp-24-C0-CF-12-6A-AF-0C-94-CE-F2-CE-69-40-02-7B-73-FC-F9-2B-EB&
thumbprint=24:C0:CF:12:6A:AF:0C:94:CE:F2:CE:69:40:02:7B:73:FC:F9:2B:EB

HTML Console SDK基于websocket协议,支持ws和wss,提供一个wmks.min.js的JS库,可以通过浏览器提供鼠标、键盘、触摸屏以及屏幕刷新、鼠标移动等输入处理的SDK。 在Windows,Mac,Linux测试过的浏览器有:

  • Google Chrome 30+
  • Microsoft Internet Explorer 10+
  • Mozilla Firefox 24+
  • Safari 6.1+

HTML Console架构(基于WebMKS)- 直连方式 这种架构方式是直接连接vm所在的ESXi物理主机,提供console功能,就实现方式而言简单直接,需要能够直连到ESXi主机; 其它非直连方式参考:HTML Console SDK Programming Guide

4. vmware golang sdk调用

4.1 根据模版创建虚拟机

package main

import (
    "context"
    "fmt"
    "github.com/vmware/govmomi"
    "github.com/vmware/govmomi/find"
    "github.com/vmware/govmomi/object"
    "github.com/vmware/govmomi/vim25/types"
    glog "k8s.io/klog"
    "math/rand"
    "net/url"
)

const (
    ip       = "<vcenter-ip>"
    user     = "vsphere.local\\testxxx"
    password = "Testxxx#$"
    template_path = "/test/vm/已发现虚拟机/test-node01"
    vm_name = "testxxx"
)

func main() {
    ctx := context.Background()
    u := &url.URL{
        Scheme: "https",
        Host:   ip,
        Path:   "/sdk",
    }
    u.User = url.UserPassword(user, password)
    c, err := govmomi.NewClient(ctx, u, true)
    if err != nil {
        glog.Fatal(err)
    }

    finder := find.NewFinder(c.Client, false)

    dc, err := finder.DefaultDatacenter(ctx)
    if err != nil {
        glog.Fatal(err)
    }

    finder.SetDatacenter(dc)

    folders, err := dc.Folders(ctx)

    if err != nil {
        glog.Fatal(err)
    }

    dsList, err := finder.DatastoreList(ctx, "*")
    for _, i := range dsList {
        fmt.Println(i)
    }

    ds, err := finder.Datastore(ctx, dsList[0].InventoryPath)
    if err != nil {
        glog.Fatal(err)
    }

    hosts, err := finder.HostSystemList(ctx, "*/*")
    if err != nil {
        glog.Fatal(err)
    }

    nhosts := len(hosts)
    host := hosts[rand.Intn(nhosts)]
    pool, err := host.ResourcePool(ctx)
    if err != nil {
        glog.Fatal(err)
    }

    /*
    if nhosts == 1 {
        // test the default path against the ESX model
        host = nil
    }
    */

    vmFolder := folders.VmFolder
    err = cloneVm(finder, vmFolder, ctx, pool, ds, host)
    if err != nil {
        glog.Fatal(err)
    }
}

func cloneVm(finder *find.Finder, f *object.Folder, ctx context.Context, p *object.ResourcePool, ds *object.Datastore, h *object.HostSystem) error {
    //Logf("%s cloning virtual machine from %s\n", vm.ID(), vm.TemplateConfig.Use)

    obj, err := finder.VirtualMachine(ctx, template_path)
    if err != nil {
        return err
    }

    folderRef := f.Reference()
    datastoreRef := ds.Reference()
    poolRef := p.Reference()

    var hostRef *types.ManagedObjectReference
    if h != nil {
        ref := h.Reference()
        hostRef = &ref
    }

    spec := types.VirtualMachineCloneSpec{
        Location: types.VirtualMachineRelocateSpec{
            Folder:    &folderRef,
            Datastore: &datastoreRef,
            Pool:      &poolRef,
            Host:      hostRef,
        },
        Template: false,
        PowerOn:  true,
    }

    task, err := obj.Clone(ctx, f, vm_name, spec)
    if err != nil {
        return err
    }

    return task.Wait(ctx)
}

4.2 HTML5 Console控制台

官方简洁的例子

<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Console</title>
</head>
<body>
<link rel="stylesheet" type="text/css" href="css/wmks-all.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.8.16/jquery-ui.min.js"></script>
<script type="text/javascript" src="wmks.min.js"></script>
<div id="wmksContainer" style="position:absolute;width:100%;height:100%"></div>
<script>
var wmks = WMKS.createWMKS("wmksContainer",{})
 .register(WMKS.CONST.Events.CONNECTION_STATE_CHANGE, function(event,data){
 if(data.state == WMKS.CONST.ConnectionState.CONNECTED){
  console.log("connection state change : connected");}
 });
wmks.connect("ws://<websocket server地址>");
</script>
</body>
</html>

5. 参考链接

「真诚赞赏,手留余香」

爱折腾的工程师

真诚赞赏,手留余香

使用微信扫描二维码完成支付