[关闭]
@meilei007 2017-10-24T15:02:16.000000Z 字数 63614 阅读 2190

ZStack RESTful API cookbook

zstack RESTful


前言

本书将指导用户如何通过REST API来生成基于ZStack企业版的私有云环境。本书面向的对象是有基于ZStack RESTful API做二次开发需求的读者,或希望将ZStack整合进公司已有业务系统需求的读者。
在阅读本书之前,读者需阅读《ZStack 企业版开发手册》,了解ZStack目前提供的RESTful API使用方式。
本书分为两个章节,第一章节为基本场景,主要描述如何对ZStack中的基本资源做操作。第二章节为特定的私有云场景,主要描述一些现实环境中的私有云部署方案,并描述如何基于ZStack提供的基本资源,通过RESTful API完成私有云场景的创建。

第一章 基本场景操作

场景1: 登录ZStack(Login)

REST由于是无状态的传输,所以每一次请求都得带上身份认证信息。读者如果想通过rest API 来创建一个私有云环境,首先需要通过ZStack的API: LogInByAccount 获得一个令牌,这个令牌作为之后每一步操作的身份认证信息。

  1. //声明sessionId;每个action均需要sessionId
  2. String sessionId;
  3. //设置登录zstack的地址
  4. ZSConfig.Builder zBuilder = new ZSConfig.Builder();
  5. zBuilder.setContextPath("zstack");
  6. zBuilder.setHostname("172.20.12.9");
  7. ZSClient.configure(zBuilder.build());
  8. //登录zstack;获取session;需要对密码进行SHA-512算法加密
  9. LogInByAccountAction logInByAccountAction = new LogInByAccountAction();
  10. logInByAccountAction.accountName = "admin";
  11. logInByAccountAction.password = SHA("password", "SHA-512");
  12. LogInByAccountAction.Result logInByAccountActionRes = logInByAccountAction.call();
  13. sessionId = logInByAccountActionRes.value.getInventory().getUuid();

场景2 创建区域(Zone)

拿到login的令牌之后,第一步是创建一个区域。一个区域是由类似主存储,集群,L2网络的资源组成的逻辑组; 它定义一个可见的边界,在相同区域中的资源互相可见并且可以形成某种关系,但在不同区域中的资源是不行的. 例如, 区域A中的一个主存储可以挂载到区域A中的一个集群,但不能挂载到区域B的集群上。区域的子资源,包括集群,L2网络和主存储等。

  1. CreateZoneAction createZoneAction = new CreateZoneAction();
  2. createZoneAction.name = "zone1";
  3. createZoneAction.description = "this is a zone";
  4. createZoneAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  5. ZoneInventory zone = createZoneAction.call().value.inventory;

场景3 创建集群(Cluster)

区域创建完成后,需要创建集群。一个集群是类似主机(Host)组成的逻辑组。 在同一个集群中的主机必须安装相同的操作系统, 拥有相同的二层网络连接, 可以访问相同的主存储。 在实际的数据中心, 一个集群通常对应一个机架(rack)。

  1. CreateClusterAction createClusterAction = new CreateClusterAction();
  2. createClusterAction.zoneUuid = "dad0910508e8498da2f247174ab714bc";
  3. createClusterAction.name = "cluster1";
  4. createClusterAction.description = "this is a cluster";
  5. createClusterAction.hypervisorType = "KVM";
  6. createClusterAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  7. ClusterInventory cluster = createClusterAction.call().value.inventory;

场景4 添加物理机(Host)

集群创建完后,再添加物理机。物理机是一个安装有操作系统的物理服务器。

  1. AddKVMHostAction addKVMHostAction = new AddKVMHostAction();
  2. addKVMHostAction.name = "host1";
  3. addKVMHostAction.username = "root";
  4. addKVMHostAction.password = "password";
  5. addKVMHostAction.clusterUuid = "db2e569c4e2c41448fb6f9309d2bf52f";
  6. addKVMHostAction.managementIp = "172.20.12.9";
  7. addKVMHostAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  8. HostInventory host = addKVMHostAction.call().value.inventory;

场景5 添加主存储(Primary Storage)

添加完物理机之后,再添加主存储。主存储是数据中心里为云主机提供根云盘和数据云盘的存储系统. ZStack的主存储分多种类型,包括LocalStorage,NFS,Ceph,FusionStor,Shared Mount Point

  1. //这里添加本地主存储
  2. AddLocalPrimaryStorageAction addLocalPrimaryStorageAction = new AddLocalPrimaryStorageAction();
  3. addLocalPrimaryStorageAction.url = "/zstack_ps";
  4. addLocalPrimaryStorageAction.name = "ps1";
  5. addLocalPrimaryStorageAction.zoneUuid = "dad0910508e8498da2f247174ab714bc";
  6. addLocalPrimaryStorageAction.sessionId = sessionId;
  7. PrimaryStorageInventory primaryStorage = addLocalPrimaryStorageAction.call().value.inventory;
  8. //将本地主存储挂载到集群
  9. AttachPrimaryStorageToClusterAction attachPrimaryStorageToClusterAction = new AttachPrimaryStorageToClusterAction();
  10. attachPrimaryStorageToClusterAction.clusterUuid = "db2e569c4e2c41448fb6f9309d2bf52f";
  11. attachPrimaryStorageToClusterAction.primaryStorageUuid = "0e6f4c9d89bd4cc2b0cb420568ee46ec";
  12. attachPrimaryStorageToClusterAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  13. attachPrimaryStorageToClusterAction.call();

场景6 添加备份存储(Backup Storage)

添加完主存储之后,再添加备份存储。备份存储又叫镜像服务器。备份存储是保存用于创建云盘的镜像的存储系统。Mevoco的备份存储分多种类型,包括ImageStore,Ceph,FusionStor

  1. //这里添加本地备份存储
  2. AddImageStoreBackupStorageAction addImageStoreBackupStorageAction = new AddImageStoreBackupStorageAction();
  3. addImageStoreBackupStorageAction.hostname = "172.20.12.9";
  4. addImageStoreBackupStorageAction.username = "root";
  5. addImageStoreBackupStorageAction.password = "password";
  6. addImageStoreBackupStorageAction.url = "/zstack_bs";
  7. addImageStoreBackupStorageAction.name = "bs1";
  8. addImageStoreBackupStorageAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  9. ImageStoreBackupStorageInventory imageStoreBackupStoage = addImageStoreBackupStorageAction.call().value.inventory;
  10. //将镜像存储挂载到集群
  11. AttachBackupStorageToZoneAction attachBackupStorageToZoneAction = new AttachBackupStorageToZoneAction();
  12. attachBackupStorageToZoneAction.zoneUuid = "dad0910508e8498da2f247174ab714bc";
  13. attachBackupStorageToZoneAction.backupStorageUuid = "15a01470b6fb4468b64b62ae58eb22c0";
  14. attachBackupStorageToZoneAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  15. attachBackupStorageToZoneAction.call();

场景7 添加二层网络(L2 Network)

存储和物理机全部添加完成后,我们具备了基本云主机启动条件,下面我们为云主机创建网络环境。首先,创建二层网络。L2网络在数据中心中代表了一个二层广播域, 在ZStack中, L2网络负责为L3网络提供二层隔离。

  1. //创建无服务L2NoVlan网络
  2. CreateL2NoVlanNetworkAction createL2NoVlanNetworkAction = new CreateL2NoVlanNetworkAction();
  3. createL2NoVlanNetworkAction.name = "public-management-l2";
  4. createL2NoVlanNetworkAction.description = "this is a no-serivce network";
  5. createL2NoVlanNetworkAction.zoneUuid = "dad0910508e8498da2f247174ab714bc";
  6. createL2NoVlanNetworkAction.physicalInterface = "eth0";
  7. createL2NoVlanNetworkAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  8. L2NetworkInventory l2NoVlanNetwork = createL2NoVlanNetworkAction.call().value.inventory;
  9. //挂载无服务L2NoVlan网络到集群
  10. AttachL2NetworkToClusterAction attachL2NoVlanNetworkToClusterAction = new AttachL2NetworkToClusterAction();
  11. attachL2NoVlanNetworkToClusterAction.l2NetworkUuid = d45c8fea42324c939b71931eabb7f932;
  12. attachL2NoVlanNetworkToClusterAction.clusterUuid = "db2e569c4e2c41448fb6f9309d2bf52f";
  13. attachL2NoVlanNetworkToClusterAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  14. attachL2NoVlanNetworkToClusterAction.call();

场景8 添加三层网络(L3 Network)

二层网络创建完成后,需要创建三层网络。三层网络是由子网(subnet)以及一系列网络服务(network services)组成。网络服务提供模块(network service providers)提供的网络服务, 通常是OSI三层到七层协议的软件实现。

  1. //基于L2NoVlan网络创建L3网络,作为公有网络
  2. CreateL3NetworkAction createL3PublicNetworkAction = new CreateL3NetworkAction();
  3. createL3PublicNetworkAction.name = "public-management-l3";
  4. createL3PublicNetworkAction.type = "L3BasicNetwork";
  5. createL3PublicNetworkAction.l2NetworkUuid = "68a05a0154d4472bb7a059b54a53f166";
  6. createL3PublicNetworkAction.system = false;
  7. createL3PublicNetworkAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  8. L3NetworkInventory l3PublicNetwork = createL3PublicNetworkAction.call().value.inventory;
  9. //挂载IP地址段到公有网络;
  10. AddIpRangeAction addIpRangeAction = new AddIpRangeAction();
  11. addIpRangeAction.l3NetworkUuid = "917fe2f51ab7423ca6e74648c5ae8931";
  12. addIpRangeAction.name = "iprange1";
  13. addIpRangeAction.startIp = "10.101.50.2";
  14. addIpRangeAction.endIp = "10.101.50.254";
  15. addIpRangeAction.netmask = "255.0.0.0";
  16. addIpRangeAction.gateway = "10.0.0.1";
  17. addIpRangeAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  18. addIpRangeAction.call();
  19. //为共有网络private-l3添加DNS服务
  20. AddDnsToL3NetworkAction addDnsToL3NetworkAction = new AddDnsToL3NetworkAction();
  21. addDnsToL3NetworkAction.l3NetworkUuid = "917fe2f51ab7423ca6e74648c5ae8931";
  22. addDnsToL3NetworkAction.dns = "8.8.8.8";
  23. addDnsToL3NetworkAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  24. addDnsToL3NetworkAction.call();
  25. //获取网络服务的Uuid
  26. QueryNetworkServiceProviderAction queryNetworkServiceProviderAction = new QueryNetworkServiceProviderAction();
  27. queryNetworkServiceProviderAction.conditions = Collections.singletonList("type=Flat");
  28. queryNetworkServiceProviderAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  29. NetworkServiceProviderInventory networkServiceProvider = queryNetworkServiceProviderAction.call().value.inventories.get(0);
  30. Map<String, List<String>> networkServices = new HashMap<String, List<String>>();
  31. networkServices.put(networkServiceProvider.uuid, asList("DHCP", "Eip", "Userdata"));
  32. //为公有网络添加网络服务
  33. AttachNetworkServiceToL3NetworkAction attachNetworkServiceToL3NetworkAction = new AttachNetworkServiceToL3NetworkAction();
  34. attachNetworkServiceToL3NetworkAction.l3NetworkUuid = ""68a05a0154d4472bb7a059b54a53f166"";
  35. attachNetworkServiceToL3NetworkAction.networkServices = networkServices;
  36. attachNetworkServiceToL3NetworkAction.sessionId = sessionId;
  37. attachNetworkServiceToL3NetworkAction.call();

