cloudstack简介
CloudStack是一个开源的具有高可用性及扩展性的云计算平台。目前Cloudstack支持管理大部分主流的hypervisors,如KVM,XenServer,VMware,Oracle VM,Xen等。同时CloudStack是一个开源云计算解决方案。可以加速高伸缩性的公共和私有云(IaaS)的部署、管理、配置。使用CloudStack作为基础,数据中心操作者可以快速方便的通过现存基础架构创建云服务。
cloudstack概念架构
- 用户:通过网络访问属于“我”的虚拟机、存储空间、管理“我”的个人模板。
- 管理员:部署配置,管理账户,监控资源,安排作业,排除故障。
- 开发人员:开发计费、监控、统计报表等功能模块,定制图形界面、工作流。
cloudstack部署架构
上图中的各个组件介绍如下:
Regions:为了提高云的可靠性,可以选择将资源分为多个地理区域。区域是CloudStack部署中最大的可用组织单位。一个区域由几个可用性zones组成,其中每个zone大致相当于一个数据中心。每个Regions均由其在一个zone中运行的管理服务器集群控制。regions中的zones通常相隔非常近。Regions 是用于提供容错和灾难恢复的有用技术。
Zone:Zone 对应于现实中的一个数据中心。
Pod:Pod 对应着一个机架。同一个 pod 中的机器在同一个子网(网段)中。
Cluster:Cluster 是多个主机组成的一个集群。同一个 cluster 中的主机有相同的硬件,相同的 Hypervisor,和共用同样的存储。同一个 cluster 中的虚拟机,可以实现无中断服务地从一个主机迁移到另外一个上。
Host:Host 就是运行虚拟机(VM)的主机。
CloudStack
存储按用途分为主存储(Primary Storage)
和二级存储(Secondary Storage)
,主存储用来存储虚拟机的卷
,二级存储用来存放虚拟机的模板,ISO镜像和快照
Primary storage:一级存储与 cluster 关联,它为该 cluster 中的主机的全部虚拟机提供磁盘卷。一个 cluster 至少有一个一级存储,且在部署时位置要临近主机以提供高性能。
Secondary storage:二级存储与 zone 关联,它存储模板文件,ISO 镜像和磁盘卷快照。
- 模板:可以启动虚拟机的操作系统镜像,也包括了诸如已安装应用的其余配置信息。
- ISO 镜像:包含操作系统数据或启动媒质的磁盘镜像。
- 磁盘卷快照:虚拟机数据的已储存副本,能用于数据恢复或者创建新模板。
即从包含关系上来说,一个regions包含多个zone,一个 zone 包含多个 pod,一个 pod 包含多个 cluster,一个 cluster 包含多个 host。
cloudstack和kvm一起部署的架构
如上所述:在每个kvm的宿主机上都需要部署agent程序。
如果部署vmware的产品就必须部署vcenter server。
cloudstack部署实践
关于这部分内容,请阅读官方文档。
主要是介绍cloudstack支持的存储协议、架构模式、机器配置等建议。
cloudstack和openstack比较
难易度 | 适合规模 | 参考资料 | 是否开源 | 市场占有率 | |
---|---|---|---|---|---|
cloudstack | 组件少,较易 | 小、中、大 | 较少 | 是 | 低 |
openstack | 组件多,较难 | 中、大 | 较多 | 是 | 高 |
部署cloudstack
环境准备
OS | 主机名 | IP | rules | services | explain |
---|---|---|---|---|---|
cenots 7.7 | management | 10.10.10.5 | 管理节点 | chronyd、cloudstack-management、mariadb、nginx | 用于管理整个cloudstack,最少2c4g |
cenots 7.7 | kvm1 | 10.10.10.22 | 计算节点 | kvm | 用于运行租户创建的虚拟机,建议4c4g |
cenots 7.7 | nfs | 10.10.10.5 | 存储节点 | nfs | 提供主存储、二级存储,最少2g1c,一块100G磁盘 |
系统初始化
系统初始化这一小节,如果没有特别说明,均需在所有节点执行。
修改主机名
$ hostnamectl set-hostname management
$ hostnamectl set-hostname kvm1
$ hostnamectl set-hostname nfs
source /etc/profile
关闭防火墙及selinux
在生产环境中,建议防火墙放行内网网段即可。selinux设置为permissive模式。(视频资料中说selinux设置为disable会有问题,具体待验证。)
$ systemctl stop firewalld && systemctl disable firewalld
setenforce 0
sed -i 's#^SELINUX=.*#SELINUX=permissive#g' /etc/selinux/config
sed -i 's#^SELINUX=.*#SELINUX=permissive#g' /etc/sysconfig/selinux
配置yum源
这一步主要是将默认的国外yum源配置为国内阿里的yum,如果你有自己内网的yum源服务器,请跳过此步骤。
# 更换为阿里云源
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
cat > /etc/yum.repos.d/cloudstack.repo << 'EOF'
[cloudstack]
name=cloudstack
baseurl=http://download.cloudstack.org/centos/$releasever/4.15/
enabled=1
gpgcheck=0
EOF
配置nfs服务
(此步骤在nfs节点执行)
yum -y install nfs-utils
cat >> /etc/exports << EOF
/export/secondary *(rw,async,no_root_squash,no_subtree_check)
/export/primary *(rw,async,no_root_squash,no_subtree_check)
EOF
# 创建共享目录
mkdir /export/{primary,secondary}
# 启动nfs
systemctl enable rpcbind nfs
systemctl start rpcbind nfs
其他任意节点确保可查看到共享目录:
showmount -e 10.10.10.5
安装cloudstack-management
yum install -y cloudstack-management cloudstack-common
导入数据库(此处使用已有的mysql作为存储)
# 可通过 cloudstack-setup-databases --help 查看其他命令选项及其含义
$ cloudstack-setup-databases cloud:epai706@localhost:3306 --deploy-as=root:epai706
# cloud:epai706:表示执行成功后,mysql数据库将创建一个密码为epai706的cloud用户供管理节点使用。
# --deploy-as:指定你本次使用哪个数据库用户导入数据
输出如下信息,表示数据库初始化成功:
启动manager server
# 第一次启动请这样启动
$ cloudstack-setup-management
# 执行后将输出如下信息,则表示启动成功:
Starting to configure CloudStack Management Server:
Configure Firewall ... [OK]
Configure CloudStack Management Server ...[OK]
CloudStack Management Server setup is Done!
# 后续启动方式请使用
$ systemctl restart cloudstack-management
访问dashboard
访问management的8080端口,可以看到如下界面,则表示management安装成功(默认用户名/密码:admin/password):
上传系统虚机镜像
cloudstack默认依赖几个虚机运行,当cloudstack添加区域后,他将自动启动相关虚机,所以还需要将镜像导入到二级存储中。
下载虚拟机系统模板
,放到二级存储
目录上
#官方下载地址http://cloudstack.apt-get.eu/systemvm/4.15/
wget http://cloudstack.apt-get.eu/systemvm/4.15/systemvmtemplate-4.15.0-kvm.qcow2.bz2
wget http://cloudstack.apt-get.eu/systemvm/4.15/systemvmtemplate-4.15.0-vmware.ova
wget http://cloudstack.apt-get.eu/systemvm/4.15/systemvmtemplate-4.15.0-ovm.raw.bz2
wget http://cloudstack.apt-get.eu/systemvm/4.15/systemvmtemplate-4.15.0-xen.vhd.bz2
wget http://cloudstack.apt-get.eu/systemvm/4.15/systemvmtemplate-4.15.0-hyperv.vhd.zip
#kvm
/usr/share/cloudstack-common/scripts/storage/secondary/cloud-install-sys-tmplt \
-m /export/secondary -f /root/systemvmtemplate-4.15.0-kvm.qcow2.bz2 -h kvm -F
#vmware
/usr/share/cloudstack-common/scripts/storage/secondary/cloud-install-sys-tmplt \
-m /export/secondary -f /root/systemvmtemplate-4.15.0-vmware.ova -h vmware -F
输出如下,则表示上传成功:
配置计算节点
注:此步骤只需在计算节点上执行。
修改网络配置
主要是生成一个网桥设备,以便VM都可以连接到此网桥。
# 备份源网卡配置文件
$ cp /etc/sysconfig/network-scripts/ifcfg-ens33{,_$(date +%F_%H).bak}
# 修改网卡配置文件
cat > /etc/sysconfig/network-scripts/ifcfg-ens33 << EOF
TYPE=Ethernet
DEVICE=ens33
ONBOOT=yes
BRIDGE=cloudbr0
EOF
cat > /etc/sysconfig/network-scripts/ifcfg-cloudbr0 << EOF
DEVICE=cloudbr0
TYPE=Bridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=10.10.10.22
GATEWAY=10.10.10.1
DNS1=223.5.5.5
EOF
# 修改完成后,务必检查是否修改正确,网卡名称、IP地址与你的实际环境是否一致
# 确认无误后,重启网络服务
$ systemctl restart network
安装cloudstack-agent
yum -y install cloudstack-agent cloudstack-common
确认加载kvm模块
$ lsmod | grep kvm # 输出如下,则表示已加载
[root@WT-TEST-10-22 ~]# lsmod | grep kvm
kvm_intel 188688 15
kvm 636969 1 kvm_intel
irqbypass 13503 21 kvm
[root@WT-TEST-10-22 ~]#
安装ibvirt
yum -y install qemu-kvm libvirt python-virtinst bridge-utils
修改libvirt默认配置
修改vnc默认监听地址
sed -i 's/^#vnc_listen =.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
# 指定cloudstack-management地址
sed -i "s/host=.*/host=10.10.10.5/g" /etc/cloudstack/agent/agent.properties
# 重启libvirt
systemctl restart libvirtd
启动cloudstack-agent并加入开机自启
$ systemctl start cloudstack-agent && systemctl enable cloudstack-agent
规划cloustack网络
在cloudstack中,提供了两种网络:基本网络和高级网络。这篇博文将基于基本网络进行配置,如果要配置高级网络,那么这篇博文不用继续往下看了,移步即可。
基本网络
基本网络模式采用传统扁平网络,与现有网络完美兼容,其网络通信拓扑如下:
基础网络模式只提供了简单的网络模型,管理网络、来宾网络、存储网络、V-Route(只提供了DNS、dhcp,并不提供网关服务)等。
高级网络
高级网络模式中,每个租户获得一个或多个来宾网络,每个网络属于独立的VLAN,由虚拟路由器为这些来宾网络提供网关服务。
虚拟路由器(系统虚拟机提供)在高级网络中十分重要,它将成为租户私有网络与公共网络之间的接口,并未租户私有网络提供各种网络服务,包括NAT、静态NAT、DHCP、DNS、Load Balancing、Port Forwording、Firewalls、Site-to-Site 虚拟专用网、VPC等。
两种不同的网络,对来宾网络(Guest Network)采用的隔离方式不同,在基本模式下,采用安全组(Security Group)方式进行隔离;而在高级网络中,采用VLAN方式进行隔离。
具体网络规划(内网实验用)
角色 | 网络 |
---|---|
management+nfs | 10.10.10.5 |
kvm1 | 10.10.10.22 |
虚拟机(来宾网络) | 10.10.10.150-10.10.10.160 |
创建zone
登录到cloudstack-management的管理控制台,进行如下操作,以便添加第一个zone:
网络方案介绍:
DefaultSharedNetworkOfferingWithSGService:带有安全组的网络方案,推荐选择此选项。
DefaultSharedNetworkOffering:不带安全组功能。
DefaultSharedNetscalerEIPandELBNetworkOffering:如果你在CLOUDSTACK内安装了Citrix NetScaler应用,并且你需要Elastic IP和Elastic Load Balancing这些功能的话,那就选择这个选项。EIP 和ELB技术在安全组启用的情况下,可以提供1:1的NAT映射和负载均衡功能。此功能需要citrix硬件支持,一般很少用。
QuickCloudNoServices:表示什么都不用,新增选项,不建议使用。
3、网络
4、添加提供点
5、设置来宾网络
6、设置群集名称
7、添加kvm主机节点
8、配置主存储
9、配置二级存储
11、启用资源域
激动人心的时刻到了,这一步,将检验你之前所有的操作是否正确。
验证cloudstack可用性
至此,你必须保证下面的任意资源都为“UP” 状态,如下:
1、资源域状态为“Enabled”
2、提供点状态状态为“Enabled”
3、群集状态“Enabled”
4、主机状态必须为 “Up”
5、主存储状态必须为 “Up”
6、二级存储状态必须为 “Up”
7、系统VM必须正常状态必须为 “Up”
至此,可以说你的集群完全可用了,但虚拟路由器现在数量为 “0”,当我们创建第一个实例后,虚拟路由器就被创建了。
注册ISO
现在,我们就来启动一个实例进行验证。需要自行准备一张系统盘。最好是centos的。附:centos镜像下载链接。
注册ISO镜像支持两种方式,一种是从本地上传,一种是从一个URL主机,为了速度考虑,建议自行准备http服务器,然后配置为文件服务器,进行注册ISO(本地上传功能不靠谱)。
1、安装nginx
任意节点安装即可,既然博文开头规划在了management节点,那就在这个节点吧。
server {
listen 80;
server_name 10.10.10.5;
location / {
root /data;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}
}
#可以看到在正常下载即可:
wget http://10.10.10.5/CentOS-7-x86_64-DVD-2009.iso
2、定义允许哪些网络可以访问二级存储(不配置iso安装的时候会拒绝
)
3、重启cloudstack-management生效
systemctl restart cloudstack-management
重启后,需要稍等片刻,待8080端口在监听,才可以继续访问控制台:
4、注册ISO
访问控制台,进行如下操作:
查看镜像上传进度:
自行刷新页面,直至完成:
稍等片刻,看到镜像状态如下,则表示成功:
创建vm虚拟机
启动VM后,进入虚机控制台,则可以和正常一样装系统了
:
此处省略一万字...............
取消附加ISO
当装完系统后,重启VM,默认还会进入装系统的界面,我们需要进行如下操作,才可以正常使用虚机,如下(需在VM关机状态下执行):
安装centos系统后 ,没有IP地址
- 配置网卡及初始化系统
#必须要修改网络接口的配置文件,编辑/etc/sysconfig/network-scripts/ifcfg-eth0文件
DEVICE=eth0
TYPE=Ethernet
BOOTPROTO=dhcp
ONBOOT=yes
DNS1=223.5.5.5
#----------系统初始化操作可以放在此处---------------------
#移除udev持久设备规则
rm -f /etc/udev/rules.d/70*
rm -f /var/lib/dhclient/*
#移除SSH Keys这步是为了确认所有要作为模板的VMs的SSH Keys都不相同,否则这样会降低虚拟机的安全性。
rm -f /etc/ssh/*key*
#清除日志文件,从主模板移除旧的日志文件是一个好习惯。
cat /dev/null > /var/log/audit/audit.log 2>/dev/null1
cat /dev/null > /var/log/wtmp 2>/dev/null
logrotate -f /etc/logrotate.conf 2>/dev/null
rm -f /var/log/*-* /var/log/*.gz 2>/dev/null
#清除用户历史bash命令。
history -c
unset HISTFILE
#关闭selinux和防火墙
sed -i "s/SELINUX=enforcing/SELINUX=disable/g" /etc/selinux/config
systemctl stop firewalld.service;systemctl disable firewalld.service
- 关闭VM
- 基于关闭vm的模板并且创建
新模板
从当前实例进来,点击**卷**
基于卷创建模板
等待最终模板的状态是"Download Complete
"
从此可以使用"tmp_centos7
"模板创建虚拟机了
API操作
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time : 2022/2/11 14:41
# @Author : XuLiLiang
# @File : cloudstack-api.py
import base64
import hashlib
import hmac
import json
import requests
from urllib import parse
baseurl = 'http://10.10.10.5:8080/client/api?'
api_key = 'g1Z0AutTl4Fbl3OeNX_rLJjaecOwMHkY3iUy6OiXlC6S3deP4s2NeLM2u8hGLqBHz509CHeC9eInPGvAqJ5KBg'
secret_key = b'MiX6r_vBgO3c9ZUnadq8aOzHg18Y0FnHjP-NPLfCcS1wOsLYcoJdVXEU4aUK6reHjsB7Z4sP4pQbV8yLLmzIyA'
class CloudApi:
def __init__(self):
self.baseurl = baseurl
self.api_key = api_key
self.secret_key = secret_key
def GetSing(self, command,**kwargs):
request = {}
request['command'] = command
request['response'] = 'json'
request['apikey'] = self.api_key
for k,v in kwargs.items():
request[k]=v
request_str = '&'.join(['='.join([k, parse.quote_plus(request[k])]) for k in request.keys()])
sig_str = '&'.join(['='.join([k.lower(), parse.quote_plus(request[k].lower().replace('+', '%20'))]) for k in
sorted(request.keys())]).encode("utf-8")
sig = hmac.new(self.secret_key, sig_str, hashlib.sha1).digest()
sig = base64.encodebytes(hmac.new(self.secret_key, sig_str, hashlib.sha1).digest())
sig = base64.encodebytes(hmac.new(self.secret_key, sig_str, hashlib.sha1).digest()).strip()
sig = parse.quote_plus(base64.encodebytes(hmac.new(self.secret_key, sig_str, hashlib.sha1).digest()).strip())
req = self.baseurl + request_str + '&signature=' + sig
return req
def listClusters(self):
req=self.GetSing('listClusters')
s = requests.get(req)
print(json.loads(s.content.decode("utf-8"))['listclustersresponse']['cluster'])
def listVirtualMachines(self):
req = self.GetSing('listVirtualMachines')
s = requests.get(req)
print(json.loads(s.content.decode("utf-8"))['listvirtualmachinesresponse']['virtualmachine'])
def listTemplates(self):
req = self.GetSing('listTemplates',templatefilter='all',aaa='123123')
s = requests.get(req)
response=json.loads(s.content.decode("utf-8"))['listtemplatesresponse']['template']
print(response)
if __name__ == '__main__':
api = CloudApi()
api.listVirtualMachines()
api.listClusters()
api.listTemplates()