cloudstack-4.1.5版本最全入门笔记【2022】
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.88 | 计算节点 | kvm | 用于运行租户创建的虚拟机,建议4c4g |
cenots 7.7 | nfs | 10.10.10.87 | 存储节点 | 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
exportfs -a 表示将所有的更新
其他任意节点确保可查看到共享目录:
showmount -e 10.10.10.87
安装cloudstack-management
yum install -y cloudstack-management cloudstack-common
导入数据库(此处使用已有的mysql作为存储)
# 可通过 cloudstack-setup-databases --help 查看其他命令选项及其含义
cloudstack-setup-databases cloud:password00038@10.10.10.5:3306 --deploy-as=usertest:password00038
# cloud:password00038:表示执行成功后,mysql数据库将创建一个密码为password00038的cloud用户供管理节点使用。
# --deploy-as:指定你本次使用哪个数据库用户导入数据
额外提下:如果server要做高可用,在另一节点只需要执行cloudstack-setup-databases cloud:password00038@10.10.10.5:3306
,不要加不要加不要加--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):
上传系统虚拟机模板
此处使用单独的 NFS 服务器
,在server上执行挂载
mount -t nfs 10.10.10.87:/export/secondary /mnt/secondary
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
输出如下,则表示上传成功:
如果您使用的是单独的 NFS 服务器,请务必执行此步骤
,不然下次重启server时候会报错卡主
# 卸载辅助存储并删除创建的目录
umount /mnt/secondary
rmdir /mnt/secondary
报错如下:
[o.a.c.s.NfsMountManager] (main:null) (logid:) Clean up mounted NFS mount points used in current session.
配置计算节点
注:此步骤只需在计算节点上执行。
修改网络配置
主要是生成一个网桥设备,以便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:
1、网络选择基本的:
2、资源域详细信息:
网络方案介绍:
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安装的时候会拒绝
)
secstorage.allowed.internal.sites
3、重启cloudstack-management生效
systemctl restart cloudstack-management
重启后,需要稍等片刻,待8080端口在监听,才可以继续访问控制台:
4、注册ISO
访问控制台,进行如下操作:
查看镜像上传进度:
自行刷新页面,直至完成:
稍等片刻,看到镜像状态如下,则表示成功:
修改下全局配置
-
cpu.overprovisioning.factor
CPU超配倍数 一般设置3-4倍,内存超配倍数,如果准备运行虚拟机大多是Linux无界面系统,可以设置2倍,如果运行Windows等有图形界面的。最好选择不修改,因为经过个人测试,图形界面虚拟机相应的qemu进程真的会占用宿主机分配的那么多内存。当然,这有可能是因为我使用kvm 作为虚拟机管理程序的原因,Xenserver或者VMware可能会好一点。
-
mem.overprovisioning.factor
内存超配倍数
-
secstorage.allowed.internal.sites
允许下载模板或ISO的网段。。。可以设置成0.0.0.0/0表示允许所有网段,或者设置成 自己网络所在网段如 192.168.199.0/24 -
kvm.snapshot.enabled
是否启用KVM 的VM快照功能
-
expunge.delay
删除vm后,卷清理等待时间
-
enable.dynamic.scale.vm
配置动态 CPU 和内存扩展
创建vm虚拟机
启动VM后,进入虚机控制台,则可以和正常一样装系统了
:
此处省略一万字...............
取消附加ISO
当装完系统后,重启VM,默认还会进入装系统的界面,我们需要进行如下操作,才可以正常使用虚机,如下(需在VM关机状态下执行):
安装centos系统后 ,没有IP地址
- 配置网卡及初始化系统
#必须要修改网络接口的配置文件,编辑/etc/sysconfig/network-scripts/ifcfg-eth0文件
TYPE=Ethernet
BOOTPROTO=dhcp
NAME=eth0
DEVICE=eth0
ONBOOT=yes
DNS1=223.5.5.5
PEERDNS="no" #该配置可以禁用dhclient-script更新 resolv.conf文件,否则手动修改dns后重启系统后被改回虚拟路由器的地址,还有另外一种方法见https://forums.centos.org/viewtopic.php?t=24741#p116748
#----------系统初始化操作可以放在此处---------------------
#移除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
# @Email : xuliliang@epailive.com
# @File : cloudstack-api.py
import base64
import hashlib
import hmac
import json
import urllib
import httpx
import requests
from urllib import parse
baseurl = 'http://10.10.10.5:8080/client/api?'
api_key = '6QAhoFguQkIo-pxyggaaVRlsiSAD--Xrg18_5SDB4xptddp1PEcNCe5RcryXLhUKXox6Rujlcun4A8kRcbX23g'
secret_key = 'kVN31BNvJzl-60KgI2Y_n9DDk13Loe2PMn85g2VZoM8R6LgKYqZ5XOszjTAiENgSnsacjkmLMoX2f0754Z38eA'
class CloudApi:
def __init__(self):
self.baseurl = baseurl
self.api_key = api_key
self.secret_key = secret_key
def GetSing(self, params,args=None):
"""
封装request
"""
params['response'] = 'json'
params['apikey'] = self.api_key
request_str = '&'.join(['='.join([k, parse.quote_plus(params[k])]) for k in params.keys()])
sig_url = urllib.parse.urlencode(params)
sig_str = '&'.join(['='.join([k.lower(), parse.quote_plus(params[k].lower().replace('+', '%20'))]) for k in
sorted(params.keys())])
# sig1 = hmac.new(self.secret_key, sig_str, hashlib.sha1).digest()
# sig2 = base64.encodebytes(hmac.new(self.secret_key, sig_str, hashlib.sha1).digest())
# sig3 = base64.encodebytes(hmac.new(self.secret_key, sig_str, hashlib.sha1).digest()).strip()
sig = parse.quote_plus(base64.b64encode(hmac.new(self.secret_key.encode('utf-8'), sig_str.encode('utf-8'), hashlib.sha1).digest()).strip())
req = self.baseurl + request_str +args + '&signature=' + sig
return req
def listVirtualMachines(self,name=''):
"""
列出vms
"""
params = {
'command': 'listVirtualMachines',
'name':name
}
req = self.GetSing(params)
s = requests.get(req).content.decode("utf-8")
res = json.loads(s)
intances=[]
if not res['listvirtualmachinesresponse']['virtualmachine']:
print("VM is \033[31mnot exist\033[0m!")
return False
else:
if name:
for instance in res['listvirtualmachinesresponse']['virtualmachine']:
try:
if name==instance['name']:
instance_info = [instance['id'], instance['name'], instance['nic'][0]['ipaddress'],
instance['state']]
intances.append(instance_info)
break
except Exception as e:
raise e
else:
for instance in res['listvirtualmachinesresponse']['virtualmachine']:
if instance['state'] != 'Error' :
instance_info = [instance['id'], instance['name'],instance['nic'][0]['ipaddress'],
instance['state']]
intances.append(instance_info)
# print(intances)
return intances
def listTemplates(self):
"""
获取模板列表
"""
args_dict = {
'command': 'listTemplates',
'templatefilter': 'all',
}
req = self.GetSing(args_dict)
httpx.AsyncClient()
s = httpx.get(req)
response = json.loads(s.content.decode("utf-8"))['listtemplatesresponse']['template']
for x in response:
print(x['id'], x['name'])
def getZones(self):
"""
获取zones
"""
args_dict = {
'command': 'listZones',
}
req = self.GetSing(args_dict)
s = requests.get(req)
response = json.loads(s.content.decode("utf-8"))['listzonesresponse']['zone']
for x in response:
print (x['id'])
return (x['id'])
def listServiceOfferings(self):
"""
列出计算方案
"""
args_dict = {
'command': 'listServiceOfferings',
}
req = self.GetSing(args_dict)
s = requests.get(req)
response = json.loads(s.content.decode("utf-8"))['listserviceofferingsresponse']['serviceoffering']
for x in response:
print(x['id'], x['name'])
# print(response)
def listDiskOfferings(self):
"""
列出所有磁盘方案
"""
args_dict = {
'command': 'listDiskOfferings',
}
req = self.GetSing(args_dict)
try:
with httpx.Client() as client:
s = client.get(req, timeout=10)
response = json.loads(s.content.decode("utf-8"))
print(response)
except Exception as e:
raise e
def deployVirtualMachine(self):
"""
创建vm
"""
import uuid
suid = str(uuid.uuid4())
vm_name = f"VM-{suid}"
filepath = 'init.sh'
with open(filepath, 'rb') as f1:
base64_str = base64.encodebytes(f1.read())
u_data = base64_str.decode('utf-8')
# print(u_data)
# user_data = """#!/bin/bash
# env
# echo "export AAAAAA=1234567890" >> ~/.bashrc
# echo "export BBBBBB=0123456789" >> ~/.bashrc
# source ~/.bashrc
# env
# """
# bs = str(base64.b64encode(user_data.encode("utf-8")), "utf-8")
# print(bs)
args_dict = {
'command': 'deployVirtualMachine',
"diskofferingid": '6f17d452-b307-4005-93db-5f4e9060f1af',
"name": vm_name,
"serviceofferingid": '7e792106-53f6-402d-a671-80e86cc00486',
"templateid": '4ecb75d3-c060-4ccf-af88-717e2987389e',
"zoneid": '2d6c3c0a-6c42-4c10-8273-5879bf02cc70',
}
data=f"&userdata={u_data}"
req = self.GetSing(args_dict,data)
try:
s = requests.get(req)
response = json.loads(s.content.decode("utf-8"))
print(response)
except Exception as e:
raise e
def actionVirtualMachine(self, id, action):
status = {
'destroy': 'destroy',
'recover': 'recover',
'start': 'start',
'stop': 'stop',
'reboot': 'reboot',
'restore':'restore',
'running':'running',
}
host_info=self.listVirtualMachines(id)
print(host_info)
if host_info[0][3] == status[action]:
print("The \033[36m%s\033[0m Status is \033[33m%s\033[0m !")
import sys
sys.exit(500)
args_dict = {
'command': status[action]+'VirtualMachine',
'id': host_info[0][0],
}
req = self.GetSing(args_dict)
try:
s = requests.get(req)
res = json.loads(s.content.decode("utf-8"))
print(res)
except Exception as e:
raise e
def queryAsyncJobResult(self,id):
args_dict={
'command': 'queryAsyncJobResult',
'jobid':id,
}
req = self.GetSing(args_dict)
try:
with httpx.Client() as client:
s = client.get(req, timeout=10)
response = json.loads(s.content.decode("utf-8"))
print(response)
return response
except Exception as e:
raise e
def listNetworks(self):
args_dict={
'command': 'listNetworks',
}
req = self.GetSing(args_dict)
try:
with httpx.Client() as client:
s = client.get(req, timeout=10)
response = json.loads(s.content.decode("utf-8"))
print(response)
return response
except Exception as e:
raise e
if __name__ == '__main__':
api = CloudApi()
# 0 - Job表示程序还在进行
# 1 - Job表示成功地完成了
# 2 - Job表示执行失败
# api.listVirtualMachines()
# api.actionVirtualMachine('centos','destroy')
# api.listClusters()
# api.listServiceOfferings()
# api.listTemplates()
# api.getZones()
api.deployVirtualMachine()
# api.listDiskOfferings()
# api.listNetworks()
# api.queryAsyncJobResult('cedd5f88-dfba-4356-9df3-c13e1d3fe47b')
cloud-init实战
在云平台中,创建云主机的时候希望能够对主机进行一些初始化操作,如配置ip,主机名,密码,ssh登录等。openstack或cloudstack上可以使用cloud-init进行初始化。
cloud-init官方文档
阿里云官方文档 安装cloud-init
前提条件
• 一台KVM机器,用于制作初始的centos7镜像
• 已为Linux云服务器绑定弹性IP。
• 已登录Linux云服务器。
• Linux云服务器的网卡属性为DHCP方式。
以下均在模板机器
上配置
1. 下载cloud-init
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum install cloud-init -y
cloud-init init --local
#设置开机自启动
systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service
2. 安装相应的包
# ACPI服务是控制重启和关闭实例
yum -y install acpid
systemctl enable acpid
# 安装cloud-utils-growpart 允许分区调整
yum -y install cloud-utils-growpart
3. 配置Cloud-Init工具
- 用户可以根据需要根据用户类型配置登录云服务器的用户权限。使用root帐户登录,需要开启root用户的ssh权限,并开启密码远程登录。
- 若用户选择注入密码,则通过自己注入的密码进行远程SSH或noVNC登录。
- 若用户选择注入密钥,则通过自己注入的密钥进行远程SSH登录。
配置ssh文件
vim /etc/ssh/sshd_config
PasswordAuthentication yes
2 . 编辑配置文件/etc/cloud/cloud.cfg
在cloud.cfg文件增加该配置之后,cloud-init不会管理/etc/sysconfig/network-scripts/下网络配置,需要自行管理。
建议提前配置好网卡配置文件为dhcp获取,否则在私有云上创建的实例可能会导致获取不到IP地址;原因是cloud-init中的自动配置网卡文件可能会导致mac地址不一致
network:
config: disabled
最终配置如下
users:
- name: root
ssh_authorized_keys: #配置远程控制节点的ssh-keygen,
- ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvGQtIxNSwb3DqHJuDqBW0Gz6uc/B1gc4Un+7tQgMEcBbsOtaeLlmfF8D0DT4Tk349f2wmP12TyjqG+fekXB4HvrcXq/xVzloWalN0bzXNhVhy4ymXTq4lc6vYEkXLIyWN57FFp6NHbiKHBWkKHAYraYnf5a7wWOpPTq20bdHaIi4Pw9ADxWpQMVxyeMhBW9ZvBgPr4aGpkrKmARZShmLwEWpSHxRJymErnL6p/64s3xfRY4L9YdVLGBZfrzsoNVD20tTw1ctDswEkvTp46SNLK8BcM3qIk0WUpMEcNus7WtG4pQr9cob3qVAiMYGUP5KOiDa4PdjccvWP+bkDTjzsQ== root@kaifa-dev02
disable_root: 0
ssh_pwauth: 1
preserve_hostname: flase
manage_etc_hosts: true
manage_resolv_conf: true
resolv_conf:
nameservers:
- 8.8.8.8
- 8.8.4.4
options:
rotate: true
timeout: 1
network:
config: disabled
runcmd:
- [ sh, -c, echo "=========Welcome To cloudstack'=========" > /root/runcmd.log ]
cloud_init_modules:
- ssh
- migrator
- bootcmd
- write-files
- growpart
- resizefs
#- set_hostname
#- update_hostname
- update_etc_hosts
- rsyslog
- users-groups
cloud_config_modules:
- mounts
- locale
- set-passwords
- yum-add-repo
- package-update-upgrade-install
- timezone
- puppet
- chef
- salt-minion
- mcollective
- disable-ec2-metadata
- runcmd
- ntp-conf
cloud_final_modules:
- rightscale_userdata
- scripts-per-once
- scripts-per-boot
- scripts-per-instance
- scripts-user
- ssh-authkey-fingerprints
- keys-to-console
- phone-home
- final-message
- power-state-change
system_info:
distro: centos
paths:
cloud_dir: /var/lib/cloud/
templates_dir: /etc/cloud/templates/
ssh_svcname: sshd
chpasswd:
list: |
root:123456
expire: False
timezone: Asia/Shanghai
packages:
- wget
- zip
- iftop
- htop
- curl
- bind-utils
日志输出路径配置文件
#日志处理方式handlers**
#文件路径:/etc/cloud/cloud.cfg.d/05_logging.cfg
[logger_cloudinit]
level=DEBUG
qualname=cloudinit
handlers=cloudLogHandler
propagate=1
#最后一行增加输出的日志文件
output: {all: '| tee -a /var/log/cloud-init-output.log'}
检查Cloud-Init工具相关配置是否成功
执行以下命令,无错误发生,说明Cloud-Init配置成功
[Docker][root VM-438178de-b93e-400a-8981-581bfdcba864 ~]$ cloud-init init --local
Cloud-init v. 19.4 running 'init-local' at Wed, 16 Feb 2022 09:29:47 +0000. Up 1026.33 seconds.
[Docker][root VM-438178de-b93e-400a-8981-581bfdcba864 ~]$
设置完成后关闭虚拟机,准备下一阶段生成镜像
history -c
shutdown -h now
基于此卷创建模板
基于HAproxy高可用
安装
yum -y install haproxy
/etc/haproxy/haproxy.cfg
完整配置文件如下
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
listen web-ui-80
bind *:80
option httpchk OPTIONS /client
log global
mode http
option httplog
option forwardfor
balance source
cookie JSESSIONID insert preserve
server msg01 10.10.10.5:8080 cookie JSESSIONID_SERVER_1 check inter 50000 rise 2 fall 5
server msg02 10.10.10.68:8080 cookie JSESSIONID_SERVER_1 check inter 50000 rise 2 fall 5
listen web-ui-8080
bind *:8080
option httpchk OPTIONS /client
log global
mode http
option httplog
option forwardfor
balance source
cookie JSESSIONID insert preserve
server msg01 10.10.10.5:8080 cookie JSESSIONID_SERVER_1 check inter 50000 rise 2 fall 5
server msg02 10.10.10.68:8080 cookie JSESSIONID_SERVER_1 check inter 50000 rise 2 fall 5
重启haproxy
systemctl restart haproxy
访问 本机ip
即可进入CloudStack的UI界面 ,修改 全局设置 host
值为 本机ip
密码管理
CloudStack提供可选的密码重置功能,允许用户设置临时的admin或root密码,也可以从CloudStack UI中重置现有的admin或root密码。
要启用重置密码功能,您需要下载一个附加脚本来给模板打补丁
模板vm中执行
#下载脚本
wget https://download.cloudstack.org/templates/4.2/bindir/cloud-set-guest-password.in
mv cloud-set-guest-password.in cloud-set-guest-password
mv cloud-set-guest-password /etc/init.d/
chmod +x /etc/init.d/cloud-set-guest-password
#加到开机自启动
chkconfig --add cloud-set-guest-password
模板中启用密码功能
基于此卷创建模板时启动密码功能