场景9 创建计算规格(Instance Offering)

三层网络创建完后,云主机的基本环境已经准备就绪,现在,需要设置云主机的计算规格。计算规格定义了云主机的内存,CPU以及云主机的磁盘IO和网络带宽IO。

  1. //创建计算规格
  2. CreateInstanceOfferingAction createInstanceOfferingAction = new CreateInstanceOfferingAction();
  3. createInstanceOfferingAction.name = "instanceoffering1";
  4. createInstanceOfferingAction.cpuNum = 1;
  5. createInstanceOfferingAction.memorySize = 2148000000l;
  6. createInstanceOfferingAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  7. InstanceOfferingInventory instanceOffering = createInstanceOfferingAction.call().value.inventory;

场景10 添加镜像(Image)

到这里,只剩下云主机启动的镜像没有添加了,镜像为云主机文件系统提供模板。 镜像可以是为云主机安装操作系统的根云盘(root volume)提供模板的RootVolumeTemplate; 镜像也可以是为云主机存储非操作系统数据的数据云盘(data volumes)提供模板的DataVolumeTemplate; 同时镜像也可以是用来在空白根云盘(blank root volumes)上安装操作系统的ISO文件。

  1. //添加镜像到本地镜像仓库
  2. AddImageAction addImageAction = new AddImageAction();
  3. addImageAction.name = "image1";
  4. addImageAction.url = "http://192.168.200.100/mirror/diskimages/centos7.2-mini-qemu-qa.qcow2";
  5. addImageAction.format = "qcow2";
  6. addImageAction.backupStorageUuids = "15a01470b6fb4468b64b62ae58eb22c0";
  7. addImageAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  8. ImageInventory image = addImageAction.call().value.inventory;

场景11 创建云主机(VM instance)

当所有资源准备就绪,我们可以开始创建云主机了。

  1. //创建虚拟机
  2. CreateVmInstanceAction createVmInstanceAction = new CreateVmInstanceAction();
  3. createVmInstanceAction.name = "vm1";
  4. createVmInstanceAction.instanceOfferingUuid = "416ba9d9365643bbbe18c8ed2dca2e2c";
  5. createVmInstanceAction.imageUuid = "0403f3b539cf49b68cecdb0b5da92b8b";
  6. createVmInstanceAction.l3NetworkUuids = "917fe2f51ab7423ca6e74648c5ae8931";
  7. createVmInstanceAction.dataDiskOfferingUuids = "c87fea8ea690429a8825a9bf9fa68b4d";
  8. createVmInstanceAction.clusterUuid = "db2e569c4e2c41448fb6f9309d2bf52f";
  9. createVmInstanceAction.description = "this is a vm";
  10. createVmInstanceAction.sessionId = "68a05a0154d4472bb7a059b54a53f166";
  11. VmInstanceInventory vm = createVmInstanceAction.call().value.inventory;

其中,每个所依赖资源的uuid都通过对应资源的Inventory获取

场景12 创建快照(Snapshot)

云主机运行起来后,用户为了保证数据的安全性,可以为云主机做快照备份。快照可以保存云主机的根云盘(Root Volume)或者数据云盘(Data Volume)在某一时刻的所有数据。根云盘和数据云盘创建快照使用的是相同的API。

  1. CreateVolumeSnapshotAction action = new CreateVolumeSnapshotAction();
  2. action.volumeUuid = "5d7edc10db7b4187a27e310bac3d3201";
  3. action.name = "snapshot-volume";
  4. action.description = "a snapshot for volume";
  5. action.sessionUuid = "68a05a0154d4472bb7a059b54a53f166";
  6. CreateVolumeSnapshotAction.Result res = action.call();

场景13 修改云主机配置(Instance Offering)

当用户的业务量增加,需要调整CPU,内存,网络IO,硬盘IO时,可以通过该方式生效。需要注意的是,在目前版本中,需要停止云主机,再启动云主机,才能读取修改后的配置。

  1. UpdateVmInstanceAction action = new UpdateVmInstanceAction();
  2. action.uuid = "6cff485bf490471bb64a9f2824aca8d6";
  3. action.name = "new vm name";
  4. action.sessionUuid = "68a05a0154d4472bb7a059b54a53f166";
  5. UpdateVmInstanceAction.Result res = action.call();

场景14 调用Console访问接口(Request Console Access)

用户可以通过前端代码调用Console访问接口,获取云主机Console界面的信息,在前端页面打开云主机的Console界面。

  1. RequestConsoleAccessAction action = new RequestConsoleAccessAction();
  2. action.vmInstanceUuid = "6cff485bf490471bb64a9f2824aca8d6";
  3. action.sessionUuid = "68a05a0154d4472bb7a059b54a53f166";
  4. RequestConsoleAccessAction.Result res = action.call();

当调用该接口获得云主机console的访问信息后,可以通过如下javascript示例代码在前端页面打开云主机的Console访问:

  1. $window.open("personal_dir/vnc.html?host=" + hostname +
  2. "&port=" + port +
  3. "&token=" +token +
  4. "&title=" + name)

其中,hostname, port, token是通过API返回的Console访问信息res获得的,name是用户自定义的名称,不做限制。

场景15 获取用户资源配额(Quota)

当业务规模不断扩大,管理员可以创建不同的账户,并且给账户分配不同的配额。管理员可以根据账户的uuid获得账户对当前资源的使用配额。

  1. QueryQuotaAction action = new QueryQuotaAction();
  2. action.conditions = asList("name=test");
  3. action.sessionUuid = "68a05a0154d4472bb7a059b54a53f166";
  4. QueryQuotaAction.Result res = action.call();

第二章 特定场景操作

了解了ZStack基本的资源创建操作方法后,本章将给读者展示如何基于已有的知识,快速创建不同场景下的私有云环境。

本章节的各类场景将覆盖以下资源:
网络类型覆盖扁平网络,云路由网络;
主存储类型覆盖本地存储,ceph分布式存储,NFS
备份存储类型覆盖镜像仓库,ceph分布式存储

由于以下场景为笔者模拟的网络环境,公网IP段并非真实公网IP段,请读者根据实际网络环境调整

用户场景1: ZStack构建常见私有云架构

该类场景通常内部有一个私有网络段,对外有一个公有网络段,但公有网络IP地址有限,需要作为弹性IP分配给云平台的云主机使用。同时,客户的运维团队不希望运维分布式存储,希望通过RAID阵列卡来对磁盘做冗余,解决存储安全的问题。在这种场景下,ZStack提供的私有云方案如下:
网络类型: 扁平网络+弹性IP
主存储类型:本地存储
备份存储: 镜像服务器
公有网络: 公网地址段(弹性IP)
私有网络: 内网地址段(云主机之间通讯使用)

网络拓扑图如下:
cmd-markdown-logo

在上图中,我们可以看到三个网络,分别连接了ZStack管理节点,物理服务器,镜像服务器。 ZStack管理节点通过192.168.0.0/24的网络连接并控制物理服务器和镜像服务器。 物理服务器上的云主机则通过192.168.100.0/24的网络进行数据交换,并通过公有网络10.0.0.0/8获取弹性IP,透过企业的防火墙访问Internet,并支持外部访问绑定了弹性IP的云主机。
这种场景的优势在于,部署简单,成本较低,用户的设备可以利旧,并且分布式网络架构保证了云平台的网络不会出现单点故障。

