@meilei007
2017-10-24T07:02:16.000000Z
字数 63614
阅读 2398
zstack RESTful
本书将指导用户如何通过REST API来生成基于ZStack企业版的私有云环境。本书面向的对象是有基于ZStack RESTful API做二次开发需求的读者,或希望将ZStack整合进公司已有业务系统需求的读者。
在阅读本书之前,读者需阅读《ZStack 企业版开发手册》,了解ZStack目前提供的RESTful API使用方式。
本书分为两个章节,第一章节为基本场景,主要描述如何对ZStack中的基本资源做操作。第二章节为特定的私有云场景,主要描述一些现实环境中的私有云部署方案,并描述如何基于ZStack提供的基本资源,通过RESTful API完成私有云场景的创建。
REST由于是无状态的传输,所以每一次请求都得带上身份认证信息。读者如果想通过rest API 来创建一个私有云环境,首先需要通过ZStack的API: LogInByAccount 获得一个令牌,这个令牌作为之后每一步操作的身份认证信息。
//声明sessionId;每个action均需要sessionIdString sessionId;//设置登录zstack的地址ZSConfig.Builder zBuilder = new ZSConfig.Builder();zBuilder.setContextPath("zstack");zBuilder.setHostname("172.20.12.9");ZSClient.configure(zBuilder.build());//登录zstack;获取session;需要对密码进行SHA-512算法加密LogInByAccountAction logInByAccountAction = new LogInByAccountAction();logInByAccountAction.accountName = "admin";logInByAccountAction.password = SHA("password", "SHA-512");LogInByAccountAction.Result logInByAccountActionRes = logInByAccountAction.call();sessionId = logInByAccountActionRes.value.getInventory().getUuid();
拿到login的令牌之后,第一步是创建一个区域。一个区域是由类似主存储,集群,L2网络的资源组成的逻辑组; 它定义一个可见的边界,在相同区域中的资源互相可见并且可以形成某种关系,但在不同区域中的资源是不行的. 例如, 区域A中的一个主存储可以挂载到区域A中的一个集群,但不能挂载到区域B的集群上。区域的子资源,包括集群,L2网络和主存储等。
CreateZoneAction createZoneAction = new CreateZoneAction();createZoneAction.name = "zone1";createZoneAction.description = "this is a zone";createZoneAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";ZoneInventory zone = createZoneAction.call().value.inventory;
区域创建完成后,需要创建集群。一个集群是类似主机(Host)组成的逻辑组。 在同一个集群中的主机必须安装相同的操作系统, 拥有相同的二层网络连接, 可以访问相同的主存储。 在实际的数据中心, 一个集群通常对应一个机架(rack)。
CreateClusterAction createClusterAction = new CreateClusterAction();createClusterAction.zoneUuid = "dad0910508e8498da2f247174ab714bc";createClusterAction.name = "cluster1";createClusterAction.description = "this is a cluster";createClusterAction.hypervisorType = "KVM";createClusterAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";ClusterInventory cluster = createClusterAction.call().value.inventory;
集群创建完后,再添加物理机。物理机是一个安装有操作系统的物理服务器。
AddKVMHostAction addKVMHostAction = new AddKVMHostAction();addKVMHostAction.name = "host1";addKVMHostAction.username = "root";addKVMHostAction.password = "password";addKVMHostAction.clusterUuid = "db2e569c4e2c41448fb6f9309d2bf52f";addKVMHostAction.managementIp = "172.20.12.9";addKVMHostAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";HostInventory host = addKVMHostAction.call().value.inventory;
添加完物理机之后,再添加主存储。主存储是数据中心里为云主机提供根云盘和数据云盘的存储系统. ZStack的主存储分多种类型,包括LocalStorage,NFS,Ceph,FusionStor,Shared Mount Point
//这里添加本地主存储AddLocalPrimaryStorageAction addLocalPrimaryStorageAction = new AddLocalPrimaryStorageAction();addLocalPrimaryStorageAction.url = "/zstack_ps";addLocalPrimaryStorageAction.name = "ps1";addLocalPrimaryStorageAction.zoneUuid = "dad0910508e8498da2f247174ab714bc";addLocalPrimaryStorageAction.sessionId = sessionId;PrimaryStorageInventory primaryStorage = addLocalPrimaryStorageAction.call().value.inventory;//将本地主存储挂载到集群AttachPrimaryStorageToClusterAction attachPrimaryStorageToClusterAction = new AttachPrimaryStorageToClusterAction();attachPrimaryStorageToClusterAction.clusterUuid = "db2e569c4e2c41448fb6f9309d2bf52f";attachPrimaryStorageToClusterAction.primaryStorageUuid = "0e6f4c9d89bd4cc2b0cb420568ee46ec";attachPrimaryStorageToClusterAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";attachPrimaryStorageToClusterAction.call();
添加完主存储之后,再添加备份存储。备份存储又叫镜像服务器。备份存储是保存用于创建云盘的镜像的存储系统。Mevoco的备份存储分多种类型,包括ImageStore,Ceph,FusionStor
//这里添加本地备份存储AddImageStoreBackupStorageAction addImageStoreBackupStorageAction = new AddImageStoreBackupStorageAction();addImageStoreBackupStorageAction.hostname = "172.20.12.9";addImageStoreBackupStorageAction.username = "root";addImageStoreBackupStorageAction.password = "password";addImageStoreBackupStorageAction.url = "/zstack_bs";addImageStoreBackupStorageAction.name = "bs1";addImageStoreBackupStorageAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";ImageStoreBackupStorageInventory imageStoreBackupStoage = addImageStoreBackupStorageAction.call().value.inventory;//将镜像存储挂载到集群AttachBackupStorageToZoneAction attachBackupStorageToZoneAction = new AttachBackupStorageToZoneAction();attachBackupStorageToZoneAction.zoneUuid = "dad0910508e8498da2f247174ab714bc";attachBackupStorageToZoneAction.backupStorageUuid = "15a01470b6fb4468b64b62ae58eb22c0";attachBackupStorageToZoneAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";attachBackupStorageToZoneAction.call();
存储和物理机全部添加完成后,我们具备了基本云主机启动条件,下面我们为云主机创建网络环境。首先,创建二层网络。L2网络在数据中心中代表了一个二层广播域, 在ZStack中, L2网络负责为L3网络提供二层隔离。
//创建无服务L2NoVlan网络CreateL2NoVlanNetworkAction createL2NoVlanNetworkAction = new CreateL2NoVlanNetworkAction();createL2NoVlanNetworkAction.name = "public-management-l2";createL2NoVlanNetworkAction.description = "this is a no-serivce network";createL2NoVlanNetworkAction.zoneUuid = "dad0910508e8498da2f247174ab714bc";createL2NoVlanNetworkAction.physicalInterface = "eth0";createL2NoVlanNetworkAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";L2NetworkInventory l2NoVlanNetwork = createL2NoVlanNetworkAction.call().value.inventory;//挂载无服务L2NoVlan网络到集群AttachL2NetworkToClusterAction attachL2NoVlanNetworkToClusterAction = new AttachL2NetworkToClusterAction();attachL2NoVlanNetworkToClusterAction.l2NetworkUuid = d45c8fea42324c939b71931eabb7f932;attachL2NoVlanNetworkToClusterAction.clusterUuid = "db2e569c4e2c41448fb6f9309d2bf52f";attachL2NoVlanNetworkToClusterAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";attachL2NoVlanNetworkToClusterAction.call();
二层网络创建完成后,需要创建三层网络。三层网络是由子网(subnet)以及一系列网络服务(network services)组成。网络服务提供模块(network service providers)提供的网络服务, 通常是OSI三层到七层协议的软件实现。
//基于L2NoVlan网络创建L3网络,作为公有网络CreateL3NetworkAction createL3PublicNetworkAction = new CreateL3NetworkAction();createL3PublicNetworkAction.name = "public-management-l3";createL3PublicNetworkAction.type = "L3BasicNetwork";createL3PublicNetworkAction.l2NetworkUuid = "68a05a0154d4472bb7a059b54a53f166";createL3PublicNetworkAction.system = false;createL3PublicNetworkAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";L3NetworkInventory l3PublicNetwork = createL3PublicNetworkAction.call().value.inventory;//挂载IP地址段到公有网络;AddIpRangeAction addIpRangeAction = new AddIpRangeAction();addIpRangeAction.l3NetworkUuid = "917fe2f51ab7423ca6e74648c5ae8931";addIpRangeAction.name = "iprange1";addIpRangeAction.startIp = "10.101.50.2";addIpRangeAction.endIp = "10.101.50.254";addIpRangeAction.netmask = "255.0.0.0";addIpRangeAction.gateway = "10.0.0.1";addIpRangeAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";addIpRangeAction.call();//为共有网络private-l3添加DNS服务AddDnsToL3NetworkAction addDnsToL3NetworkAction = new AddDnsToL3NetworkAction();addDnsToL3NetworkAction.l3NetworkUuid = "917fe2f51ab7423ca6e74648c5ae8931";addDnsToL3NetworkAction.dns = "8.8.8.8";addDnsToL3NetworkAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";addDnsToL3NetworkAction.call();//获取网络服务的UuidQueryNetworkServiceProviderAction queryNetworkServiceProviderAction = new QueryNetworkServiceProviderAction();queryNetworkServiceProviderAction.conditions = Collections.singletonList("type=Flat");queryNetworkServiceProviderAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";NetworkServiceProviderInventory networkServiceProvider = queryNetworkServiceProviderAction.call().value.inventories.get(0);Map<String, List<String>> networkServices = new HashMap<String, List<String>>();networkServices.put(networkServiceProvider.uuid, asList("DHCP", "Eip", "Userdata"));//为公有网络添加网络服务AttachNetworkServiceToL3NetworkAction attachNetworkServiceToL3NetworkAction = new AttachNetworkServiceToL3NetworkAction();attachNetworkServiceToL3NetworkAction.l3NetworkUuid = ""68a05a0154d4472bb7a059b54a53f166"";attachNetworkServiceToL3NetworkAction.networkServices = networkServices;attachNetworkServiceToL3NetworkAction.sessionId = sessionId;attachNetworkServiceToL3NetworkAction.call();
三层网络创建完后,云主机的基本环境已经准备就绪,现在,需要设置云主机的计算规格。计算规格定义了云主机的内存,CPU以及云主机的磁盘IO和网络带宽IO。
//创建计算规格CreateInstanceOfferingAction createInstanceOfferingAction = new CreateInstanceOfferingAction();createInstanceOfferingAction.name = "instanceoffering1";createInstanceOfferingAction.cpuNum = 1;createInstanceOfferingAction.memorySize = 2148000000l;createInstanceOfferingAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";InstanceOfferingInventory instanceOffering = createInstanceOfferingAction.call().value.inventory;
到这里,只剩下云主机启动的镜像没有添加了,镜像为云主机文件系统提供模板。 镜像可以是为云主机安装操作系统的根云盘(root volume)提供模板的RootVolumeTemplate; 镜像也可以是为云主机存储非操作系统数据的数据云盘(data volumes)提供模板的DataVolumeTemplate; 同时镜像也可以是用来在空白根云盘(blank root volumes)上安装操作系统的ISO文件。
//添加镜像到本地镜像仓库AddImageAction addImageAction = new AddImageAction();addImageAction.name = "image1";addImageAction.url = "http://192.168.200.100/mirror/diskimages/centos7.2-mini-qemu-qa.qcow2";addImageAction.format = "qcow2";addImageAction.backupStorageUuids = "15a01470b6fb4468b64b62ae58eb22c0";addImageAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";ImageInventory image = addImageAction.call().value.inventory;
当所有资源准备就绪,我们可以开始创建云主机了。
//创建虚拟机CreateVmInstanceAction createVmInstanceAction = new CreateVmInstanceAction();createVmInstanceAction.name = "vm1";createVmInstanceAction.instanceOfferingUuid = "416ba9d9365643bbbe18c8ed2dca2e2c";createVmInstanceAction.imageUuid = "0403f3b539cf49b68cecdb0b5da92b8b";createVmInstanceAction.l3NetworkUuids = "917fe2f51ab7423ca6e74648c5ae8931";createVmInstanceAction.dataDiskOfferingUuids = "c87fea8ea690429a8825a9bf9fa68b4d";createVmInstanceAction.clusterUuid = "db2e569c4e2c41448fb6f9309d2bf52f";createVmInstanceAction.description = "this is a vm";createVmInstanceAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";VmInstanceInventory vm = createVmInstanceAction.call().value.inventory;
其中,每个所依赖资源的uuid都通过对应资源的Inventory获取
云主机运行起来后,用户为了保证数据的安全性,可以为云主机做快照备份。快照可以保存云主机的根云盘(Root Volume)或者数据云盘(Data Volume)在某一时刻的所有数据。根云盘和数据云盘创建快照使用的是相同的API。
CreateVolumeSnapshotAction action = new CreateVolumeSnapshotAction();action.volumeUuid = "5d7edc10db7b4187a27e310bac3d3201";action.name = "snapshot-volume";action.description = "a snapshot for volume";action.sessionUuid = "68a05a0154d4472bb7a059b54a53f166";CreateVolumeSnapshotAction.Result res = action.call();
当用户的业务量增加,需要调整CPU,内存,网络IO,硬盘IO时,可以通过该方式生效。需要注意的是,在目前版本中,需要停止云主机,再启动云主机,才能读取修改后的配置。
UpdateVmInstanceAction action = new UpdateVmInstanceAction();action.uuid = "6cff485bf490471bb64a9f2824aca8d6";action.name = "new vm name";action.sessionUuid = "68a05a0154d4472bb7a059b54a53f166";UpdateVmInstanceAction.Result res = action.call();
用户可以通过前端代码调用Console访问接口,获取云主机Console界面的信息,在前端页面打开云主机的Console界面。
RequestConsoleAccessAction action = new RequestConsoleAccessAction();action.vmInstanceUuid = "6cff485bf490471bb64a9f2824aca8d6";action.sessionUuid = "68a05a0154d4472bb7a059b54a53f166";RequestConsoleAccessAction.Result res = action.call();
当调用该接口获得云主机console的访问信息后,可以通过如下javascript示例代码在前端页面打开云主机的Console访问:
$window.open("personal_dir/vnc.html?host=" + hostname +"&port=" + port +"&token=" +token +"&title=" + name)
其中,hostname, port, token是通过API返回的Console访问信息res获得的,name是用户自定义的名称,不做限制。
当业务规模不断扩大,管理员可以创建不同的账户,并且给账户分配不同的配额。管理员可以根据账户的uuid获得账户对当前资源的使用配额。
QueryQuotaAction action = new QueryQuotaAction();action.conditions = asList("name=test");action.sessionUuid = "68a05a0154d4472bb7a059b54a53f166";QueryQuotaAction.Result res = action.call();
了解了ZStack基本的资源创建操作方法后,本章将给读者展示如何基于已有的知识,快速创建不同场景下的私有云环境。
本章节的各类场景将覆盖以下资源:
网络类型覆盖扁平网络,云路由网络;
主存储类型覆盖本地存储,ceph分布式存储,NFS
备份存储类型覆盖镜像仓库,ceph分布式存储
由于以下场景为笔者模拟的网络环境,公网IP段并非真实公网IP段,请读者根据实际网络环境调整
该类场景通常内部有一个私有网络段,对外有一个公有网络段,但公有网络IP地址有限,需要作为弹性IP分配给云平台的云主机使用。同时,客户的运维团队不希望运维分布式存储,希望通过RAID阵列卡来对磁盘做冗余,解决存储安全的问题。在这种场景下,ZStack提供的私有云方案如下:
网络类型: 扁平网络+弹性IP
主存储类型:本地存储
备份存储: 镜像服务器
公有网络: 公网地址段(弹性IP)
私有网络: 内网地址段(云主机之间通讯使用)
网络拓扑图如下:
在上图中,我们可以看到三个网络,分别连接了ZStack管理节点,物理服务器,镜像服务器。 ZStack管理节点通过192.168.0.0/24的网络连接并控制物理服务器和镜像服务器。 物理服务器上的云主机则通过192.168.100.0/24的网络进行数据交换,并通过公有网络10.0.0.0/8获取弹性IP,透过企业的防火墙访问Internet,并支持外部访问绑定了弹性IP的云主机。
这种场景的优势在于,部署简单,成本较低,用户的设备可以利旧,并且分布式网络架构保证了云平台的网络不会出现单点故障。
通过Java SDK创建该私有云环境的代码如下:
package org.zstack.scene;import org.zstack.sdk.*;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Map;import static java.util.Arrays.asList;/*** Created by ZStack on 17-3-3.*/public class flatNetworkLocalStorageEipScene {public static String SHA(final String strText, final String strType){String strResult = null;if (strText != null && strText.length() > 0) {try {// SHA 加密开始// 创建加密对象 并传入加密类型MessageDigest messageDigest = MessageDigest.getInstance(strType);// 传入要加密的字符串messageDigest.update(strText.getBytes());// 得到 byte 类型结果byte byteBuffer[] = messageDigest.digest();// 将 byte 转换为 stringStringBuffer strHexString = new StringBuffer();// 遍历 byte bufferfor (int i = 0; i < byteBuffer.length; i++){String hex = Integer.toHexString(0xff & byteBuffer[i]);if (hex.length() == 1){strHexString.append('0');}strHexString.append(hex);}// 得到返回结果strResult = strHexString.toString();}catch (NoSuchAlgorithmException e){e.printStackTrace();}}return strResult;}public static void main(String[] args){//声明sessionId;每个action均需要sessionIdString sessionId = null;//设置登录zstack的地址;通过172.20.12.4连接到部署zstack管理节点环境的主机ZSConfig.Builder zBuilder = new ZSConfig.Builder();zBuilder.setContextPath("zstack");zBuilder.setHostname("172.20.12.4");ZSClient.configure(zBuilder.build());//登录zstack;获取sessionLogInByAccountAction logInByAccountAction = new LogInByAccountAction();logInByAccountAction.accountName = "admin";logInByAccountAction.password = SHA("password","SHA-512");LogInByAccountAction.Result logInByAccountActionRes = logInByAccountAction.call();if(logInByAccountActionRes.error ==null) {System.out.println("logInByAccount successfully");sessionId = logInByAccountActionRes.value.getInventory().getUuid();}else logInByAccountActionRes.throwExceptionIfError();//创建区域CreateZoneAction createZoneAction = new CreateZoneAction();createZoneAction.name = "zone1";createZoneAction.description = "this is a zone";createZoneAction.sessionId = sessionId;ZoneInventory zone = createZoneAction.call().value.inventory;System.out.println(String.format("createZone:%s successfully",zone.name));//创建集群CreateClusterAction createClusterAction = new CreateClusterAction();createClusterAction.zoneUuid = zone.uuid;createClusterAction.name = "cluster1";createClusterAction.description = "this is a cluster";createClusterAction.hypervisorType = "KVM";createClusterAction.sessionId = sessionId;ClusterInventory cluster = createClusterAction.call().value.inventory;System.out.println(String.format("createCluster:%s successfully",cluster.name));//添加物理机;物理机IP应处于与公网IP不同的网络段,作为管理网络,实现公有网络与管理网络分离AddKVMHostAction addKVMHostAction = new AddKVMHostAction();addKVMHostAction.name="host1";addKVMHostAction.username = "root";addKVMHostAction.password = "password";addKVMHostAction.clusterUuid = cluster.uuid;addKVMHostAction.managementIp= "192.168.99.93";addKVMHostAction.sessionId = sessionId;HostInventory host = addKVMHostAction.call().value.inventory;System.out.println("addKVMHost successfully");//添加本地主存储AddLocalPrimaryStorageAction addLocalPrimaryStorageAction = new AddLocalPrimaryStorageAction();addLocalPrimaryStorageAction.url = "/zstack_ps";addLocalPrimaryStorageAction.name = "ps1";addLocalPrimaryStorageAction.zoneUuid = zone.uuid;addLocalPrimaryStorageAction.sessionId = sessionId;PrimaryStorageInventory primaryStorage = addLocalPrimaryStorageAction.call().value.inventory;System.out.println(String.format("addLocalPrimaryStorage:%s successfully",primaryStorage.name));//将本地主存储挂载到集群AttachPrimaryStorageToClusterAction attachPrimaryStorageToClusterAction = new AttachPrimaryStorageToClusterAction();attachPrimaryStorageToClusterAction.clusterUuid = cluster.uuid;attachPrimaryStorageToClusterAction.primaryStorageUuid = primaryStorage.uuid;attachPrimaryStorageToClusterAction.sessionId = sessionId;attachPrimaryStorageToClusterAction.call();System.out.println("attachPrimaryStorageToCluster successfully");//添加本地镜像存储;笔者测试环境中部署ZStack、主存储、镜像存储三者实质是同一台物理机AddImageStoreBackupStorageAction addImageStoreBackupStorageAction = new AddImageStoreBackupStorageAction();addImageStoreBackupStorageAction.hostname = "192.168.99.93";addImageStoreBackupStorageAction.username = "root";addImageStoreBackupStorageAction.password = "password";addImageStoreBackupStorageAction.url = "/zstack_bs";addImageStoreBackupStorageAction.name = "bs1";addImageStoreBackupStorageAction.sessionId = sessionId;ImageStoreBackupStorageInventory imageStoreBackupStoage = addImageStoreBackupStorageAction.call().value.inventory;System.out.println(String.format("addImageStoreBackupStorage:%s successfully",imageStoreBackupStoage.name));//将镜像存储挂载到区域;注意与主存储不同,这是由zstack的设计架构决定的AttachBackupStorageToZoneAction attachBackupStorageToZoneAction = new AttachBackupStorageToZoneAction();attachBackupStorageToZoneAction.zoneUuid = zone.uuid;attachBackupStorageToZoneAction.backupStorageUuid = imageStoreBackupStoage.uuid;attachBackupStorageToZoneAction.sessionId = sessionId;attachBackupStorageToZoneAction.call();System.out.println("attachBackupStorageToZone successfully");//添加镜像到本地镜像仓库AddImageAction addImageAction = new AddImageAction();addImageAction.name = "image1";addImageAction.url = "http://cdn.zstack.io/product_downloads/iso/ZStack-Enterprise-x86_64-DVD-1.9.0.iso";addImageAction.format = "qcow2";addImageAction.backupStorageUuids = Collections.singletonList(imageStoreBackupStoage.uuid);addImageAction.sessionId = sessionId;ImageInventory image = addImageAction.call().value.inventory;System.out.println(String.format("addImage:%s successfully",image.name));//创建无服务L2NoVlan公有网络CreateL2NoVlanNetworkAction createL2NoVlanNetworkAction = new CreateL2NoVlanNetworkAction();createL2NoVlanNetworkAction.name = "public-l2";createL2NoVlanNetworkAction.description = "this is a no-serivce network";createL2NoVlanNetworkAction.zoneUuid = zone.uuid;createL2NoVlanNetworkAction.physicalInterface = "eth1";createL2NoVlanNetworkAction.sessionId = sessionId;L2NetworkInventory l2NoVlanNetwork = createL2NoVlanNetworkAction.call().value.inventory;System.out.println(String.format("createL2NoVlanNetwork:%s successfully",l2NoVlanNetwork.name));//挂载无服务L2NoVlan公有网络到集群AttachL2NetworkToClusterAction attachL2NoVlanNetworkToClusterAction = new AttachL2NetworkToClusterAction();attachL2NoVlanNetworkToClusterAction.l2NetworkUuid = l2NoVlanNetwork.uuid;attachL2NoVlanNetworkToClusterAction.clusterUuid = cluster.uuid;attachL2NoVlanNetworkToClusterAction.sessionId = sessionId;attachL2NoVlanNetworkToClusterAction.call();//创建无服务L2Vlan私有网络CreateL2VlanNetworkAction createL2VlanNetworkAction = new CreateL2VlanNetworkAction();createL2VlanNetworkAction.vlan = 3000;createL2VlanNetworkAction.name = "private-l2";createL2VlanNetworkAction.description = "this is a l2-vlan network";createL2VlanNetworkAction.zoneUuid = zone.uuid;createL2VlanNetworkAction.physicalInterface = "eth1";createL2VlanNetworkAction.sessionId = sessionId;L2NetworkInventory l2VlanNetwork = createL2VlanNetworkAction.call().value.inventory;System.out.println(String.format("createL2VlanNetwork:%s successfully",l2VlanNetwork.name));//挂载无服务L2Vlan私有网络到集群AttachL2NetworkToClusterAction attachL2VlanNetworkToClusterAction = new AttachL2NetworkToClusterAction();attachL2VlanNetworkToClusterAction.l2NetworkUuid = l2VlanNetwork.uuid;attachL2VlanNetworkToClusterAction.clusterUuid = cluster.uuid;attachL2VlanNetworkToClusterAction.sessionId = sessionId;attachL2VlanNetworkToClusterAction.call();//基于L2NoVlan公有网络创建L3公有网络CreateL3NetworkAction createL3PublicNetworkAction = new CreateL3NetworkAction();createL3PublicNetworkAction.name = "public-l3";createL3PublicNetworkAction.type = "L3BasicNetwork";createL3PublicNetworkAction.l2NetworkUuid = l2NoVlanNetwork.uuid;createL3PublicNetworkAction.system = false;createL3PublicNetworkAction.sessionId = sessionId;L3NetworkInventory l3PublicNetwork = createL3PublicNetworkAction.call().value.inventory;System.out.println(String.format("createL2VlanNetwork:%s successfully",l3PublicNetwork.name));//挂载IP地址段到l3公有网络;AddIpRangeAction addIpRangeAction = new AddIpRangeAction();addIpRangeAction.l3NetworkUuid = l3PublicNetwork.uuid;addIpRangeAction.name = "iprange1";addIpRangeAction.startIp = "10.101.50.2";addIpRangeAction.endIp = "10.101.50.254";addIpRangeAction.netmask = "255.0.0.0";addIpRangeAction.gateway = "10.0.0.1";addIpRangeAction.sessionId = sessionId;addIpRangeAction.call();//基于L2Vlan私有网络 创建L3私有网络CreateL3NetworkAction createL3PrivateNetworkAction = new CreateL3NetworkAction();createL3PrivateNetworkAction.name = "private-l3";createL3PrivateNetworkAction.type = "L3BasicNetwork";createL3PrivateNetworkAction.l2NetworkUuid = l2VlanNetwork.uuid;createL3PrivateNetworkAction.system = false;createL3PrivateNetworkAction.sessionId = sessionId;L3NetworkInventory l3PrivateNetwork = createL3PrivateNetworkAction.call().value.inventory;System.out.println(String.format("createL2VlanNetwork:%s successfully",l3PrivateNetwork.name));//挂载Ip地址段到l3私有网络;这里使用CIDR方式,与上文中的直接挂载IP地址段效果相同AddIpRangeByNetworkCidrAction addIpRangeByNetworkCidrAction = new AddIpRangeByNetworkCidrAction();addIpRangeByNetworkCidrAction.name = "iprange2";addIpRangeByNetworkCidrAction.l3NetworkUuid = l3PrivateNetwork.uuid;addIpRangeByNetworkCidrAction.networkCidr = "192.168.100.0/24";addIpRangeByNetworkCidrAction.sessionId = sessionId;addIpRangeByNetworkCidrAction.call();//为私有网络private-l3添加DNS服务AddDnsToL3NetworkAction addDnsToL3NetworkAction = new AddDnsToL3NetworkAction();addDnsToL3NetworkAction.l3NetworkUuid = l3PrivateNetwork.uuid;addDnsToL3NetworkAction.dns = "8.8.8.8";addDnsToL3NetworkAction.sessionId = sessionId;addDnsToL3NetworkAction.call();//获取扁平网络服务的UuidQueryNetworkServiceProviderAction queryNetworkServiceProviderAction = new QueryNetworkServiceProviderAction();queryNetworkServiceProviderAction.conditions = Collections.singletonList("type=Flat");queryNetworkServiceProviderAction.sessionId = sessionId;NetworkServiceProviderInventory networkServiceProvider = queryNetworkServiceProviderAction.call().value.inventories.get(0);System.out.println(String.format("queryNetworkServiceprovider:%s successfully",networkServiceProvider.getName()));Map<String,List<String>> networkServices = new HashMap<String, List<String>>();networkServices.put(networkServiceProvider.uuid, asList("DHCP", "Eip", "Userdata"));//为私有网络添加扁平网络服务AttachNetworkServiceToL3NetworkAction attachNetworkServiceToL3NetworkAction = new AttachNetworkServiceToL3NetworkAction();attachNetworkServiceToL3NetworkAction.l3NetworkUuid = l3PrivateNetwork.uuid;attachNetworkServiceToL3NetworkAction.networkServices = networkServices;attachNetworkServiceToL3NetworkAction.sessionId = sessionId;attachNetworkServiceToL3NetworkAction.call();System.out.println("attachNetworkServiceToL3Network successfully");//创建计算规格CreateInstanceOfferingAction createInstanceOfferingAction = new CreateInstanceOfferingAction();createInstanceOfferingAction.name = "instanceoffering1";createInstanceOfferingAction.cpuNum = 1;createInstanceOfferingAction.memorySize = 2148000000l;createInstanceOfferingAction.sessionId = sessionId;InstanceOfferingInventory instanceOffering = createInstanceOfferingAction.call().value.inventory;System.out.println(String.format("createInstanceOffering:%s successfully",instanceOffering.name));//创建云盘规格CreateDiskOfferingAction createDiskOfferingAction = new CreateDiskOfferingAction();createDiskOfferingAction.name = "diskOffering1";createDiskOfferingAction.diskSize = 2148000000l;createDiskOfferingAction.sessionId = sessionId;DiskOfferingInventory diskOffering = createDiskOfferingAction.call().value.inventory;System.out.println(String.format("createDiskOffering:%s successfully",diskOffering.name));//创建虚拟机CreateVmInstanceAction createVmInstanceAction = new CreateVmInstanceAction();createVmInstanceAction.name = "vm1";createVmInstanceAction.instanceOfferingUuid = instanceOffering.uuid;createVmInstanceAction.imageUuid = image.uuid;createVmInstanceAction.l3NetworkUuids = Collections.singletonList(l3PrivateNetwork.uuid);createVmInstanceAction.dataDiskOfferingUuids = Collections.singletonList(diskOffering.uuid);createVmInstanceAction.clusterUuid = cluster.uuid;createVmInstanceAction.description = "this is a vm";createVmInstanceAction.sessionId = sessionId;VmInstanceInventory vm = createVmInstanceAction.call().value.inventory;System.out.println(String.format("createVm:%s successfully",vm.name));//基于公有网络public-l3 创建Vip,为Eip作准备CreateVipAction createVipAction = new CreateVipAction();createVipAction.name = "vip1";createVipAction.l3NetworkUuid = l3PublicNetwork.uuid;createVipAction.sessionId = sessionId;VipInventory vip = createVipAction.call().value.inventory;System.out.println(String.format("createVip:%s successfully",vip.name));//创建EipCreateEipAction createEipAction = new CreateEipAction();createEipAction.name = "eip1";createEipAction.vipUuid = vip.uuid;createEipAction.vmNicUuid = vm.vmNics.get(0).uuid;createEipAction.sessionId = sessionId;EipInventory eip = createEipAction.call().value.inventory;System.out.println(String.format("createEip:%s successfully",eip.name));//挂载Eip到虚拟机AttachEipAction attachEipAction = new AttachEipAction();attachEipAction.eipUuid = eip.uuid;attachEipAction.vmNicUuid = vm.vmNics.get(0).uuid;attachEipAction.sessionId = sessionId;attachEipAction.call();}}
在该场景下,用户内部业务部门对数据安全性的要求很高,不希望产生数据丢失的情况,并希望使用业界流行的超融合架构,即每个物理机均提供网络、存储、计算的功能。用户提供一个网关,所有云主机能够和该网关下其他设备能够直接通讯。在这种场景下,ZStack提供的私有云方案如下:
网络类型: 扁平网络
主存储类型:ceph分布式存储
备份存储: ceph分布式存储
私有网络: 内网地址段(云主机使用)
网络拓扑图如下:
这种模式也需要用户拥有万兆的网络环境,而在ZStack中搭建分布式存储网络模型,则和NAS架构相比,仅需在添加主存储时,选择使用Ceph,并且指定192.168.0.0/24网段Ceph的MonURLs。
使用Ceph的好处有:成本相对低廉(完全使用免费开源软件搭建,且不考虑聘请额外的Ceph运维人员),数据“没有”单点故障(要求运维良好),数据相对安全(多副本存储于不同的机器)。注意到当前市场上以有一部分公司都已经在生产环境中使用了Ceph。 不过考虑到目前的市场反馈,保证Ceph稳定性,如果中小公司打算采用Ceph方案, 也可以通过ZStack获得商业级ceph存储。
另外,细心的读者可能会问,我们为什么图中使用计算和存储分离的Ceph架构,而不是计算和存储融合的架构。 这个地方主要也是考虑到Ceph在大IO(例如计算节点上云主机较多,且IO操作比较频繁)的时候,会消耗大量的物理机CPU。 如果采用融合的架构,如果不进行有效的隔离,可能会导致云主机的效率降低。当然,具体采用何种分布式架构,还需要客户根据自己的场景来进行规划。
通过Java SDK创建该私有云环境的代码如下:
package org.zstack.scene;import org.zstack.sdk.*;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Map;import static java.util.Arrays.asList;/*** Created by ZStack on 17-3-3.*/public class flatNetworkCephStorageScene {public static String SHA(final String strText, final String strType){String strResult = null;if (strText != null && strText.length() > 0) {try {// SHA 加密开始// 创建加密对象 并传入加密类型MessageDigest messageDigest = MessageDigest.getInstance(strType);// 传入要加密的字符串messageDigest.update(strText.getBytes());// 得到 byte 类型结果byte byteBuffer[] = messageDigest.digest();// 将 byte 转换为 stringStringBuffer strHexString = new StringBuffer();// 遍历 byte bufferfor (int i = 0; i < byteBuffer.length; i++){String hex = Integer.toHexString(0xff & byteBuffer[i]);if (hex.length() == 1){strHexString.append('0');}strHexString.append(hex);}// 得到返回结果strResult = strHexString.toString();}catch (NoSuchAlgorithmException e){e.printStackTrace();}}return strResult;}public static void main(String[] args) {//声明sessionId;每个action均需要sessionIdString sessionId = null;//设置登录zstack的地址;通过172.20.12.4连接到部署zstack管理节点环境的主机ZSConfig.Builder zBuilder = new ZSConfig.Builder();zBuilder.setContextPath("zstack");zBuilder.setHostname("172.20.12.4");ZSClient.configure(zBuilder.build());//登录zstack;获取sessionLogInByAccountAction logInByAccountAction = new LogInByAccountAction();logInByAccountAction.accountName = "admin";logInByAccountAction.password = SHA("password", "SHA-512");LogInByAccountAction.Result logInByAccountActionRes = logInByAccountAction.call();if (logInByAccountActionRes.error == null) {System.out.println("logInByAccount successfully");sessionId = logInByAccountActionRes.value.getInventory().getUuid();}else logInByAccountActionRes.throwExceptionIfError();//创建区域CreateZoneAction createZoneAction = new CreateZoneAction();createZoneAction.name = "zone1";createZoneAction.description = "this is a zone";createZoneAction.sessionId = sessionId;ZoneInventory zone = createZoneAction.call().value.inventory;System.out.println(String.format("createZone:%s successfully", zone.name));//创建集群CreateClusterAction createClusterAction = new CreateClusterAction();createClusterAction.zoneUuid = zone.uuid;createClusterAction.name = "cluster1";createClusterAction.description = "this is a cluster";createClusterAction.hypervisorType = "KVM";createClusterAction.sessionId = sessionId;ClusterInventory cluster = createClusterAction.call().value.inventory;System.out.println(String.format("createCluster:%s successfully", cluster.name));//添加物理机;物理机IP应处于与公网IP不同的网络段,实现公有网络与管理网络分离AddKVMHostAction addKVMHostAction = new AddKVMHostAction();addKVMHostAction.name = "host1";addKVMHostAction.username = "root";addKVMHostAction.password = "password";addKVMHostAction.clusterUuid = cluster.uuid;addKVMHostAction.managementIp = "192.168.99.93";addKVMHostAction.sessionId = sessionId;HostInventory host = addKVMHostAction.call().value.inventory;System.out.println("addKVMHost successfully");//添加Ceph主存储;根据需要添加多个ceph节点;zstack通过管理网络连接到ceph集群,这里与NFS集群不同AddCephPrimaryStorageAction addCephPrimaryStorageAction = new AddCephPrimaryStorageAction();addCephPrimaryStorageAction.monUrls = Collections.singletonList("root:password@192.168.99.93");addCephPrimaryStorageAction.name = "cephPs1";addCephPrimaryStorageAction.zoneUuid = zone.uuid;addCephPrimaryStorageAction.sessionId = sessionId;PrimaryStorageInventory cephPrimaryStorage = addCephPrimaryStorageAction.call().value.inventory;System.out.println(String.format("addCephPrimaryStorage:%s successfully", cephPrimaryStorage.name));//将Ceph主存储挂载到集群,与本地存储操作一致AttachPrimaryStorageToClusterAction attachPrimaryStorageToClusterAction = new AttachPrimaryStorageToClusterAction();attachPrimaryStorageToClusterAction.clusterUuid = cluster.uuid;attachPrimaryStorageToClusterAction.primaryStorageUuid = cephPrimaryStorage.uuid;attachPrimaryStorageToClusterAction.sessionId = sessionId;attachPrimaryStorageToClusterAction.call();System.out.println("attachCephPrimaryStorageToCluster successfully");//添加Ceph镜像存储;根据需要添加多个ceph节点AddCephBackupStorageAction addCephBackupStorageAction = new AddCephBackupStorageAction();addCephBackupStorageAction.monUrls = Collections.singletonList("root:password@192.168.99.93");addCephBackupStorageAction.name = "cephBs1";addCephBackupStorageAction.sessionId = sessionId;BackupStorageInventory cephBackupStoage = addCephBackupStorageAction.call().value.inventory;System.out.println(String.format("addCephImageStoreBackupStorage:%s successfully", cephBackupStoage.name));//将Ceph镜像存储挂载到区域,与本地镜像存储操作一致AttachBackupStorageToZoneAction attachBackupStorageToZoneAction = new AttachBackupStorageToZoneAction();attachBackupStorageToZoneAction.zoneUuid = zone.uuid;attachBackupStorageToZoneAction.backupStorageUuid = cephBackupStoage.uuid;attachBackupStorageToZoneAction.sessionId = sessionId;attachBackupStorageToZoneAction.call();System.out.println("attachBackupStorageToZone successfully");//添加虚拟机镜像到Ceph镜像仓库AddImageAction addVmImageAction = new AddImageAction();addVmImageAction.name = "image1";addVmImageAction.url = "http://cdn.zstack.io/product_downloads/iso/ZStack-Enterprise-x86_64-DVD-1.9.0.iso";addVmImageAction.format = "qcow2";addVmImageAction.backupStorageUuids = Collections.singletonList(cephBackupStoage.uuid);addVmImageAction.sessionId = sessionId;ImageInventory image = addVmImageAction.call().value.inventory;System.out.println(String.format("addImage:%s successfully", image.name));//创建无服务L2NoVlan公有网络CreateL2NoVlanNetworkAction createL2NoVlanNetworkAction = new CreateL2NoVlanNetworkAction();createL2NoVlanNetworkAction.name = "public-l2";createL2NoVlanNetworkAction.description = "this is a no-serivce network";createL2NoVlanNetworkAction.zoneUuid = zone.uuid;createL2NoVlanNetworkAction.physicalInterface = "eth0";createL2NoVlanNetworkAction.sessionId = sessionId;L2NetworkInventory l2NoVlanNetwork = createL2NoVlanNetworkAction.call().value.inventory;System.out.println(String.format("createL2NoVlanNetwork:%s successfully", l2NoVlanNetwork.name));//挂载无服务L2NoVlan公有网络到集群AttachL2NetworkToClusterAction attachL2NoVlanNetworkToClusterAction = new AttachL2NetworkToClusterAction();attachL2NoVlanNetworkToClusterAction.l2NetworkUuid = l2NoVlanNetwork.uuid;attachL2NoVlanNetworkToClusterAction.clusterUuid = cluster.uuid;attachL2NoVlanNetworkToClusterAction.sessionId = sessionId;attachL2NoVlanNetworkToClusterAction.call();//基于L2NoVlan公有网络创建L3公有网络CreateL3NetworkAction createL3PublicNetworkAction = new CreateL3NetworkAction();createL3PublicNetworkAction.name = "public-l3";createL3PublicNetworkAction.type = "L3BasicNetwork";createL3PublicNetworkAction.l2NetworkUuid = l2NoVlanNetwork.uuid;createL3PublicNetworkAction.system = false;createL3PublicNetworkAction.sessionId = sessionId;L3NetworkInventory l3PublicNetwork = createL3PublicNetworkAction.call().value.inventory;System.out.println(String.format("createL2VlanNetwork:%s successfully", l3PublicNetwork.name));//挂载IP地址段到公有网络;AddIpRangeAction addIpRangeAction = new AddIpRangeAction();addIpRangeAction.l3NetworkUuid = l3PublicNetwork.uuid;addIpRangeAction.name = "iprange1";addIpRangeAction.startIp = "10.101.10.2";addIpRangeAction.endIp = "10.101.10.254";addIpRangeAction.netmask = "255.0.0.0";addIpRangeAction.gateway = "10.0.0.1";addIpRangeAction.sessionId = sessionId;addIpRangeAction.call();//为公有网络public-l3添加DNS服务AddDnsToL3NetworkAction addDnsToL3NetworkAction = new AddDnsToL3NetworkAction();addDnsToL3NetworkAction.l3NetworkUuid = l3PublicNetwork.uuid;addDnsToL3NetworkAction.dns = "8.8.8.8";addDnsToL3NetworkAction.sessionId = sessionId;addDnsToL3NetworkAction.call();//获取扁平网络服务的UuidQueryNetworkServiceProviderAction queryNetworkServiceProviderAction = new QueryNetworkServiceProviderAction();queryNetworkServiceProviderAction.conditions = Collections.singletonList("type=Flat");queryNetworkServiceProviderAction.sessionId = sessionId;NetworkServiceProviderInventory networkServiceProvider = queryNetworkServiceProviderAction.call().value.inventories.get(0);System.out.println(String.format("queryNetworkServiceprovider:%s successfully", networkServiceProvider.getName()));Map<String, List<String>> networkServices = new HashMap<String, List<String>>();networkServices.put(networkServiceProvider.uuid, asList("DHCP", "Eip", "Userdata"));//为公有网络添加扁平网络服务AttachNetworkServiceToL3NetworkAction attachNetworkServiceToL3NetworkAction = new AttachNetworkServiceToL3NetworkAction();attachNetworkServiceToL3NetworkAction.l3NetworkUuid = l3PublicNetwork.uuid;attachNetworkServiceToL3NetworkAction.networkServices = networkServices;attachNetworkServiceToL3NetworkAction.sessionId = sessionId;attachNetworkServiceToL3NetworkAction.call();System.out.println("attachNetworkServiceToL3Network successfully");//创建计算规格CreateInstanceOfferingAction createInstanceOfferingAction = new CreateInstanceOfferingAction();createInstanceOfferingAction.name = "instanceoffering1";createInstanceOfferingAction.cpuNum = 2;createInstanceOfferingAction.memorySize = 2148000000l;createInstanceOfferingAction.sessionId = sessionId;InstanceOfferingInventory instanceOffering = createInstanceOfferingAction.call().value.inventory;System.out.println(String.format("createInstanceOffering:%s successfully", instanceOffering.name));//创建云盘规格CreateDiskOfferingAction createDiskOfferingAction = new CreateDiskOfferingAction();createDiskOfferingAction.name = "diskOffering1";createDiskOfferingAction.diskSize = 2148000000l;createDiskOfferingAction.sessionId = sessionId;DiskOfferingInventory diskOffering = createDiskOfferingAction.call().value.inventory;System.out.println(String.format("createDiskOffering:%s successfully", diskOffering.name));//创建虚拟机CreateVmInstanceAction createVmInstanceAction = new CreateVmInstanceAction();createVmInstanceAction.name = "vm1";createVmInstanceAction.instanceOfferingUuid = instanceOffering.uuid;createVmInstanceAction.imageUuid = image.uuid;createVmInstanceAction.l3NetworkUuids = Collections.singletonList(l3PublicNetwork.uuid);createVmInstanceAction.dataDiskOfferingUuids = Collections.singletonList(diskOffering.uuid);createVmInstanceAction.clusterUuid = cluster.uuid;createVmInstanceAction.description = "this is a vm";createVmInstanceAction.sessionId = sessionId;VmInstanceInventory vm = createVmInstanceAction.call().value.inventory;System.out.println(String.format("createVm:%s successfully", vm.name));}}
在该场景下,用户内部的业务部门较多,每个业务部门希望自己的网络环境是完全隔离的,不受其他业务部门影响,该私有云环境更多的运行各业务部门对内的系统,例如OA系统、开发系统、测试系统等。在这种场景下,ZStack提供的私有云方案如下:
网络类型: 云路由
主存储类型: 本地存储
备份存储: 镜像仓库
私有网络: 内网地址段(云主机之间通讯使用)
公有网络: 云主机弹性IP使用的网络段
管理网络: 和云路由、物理机、备份存储等资源通信的网络
网络拓扑图如下:
这种场景下,每个云路由内部的云主机之间可以相互通信,跨云路由的云主机之间无法直接通讯,需要通过弹性IP相互通讯。在创建该场景的过程中,需要显示的创建管理网络,并设置网络类型为“无服务网络”,这样做的原因在于创建云路由规格时,需要显示的添加云路由的管理网络,否则,云路由将不知道如何和管理节点通讯。
这种场景的好处在于,每个业务部门之间的网络完全隔离,并且,云路由能够提供更多的网络增值服务,例如,端口转发,负载均衡。
通过Java SDK创建该私有云环境的代码如下:
package org.zstack.scene;import org.zstack.sdk.*;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Map;import static java.util.Arrays.asList;/*** Created by ZStack on 17-3-3.*/public class virtualRouterLocalStorageEipScene {public static String SHA(final String strText, final String strType){String strResult = null;if (strText != null && strText.length() > 0) {try {// SHA 加密开始// 创建加密对象 并传入加密类型MessageDigest messageDigest = MessageDigest.getInstance(strType);// 传入要加密的字符串messageDigest.update(strText.getBytes());// 得到 byte 类型结果byte byteBuffer[] = messageDigest.digest();// 将 byte 转换为 stringStringBuffer strHexString = new StringBuffer();// 遍历 byte bufferfor (int i = 0; i < byteBuffer.length; i++){String hex = Integer.toHexString(0xff & byteBuffer[i]);if (hex.length() == 1){strHexString.append('0');}strHexString.append(hex);}// 得到返回結果strResult = strHexString.toString();}catch (NoSuchAlgorithmException e){e.printStackTrace();}}return strResult;}public static void main(String[] args) {//声明sessionId;每个action均需要sessionIdString sessionId = null;//设置登录zstack的地址;通过172.20.12.4连接到部署zstack管理节点环境的主机ZSConfig.Builder zBuilder = new ZSConfig.Builder();zBuilder.setContextPath("zstack");zBuilder.setHostname("172.20.12.4");ZSClient.configure(zBuilder.build());//登录zstack;获取sessionLogInByAccountAction logInByAccountAction = new LogInByAccountAction();logInByAccountAction.accountName = "admin";logInByAccountAction.password = SHA("password", "SHA-512");LogInByAccountAction.Result logInByAccountActionRes = logInByAccountAction.call();if (logInByAccountActionRes.error == null) {System.out.println("logInByAccount successfully");sessionId = logInByAccountActionRes.value.getInventory().getUuid();} else logInByAccountActionRes.throwExceptionIfError();//创建区域CreateZoneAction createZoneAction = new CreateZoneAction();createZoneAction.name = "zone1";createZoneAction.description = "this is a zone";createZoneAction.sessionId = sessionId;ZoneInventory zone = createZoneAction.call().value.inventory;System.out.println(String.format("createZone:%s successfully", zone.name));//创建集群CreateClusterAction createClusterAction = new CreateClusterAction();createClusterAction.zoneUuid = zone.uuid;createClusterAction.name = "cluster1";createClusterAction.description = "this is a cluster";createClusterAction.hypervisorType = "KVM";createClusterAction.sessionId = sessionId;ClusterInventory cluster = createClusterAction.call().value.inventory;System.out.println(String.format("createCluster:%s successfully", cluster.name));//添加物理机;物理机IP应处于与公网IP不同的网络段,实现公有网络与管理网络分离AddKVMHostAction addKVMHostAction = new AddKVMHostAction();addKVMHostAction.name = "host1";addKVMHostAction.username = "root";addKVMHostAction.password = "password";addKVMHostAction.clusterUuid = cluster.uuid;addKVMHostAction.managementIp = "192.168.99.93";addKVMHostAction.sessionId = sessionId;HostInventory host = addKVMHostAction.call().value.inventory;System.out.println("addKVMHost successfully");//添加本地主存储AddLocalPrimaryStorageAction addLocalPrimaryStorageAction = new AddLocalPrimaryStorageAction();addLocalPrimaryStorageAction.url = "/zstack_ps";addLocalPrimaryStorageAction.name = "ps1";addLocalPrimaryStorageAction.zoneUuid = zone.uuid;addLocalPrimaryStorageAction.sessionId = sessionId;PrimaryStorageInventory primaryStorage = addLocalPrimaryStorageAction.call().value.inventory;System.out.println(String.format("addLocalPrimaryStorage:%s successfully",primaryStorage.name));//将本地主存储挂载到集群AttachPrimaryStorageToClusterAction attachPrimaryStorageToClusterAction = new AttachPrimaryStorageToClusterAction();attachPrimaryStorageToClusterAction.clusterUuid = cluster.uuid;attachPrimaryStorageToClusterAction.primaryStorageUuid = primaryStorage.uuid;attachPrimaryStorageToClusterAction.sessionId = sessionId;attachPrimaryStorageToClusterAction.call();System.out.println("attachPrimaryStorageToCluster successfully");//添加本地镜像存储AddImageStoreBackupStorageAction addImageStoreBackupStorageAction = new AddImageStoreBackupStorageAction();addImageStoreBackupStorageAction.hostname = "192.168.99.93";addImageStoreBackupStorageAction.username = "root";addImageStoreBackupStorageAction.password = "password";addImageStoreBackupStorageAction.url = "/zstack_bs";addImageStoreBackupStorageAction.name = "bs1";addImageStoreBackupStorageAction.sessionId = sessionId;ImageStoreBackupStorageInventory imageStoreBackupStoage = addImageStoreBackupStorageAction.call().value.inventory;System.out.println(String.format("addImageStoreBackupStorage:%s successfully",imageStoreBackupStoage.name));//将镜像存储挂载到区域;注意与主存储不同,这是由zstack的设计架构决定的AttachBackupStorageToZoneAction attachBackupStorageToZoneAction = new AttachBackupStorageToZoneAction();attachBackupStorageToZoneAction.zoneUuid = zone.uuid;attachBackupStorageToZoneAction.backupStorageUuid = imageStoreBackupStoage.uuid;attachBackupStorageToZoneAction.sessionId = sessionId;attachBackupStorageToZoneAction.call();System.out.println("attachBackupStorageToZone successfully");//添加镜像到本地镜像仓库AddImageAction addImageAction = new AddImageAction();addImageAction.name = "image1";addImageAction.url = "http://cdn.zstack.io/product_downloads/iso/ZStack-Enterprise-x86_64-DVD-1.9.0.iso";addImageAction.format = "qcow2";addImageAction.backupStorageUuids = Collections.singletonList(imageStoreBackupStoage.uuid);addImageAction.sessionId = sessionId;ImageInventory image = addImageAction.call().value.inventory;System.out.println(String.format("addImage:%s successfully",image.name));//添加云路由镜像到本地镜像仓库AddImageAction addVRImageAction = new AddImageAction();addVRImageAction.name = "vrimage";addVRImageAction.url = "http://cdn.zstack.io/product_downloads/vrouter/vCenter-Vrouter-template-20170208.vmdk";addVRImageAction.format = "qcow2";addVRImageAction.system = true;addVRImageAction.backupStorageUuids = Collections.singletonList(imageStoreBackupStoage.uuid);addVRImageAction.sessionId = sessionId;ImageInventory VRImage = addVRImageAction.call().value.inventory;System.out.println(String.format("addImage:%s successfully", VRImage.name));//创建无服务L2NoVlan公有网络CreateL2NoVlanNetworkAction createL2NoVlanPublicNetworkAction = new CreateL2NoVlanNetworkAction();createL2NoVlanPublicNetworkAction.name = "public-l2";createL2NoVlanPublicNetworkAction.description = "this is a no-serivce network";createL2NoVlanPublicNetworkAction.zoneUuid = zone.uuid;createL2NoVlanPublicNetworkAction.physicalInterface = "eth1";createL2NoVlanPublicNetworkAction.sessionId = sessionId;L2NetworkInventory l2NoVlanPublicNetwork = createL2NoVlanPublicNetworkAction.call().value.inventory;System.out.println(String.format("createL2NoVlanPublicNetwork:%s successfully", l2NoVlanPublicNetwork.name));//挂载无服务L2NoVlan公有网络到集群AttachL2NetworkToClusterAction attachL2NoVlanPublicNetworkToClusterAction = new AttachL2NetworkToClusterAction();attachL2NoVlanPublicNetworkToClusterAction.l2NetworkUuid = l2NoVlanPublicNetwork.uuid;attachL2NoVlanPublicNetworkToClusterAction.clusterUuid = cluster.uuid;attachL2NoVlanPublicNetworkToClusterAction.sessionId = sessionId;attachL2NoVlanPublicNetworkToClusterAction.call();//创建无服务L2Vlan管理网络;云路由环境中用户需要手动创建管理网络,与扁平网络环境不同CreateL2NoVlanNetworkAction createL2NoVlanManagementNetworkAction = new CreateL2NoVlanNetworkAction();createL2NoVlanManagementNetworkAction.name = "management-l2";createL2NoVlanManagementNetworkAction.description = "this is a no-serivce network";createL2NoVlanManagementNetworkAction.zoneUuid = zone.uuid;createL2NoVlanManagementNetworkAction.physicalInterface = "eth0";createL2NoVlanManagementNetworkAction.sessionId = sessionId;L2NetworkInventory l2NoVlanManagmentNetwork = createL2NoVlanManagementNetworkAction.call().value.inventory;System.out.println(String.format("createL2NoVlanManagementNetwork:%s successfully", l2NoVlanManagmentNetwork.name));//挂载无服务L2NoVlan管理网络到集群AttachL2NetworkToClusterAction attachL2NoVlanManagementNetworkToClusterAction = new AttachL2NetworkToClusterAction();attachL2NoVlanManagementNetworkToClusterAction.l2NetworkUuid = l2NoVlanManagmentNetwork.uuid;attachL2NoVlanManagementNetworkToClusterAction.clusterUuid = cluster.uuid;attachL2NoVlanManagementNetworkToClusterAction.sessionId = sessionId;attachL2NoVlanManagementNetworkToClusterAction.call();//创建无服务L2Vlan私有网络CreateL2VlanNetworkAction createL2VlanPrivateNetworkAction = new CreateL2VlanNetworkAction();createL2VlanPrivateNetworkAction.vlan = 3000;createL2VlanPrivateNetworkAction.name = "private-l2";createL2VlanPrivateNetworkAction.description = "this is a l2-vlan network";createL2VlanPrivateNetworkAction.zoneUuid = zone.uuid;createL2VlanPrivateNetworkAction.physicalInterface = "eth1";createL2VlanPrivateNetworkAction.sessionId = sessionId;L2NetworkInventory l2VlanPrivateNetwork = createL2VlanPrivateNetworkAction.call().value.inventory;System.out.println(String.format("createL2VlanPrivateNetwork:%s successfully", l2VlanPrivateNetwork.name));//挂载无服务L2Vlan私有网络到集群AttachL2NetworkToClusterAction attachL2VlanPirvateNetworkToClusterAction = new AttachL2NetworkToClusterAction();attachL2VlanPirvateNetworkToClusterAction.l2NetworkUuid = l2VlanPrivateNetwork.uuid;attachL2VlanPirvateNetworkToClusterAction.clusterUuid = cluster.uuid;attachL2VlanPirvateNetworkToClusterAction.sessionId = sessionId;attachL2VlanPirvateNetworkToClusterAction.call();//基于L2NoVlan公有网络创建L3公有网络CreateL3NetworkAction createL3PublicNetworkAction = new CreateL3NetworkAction();createL3PublicNetworkAction.name = "public-l3";createL3PublicNetworkAction.type = "L3BasicNetwork";createL3PublicNetworkAction.l2NetworkUuid = l2NoVlanPublicNetwork.uuid;createL3PublicNetworkAction.system = false;createL3PublicNetworkAction.sessionId = sessionId;L3NetworkInventory l3PublicNetwork = createL3PublicNetworkAction.call().value.inventory;System.out.println(String.format("createL3PublicNetwork:%s successfully", l3PublicNetwork.name));//挂载IP地址段到公有网络public-l3;AddIpRangeAction addPublicIpRangeAction = new AddIpRangeAction();addPublicIpRangeAction.l3NetworkUuid = l3PublicNetwork.uuid;addPublicIpRangeAction.name = "iprange1";addPublicIpRangeAction.startIp = "10.101.20.2";addPublicIpRangeAction.endIp = "10.101.20.254";addPublicIpRangeAction.netmask = "255.0.0.0";addPublicIpRangeAction.gateway = "10.0.0.1";addPublicIpRangeAction.sessionId = sessionId;addPublicIpRangeAction.call();//基于L2Vlan管理网络创建L3管理网络CreateL3NetworkAction createL3MangementNetworkAction = new CreateL3NetworkAction();createL3MangementNetworkAction.name = "management-l3";createL3MangementNetworkAction.type = "L3BasicNetwork";createL3MangementNetworkAction.l2NetworkUuid = l2NoVlanManagmentNetwork.uuid;createL3MangementNetworkAction.system = false;createL3MangementNetworkAction.sessionId = sessionId;L3NetworkInventory l3MangementNetwork = createL3MangementNetworkAction.call().value.inventory;System.out.println(String.format("createL3ManagementNetwork:%s successfully", l3PublicNetwork.name));//挂载IP地址段到管理网络management-l3;注意此处挂载的网络段须与物理机实际配置的IP相匹配AddIpRangeAction addManagementIpRangeAction = new AddIpRangeAction();addManagementIpRangeAction.l3NetworkUuid = l3MangementNetwork.uuid;addManagementIpRangeAction.name = "iprange2";addManagementIpRangeAction.startIp = "192.168.99.200";addManagementIpRangeAction.endIp = "192.168.99.210";addManagementIpRangeAction.netmask = "255.255.255.0";addManagementIpRangeAction.gateway = "192.168.99.1";addManagementIpRangeAction.sessionId = sessionId;addManagementIpRangeAction.call();//基于L2Vlan网络 创建L3私有网络CreateL3NetworkAction createL3PrivateNetworkAction = new CreateL3NetworkAction();createL3PrivateNetworkAction.name = "private-l3";createL3PrivateNetworkAction.type = "L3BasicNetwork";createL3PrivateNetworkAction.l2NetworkUuid = l2VlanPrivateNetwork.uuid;createL3PrivateNetworkAction.system = false;createL3PrivateNetworkAction.sessionId = sessionId;L3NetworkInventory l3PrivateNetwork = createL3PrivateNetworkAction.call().value.inventory;System.out.println(String.format("createl3PrivaetNetwork:%s successfully", l3PrivateNetwork.name));//挂载Ip地址段到私有网络private-l3;这里使用CIDR方式,与上文中的直接挂载IP地址段效果相同AddIpRangeByNetworkCidrAction addPrivateIpRangeByNetworkCidrAction = new AddIpRangeByNetworkCidrAction();addPrivateIpRangeByNetworkCidrAction.name = "iprange3";addPrivateIpRangeByNetworkCidrAction.l3NetworkUuid = l3PrivateNetwork.uuid;addPrivateIpRangeByNetworkCidrAction.networkCidr = "192.168.100.0/24";addPrivateIpRangeByNetworkCidrAction.sessionId = sessionId;addPrivateIpRangeByNetworkCidrAction.call();//为私有网络private-l3添加DNS服务AddDnsToL3NetworkAction addDnsToL3NetworkAction = new AddDnsToL3NetworkAction();addDnsToL3NetworkAction.l3NetworkUuid = l3PrivateNetwork.uuid;addDnsToL3NetworkAction.dns = "8.8.8.8";addDnsToL3NetworkAction.sessionId = sessionId;addDnsToL3NetworkAction.call();//获取云路由网络服务的UuidQueryNetworkServiceProviderAction queryNetworkServiceProviderAction = new QueryNetworkServiceProviderAction();queryNetworkServiceProviderAction.conditions = Collections.singletonList("type=vrouter");queryNetworkServiceProviderAction.sessionId = sessionId;NetworkServiceProviderInventory networkServiceProvider = queryNetworkServiceProviderAction.call().value.inventories.get(0);System.out.println(String.format("queryNetworkServiceprovider:%s successfully", networkServiceProvider.getName()));Map<String, List<String>> networkServices = new HashMap<String, List<String>>();networkServices.put(networkServiceProvider.uuid, asList("DHCP", "Eip", "DNS","SNAT"));//为私有网络private-l3添加网络服务AttachNetworkServiceToL3NetworkAction attachNetworkServiceToL3NetworkAction = new AttachNetworkServiceToL3NetworkAction();attachNetworkServiceToL3NetworkAction.l3NetworkUuid = l3PrivateNetwork.uuid;attachNetworkServiceToL3NetworkAction.networkServices = networkServices;attachNetworkServiceToL3NetworkAction.sessionId = sessionId;attachNetworkServiceToL3NetworkAction.call();System.out.println("attachNetworkServiceToL3Network successfully");//创建计算规格CreateInstanceOfferingAction createInstanceOfferingAction = new CreateInstanceOfferingAction();createInstanceOfferingAction.name = "instanceoffering1";createInstanceOfferingAction.cpuNum = 2;createInstanceOfferingAction.memorySize = 2148000000l;createInstanceOfferingAction.sessionId = sessionId;InstanceOfferingInventory instanceOffering = createInstanceOfferingAction.call().value.inventory;System.out.println(String.format("createInstanceOffering:%s successfully", instanceOffering.name));//创建云盘规格CreateDiskOfferingAction createDiskOfferingAction = new CreateDiskOfferingAction();createDiskOfferingAction.name = "diskOffering1";createDiskOfferingAction.diskSize = 2148000000l;createDiskOfferingAction.sessionId = sessionId;DiskOfferingInventory diskOffering = createDiskOfferingAction.call().value.inventory;System.out.println(String.format("createDiskOffering:%s successfully", diskOffering.name));//创建云路由规格;推荐管理网络、公有网络隔离CreateVirtualRouterOfferingAction createVirtualRouterOfferingAction = new CreateVirtualRouterOfferingAction();createVirtualRouterOfferingAction.zoneUuid = zone.uuid;createVirtualRouterOfferingAction.managementNetworkUuid = l3MangementNetwork.uuid;createVirtualRouterOfferingAction.publicNetworkUuid = l3PublicNetwork.uuid;createVirtualRouterOfferingAction.imageUuid = VRImage.uuid;createVirtualRouterOfferingAction.name = "vr1";createVirtualRouterOfferingAction.cpuNum = 4;createVirtualRouterOfferingAction.memorySize = 2148000000l;createVirtualRouterOfferingAction.sessionId = sessionId;createVirtualRouterOfferingAction.call();System.out.println("createVirtualRouterOffering successfully");//创建虚拟机CreateVmInstanceAction createVmInstanceAction = new CreateVmInstanceAction();createVmInstanceAction.name = "vm1";createVmInstanceAction.instanceOfferingUuid = instanceOffering.uuid;createVmInstanceAction.imageUuid = image.uuid;createVmInstanceAction.l3NetworkUuids = Collections.singletonList(l3PrivateNetwork.uuid);createVmInstanceAction.dataDiskOfferingUuids = Collections.singletonList(diskOffering.uuid);createVmInstanceAction.clusterUuid = cluster.uuid;createVmInstanceAction.description = "this is a vm";createVmInstanceAction.sessionId = sessionId;VmInstanceInventory vm = createVmInstanceAction.call().value.inventory;System.out.println(String.format("createVm:%s successfully", vm.name));//基于公有网络 创建Vip,为Eip作准备CreateVipAction createVipAction = new CreateVipAction();createVipAction.name = "vip1";createVipAction.l3NetworkUuid = l3PublicNetwork.uuid;createVipAction.sessionId = sessionId;VipInventory vip = createVipAction.call().value.inventory;System.out.println(String.format("createVip:%s successfully", vip.name));//创建EipCreateEipAction createEipAction = new CreateEipAction();createEipAction.name = "eip1";createEipAction.vipUuid = vip.uuid;createEipAction.vmNicUuid = vm.vmNics.get(0).uuid;createEipAction.sessionId = sessionId;EipInventory eip = createEipAction.call().value.inventory;System.out.println(String.format("createEip:%s successfully", eip.name));//挂载Eip到虚拟机AttachEipAction attachEipAction = new AttachEipAction();attachEipAction.eipUuid = eip.uuid;attachEipAction.vmNicUuid = vm.vmNics.get(0).uuid;attachEipAction.sessionId = sessionId;attachEipAction.call();}}
用户预算较多,购买了商业存储,希望在一个集中式的NAS存储上,使用私有云
用户是一个学校或较大规模的企业,已经在过去的IT基础设施中采用的商业NAS存储,在使用私有云的过程中,更希望能够对已有设备利旧,同时,对商业存储的信赖度较高,希望整个私有云的环境能够部署在商业存储上。在这种场景下,ZStack提供的私有云方案如下:
网络类型: 扁平网络
主存储类型:NFS
备份存储: 镜像仓库
私有网络: 内网地址段(云主机使用)
管理网络: 和云路由、物理机、备份存储等资源通信的网络
公共网络:云主机弹性IP使用的网络段
网络拓扑图如下:
用户在添加NAS存储的过程中,只需在选择主存储的时候,选择NFS的方式。 另外由于使用了网络共享存储,云主机的磁盘IO访问都会通过网络访问NFS主存储。 因此单一的数据网络很可能无法满足大量的磁盘读写请求。我们需要新划分一个存储网络(万兆)。 为什么需要万兆呢?因为云主机的云盘都是放在NFS存储中,如果只是千兆的网络环境, 即使仅有一个云主机在进行磁盘操作,最多也只能使用到1gbps的带宽,理论磁盘读写的上限为125MB/s。 考虑到多云主机以及网络传输效率,千兆网络将会极大的限制云主机的磁盘IO性能。
在使用存储网络的时候,我们需要先将物理服务器,NFS主存储,镜像服务器,管理节点上空闲的网卡连接到新的存储网络, 并且配置存储网络的IP地址(例如192.168.100.0/24网段)。在添加NFS主存储和镜像服务器的时候,使用这些IP地址即可。
该场景的优势是,计算和存储分离。云主机可以在线迁移,一旦计算节点失效,云主机可以快速恢复。 商业NFS主存储在数据的高可靠、高可用、性能方面都有较好的表现。
package org.zstack.scene;import org.zstack.sdk.*;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Map;import static java.util.Arrays.asList;/*** Created by ZStack on 17-3-3.*/public class flatNetworkNfsStorageScene {public static String SHA(final String strText, final String strType){String strResult = null;if (strText != null && strText.length() > 0) {try {// SHA 加密开始// 创建加密对象 并传入加密类型MessageDigest messageDigest = MessageDigest.getInstance(strType);// 传入要加密的字符串messageDigest.update(strText.getBytes());// 得到 byte 类型结果byte byteBuffer[] = messageDigest.digest();// 将 byte 转换为 stringStringBuffer strHexString = new StringBuffer();// 遍历 byte bufferfor (int i = 0; i < byteBuffer.length; i++){String hex = Integer.toHexString(0xff & byteBuffer[i]);if (hex.length() == 1){strHexString.append('0');}strHexString.append(hex);}// 得到返回结果strResult = strHexString.toString();}catch (NoSuchAlgorithmException e){e.printStackTrace();}}return strResult;}public static void main(String[] args) {//声明sessionId;每个action均需要sessionIdString sessionId = null;//设置登录zstack的地址;通过172.20.12.4连接到部署zstack管理节点环境的主机ZSConfig.Builder zBuilder = new ZSConfig.Builder();zBuilder.setContextPath("zstack");zBuilder.setHostname("172.20.12.4");ZSClient.configure(zBuilder.build());//登录zstack;获取sessionLogInByAccountAction logInByAccountAction = new LogInByAccountAction();logInByAccountAction.accountName = "admin";logInByAccountAction.password = SHA("password", "SHA-512");LogInByAccountAction.Result logInByAccountActionRes = logInByAccountAction.call();if (logInByAccountActionRes.error == null) {System.out.println("logInByAccount successfully");sessionId = logInByAccountActionRes.value.getInventory().getUuid();} else logInByAccountActionRes.throwExceptionIfError();//创建区域CreateZoneAction createZoneAction = new CreateZoneAction();createZoneAction.name = "zone1";createZoneAction.description = "this is a zone";createZoneAction.sessionId = sessionId;ZoneInventory zone = createZoneAction.call().value.inventory;System.out.println(String.format("createZone:%s successfully", zone.name));//创建集群CreateClusterAction createClusterAction = new CreateClusterAction();createClusterAction.zoneUuid = zone.uuid;createClusterAction.name = "cluster1";createClusterAction.description = "this is a cluster";createClusterAction.hypervisorType = "KVM";createClusterAction.sessionId = sessionId;ClusterInventory cluster = createClusterAction.call().value.inventory;System.out.println(String.format("createCluster:%s successfully", cluster.name));//添加物理机;物理机IP应处于与公网IP不同的网络段,实现公有网络与管理网络分离AddKVMHostAction addKVMHostAction = new AddKVMHostAction();addKVMHostAction.name = "host1";addKVMHostAction.username = "root";addKVMHostAction.password = "password";addKVMHostAction.clusterUuid = cluster.uuid;addKVMHostAction.managementIp = "192.168.99.93";addKVMHostAction.sessionId = sessionId;HostInventory host = addKVMHostAction.call().value.inventory;System.out.println("addKVMHost successfully");//添加NFS主存储;此处添加的IP地址应属于NFS自有的万兆存储网络AddNfsPrimaryStorageAction addNfsPrimaryStorageAction = new AddNfsPrimaryStorageAction();addNfsPrimaryStorageAction.url = "192.168.100.20:/nfs_root";addNfsPrimaryStorageAction.name = "ps1";addNfsPrimaryStorageAction.type = "NFS";addNfsPrimaryStorageAction.zoneUuid = zone.uuid;addNfsPrimaryStorageAction.sessionId = sessionId;PrimaryStorageInventory nfsPrimaryStorage = addNfsPrimaryStorageAction.call().value.inventory;System.out.println("addNfsPrimaryStorage successfully");//将NFS主存储挂载到集群,与本地存储操作一致AttachPrimaryStorageToClusterAction attachPrimaryStorageToClusterAction = new AttachPrimaryStorageToClusterAction();attachPrimaryStorageToClusterAction.clusterUuid = cluster.uuid;attachPrimaryStorageToClusterAction.primaryStorageUuid = nfsPrimaryStorage.uuid;attachPrimaryStorageToClusterAction.sessionId = sessionId;attachPrimaryStorageToClusterAction.call();System.out.println("attachNFSPrimaryStorageToCluster successfully");//添加本地镜像存储AddImageStoreBackupStorageAction addImageStoreBackupStorageAction = new AddImageStoreBackupStorageAction();addImageStoreBackupStorageAction.hostname = "192.168.99.93";addImageStoreBackupStorageAction.username = "root";addImageStoreBackupStorageAction.password = "password";addImageStoreBackupStorageAction.url = "/zstack_bs";addImageStoreBackupStorageAction.name = "bs1";addImageStoreBackupStorageAction.sessionId = sessionId;ImageStoreBackupStorageInventory imageStoreBackupStoage = addImageStoreBackupStorageAction.call().value.inventory;System.out.println(String.format("addImageStoreBackupStorage:%s successfully",imageStoreBackupStoage.name));//将镜像存储挂载到区域;注意与主存储不同,这是由zstack的设计架构决定的AttachBackupStorageToZoneAction attachBackupStorageToZoneAction = new AttachBackupStorageToZoneAction();attachBackupStorageToZoneAction.zoneUuid = zone.uuid;attachBackupStorageToZoneAction.backupStorageUuid = imageStoreBackupStoage.uuid;attachBackupStorageToZoneAction.sessionId = sessionId;attachBackupStorageToZoneAction.call();System.out.println("attachBackupStorageToZone successfully");//添加镜像到本地镜像仓库AddImageAction addImageAction = new AddImageAction();addImageAction.name = "image1";addImageAction.url = "http://cdn.zstack.io/product_downloads/iso/ZStack-Enterprise-x86_64-DVD-1.9.0.iso";addImageAction.format = "qcow2";addImageAction.backupStorageUuids = Collections.singletonList(imageStoreBackupStoage.uuid);addImageAction.sessionId = sessionId;ImageInventory image = addImageAction.call().value.inventory;System.out.println(String.format("addImage:%s successfully",image.name));//创建无服务L2NoVlan公有网络CreateL2NoVlanNetworkAction createL2NoVlanNetworkAction = new CreateL2NoVlanNetworkAction();createL2NoVlanNetworkAction.name = "public-l2";createL2NoVlanNetworkAction.description = "this is a no-serivce network";createL2NoVlanNetworkAction.zoneUuid = zone.uuid;createL2NoVlanNetworkAction.physicalInterface = "eth1";createL2NoVlanNetworkAction.sessionId = sessionId;L2NetworkInventory l2NoVlanNetwork = createL2NoVlanNetworkAction.call().value.inventory;System.out.println(String.format("createL2NoVlanNetwork:%s successfully", l2NoVlanNetwork.name));//挂载无服务L2NoVlan公有网络到集群AttachL2NetworkToClusterAction attachL2NoVlanNetworkToClusterAction = new AttachL2NetworkToClusterAction();attachL2NoVlanNetworkToClusterAction.l2NetworkUuid = l2NoVlanNetwork.uuid;attachL2NoVlanNetworkToClusterAction.clusterUuid = cluster.uuid;attachL2NoVlanNetworkToClusterAction.sessionId = sessionId;attachL2NoVlanNetworkToClusterAction.call();//基于L2NoVlan公有网络创建L3公有网络CreateL3NetworkAction createL3PublicNetworkAction = new CreateL3NetworkAction();createL3PublicNetworkAction.name = "public-l3";createL3PublicNetworkAction.type = "L3BasicNetwork";createL3PublicNetworkAction.l2NetworkUuid = l2NoVlanNetwork.uuid;createL3PublicNetworkAction.system = false;createL3PublicNetworkAction.sessionId = sessionId;L3NetworkInventory l3PublicNetwork = createL3PublicNetworkAction.call().value.inventory;System.out.println(String.format("createL2VlanNetwork:%s successfully", l3PublicNetwork.name));//挂载IP地址段到公有网络public-l3;AddIpRangeAction addIpRangeAction = new AddIpRangeAction();addIpRangeAction.l3NetworkUuid = l3PublicNetwork.uuid;addIpRangeAction.name = "iprange1";addIpRangeAction.startIp = "10.101.30.2";addIpRangeAction.endIp = "10.101.30.254";addIpRangeAction.netmask = "255.0.0.0";addIpRangeAction.gateway = "10.0.0.1";addIpRangeAction.sessionId = sessionId;addIpRangeAction.call();//为公有网络public-l3添加DNS服务AddDnsToL3NetworkAction addDnsToL3NetworkAction = new AddDnsToL3NetworkAction();addDnsToL3NetworkAction.l3NetworkUuid = l3PublicNetwork.uuid;addDnsToL3NetworkAction.dns = "8.8.8.8";addDnsToL3NetworkAction.sessionId = sessionId;addDnsToL3NetworkAction.call();//获取扁平网络服务的UuidQueryNetworkServiceProviderAction queryNetworkServiceProviderAction = new QueryNetworkServiceProviderAction();queryNetworkServiceProviderAction.conditions = Collections.singletonList("type=Flat");queryNetworkServiceProviderAction.sessionId = sessionId;NetworkServiceProviderInventory networkServiceProvider = queryNetworkServiceProviderAction.call().value.inventories.get(0);System.out.println(String.format("queryNetworkServiceprovider:%s successfully", networkServiceProvider.getName()));Map<String, List<String>> networkServices = new HashMap<String, List<String>>();networkServices.put(networkServiceProvider.uuid, asList("DHCP", "Eip", "Userdata"));//为公有网络添加网络服务AttachNetworkServiceToL3NetworkAction attachNetworkServiceToL3NetworkAction = new AttachNetworkServiceToL3NetworkAction();attachNetworkServiceToL3NetworkAction.l3NetworkUuid = l3PublicNetwork.uuid;attachNetworkServiceToL3NetworkAction.networkServices = networkServices;attachNetworkServiceToL3NetworkAction.sessionId = sessionId;attachNetworkServiceToL3NetworkAction.call();System.out.println("attachNetworkServiceToL3Network successfully");//创建计算规格CreateInstanceOfferingAction createInstanceOfferingAction = new CreateInstanceOfferingAction();createInstanceOfferingAction.name = "instanceoffering1";createInstanceOfferingAction.cpuNum = 2;createInstanceOfferingAction.memorySize = 21480000000l;createInstanceOfferingAction.sessionId = sessionId;InstanceOfferingInventory instanceOffering = createInstanceOfferingAction.call().value.inventory;System.out.println(String.format("createInstanceOffering:%s successfully", instanceOffering.name));//创建云盘规格CreateDiskOfferingAction createDiskOfferingAction = new CreateDiskOfferingAction();createDiskOfferingAction.name = "diskOffering1";createDiskOfferingAction.diskSize = 2148000000l;createDiskOfferingAction.sessionId = sessionId;DiskOfferingInventory diskOffering = createDiskOfferingAction.call().value.inventory;System.out.println(String.format("createDiskOffering:%s successfully", diskOffering.name));//创建虚拟机CreateVmInstanceAction createVmInstanceAction = new CreateVmInstanceAction();createVmInstanceAction.name = "vm1";createVmInstanceAction.instanceOfferingUuid = instanceOffering.uuid;createVmInstanceAction.imageUuid = image.uuid;createVmInstanceAction.l3NetworkUuids = Collections.singletonList(l3PublicNetwork.uuid);createVmInstanceAction.dataDiskOfferingUuids = Collections.singletonList(diskOffering.uuid);createVmInstanceAction.clusterUuid = cluster.uuid;createVmInstanceAction.description = "this is a vm";createVmInstanceAction.sessionId = sessionId;VmInstanceInventory vm = createVmInstanceAction.call().value.inventory;System.out.println(String.format("createVm:%s successfully", vm.name));}}