通过Java SDK创建该私有云环境的代码如下:

  1. package org.zstack.scene;
  2. import org.zstack.sdk.*;
  3. import java.security.MessageDigest;
  4. import java.security.NoSuchAlgorithmException;
  5. import java.util.Collections;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import static java.util.Arrays.asList;
  10. /**
  11. * Created by ZStack on 17-3-3.
  12. */
  13. public class flatNetworkLocalStorageEipScene {
  14. public static String SHA(final String strText, final String strType){
  15. String strResult = null;
  16. if (strText != null && strText.length() > 0) {
  17. try {
  18. // SHA 加密开始
  19. // 创建加密对象 并传入加密类型
  20. MessageDigest messageDigest = MessageDigest.getInstance(strType);
  21. // 传入要加密的字符串
  22. messageDigest.update(strText.getBytes());
  23. // 得到 byte 类型结果
  24. byte byteBuffer[] = messageDigest.digest();
  25. // 将 byte 转换为 string
  26. StringBuffer strHexString = new StringBuffer();
  27. // 遍历 byte buffer
  28. for (int i = 0; i < byteBuffer.length; i++)
  29. {
  30. String hex = Integer.toHexString(0xff & byteBuffer[i]);
  31. if (hex.length() == 1)
  32. {
  33. strHexString.append('0');
  34. }
  35. strHexString.append(hex);
  36. }
  37. // 得到返回结果
  38. strResult = strHexString.toString();
  39. }
  40. catch (NoSuchAlgorithmException e)
  41. {
  42. e.printStackTrace();
  43. }
  44. }
  45. return strResult;
  46. }
  47. public static void main(String[] args){
  48. //声明sessionId;每个action均需要sessionId
  49. String sessionId = null;
  50. //设置登录zstack的地址;通过172.20.12.4连接到部署zstack管理节点环境的主机
  51. ZSConfig.Builder zBuilder = new ZSConfig.Builder();
  52. zBuilder.setContextPath("zstack");
  53. zBuilder.setHostname("172.20.12.4");
  54. ZSClient.configure(zBuilder.build());
  55. //登录zstack;获取session
  56. LogInByAccountAction logInByAccountAction = new LogInByAccountAction();
  57. logInByAccountAction.accountName = "admin";
  58. logInByAccountAction.password = SHA("password","SHA-512");
  59. LogInByAccountAction.Result logInByAccountActionRes = logInByAccountAction.call();
  60. if(logInByAccountActionRes.error ==null) {
  61. System.out.println("logInByAccount successfully");
  62. sessionId = logInByAccountActionRes.value.getInventory().getUuid();
  63. }
  64. else logInByAccountActionRes.throwExceptionIfError();
  65. //创建区域
  66. CreateZoneAction createZoneAction = new CreateZoneAction();
  67. createZoneAction.name = "zone1";
  68. createZoneAction.description = "this is a zone";
  69. createZoneAction.sessionId = sessionId;
  70. ZoneInventory zone = createZoneAction.call().value.inventory;
  71. System.out.println(String.format("createZone:%s successfully",zone.name));
  72. //创建集群
  73. CreateClusterAction createClusterAction = new CreateClusterAction();
  74. createClusterAction.zoneUuid = zone.uuid;
  75. createClusterAction.name = "cluster1";
  76. createClusterAction.description = "this is a cluster";
  77. createClusterAction.hypervisorType = "KVM";
  78. createClusterAction.sessionId = sessionId;
  79. ClusterInventory cluster = createClusterAction.call().value.inventory;
  80. System.out.println(String.format("createCluster:%s successfully",cluster.name));
  81. //添加物理机;物理机IP应处于与公网IP不同的网络段,作为管理网络,实现公有网络与管理网络分离
  82. AddKVMHostAction addKVMHostAction = new AddKVMHostAction();
  83. addKVMHostAction.name="host1";
  84. addKVMHostAction.username = "root";
  85. addKVMHostAction.password = "password";
  86. addKVMHostAction.clusterUuid = cluster.uuid;
  87. addKVMHostAction.managementIp= "192.168.99.93";
  88. addKVMHostAction.sessionId = sessionId;
  89. HostInventory host = addKVMHostAction.call().value.inventory;
  90. System.out.println("addKVMHost successfully");
  91. //添加本地主存储
  92. AddLocalPrimaryStorageAction addLocalPrimaryStorageAction = new AddLocalPrimaryStorageAction();
  93. addLocalPrimaryStorageAction.url = "/zstack_ps";
  94. addLocalPrimaryStorageAction.name = "ps1";
  95. addLocalPrimaryStorageAction.zoneUuid = zone.uuid;
  96. addLocalPrimaryStorageAction.sessionId = sessionId;
  97. PrimaryStorageInventory primaryStorage = addLocalPrimaryStorageAction.call().value.inventory;
  98. System.out.println(String.format("addLocalPrimaryStorage:%s successfully",primaryStorage.name));
  99. //将本地主存储挂载到集群
  100. AttachPrimaryStorageToClusterAction attachPrimaryStorageToClusterAction = new AttachPrimaryStorageToClusterAction();
  101. attachPrimaryStorageToClusterAction.clusterUuid = cluster.uuid;
  102. attachPrimaryStorageToClusterAction.primaryStorageUuid = primaryStorage.uuid;
  103. attachPrimaryStorageToClusterAction.sessionId = sessionId;
  104. attachPrimaryStorageToClusterAction.call();
  105. System.out.println("attachPrimaryStorageToCluster successfully");
  106. //添加本地镜像存储;笔者测试环境中部署ZStack、主存储、镜像存储三者实质是同一台物理机
  107. AddImageStoreBackupStorageAction addImageStoreBackupStorageAction = new AddImageStoreBackupStorageAction();
  108. addImageStoreBackupStorageAction.hostname = "192.168.99.93";
  109. addImageStoreBackupStorageAction.username = "root";
  110. addImageStoreBackupStorageAction.password = "password";
  111. addImageStoreBackupStorageAction.url = "/zstack_bs";
  112. addImageStoreBackupStorageAction.name = "bs1";
  113. addImageStoreBackupStorageAction.sessionId = sessionId;
  114. ImageStoreBackupStorageInventory imageStoreBackupStoage = addImageStoreBackupStorageAction.call().value.inventory;
  115. System.out.println(String.format("addImageStoreBackupStorage:%s successfully",imageStoreBackupStoage.name));
  116. //将镜像存储挂载到区域;注意与主存储不同,这是由zstack的设计架构决定的
  117. AttachBackupStorageToZoneAction attachBackupStorageToZoneAction = new AttachBackupStorageToZoneAction();
  118. attachBackupStorageToZoneAction.zoneUuid = zone.uuid;
  119. attachBackupStorageToZoneAction.backupStorageUuid = imageStoreBackupStoage.uuid;
  120. attachBackupStorageToZoneAction.sessionId = sessionId;
  121. attachBackupStorageToZoneAction.call();
  122. System.out.println("attachBackupStorageToZone successfully");
  123. //添加镜像到本地镜像仓库
  124. AddImageAction addImageAction = new AddImageAction();
  125. addImageAction.name = "image1";
  126. addImageAction.url = "http://cdn.zstack.io/product_downloads/iso/ZStack-Enterprise-x86_64-DVD-1.9.0.iso";
  127. addImageAction.format = "qcow2";
  128. addImageAction.backupStorageUuids = Collections.singletonList(imageStoreBackupStoage.uuid);
  129. addImageAction.sessionId = sessionId;
  130. ImageInventory image = addImageAction.call().value.inventory;
  131. System.out.println(String.format("addImage:%s successfully",image.name));
  132. //创建无服务L2NoVlan公有网络
  133. CreateL2NoVlanNetworkAction createL2NoVlanNetworkAction = new CreateL2NoVlanNetworkAction();
  134. createL2NoVlanNetworkAction.name = "public-l2";
  135. createL2NoVlanNetworkAction.description = "this is a no-serivce network";
  136. createL2NoVlanNetworkAction.zoneUuid = zone.uuid;
  137. createL2NoVlanNetworkAction.physicalInterface = "eth1";
  138. createL2NoVlanNetworkAction.sessionId = sessionId;
  139. L2NetworkInventory l2NoVlanNetwork = createL2NoVlanNetworkAction.call().value.inventory;
  140. System.out.println(String.format("createL2NoVlanNetwork:%s successfully",l2NoVlanNetwork.name));
  141. //挂载无服务L2NoVlan公有网络到集群
  142. AttachL2NetworkToClusterAction attachL2NoVlanNetworkToClusterAction = new AttachL2NetworkToClusterAction();
  143. attachL2NoVlanNetworkToClusterAction.l2NetworkUuid = l2NoVlanNetwork.uuid;
  144. attachL2NoVlanNetworkToClusterAction.clusterUuid = cluster.uuid;
  145. attachL2NoVlanNetworkToClusterAction.sessionId = sessionId;
  146. attachL2NoVlanNetworkToClusterAction.call();
  147. //创建无服务L2Vlan私有网络
  148. CreateL2VlanNetworkAction createL2VlanNetworkAction = new CreateL2VlanNetworkAction();
  149. createL2VlanNetworkAction.vlan = 3000;
  150. createL2VlanNetworkAction.name = "private-l2";
  151. createL2VlanNetworkAction.description = "this is a l2-vlan network";
  152. createL2VlanNetworkAction.zoneUuid = zone.uuid;
  153. createL2VlanNetworkAction.physicalInterface = "eth1";
  154. createL2VlanNetworkAction.sessionId = sessionId;
  155. L2NetworkInventory l2VlanNetwork = createL2VlanNetworkAction.call().value.inventory;
  156. System.out.println(String.format("createL2VlanNetwork:%s successfully",l2VlanNetwork.name));
  157. //挂载无服务L2Vlan私有网络到集群
  158. AttachL2NetworkToClusterAction attachL2VlanNetworkToClusterAction = new AttachL2NetworkToClusterAction();
  159. attachL2VlanNetworkToClusterAction.l2NetworkUuid = l2VlanNetwork.uuid;
  160. attachL2VlanNetworkToClusterAction.clusterUuid = cluster.uuid;
  161. attachL2VlanNetworkToClusterAction.sessionId = sessionId;
  162. attachL2VlanNetworkToClusterAction.call();
  163. //基于L2NoVlan公有网络创建L3公有网络
  164. CreateL3NetworkAction createL3PublicNetworkAction = new CreateL3NetworkAction();
  165. createL3PublicNetworkAction.name = "public-l3";
  166. createL3PublicNetworkAction.type = "L3BasicNetwork";
  167. createL3PublicNetworkAction.l2NetworkUuid = l2NoVlanNetwork.uuid;
  168. createL3PublicNetworkAction.system = false;
  169. createL3PublicNetworkAction.sessionId = sessionId;
  170. L3NetworkInventory l3PublicNetwork = createL3PublicNetworkAction.call().value.inventory;
  171. System.out.println(String.format("createL2VlanNetwork:%s successfully",l3PublicNetwork.name));
  172. //挂载IP地址段到l3公有网络;
  173. AddIpRangeAction addIpRangeAction = new AddIpRangeAction();
  174. addIpRangeAction.l3NetworkUuid = l3PublicNetwork.uuid;
  175. addIpRangeAction.name = "iprange1";
  176. addIpRangeAction.startIp = "10.101.50.2";
  177. addIpRangeAction.endIp = "10.101.50.254";
  178. addIpRangeAction.netmask = "255.0.0.0";
  179. addIpRangeAction.gateway = "10.0.0.1";
  180. addIpRangeAction.sessionId = sessionId;
  181. addIpRangeAction.call();
  182. //基于L2Vlan私有网络 创建L3私有网络
  183. CreateL3NetworkAction createL3PrivateNetworkAction = new CreateL3NetworkAction();
  184. createL3PrivateNetworkAction.name = "private-l3";
  185. createL3PrivateNetworkAction.type = "L3BasicNetwork";
  186. createL3PrivateNetworkAction.l2NetworkUuid = l2VlanNetwork.uuid;
  187. createL3PrivateNetworkAction.system = false;
  188. createL3PrivateNetworkAction.sessionId = sessionId;
  189. L3NetworkInventory l3PrivateNetwork = createL3PrivateNetworkAction.call().value.inventory;
  190. System.out.println(String.format("createL2VlanNetwork:%s successfully",l3PrivateNetwork.name));
  191. //挂载Ip地址段到l3私有网络;这里使用CIDR方式,与上文中的直接挂载IP地址段效果相同
  192. AddIpRangeByNetworkCidrAction addIpRangeByNetworkCidrAction = new AddIpRangeByNetworkCidrAction();
  193. addIpRangeByNetworkCidrAction.name = "iprange2";
  194. addIpRangeByNetworkCidrAction.l3NetworkUuid = l3PrivateNetwork.uuid;
  195. addIpRangeByNetworkCidrAction.networkCidr = "192.168.100.0/24";
  196. addIpRangeByNetworkCidrAction.sessionId = sessionId;
  197. addIpRangeByNetworkCidrAction.call();
  198. //为私有网络private-l3添加DNS服务
  199. AddDnsToL3NetworkAction addDnsToL3NetworkAction = new AddDnsToL3NetworkAction();
  200. addDnsToL3NetworkAction.l3NetworkUuid = l3PrivateNetwork.uuid;
  201. addDnsToL3NetworkAction.dns = "8.8.8.8";
  202. addDnsToL3NetworkAction.sessionId = sessionId;
  203. addDnsToL3NetworkAction.call();
  204. //获取扁平网络服务的Uuid
  205. QueryNetworkServiceProviderAction queryNetworkServiceProviderAction = new QueryNetworkServiceProviderAction();
  206. queryNetworkServiceProviderAction.conditions = Collections.singletonList("type=Flat");
  207. queryNetworkServiceProviderAction.sessionId = sessionId;
  208. NetworkServiceProviderInventory networkServiceProvider = queryNetworkServiceProviderAction.call().value.inventories.get(0);
  209. System.out.println(String.format("queryNetworkServiceprovider:%s successfully",networkServiceProvider.getName()));
  210. Map<String,List<String>> networkServices = new HashMap<String, List<String>>();
  211. networkServices.put(networkServiceProvider.uuid, asList("DHCP", "Eip", "Userdata"));
  212. //为私有网络添加扁平网络服务
  213. AttachNetworkServiceToL3NetworkAction attachNetworkServiceToL3NetworkAction = new AttachNetworkServiceToL3NetworkAction();
  214. attachNetworkServiceToL3NetworkAction.l3NetworkUuid = l3PrivateNetwork.uuid;
  215. attachNetworkServiceToL3NetworkAction.networkServices = networkServices;
  216. attachNetworkServiceToL3NetworkAction.sessionId = sessionId;
  217. attachNetworkServiceToL3NetworkAction.call();
  218. System.out.println("attachNetworkServiceToL3Network successfully");
  219. //创建计算规格
  220. CreateInstanceOfferingAction createInstanceOfferingAction = new CreateInstanceOfferingAction();
  221. createInstanceOfferingAction.name = "instanceoffering1";
  222. createInstanceOfferingAction.cpuNum = 1;
  223. createInstanceOfferingAction.memorySize = 2148000000l;
  224. createInstanceOfferingAction.sessionId = sessionId;
  225. InstanceOfferingInventory instanceOffering = createInstanceOfferingAction.call().value.inventory;
  226. System.out.println(String.format("createInstanceOffering:%s successfully",instanceOffering.name));
  227. //创建云盘规格
  228. CreateDiskOfferingAction createDiskOfferingAction = new CreateDiskOfferingAction();
  229. createDiskOfferingAction.name = "diskOffering1";
  230. createDiskOfferingAction.diskSize = 2148000000l;
  231. createDiskOfferingAction.sessionId = sessionId;
  232. DiskOfferingInventory diskOffering = createDiskOfferingAction.call().value.inventory;
  233. System.out.println(String.format("createDiskOffering:%s successfully",diskOffering.name));
  234. //创建虚拟机
  235. CreateVmInstanceAction createVmInstanceAction = new CreateVmInstanceAction();
  236. createVmInstanceAction.name = "vm1";
  237. createVmInstanceAction.instanceOfferingUuid = instanceOffering.uuid;
  238. createVmInstanceAction.imageUuid = image.uuid;
  239. createVmInstanceAction.l3NetworkUuids = Collections.singletonList(l3PrivateNetwork.uuid);
  240. createVmInstanceAction.dataDiskOfferingUuids = Collections.singletonList(diskOffering.uuid);
  241. createVmInstanceAction.clusterUuid = cluster.uuid;
  242. createVmInstanceAction.description = "this is a vm";
  243. createVmInstanceAction.sessionId = sessionId;
  244. VmInstanceInventory vm = createVmInstanceAction.call().value.inventory;
  245. System.out.println(String.format("createVm:%s successfully",vm.name));
  246. //基于公有网络public-l3 创建Vip,为Eip作准备
  247. CreateVipAction createVipAction = new CreateVipAction();
  248. createVipAction.name = "vip1";
  249. createVipAction.l3NetworkUuid = l3PublicNetwork.uuid;
  250. createVipAction.sessionId = sessionId;
  251. VipInventory vip = createVipAction.call().value.inventory;
  252. System.out.println(String.format("createVip:%s successfully",vip.name));
  253. //创建Eip
  254. CreateEipAction createEipAction = new CreateEipAction();
  255. createEipAction.name = "eip1";
  256. createEipAction.vipUuid = vip.uuid;
  257. createEipAction.vmNicUuid = vm.vmNics.get(0).uuid;
  258. createEipAction.sessionId = sessionId;
  259. EipInventory eip = createEipAction.call().value.inventory;
  260. System.out.println(String.format("createEip:%s successfully",eip.name));
  261. //挂载Eip到虚拟机
  262. AttachEipAction attachEipAction = new AttachEipAction();
  263. attachEipAction.eipUuid = eip.uuid;
  264. attachEipAction.vmNicUuid = vm.vmNics.get(0).uuid;
  265. attachEipAction.sessionId = sessionId;
  266. attachEipAction.call();
  267. }
  268. }

用户场景2: ZStack整合分布式存储

在该场景下,用户内部业务部门对数据安全性的要求很高,不希望产生数据丢失的情况,并希望使用业界流行的超融合架构,即每个物理机均提供网络、存储、计算的功能。用户提供一个网关,所有云主机能够和该网关下其他设备能够直接通讯。在这种场景下,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创建该私有云环境的代码如下:

  1. package org.zstack.scene;
  2. import org.zstack.sdk.*;
  3. import java.security.MessageDigest;
  4. import java.security.NoSuchAlgorithmException;
  5. import java.util.Collections;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import static java.util.Arrays.asList;
  10. /**
  11. * Created by ZStack on 17-3-3.
  12. */
  13. public class flatNetworkCephStorageScene {
  14. public static String SHA(final String strText, final String strType){
  15. String strResult = null;
  16. if (strText != null && strText.length() > 0) {
  17. try {
  18. // SHA 加密开始
  19. // 创建加密对象 并传入加密类型
  20. MessageDigest messageDigest = MessageDigest.getInstance(strType);
  21. // 传入要加密的字符串
  22. messageDigest.update(strText.getBytes());
  23. // 得到 byte 类型结果
  24. byte byteBuffer[] = messageDigest.digest();
  25. // 将 byte 转换为 string
  26. StringBuffer strHexString = new StringBuffer();
  27. // 遍历 byte buffer
  28. for (int i = 0; i < byteBuffer.length; i++)
  29. {
  30. String hex = Integer.toHexString(0xff & byteBuffer[i]);
  31. if (hex.length() == 1)
  32. {
  33. strHexString.append('0');
  34. }
  35. strHexString.append(hex);
  36. }
  37. // 得到返回结果
  38. strResult = strHexString.toString();
  39. }
  40. catch (NoSuchAlgorithmException e)
  41. {
  42. e.printStackTrace();
  43. }
  44. }
  45. return strResult;
  46. }
  47. public static void main(String[] args) {
  48. //声明sessionId;每个action均需要sessionId
  49. String sessionId = null;
  50. //设置登录zstack的地址;通过172.20.12.4连接到部署zstack管理节点环境的主机
  51. ZSConfig.Builder zBuilder = new ZSConfig.Builder();
  52. zBuilder.setContextPath("zstack");
  53. zBuilder.setHostname("172.20.12.4");
  54. ZSClient.configure(zBuilder.build());
  55. //登录zstack;获取session
  56. LogInByAccountAction logInByAccountAction = new LogInByAccountAction();
  57. logInByAccountAction.accountName = "admin";
  58. logInByAccountAction.password = SHA("password", "SHA-512");
  59. LogInByAccountAction.Result logInByAccountActionRes = logInByAccountAction.call();
  60. if (logInByAccountActionRes.error == null) {
  61. System.out.println("logInByAccount successfully");
  62. sessionId = logInByAccountActionRes.value.getInventory().getUuid();
  63. }else logInByAccountActionRes.throwExceptionIfError();
  64. //创建区域
  65. CreateZoneAction createZoneAction = new CreateZoneAction();
  66. createZoneAction.name = "zone1";
  67. createZoneAction.description = "this is a zone";
  68. createZoneAction.sessionId = sessionId;
  69. ZoneInventory zone = createZoneAction.call().value.inventory;
  70. System.out.println(String.format("createZone:%s successfully", zone.name));
  71. //创建集群
  72. CreateClusterAction createClusterAction = new CreateClusterAction();
  73. createClusterAction.zoneUuid = zone.uuid;
  74. createClusterAction.name = "cluster1";
  75. createClusterAction.description = "this is a cluster";
  76. createClusterAction.hypervisorType = "KVM";
  77. createClusterAction.sessionId = sessionId;
  78. ClusterInventory cluster = createClusterAction.call().value.inventory;
  79. System.out.println(String.format("createCluster:%s successfully", cluster.name));
  80. //添加物理机;物理机IP应处于与公网IP不同的网络段,实现公有网络与管理网络分离
  81. AddKVMHostAction addKVMHostAction = new AddKVMHostAction();
  82. addKVMHostAction.name = "host1";
  83. addKVMHostAction.username = "root";
  84. addKVMHostAction.password = "password";
  85. addKVMHostAction.clusterUuid = cluster.uuid;
  86. addKVMHostAction.managementIp = "192.168.99.93";
  87. addKVMHostAction.sessionId = sessionId;
  88. HostInventory host = addKVMHostAction.call().value.inventory;
  89. System.out.println("addKVMHost successfully");
  90. //添加Ceph主存储;根据需要添加多个ceph节点;zstack通过管理网络连接到ceph集群,这里与NFS集群不同
  91. AddCephPrimaryStorageAction addCephPrimaryStorageAction = new AddCephPrimaryStorageAction();
  92. addCephPrimaryStorageAction.monUrls = Collections.singletonList("root:password@192.168.99.93");
  93. addCephPrimaryStorageAction.name = "cephPs1";
  94. addCephPrimaryStorageAction.zoneUuid = zone.uuid;
  95. addCephPrimaryStorageAction.sessionId = sessionId;
  96. PrimaryStorageInventory cephPrimaryStorage = addCephPrimaryStorageAction.call().value.inventory;
  97. System.out.println(String.format("addCephPrimaryStorage:%s successfully", cephPrimaryStorage.name));
  98. //将Ceph主存储挂载到集群,与本地存储操作一致
  99. AttachPrimaryStorageToClusterAction attachPrimaryStorageToClusterAction = new AttachPrimaryStorageToClusterAction();
  100. attachPrimaryStorageToClusterAction.clusterUuid = cluster.uuid;
  101. attachPrimaryStorageToClusterAction.primaryStorageUuid = cephPrimaryStorage.uuid;
  102. attachPrimaryStorageToClusterAction.sessionId = sessionId;
  103. attachPrimaryStorageToClusterAction.call();
  104. System.out.println("attachCephPrimaryStorageToCluster successfully");
  105. //添加Ceph镜像存储;根据需要添加多个ceph节点
  106. AddCephBackupStorageAction addCephBackupStorageAction = new AddCephBackupStorageAction();
  107. addCephBackupStorageAction.monUrls = Collections.singletonList("root:password@192.168.99.93");
  108. addCephBackupStorageAction.name = "cephBs1";
  109. addCephBackupStorageAction.sessionId = sessionId;
  110. BackupStorageInventory cephBackupStoage = addCephBackupStorageAction.call().value.inventory;
  111. System.out.println(String.format("addCephImageStoreBackupStorage:%s successfully", cephBackupStoage.name));
  112. //将Ceph镜像存储挂载到区域,与本地镜像存储操作一致
  113. AttachBackupStorageToZoneAction attachBackupStorageToZoneAction = new AttachBackupStorageToZoneAction();
  114. attachBackupStorageToZoneAction.zoneUuid = zone.uuid;
  115. attachBackupStorageToZoneAction.backupStorageUuid = cephBackupStoage.uuid;
  116. attachBackupStorageToZoneAction.sessionId = sessionId;
  117. attachBackupStorageToZoneAction.call();
  118. System.out.println("attachBackupStorageToZone successfully");
  119. //添加虚拟机镜像到Ceph镜像仓库
  120. AddImageAction addVmImageAction = new AddImageAction();
  121. addVmImageAction.name = "image1";
  122. addVmImageAction.url = "http://cdn.zstack.io/product_downloads/iso/ZStack-Enterprise-x86_64-DVD-1.9.0.iso";
  123. addVmImageAction.format = "qcow2";
  124. addVmImageAction.backupStorageUuids = Collections.singletonList(cephBackupStoage.uuid);
  125. addVmImageAction.sessionId = sessionId;
  126. ImageInventory image = addVmImageAction.call().value.inventory;
  127. System.out.println(String.format("addImage:%s successfully", image.name));
  128. //创建无服务L2NoVlan公有网络
  129. CreateL2NoVlanNetworkAction createL2NoVlanNetworkAction = new CreateL2NoVlanNetworkAction();
  130. createL2NoVlanNetworkAction.name = "public-l2";
  131. createL2NoVlanNetworkAction.description = "this is a no-serivce network";
  132. createL2NoVlanNetworkAction.zoneUuid = zone.uuid;
  133. createL2NoVlanNetworkAction.physicalInterface = "eth0";
  134. createL2NoVlanNetworkAction.sessionId = sessionId;
  135. L2NetworkInventory l2NoVlanNetwork = createL2NoVlanNetworkAction.call().value.inventory;
  136. System.out.println(String.format("createL2NoVlanNetwork:%s successfully", l2NoVlanNetwork.name));
  137. //挂载无服务L2NoVlan公有网络到集群
  138. AttachL2NetworkToClusterAction attachL2NoVlanNetworkToClusterAction = new AttachL2NetworkToClusterAction();
  139. attachL2NoVlanNetworkToClusterAction.l2NetworkUuid = l2NoVlanNetwork.uuid;
  140. attachL2NoVlanNetworkToClusterAction.clusterUuid = cluster.uuid;
  141. attachL2NoVlanNetworkToClusterAction.sessionId = sessionId;
  142. attachL2NoVlanNetworkToClusterAction.call();
  143. //基于L2NoVlan公有网络创建L3公有网络
  144. CreateL3NetworkAction createL3PublicNetworkAction = new CreateL3NetworkAction();
  145. createL3PublicNetworkAction.name = "public-l3";
  146. createL3PublicNetworkAction.type = "L3BasicNetwork";
  147. createL3PublicNetworkAction.l2NetworkUuid = l2NoVlanNetwork.uuid;
  148. createL3PublicNetworkAction.system = false;
  149. createL3PublicNetworkAction.sessionId = sessionId;
  150. L3NetworkInventory l3PublicNetwork = createL3PublicNetworkAction.call().value.inventory;
  151. System.out.println(String.format("createL2VlanNetwork:%s successfully", l3PublicNetwork.name));
  152. //挂载IP地址段到公有网络;
  153. AddIpRangeAction addIpRangeAction = new AddIpRangeAction();
  154. addIpRangeAction.l3NetworkUuid = l3PublicNetwork.uuid;
  155. addIpRangeAction.name = "iprange1";
  156. addIpRangeAction.startIp = "10.101.10.2";
  157. addIpRangeAction.endIp = "10.101.10.254";
  158. addIpRangeAction.netmask = "255.0.0.0";
  159. addIpRangeAction.gateway = "10.0.0.1";
  160. addIpRangeAction.sessionId = sessionId;
  161. addIpRangeAction.call();
  162. //为公有网络public-l3添加DNS服务
  163. AddDnsToL3NetworkAction addDnsToL3NetworkAction = new AddDnsToL3NetworkAction();
  164. addDnsToL3NetworkAction.l3NetworkUuid = l3PublicNetwork.uuid;
  165. addDnsToL3NetworkAction.dns = "8.8.8.8";
  166. addDnsToL3NetworkAction.sessionId = sessionId;
  167. addDnsToL3NetworkAction.call();
  168. //获取扁平网络服务的Uuid
  169. QueryNetworkServiceProviderAction queryNetworkServiceProviderAction = new QueryNetworkServiceProviderAction();
  170. queryNetworkServiceProviderAction.conditions = Collections.singletonList("type=Flat");
  171. queryNetworkServiceProviderAction.sessionId = sessionId;
  172. NetworkServiceProviderInventory networkServiceProvider = queryNetworkServiceProviderAction.call().value.inventories.get(0);
  173. System.out.println(String.format("queryNetworkServiceprovider:%s successfully", networkServiceProvider.getName()));
  174. Map<String, List<String>> networkServices = new HashMap<String, List<String>>();
  175. networkServices.put(networkServiceProvider.uuid, asList("DHCP", "Eip", "Userdata"));
  176. //为公有网络添加扁平网络服务
  177. AttachNetworkServiceToL3NetworkAction attachNetworkServiceToL3NetworkAction = new AttachNetworkServiceToL3NetworkAction();
  178. attachNetworkServiceToL3NetworkAction.l3NetworkUuid = l3PublicNetwork.uuid;
  179. attachNetworkServiceToL3NetworkAction.networkServices = networkServices;
  180. attachNetworkServiceToL3NetworkAction.sessionId = sessionId;
  181. attachNetworkServiceToL3NetworkAction.call();
  182. System.out.println("attachNetworkServiceToL3Network successfully");
  183. //创建计算规格
  184. CreateInstanceOfferingAction createInstanceOfferingAction = new CreateInstanceOfferingAction();
  185. createInstanceOfferingAction.name = "instanceoffering1";
  186. createInstanceOfferingAction.cpuNum = 2;
  187. createInstanceOfferingAction.memorySize = 2148000000l;
  188. createInstanceOfferingAction.sessionId = sessionId;
  189. InstanceOfferingInventory instanceOffering = createInstanceOfferingAction.call().value.inventory;
  190. System.out.println(String.format("createInstanceOffering:%s successfully", instanceOffering.name));
  191. //创建云盘规格
  192. CreateDiskOfferingAction createDiskOfferingAction = new CreateDiskOfferingAction();
  193. createDiskOfferingAction.name = "diskOffering1";
  194. createDiskOfferingAction.diskSize = 2148000000l;
  195. createDiskOfferingAction.sessionId = sessionId;
  196. DiskOfferingInventory diskOffering = createDiskOfferingAction.call().value.inventory;
  197. System.out.println(String.format("createDiskOffering:%s successfully", diskOffering.name));
  198. //创建虚拟机
  199. CreateVmInstanceAction createVmInstanceAction = new CreateVmInstanceAction();
  200. createVmInstanceAction.name = "vm1";
  201. createVmInstanceAction.instanceOfferingUuid = instanceOffering.uuid;
  202. createVmInstanceAction.imageUuid = image.uuid;
  203. createVmInstanceAction.l3NetworkUuids = Collections.singletonList(l3PublicNetwork.uuid);
  204. createVmInstanceAction.dataDiskOfferingUuids = Collections.singletonList(diskOffering.uuid);
  205. createVmInstanceAction.clusterUuid = cluster.uuid;
  206. createVmInstanceAction.description = "this is a vm";
  207. createVmInstanceAction.sessionId = sessionId;
  208. VmInstanceInventory vm = createVmInstanceAction.call().value.inventory;
  209. System.out.println(String.format("createVm:%s successfully", vm.name));
  210. }
  211. }

用户场景3: ZStack整合云路由构建VPC

在该场景下,用户内部的业务部门较多,每个业务部门希望自己的网络环境是完全隔离的,不受其他业务部门影响,该私有云环境更多的运行各业务部门对内的系统,例如OA系统、开发系统、测试系统等。在这种场景下,ZStack提供的私有云方案如下:
网络类型: 云路由
主存储类型: 本地存储
备份存储: 镜像仓库
私有网络: 内网地址段(云主机之间通讯使用)
公有网络: 云主机弹性IP使用的网络段
管理网络: 和云路由、物理机、备份存储等资源通信的网络

网络拓扑图如下:
cmd-markdown-logo

这种场景下,每个云路由内部的云主机之间可以相互通信,跨云路由的云主机之间无法直接通讯,需要通过弹性IP相互通讯。在创建该场景的过程中,需要显示的创建管理网络,并设置网络类型为“无服务网络”,这样做的原因在于创建云路由规格时,需要显示的添加云路由的管理网络,否则,云路由将不知道如何和管理节点通讯。
这种场景的好处在于,每个业务部门之间的网络完全隔离,并且,云路由能够提供更多的网络增值服务,例如,端口转发,负载均衡。

通过Java SDK创建该私有云环境的代码如下:

  1. package org.zstack.scene;
  2. import org.zstack.sdk.*;
  3. import java.security.MessageDigest;
  4. import java.security.NoSuchAlgorithmException;
  5. import java.util.Collections;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import static java.util.Arrays.asList;
  10. /**
  11. * Created by ZStack on 17-3-3.
  12. */
  13. public class virtualRouterLocalStorageEipScene {
  14. public static String SHA(final String strText, final String strType){
  15. String strResult = null;
  16. if (strText != null && strText.length() > 0) {
  17. try {
  18. // SHA 加密开始
  19. // 创建加密对象 并传入加密类型
  20. MessageDigest messageDigest = MessageDigest.getInstance(strType);
  21. // 传入要加密的字符串
  22. messageDigest.update(strText.getBytes());
  23. // 得到 byte 类型结果
  24. byte byteBuffer[] = messageDigest.digest();
  25. // 将 byte 转换为 string
  26. StringBuffer strHexString = new StringBuffer();
  27. // 遍历 byte buffer
  28. for (int i = 0; i < byteBuffer.length; i++)
  29. {
  30. String hex = Integer.toHexString(0xff & byteBuffer[i]);
  31. if (hex.length() == 1)
  32. {
  33. strHexString.append('0');
  34. }
  35. strHexString.append(hex);
  36. }
  37. // 得到返回結果
  38. strResult = strHexString.toString();
  39. }
  40. catch (NoSuchAlgorithmException e)
  41. {
  42. e.printStackTrace();
  43. }
  44. }
  45. return strResult;
  46. }
  47. public static void main(String[] args) {
  48. //声明sessionId;每个action均需要sessionId
  49. String sessionId = null;
  50. //设置登录zstack的地址;通过172.20.12.4连接到部署zstack管理节点环境的主机
  51. ZSConfig.Builder zBuilder = new ZSConfig.Builder();
  52. zBuilder.setContextPath("zstack");
  53. zBuilder.setHostname("172.20.12.4");
  54. ZSClient.configure(zBuilder.build());
  55. //登录zstack;获取session
  56. LogInByAccountAction logInByAccountAction = new LogInByAccountAction();
  57. logInByAccountAction.accountName = "admin";
  58. logInByAccountAction.password = SHA("password", "SHA-512");
  59. LogInByAccountAction.Result logInByAccountActionRes = logInByAccountAction.call();
  60. if (logInByAccountActionRes.error == null) {
  61. System.out.println("logInByAccount successfully");
  62. sessionId = logInByAccountActionRes.value.getInventory().getUuid();
  63. } else logInByAccountActionRes.throwExceptionIfError();
  64. //创建区域
  65. CreateZoneAction createZoneAction = new CreateZoneAction();
  66. createZoneAction.name = "zone1";
  67. createZoneAction.description = "this is a zone";
  68. createZoneAction.sessionId = sessionId;
  69. ZoneInventory zone = createZoneAction.call().value.inventory;
  70. System.out.println(String.format("createZone:%s successfully", zone.name));
  71. //创建集群
  72. CreateClusterAction createClusterAction = new CreateClusterAction();
  73. createClusterAction.zoneUuid = zone.uuid;
  74. createClusterAction.name = "cluster1";
  75. createClusterAction.description = "this is a cluster";
  76. createClusterAction.hypervisorType = "KVM";
  77. createClusterAction.sessionId = sessionId;
  78. ClusterInventory cluster = createClusterAction.call().value.inventory;
  79. System.out.println(String.format("createCluster:%s successfully", cluster.name));
  80. //添加物理机;物理机IP应处于与公网IP不同的网络段,实现公有网络与管理网络分离
  81. AddKVMHostAction addKVMHostAction = new AddKVMHostAction();
  82. addKVMHostAction.name = "host1";
  83. addKVMHostAction.username = "root";
  84. addKVMHostAction.password = "password";
  85. addKVMHostAction.clusterUuid = cluster.uuid;
  86. addKVMHostAction.managementIp = "192.168.99.93";
  87. addKVMHostAction.sessionId = sessionId;
  88. HostInventory host = addKVMHostAction.call().value.inventory;
  89. System.out.println("addKVMHost successfully");
  90. //添加本地主存储
  91. AddLocalPrimaryStorageAction addLocalPrimaryStorageAction = new AddLocalPrimaryStorageAction();
  92. addLocalPrimaryStorageAction.url = "/zstack_ps";
  93. addLocalPrimaryStorageAction.name = "ps1";
  94. addLocalPrimaryStorageAction.zoneUuid = zone.uuid;
  95. addLocalPrimaryStorageAction.sessionId = sessionId;
  96. PrimaryStorageInventory primaryStorage = addLocalPrimaryStorageAction.call().value.inventory;
  97. System.out.println(String.format("addLocalPrimaryStorage:%s successfully",primaryStorage.name));
  98. //将本地主存储挂载到集群
  99. AttachPrimaryStorageToClusterAction attachPrimaryStorageToClusterAction = new AttachPrimaryStorageToClusterAction();
  100. attachPrimaryStorageToClusterAction.clusterUuid = cluster.uuid;
  101. attachPrimaryStorageToClusterAction.primaryStorageUuid = primaryStorage.uuid;
  102. attachPrimaryStorageToClusterAction.sessionId = sessionId;
  103. attachPrimaryStorageToClusterAction.call();
  104. System.out.println("attachPrimaryStorageToCluster successfully");
  105. //添加本地镜像存储
  106. AddImageStoreBackupStorageAction addImageStoreBackupStorageAction = new AddImageStoreBackupStorageAction();
  107. addImageStoreBackupStorageAction.hostname = "192.168.99.93";
  108. addImageStoreBackupStorageAction.username = "root";
  109. addImageStoreBackupStorageAction.password = "password";
  110. addImageStoreBackupStorageAction.url = "/zstack_bs";
  111. addImageStoreBackupStorageAction.name = "bs1";
  112. addImageStoreBackupStorageAction.sessionId = sessionId;
  113. ImageStoreBackupStorageInventory imageStoreBackupStoage = addImageStoreBackupStorageAction.call().value.inventory;
  114. System.out.println(String.format("addImageStoreBackupStorage:%s successfully",imageStoreBackupStoage.name));
  115. //将镜像存储挂载到区域;注意与主存储不同,这是由zstack的设计架构决定的
  116. AttachBackupStorageToZoneAction attachBackupStorageToZoneAction = new AttachBackupStorageToZoneAction();
  117. attachBackupStorageToZoneAction.zoneUuid = zone.uuid;
  118. attachBackupStorageToZoneAction.backupStorageUuid = imageStoreBackupStoage.uuid;
  119. attachBackupStorageToZoneAction.sessionId = sessionId;
  120. attachBackupStorageToZoneAction.call();
  121. System.out.println("attachBackupStorageToZone successfully");
  122. //添加镜像到本地镜像仓库
  123. AddImageAction addImageAction = new AddImageAction();
  124. addImageAction.name = "image1";
  125. addImageAction.url = "http://cdn.zstack.io/product_downloads/iso/ZStack-Enterprise-x86_64-DVD-1.9.0.iso";
  126. addImageAction.format = "qcow2";
  127. addImageAction.backupStorageUuids = Collections.singletonList(imageStoreBackupStoage.uuid);
  128. addImageAction.sessionId = sessionId;
  129. ImageInventory image = addImageAction.call().value.inventory;
  130. System.out.println(String.format("addImage:%s successfully",image.name));
  131. //添加云路由镜像到本地镜像仓库
  132. AddImageAction addVRImageAction = new AddImageAction();
  133. addVRImageAction.name = "vrimage";
  134. addVRImageAction.url = "http://cdn.zstack.io/product_downloads/vrouter/vCenter-Vrouter-template-20170208.vmdk";
  135. addVRImageAction.format = "qcow2";
  136. addVRImageAction.system = true;
  137. addVRImageAction.backupStorageUuids = Collections.singletonList(imageStoreBackupStoage.uuid);
  138. addVRImageAction.sessionId = sessionId;
  139. ImageInventory VRImage = addVRImageAction.call().value.inventory;
  140. System.out.println(String.format("addImage:%s successfully", VRImage.name));
  141. //创建无服务L2NoVlan公有网络
  142. CreateL2NoVlanNetworkAction createL2NoVlanPublicNetworkAction = new CreateL2NoVlanNetworkAction();
  143. createL2NoVlanPublicNetworkAction.name = "public-l2";
  144. createL2NoVlanPublicNetworkAction.description = "this is a no-serivce network";
  145. createL2NoVlanPublicNetworkAction.zoneUuid = zone.uuid;
  146. createL2NoVlanPublicNetworkAction.physicalInterface = "eth1";
  147. createL2NoVlanPublicNetworkAction.sessionId = sessionId;
  148. L2NetworkInventory l2NoVlanPublicNetwork = createL2NoVlanPublicNetworkAction.call().value.inventory;
  149. System.out.println(String.format("createL2NoVlanPublicNetwork:%s successfully", l2NoVlanPublicNetwork.name));
  150. //挂载无服务L2NoVlan公有网络到集群
  151. AttachL2NetworkToClusterAction attachL2NoVlanPublicNetworkToClusterAction = new AttachL2NetworkToClusterAction();
  152. attachL2NoVlanPublicNetworkToClusterAction.l2NetworkUuid = l2NoVlanPublicNetwork.uuid;
  153. attachL2NoVlanPublicNetworkToClusterAction.clusterUuid = cluster.uuid;
  154. attachL2NoVlanPublicNetworkToClusterAction.sessionId = sessionId;
  155. attachL2NoVlanPublicNetworkToClusterAction.call();
  156. //创建无服务L2Vlan管理网络;云路由环境中用户需要手动创建管理网络,与扁平网络环境不同
  157. CreateL2NoVlanNetworkAction createL2NoVlanManagementNetworkAction = new CreateL2NoVlanNetworkAction();
  158. createL2NoVlanManagementNetworkAction.name = "management-l2";
  159. createL2NoVlanManagementNetworkAction.description = "this is a no-serivce network";
  160. createL2NoVlanManagementNetworkAction.zoneUuid = zone.uuid;
  161. createL2NoVlanManagementNetworkAction.physicalInterface = "eth0";
  162. createL2NoVlanManagementNetworkAction.sessionId = sessionId;
  163. L2NetworkInventory l2NoVlanManagmentNetwork = createL2NoVlanManagementNetworkAction.call().value.inventory;
  164. System.out.println(String.format("createL2NoVlanManagementNetwork:%s successfully", l2NoVlanManagmentNetwork.name));
  165. //挂载无服务L2NoVlan管理网络到集群
  166. AttachL2NetworkToClusterAction attachL2NoVlanManagementNetworkToClusterAction = new AttachL2NetworkToClusterAction();
  167. attachL2NoVlanManagementNetworkToClusterAction.l2NetworkUuid = l2NoVlanManagmentNetwork.uuid;
  168. attachL2NoVlanManagementNetworkToClusterAction.clusterUuid = cluster.uuid;
  169. attachL2NoVlanManagementNetworkToClusterAction.sessionId = sessionId;
  170. attachL2NoVlanManagementNetworkToClusterAction.call();
  171. //创建无服务L2Vlan私有网络
  172. CreateL2VlanNetworkAction createL2VlanPrivateNetworkAction = new CreateL2VlanNetworkAction();
  173. createL2VlanPrivateNetworkAction.vlan = 3000;
  174. createL2VlanPrivateNetworkAction.name = "private-l2";
  175. createL2VlanPrivateNetworkAction.description = "this is a l2-vlan network";
  176. createL2VlanPrivateNetworkAction.zoneUuid = zone.uuid;
  177. createL2VlanPrivateNetworkAction.physicalInterface = "eth1";
  178. createL2VlanPrivateNetworkAction.sessionId = sessionId;
  179. L2NetworkInventory l2VlanPrivateNetwork = createL2VlanPrivateNetworkAction.call().value.inventory;
  180. System.out.println(String.format("createL2VlanPrivateNetwork:%s successfully", l2VlanPrivateNetwork.name));
  181. //挂载无服务L2Vlan私有网络到集群
  182. AttachL2NetworkToClusterAction attachL2VlanPirvateNetworkToClusterAction = new AttachL2NetworkToClusterAction();
  183. attachL2VlanPirvateNetworkToClusterAction.l2NetworkUuid = l2VlanPrivateNetwork.uuid;
  184. attachL2VlanPirvateNetworkToClusterAction.clusterUuid = cluster.uuid;
  185. attachL2VlanPirvateNetworkToClusterAction.sessionId = sessionId;
  186. attachL2VlanPirvateNetworkToClusterAction.call();
  187. //基于L2NoVlan公有网络创建L3公有网络
  188. CreateL3NetworkAction createL3PublicNetworkAction = new CreateL3NetworkAction();
  189. createL3PublicNetworkAction.name = "public-l3";
  190. createL3PublicNetworkAction.type = "L3BasicNetwork";
  191. createL3PublicNetworkAction.l2NetworkUuid = l2NoVlanPublicNetwork.uuid;
  192. createL3PublicNetworkAction.system = false;
  193. createL3PublicNetworkAction.sessionId = sessionId;
  194. L3NetworkInventory l3PublicNetwork = createL3PublicNetworkAction.call().value.inventory;
  195. System.out.println(String.format("createL3PublicNetwork:%s successfully", l3PublicNetwork.name));
  196. //挂载IP地址段到公有网络public-l3;
  197. AddIpRangeAction addPublicIpRangeAction = new AddIpRangeAction();
  198. addPublicIpRangeAction.l3NetworkUuid = l3PublicNetwork.uuid;
  199. addPublicIpRangeAction.name = "iprange1";
  200. addPublicIpRangeAction.startIp = "10.101.20.2";
  201. addPublicIpRangeAction.endIp = "10.101.20.254";
  202. addPublicIpRangeAction.netmask = "255.0.0.0";
  203. addPublicIpRangeAction.gateway = "10.0.0.1";
  204. addPublicIpRangeAction.sessionId = sessionId;
  205. addPublicIpRangeAction.call();
  206. //基于L2Vlan管理网络创建L3管理网络
  207. CreateL3NetworkAction createL3MangementNetworkAction = new CreateL3NetworkAction();
  208. createL3MangementNetworkAction.name = "management-l3";
  209. createL3MangementNetworkAction.type = "L3BasicNetwork";
  210. createL3MangementNetworkAction.l2NetworkUuid = l2NoVlanManagmentNetwork.uuid;
  211. createL3MangementNetworkAction.system = false;
  212. createL3MangementNetworkAction.sessionId = sessionId;
  213. L3NetworkInventory l3MangementNetwork = createL3MangementNetworkAction.call().value.inventory;
  214. System.out.println(String.format("createL3ManagementNetwork:%s successfully", l3PublicNetwork.name));
  215. //挂载IP地址段到管理网络management-l3;注意此处挂载的网络段须与物理机实际配置的IP相匹配
  216. AddIpRangeAction addManagementIpRangeAction = new AddIpRangeAction();
  217. addManagementIpRangeAction.l3NetworkUuid = l3MangementNetwork.uuid;
  218. addManagementIpRangeAction.name = "iprange2";
  219. addManagementIpRangeAction.startIp = "192.168.99.200";
  220. addManagementIpRangeAction.endIp = "192.168.99.210";
  221. addManagementIpRangeAction.netmask = "255.255.255.0";
  222. addManagementIpRangeAction.gateway = "192.168.99.1";
  223. addManagementIpRangeAction.sessionId = sessionId;
  224. addManagementIpRangeAction.call();
  225. //基于L2Vlan网络 创建L3私有网络
  226. CreateL3NetworkAction createL3PrivateNetworkAction = new CreateL3NetworkAction();
  227. createL3PrivateNetworkAction.name = "private-l3";
  228. createL3PrivateNetworkAction.type = "L3BasicNetwork";
  229. createL3PrivateNetworkAction.l2NetworkUuid = l2VlanPrivateNetwork.uuid;
  230. createL3PrivateNetworkAction.system = false;
  231. createL3PrivateNetworkAction.sessionId = sessionId;
  232. L3NetworkInventory l3PrivateNetwork = createL3PrivateNetworkAction.call().value.inventory;
  233. System.out.println(String.format("createl3PrivaetNetwork:%s successfully", l3PrivateNetwork.name));
  234. //挂载Ip地址段到私有网络private-l3;这里使用CIDR方式,与上文中的直接挂载IP地址段效果相同
  235. AddIpRangeByNetworkCidrAction addPrivateIpRangeByNetworkCidrAction = new AddIpRangeByNetworkCidrAction();
  236. addPrivateIpRangeByNetworkCidrAction.name = "iprange3";
  237. addPrivateIpRangeByNetworkCidrAction.l3NetworkUuid = l3PrivateNetwork.uuid;
  238. addPrivateIpRangeByNetworkCidrAction.networkCidr = "192.168.100.0/24";
  239. addPrivateIpRangeByNetworkCidrAction.sessionId = sessionId;
  240. addPrivateIpRangeByNetworkCidrAction.call();
  241. //为私有网络private-l3添加DNS服务
  242. AddDnsToL3NetworkAction addDnsToL3NetworkAction = new AddDnsToL3NetworkAction();
  243. addDnsToL3NetworkAction.l3NetworkUuid = l3PrivateNetwork.uuid;
  244. addDnsToL3NetworkAction.dns = "8.8.8.8";
  245. addDnsToL3NetworkAction.sessionId = sessionId;
  246. addDnsToL3NetworkAction.call();
  247. //获取云路由网络服务的Uuid
  248. QueryNetworkServiceProviderAction queryNetworkServiceProviderAction = new QueryNetworkServiceProviderAction();
  249. queryNetworkServiceProviderAction.conditions = Collections.singletonList("type=vrouter");
  250. queryNetworkServiceProviderAction.sessionId = sessionId;
  251. NetworkServiceProviderInventory networkServiceProvider = queryNetworkServiceProviderAction.call().value.inventories.get(0);
  252. System.out.println(String.format("queryNetworkServiceprovider:%s successfully", networkServiceProvider.getName()));
  253. Map<String, List<String>> networkServices = new HashMap<String, List<String>>();
  254. networkServices.put(networkServiceProvider.uuid, asList("DHCP", "Eip", "DNS","SNAT"));
  255. //为私有网络private-l3添加网络服务
  256. AttachNetworkServiceToL3NetworkAction attachNetworkServiceToL3NetworkAction = new AttachNetworkServiceToL3NetworkAction();
  257. attachNetworkServiceToL3NetworkAction.l3NetworkUuid = l3PrivateNetwork.uuid;
  258. attachNetworkServiceToL3NetworkAction.networkServices = networkServices;
  259. attachNetworkServiceToL3NetworkAction.sessionId = sessionId;
  260. attachNetworkServiceToL3NetworkAction.call();
  261. System.out.println("attachNetworkServiceToL3Network successfully");
  262. //创建计算规格
  263. CreateInstanceOfferingAction createInstanceOfferingAction = new CreateInstanceOfferingAction();
  264. createInstanceOfferingAction.name = "instanceoffering1";
  265. createInstanceOfferingAction.cpuNum = 2;
  266. createInstanceOfferingAction.memorySize = 2148000000l;
  267. createInstanceOfferingAction.sessionId = sessionId;
  268. InstanceOfferingInventory instanceOffering = createInstanceOfferingAction.call().value.inventory;
  269. System.out.println(String.format("createInstanceOffering:%s successfully", instanceOffering.name));
  270. //创建云盘规格
  271. CreateDiskOfferingAction createDiskOfferingAction = new CreateDiskOfferingAction();
  272. createDiskOfferingAction.name = "diskOffering1";
  273. createDiskOfferingAction.diskSize = 2148000000l;
  274. createDiskOfferingAction.sessionId = sessionId;
  275. DiskOfferingInventory diskOffering = createDiskOfferingAction.call().value.inventory;
  276. System.out.println(String.format("createDiskOffering:%s successfully", diskOffering.name));
  277. //创建云路由规格;推荐管理网络、公有网络隔离
  278. CreateVirtualRouterOfferingAction createVirtualRouterOfferingAction = new CreateVirtualRouterOfferingAction();
  279. createVirtualRouterOfferingAction.zoneUuid = zone.uuid;
  280. createVirtualRouterOfferingAction.managementNetworkUuid = l3MangementNetwork.uuid;
  281. createVirtualRouterOfferingAction.publicNetworkUuid = l3PublicNetwork.uuid;
  282. createVirtualRouterOfferingAction.imageUuid = VRImage.uuid;
  283. createVirtualRouterOfferingAction.name = "vr1";
  284. createVirtualRouterOfferingAction.cpuNum = 4;
  285. createVirtualRouterOfferingAction.memorySize = 2148000000l;
  286. createVirtualRouterOfferingAction.sessionId = sessionId;
  287. createVirtualRouterOfferingAction.call();
  288. System.out.println("createVirtualRouterOffering successfully");
  289. //创建虚拟机
  290. CreateVmInstanceAction createVmInstanceAction = new CreateVmInstanceAction();
  291. createVmInstanceAction.name = "vm1";
  292. createVmInstanceAction.instanceOfferingUuid = instanceOffering.uuid;
  293. createVmInstanceAction.imageUuid = image.uuid;
  294. createVmInstanceAction.l3NetworkUuids = Collections.singletonList(l3PrivateNetwork.uuid);
  295. createVmInstanceAction.dataDiskOfferingUuids = Collections.singletonList(diskOffering.uuid);
  296. createVmInstanceAction.clusterUuid = cluster.uuid;
  297. createVmInstanceAction.description = "this is a vm";
  298. createVmInstanceAction.sessionId = sessionId;
  299. VmInstanceInventory vm = createVmInstanceAction.call().value.inventory;
  300. System.out.println(String.format("createVm:%s successfully", vm.name));
  301. //基于公有网络 创建Vip,为Eip作准备
  302. CreateVipAction createVipAction = new CreateVipAction();
  303. createVipAction.name = "vip1";
  304. createVipAction.l3NetworkUuid = l3PublicNetwork.uuid;
  305. createVipAction.sessionId = sessionId;
  306. VipInventory vip = createVipAction.call().value.inventory;
  307. System.out.println(String.format("createVip:%s successfully", vip.name));
  308. //创建Eip
  309. CreateEipAction createEipAction = new CreateEipAction();
  310. createEipAction.name = "eip1";
  311. createEipAction.vipUuid = vip.uuid;
  312. createEipAction.vmNicUuid = vm.vmNics.get(0).uuid;
  313. createEipAction.sessionId = sessionId;
  314. EipInventory eip = createEipAction.call().value.inventory;
  315. System.out.println(String.format("createEip:%s successfully", eip.name));
  316. //挂载Eip到虚拟机
  317. AttachEipAction attachEipAction = new AttachEipAction();
  318. attachEipAction.eipUuid = eip.uuid;
  319. attachEipAction.vmNicUuid = vm.vmNics.get(0).uuid;
  320. attachEipAction.sessionId = sessionId;
  321. attachEipAction.call();
  322. }
  323. }

用户场景4: ZStack整合NAS商业存储

用户预算较多,购买了商业存储,希望在一个集中式的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主存储在数据的高可靠、高可用、性能方面都有较好的表现。

  1. package org.zstack.scene;
  2. import org.zstack.sdk.*;
  3. import java.security.MessageDigest;
  4. import java.security.NoSuchAlgorithmException;
  5. import java.util.Collections;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import static java.util.Arrays.asList;
  10. /**
  11. * Created by ZStack on 17-3-3.
  12. */
  13. public class flatNetworkNfsStorageScene {
  14. public static String SHA(final String strText, final String strType){
  15. String strResult = null;
  16. if (strText != null && strText.length() > 0) {
  17. try {
  18. // SHA 加密开始
  19. // 创建加密对象 并传入加密类型
  20. MessageDigest messageDigest = MessageDigest.getInstance(strType);
  21. // 传入要加密的字符串
  22. messageDigest.update(strText.getBytes());
  23. // 得到 byte 类型结果
  24. byte byteBuffer[] = messageDigest.digest();
  25. // 将 byte 转换为 string
  26. StringBuffer strHexString = new StringBuffer();
  27. // 遍历 byte buffer
  28. for (int i = 0; i < byteBuffer.length; i++)
  29. {
  30. String hex = Integer.toHexString(0xff & byteBuffer[i]);
  31. if (hex.length() == 1)
  32. {
  33. strHexString.append('0');
  34. }
  35. strHexString.append(hex);
  36. }
  37. // 得到返回结果
  38. strResult = strHexString.toString();
  39. }
  40. catch (NoSuchAlgorithmException e)
  41. {
  42. e.printStackTrace();
  43. }
  44. }
  45. return strResult;
  46. }
  47. public static void main(String[] args) {
  48. //声明sessionId;每个action均需要sessionId
  49. String sessionId = null;
  50. //设置登录zstack的地址;通过172.20.12.4连接到部署zstack管理节点环境的主机
  51. ZSConfig.Builder zBuilder = new ZSConfig.Builder();
  52. zBuilder.setContextPath("zstack");
  53. zBuilder.setHostname("172.20.12.4");
  54. ZSClient.configure(zBuilder.build());
  55. //登录zstack;获取session
  56. LogInByAccountAction logInByAccountAction = new LogInByAccountAction();
  57. logInByAccountAction.accountName = "admin";
  58. logInByAccountAction.password = SHA("password", "SHA-512");
  59. LogInByAccountAction.Result logInByAccountActionRes = logInByAccountAction.call();
  60. if (logInByAccountActionRes.error == null) {
  61. System.out.println("logInByAccount successfully");
  62. sessionId = logInByAccountActionRes.value.getInventory().getUuid();
  63. } else logInByAccountActionRes.throwExceptionIfError();
  64. //创建区域
  65. CreateZoneAction createZoneAction = new CreateZoneAction();
  66. createZoneAction.name = "zone1";
  67. createZoneAction.description = "this is a zone";
  68. createZoneAction.sessionId = sessionId;
  69. ZoneInventory zone = createZoneAction.call().value.inventory;
  70. System.out.println(String.format("createZone:%s successfully", zone.name));
  71. //创建集群
  72. CreateClusterAction createClusterAction = new CreateClusterAction();
  73. createClusterAction.zoneUuid = zone.uuid;
  74. createClusterAction.name = "cluster1";
  75. createClusterAction.description = "this is a cluster";
  76. createClusterAction.hypervisorType = "KVM";
  77. createClusterAction.sessionId = sessionId;
  78. ClusterInventory cluster = createClusterAction.call().value.inventory;
  79. System.out.println(String.format("createCluster:%s successfully", cluster.name));
  80. //添加物理机;物理机IP应处于与公网IP不同的网络段,实现公有网络与管理网络分离
  81. AddKVMHostAction addKVMHostAction = new AddKVMHostAction();
  82. addKVMHostAction.name = "host1";
  83. addKVMHostAction.username = "root";
  84. addKVMHostAction.password = "password";
  85. addKVMHostAction.clusterUuid = cluster.uuid;
  86. addKVMHostAction.managementIp = "192.168.99.93";
  87. addKVMHostAction.sessionId = sessionId;
  88. HostInventory host = addKVMHostAction.call().value.inventory;
  89. System.out.println("addKVMHost successfully");
  90. //添加NFS主存储;此处添加的IP地址应属于NFS自有的万兆存储网络
  91. AddNfsPrimaryStorageAction addNfsPrimaryStorageAction = new AddNfsPrimaryStorageAction();
  92. addNfsPrimaryStorageAction.url = "192.168.100.20:/nfs_root";
  93. addNfsPrimaryStorageAction.name = "ps1";
  94. addNfsPrimaryStorageAction.type = "NFS";
  95. addNfsPrimaryStorageAction.zoneUuid = zone.uuid;
  96. addNfsPrimaryStorageAction.sessionId = sessionId;
  97. PrimaryStorageInventory nfsPrimaryStorage = addNfsPrimaryStorageAction.call().value.inventory;
  98. System.out.println("addNfsPrimaryStorage successfully");
  99. //将NFS主存储挂载到集群,与本地存储操作一致
  100. AttachPrimaryStorageToClusterAction attachPrimaryStorageToClusterAction = new AttachPrimaryStorageToClusterAction();
  101. attachPrimaryStorageToClusterAction.clusterUuid = cluster.uuid;
  102. attachPrimaryStorageToClusterAction.primaryStorageUuid = nfsPrimaryStorage.uuid;
  103. attachPrimaryStorageToClusterAction.sessionId = sessionId;
  104. attachPrimaryStorageToClusterAction.call();
  105. System.out.println("attachNFSPrimaryStorageToCluster successfully");
  106. //添加本地镜像存储
  107. AddImageStoreBackupStorageAction addImageStoreBackupStorageAction = new AddImageStoreBackupStorageAction();
  108. addImageStoreBackupStorageAction.hostname = "192.168.99.93";
  109. addImageStoreBackupStorageAction.username = "root";
  110. addImageStoreBackupStorageAction.password = "password";
  111. addImageStoreBackupStorageAction.url = "/zstack_bs";
  112. addImageStoreBackupStorageAction.name = "bs1";
  113. addImageStoreBackupStorageAction.sessionId = sessionId;
  114. ImageStoreBackupStorageInventory imageStoreBackupStoage = addImageStoreBackupStorageAction.call().value.inventory;
  115. System.out.println(String.format("addImageStoreBackupStorage:%s successfully",imageStoreBackupStoage.name));
  116. //将镜像存储挂载到区域;注意与主存储不同,这是由zstack的设计架构决定的
  117. AttachBackupStorageToZoneAction attachBackupStorageToZoneAction = new AttachBackupStorageToZoneAction();
  118. attachBackupStorageToZoneAction.zoneUuid = zone.uuid;
  119. attachBackupStorageToZoneAction.backupStorageUuid = imageStoreBackupStoage.uuid;
  120. attachBackupStorageToZoneAction.sessionId = sessionId;
  121. attachBackupStorageToZoneAction.call();
  122. System.out.println("attachBackupStorageToZone successfully");
  123. //添加镜像到本地镜像仓库
  124. AddImageAction addImageAction = new AddImageAction();
  125. addImageAction.name = "image1";
  126. addImageAction.url = "http://cdn.zstack.io/product_downloads/iso/ZStack-Enterprise-x86_64-DVD-1.9.0.iso";
  127. addImageAction.format = "qcow2";
  128. addImageAction.backupStorageUuids = Collections.singletonList(imageStoreBackupStoage.uuid);
  129. addImageAction.sessionId = sessionId;
  130. ImageInventory image = addImageAction.call().value.inventory;
  131. System.out.println(String.format("addImage:%s successfully",image.name));
  132. //创建无服务L2NoVlan公有网络
  133. CreateL2NoVlanNetworkAction createL2NoVlanNetworkAction = new CreateL2NoVlanNetworkAction();
  134. createL2NoVlanNetworkAction.name = "public-l2";
  135. createL2NoVlanNetworkAction.description = "this is a no-serivce network";
  136. createL2NoVlanNetworkAction.zoneUuid = zone.uuid;
  137. createL2NoVlanNetworkAction.physicalInterface = "eth1";
  138. createL2NoVlanNetworkAction.sessionId = sessionId;
  139. L2NetworkInventory l2NoVlanNetwork = createL2NoVlanNetworkAction.call().value.inventory;
  140. System.out.println(String.format("createL2NoVlanNetwork:%s successfully", l2NoVlanNetwork.name));
  141. //挂载无服务L2NoVlan公有网络到集群
  142. AttachL2NetworkToClusterAction attachL2NoVlanNetworkToClusterAction = new AttachL2NetworkToClusterAction();
  143. attachL2NoVlanNetworkToClusterAction.l2NetworkUuid = l2NoVlanNetwork.uuid;
  144. attachL2NoVlanNetworkToClusterAction.clusterUuid = cluster.uuid;
  145. attachL2NoVlanNetworkToClusterAction.sessionId = sessionId;
  146. attachL2NoVlanNetworkToClusterAction.call();
  147. //基于L2NoVlan公有网络创建L3公有网络
  148. CreateL3NetworkAction createL3PublicNetworkAction = new CreateL3NetworkAction();
  149. createL3PublicNetworkAction.name = "public-l3";
  150. createL3PublicNetworkAction.type = "L3BasicNetwork";
  151. createL3PublicNetworkAction.l2NetworkUuid = l2NoVlanNetwork.uuid;
  152. createL3PublicNetworkAction.system = false;
  153. createL3PublicNetworkAction.sessionId = sessionId;
  154. L3NetworkInventory l3PublicNetwork = createL3PublicNetworkAction.call().value.inventory;
  155. System.out.println(String.format("createL2VlanNetwork:%s successfully", l3PublicNetwork.name));
  156. //挂载IP地址段到公有网络public-l3;
  157. AddIpRangeAction addIpRangeAction = new AddIpRangeAction();
  158. addIpRangeAction.l3NetworkUuid = l3PublicNetwork.uuid;
  159. addIpRangeAction.name = "iprange1";
  160. addIpRangeAction.startIp = "10.101.30.2";
  161. addIpRangeAction.endIp = "10.101.30.254";
  162. addIpRangeAction.netmask = "255.0.0.0";
  163. addIpRangeAction.gateway = "10.0.0.1";
  164. addIpRangeAction.sessionId = sessionId;
  165. addIpRangeAction.call();
  166. //为公有网络public-l3添加DNS服务
  167. AddDnsToL3NetworkAction addDnsToL3NetworkAction = new AddDnsToL3NetworkAction();
  168. addDnsToL3NetworkAction.l3NetworkUuid = l3PublicNetwork.uuid;
  169. addDnsToL3NetworkAction.dns = "8.8.8.8";
  170. addDnsToL3NetworkAction.sessionId = sessionId;
  171. addDnsToL3NetworkAction.call();
  172. //获取扁平网络服务的Uuid
  173. QueryNetworkServiceProviderAction queryNetworkServiceProviderAction = new QueryNetworkServiceProviderAction();
  174. queryNetworkServiceProviderAction.conditions = Collections.singletonList("type=Flat");
  175. queryNetworkServiceProviderAction.sessionId = sessionId;
  176. NetworkServiceProviderInventory networkServiceProvider = queryNetworkServiceProviderAction.call().value.inventories.get(0);
  177. System.out.println(String.format("queryNetworkServiceprovider:%s successfully", networkServiceProvider.getName()));
  178. Map<String, List<String>> networkServices = new HashMap<String, List<String>>();
  179. networkServices.put(networkServiceProvider.uuid, asList("DHCP", "Eip", "Userdata"));
  180. //为公有网络添加网络服务
  181. AttachNetworkServiceToL3NetworkAction attachNetworkServiceToL3NetworkAction = new AttachNetworkServiceToL3NetworkAction();
  182. attachNetworkServiceToL3NetworkAction.l3NetworkUuid = l3PublicNetwork.uuid;
  183. attachNetworkServiceToL3NetworkAction.networkServices = networkServices;
  184. attachNetworkServiceToL3NetworkAction.sessionId = sessionId;
  185. attachNetworkServiceToL3NetworkAction.call();
  186. System.out.println("attachNetworkServiceToL3Network successfully");
  187. //创建计算规格
  188. CreateInstanceOfferingAction createInstanceOfferingAction = new CreateInstanceOfferingAction();
  189. createInstanceOfferingAction.name = "instanceoffering1";
  190. createInstanceOfferingAction.cpuNum = 2;
  191. createInstanceOfferingAction.memorySize = 21480000000l;
  192. createInstanceOfferingAction.sessionId = sessionId;
  193. InstanceOfferingInventory instanceOffering = createInstanceOfferingAction.call().value.inventory;
  194. System.out.println(String.format("createInstanceOffering:%s successfully", instanceOffering.name));
  195. //创建云盘规格
  196. CreateDiskOfferingAction createDiskOfferingAction = new CreateDiskOfferingAction();
  197. createDiskOfferingAction.name = "diskOffering1";
  198. createDiskOfferingAction.diskSize = 2148000000l;
  199. createDiskOfferingAction.sessionId = sessionId;
  200. DiskOfferingInventory diskOffering = createDiskOfferingAction.call().value.inventory;
  201. System.out.println(String.format("createDiskOffering:%s successfully", diskOffering.name));
  202. //创建虚拟机
  203. CreateVmInstanceAction createVmInstanceAction = new CreateVmInstanceAction();
  204. createVmInstanceAction.name = "vm1";
  205. createVmInstanceAction.instanceOfferingUuid = instanceOffering.uuid;
  206. createVmInstanceAction.imageUuid = image.uuid;
  207. createVmInstanceAction.l3NetworkUuids = Collections.singletonList(l3PublicNetwork.uuid);
  208. createVmInstanceAction.dataDiskOfferingUuids = Collections.singletonList(diskOffering.uuid);
  209. createVmInstanceAction.clusterUuid = cluster.uuid;
  210. createVmInstanceAction.description = "this is a vm";
  211. createVmInstanceAction.sessionId = sessionId;
  212. VmInstanceInventory vm = createVmInstanceAction.call().value.inventory;
  213. System.out.println(String.format("createVm:%s successfully", vm.name));
  214. }
  215. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注