私有云架构
私有云拓扑架构图
2021年10月,我购买了 HPE ProLiant DL360 Gen9服务器 来实现完整的云计算模拟,规划是采用一台二手服务器:
物理服务器安装 Ubuntu Linux
其实我更倾向于底层物理服务器采用高度定制精简的 Gentoo Linux 甚至 LFS(Linux from scratch) ,但是由于经费紧张,我需要采用 NVIDIA Virtual GPU (vGPU) 构建 GPU Kubernetes , 只能 采用商业化较好的 Ubuntu Linux 为好(或者 RedHat Linux )
如果有多块物理GPU卡,可以考虑采用 Gentoo Linux 来构建自己定制的底层操作系统(希望有一天我有充足的GPU卡来完成这个构想实践)
另一种激进的方法我构思采用 Gentoo Linux 上 Docker 运行 Ubuntu Linux 来实现 NVIDIA Virtual GPU (vGPU) (CRAZY,只是我的YY)
通过 KVM嵌套虚拟化 运行大量的一级KVM虚拟机,一级KVM虚拟机作为运行 OpenStack 的物理机,部署一个完整的OpenStack集群
物理服务器运行 Cockpit服务器统一管理平台 可以集成 Stratis - Linux存储系统 存储,以及 oVirt ,所以在第一层虚拟化上,可以不用自己手工部署 KVM ,而是集成到 oVirt
通过oVirt来管理第一层虚拟机,虚拟机开启嵌套虚拟化,这样可以同时学习oVirt的管理,体验不同于OpenStack的轻量级虚拟化管理平台
oVirt支持 Gluster 管理,可以方便在底层部署 GlusterFS
在一级虚拟机中运行 Kubernetes 模拟裸机的K8S集群
在OpenStack中部署运行大量二级虚拟机,按需运行,模拟云计算的弹性以及计费和监控
OpenStack中的二级虚拟机内部再部署一个 Kubernetes 集群,模拟云计算之上的K8S集群,结合 HashiCorp 的 Terraform 来实现全链路的自动化部署
附加:在DL360物理服务器上运行一个精简的Docker容器来做日常开发学习

多层次虚拟化服务器分布
虚拟化层 |
主机IP |
主机名 |
cpu |
内存(G) |
磁盘(G) |
NUMA |
说明 |
---|---|---|---|---|---|---|---|
1 |
192.168.6.51 |
z-o7k-m-1 |
4 |
16 |
0 |
OpenStack 管控 1 |
|
1 |
192.168.6.52 |
z-o7k-m-2 |
4 |
16 |
0 |
OpenStack 管控 2 |
|
1 |
192.168.6.53 |
z-o7k-m-3 |
4 |
16 |
0 |
OpenStack 管控 3 |
|
1 |
192.168.6.61 |
z-o7k-n-1 |
2 |
8 |
1 |
OpenStack Nova 1 |
|
1 |
192.168.6.62 |
z-o7k-n-2 |
2 |
8 |
1 |
OpenStack Nova 2 |
|
1 |
192.168.6.63 |
z-o7k-n-3 |
2 |
8 |
1 |
OpenStack Nova 3 |
|
1 |
192.168.6.64 |
z-o7k-n-4 |
2 |
8 |
1 |
OpenStack Nova 4 |
|
1 |
192.168.6.65 |
z-o7k-n-5 |
2 |
8 |
1 |
OpenStack Nova 5 |
|
1 |
192.168.6.66 |
z-o7k-n-6 |
2 |
8 |
1 |
OpenStack Nova 6 |
|
1 |
192.168.6.67 |
z-o7k-n-7 |
2 |
8 |
1 |
OpenStack Nova 7 |
|
1 |
192.168.6.68 |
z-o7k-n-8 |
2 |
8 |
1 |
OpenStack Nova 8 |
|
1 |
192.168.6.69 |
z-o7k-n-9 |
2 |
8 |
1 |
OpenStack Nova 9 |
|
1 |
192.168.6.70 |
z-o7k-n-10 |
2 |
8 |
1 |
OpenStack Nova 10 |
|
1 |
192.168.6.101 |
z-k8s-m-1 |
2 |
8 |
0 |
K8s 管控 1 |
|
1 |
192.168.6.101 |
z-k8s-api |
apiserver入口 |
||||
1 |
192.168.6.102 |
z-k8s-m-2 |
2 |
8 |
0 |
K8s 管控 2 |
|
1 |
192.168.6.102 |
z-k8s-api |
apiserver入口 |
||||
1 |
192.168.6.103 |
z-k8s-m-3 |
2 |
8 |
0 |
K8s 管控 3 |
|
1 |
192.168.6.103 |
z-k8s-api |
apiserver入口 |
||||
1 |
192.168.6.111 |
z-k8s-n-1 |
2 |
8 |
1 |
K8s node 1 |
|
1 |
192.168.6.112 |
z-k8s-n-2 |
2 |
8 |
1 |
K8s node 2 |
|
1 |
192.168.6.113 |
z-k8s-n-3 |
2 |
8 |
1 |
K8s node 3 |
|
1 |
192.168.6.114 |
z-k8s-n-4 |
2 |
8 |
1 |
K8s node 4 |
|
1 |
192.168.6.115 |
z-k8s-n-5 |
2 |
8 |
1 |
K8s node 5 |
|
1 |
192.168.6.121 |
z-okd-m-1 |
2 |
8 |
1 |
OKD(OpenShift) 管控 1 |
|
1 |
192.168.6.122 |
z-okd-m-2 |
2 |
8 |
1 |
OKD(OpenShift) 管控 2 |
|
1 |
192.168.6.123 |
z-okd-m-3 |
2 |
8 |
1 |
OKD(OpenShift) 管控 3 |
|
1 |
192.168.6.131 |
z-okd-n-1 |
2 |
8 |
1 |
OKD(OpenShift) node 1 |
|
1 |
192.168.6.132 |
z-okd-n-2 |
2 |
8 |
1 |
OKD(OpenShift) node 2 |
|
1 |
192.168.6.133 |
z-okd-n-3 |
2 |
8 |
1 |
OKD(OpenShift) node 3 |
|
1 |
192.168.6.134 |
z-okd-n-4 |
2 |
8 |
1 |
OKD(OpenShift) node 4 |
|
1 |
192.168.6.135 |
z-okd-n-5 |
2 |
8 |
1 |
OKD(OpenShift) node 5 |
|
1 |
192.168.6.151 |
z-http |
http服务案例IP |
||||
1 |
192.168.6.190 |
z-gfs-0 |
2 |
8 |
12块2G |
1 |
GlusterFS node 0 |
1 |
192.168.6.191 |
z-gfs-1 |
2 |
8 |
12块2G |
1 |
GlusterFS node 1 |
1 |
192.168.6.192 |
z-gfs-2 |
2 |
8 |
12块2G |
1 |
GlusterFS node 2 |
1 |
192.168.6.193 |
z-gfs-3 |
2 |
8 |
12块2G |
1 |
GlusterFS node 3 |
1 |
192.168.6.194 |
z-gfs-4 |
2 |
8 |
12块2G |
1 |
GlusterFS node 4 |
1 |
192.168.6.195 |
z-gfs-5 |
2 |
8 |
12块2G |
1 |
GlusterFS node 5 |
0 |
192.168.6.199 |
acloud |
4 |
16 |
0 |
Lenovo ThinkPad X220 |
|
0 |
192.168.6.200 |
zcloud |
48 |
64 |
512SSD |
HP DL360 Gen9 |
|
0 |
192.168.6.200 |
wpad |
WPAD服务 |
||||
0 |
192.168.6.200 |
proxy |
Proxy服务 |
||||
1 |
192.168.6.201 |
z-b-store-1 |
2 |
4 |
512HDD |
0(0 1) |
virtio-blk直接访问HDD(存储备份基础服务) |
1 |
192.168.6.202 |
z-b-store-2 |
2 |
4 |
512HDD |
0(2 3) |
virtio-blk直接访问HDD(存储备份基础服务) |
1 |
192.168.6.203 |
z-b-store-3 |
2 |
4 |
512HDD |
0(4 5) |
virtio-blk直接访问HDD(存储备份基础服务) |
1 |
192.168.6.204 |
z-b-data-1 |
4 |
16 |
1024NVMe |
0(24 25 26 27) |
iommu NVMe(数据基础服务) |
1 |
192.168.6.204 |
etcd |
基础etcd服务 |
||||
1 |
192.168.6.205 |
z-b-data-2 |
4 |
16 |
1024NVMe |
0(28 29 30 31) |
iommu NVMe(数据基础服务) |
1 |
192.168.6.205 |
etcd |
基础etcd服务 |
||||
1 |
192.168.6.206 |
z-b-data-3 |
4 |
16 |
1024NVMe |
0(32 33 34 35) |
iommu NVMe(数据基础服务) |
1 |
192.168.6.206 |
etcd |
基础etcd服务 |
||||
1 |
192.168.6.211 |
z-b-cache-1 |
2 |
8 |
0(6 7) |
近端访问 z-data(缓存基础服务) |
|
1 |
192.168.6.212 |
z-b-cache-2 |
2 |
8 |
0(8 9) |
近端访问 z-data(缓存基础服务) |
|
1 |
192.168.6.213 |
z-b-cache-3 |
2 |
8 |
0(10 11) |
近端访问 z-data(缓存基础服务) |
|
1 |
192.168.6.221 |
z-b-mon-1 |
2 |
4 |
基础监控 |
||
1 |
192.168.6.222 |
z-b-mon-2 |
2 |
4 |
基础监控 |
||
1 |
192.168.6.231 |
z-numa |
4 |
4 |
6 |
0 1 |
测试功能-numa |
1 |
192.168.6.232 |
z-iommu |
2 |
4 |
6 |
1 |
测试功能-iommu(fedora35) |
1 |
192.168.6.233 |
z-vgpu |
1 |
2 |
6 |
1 |
测试功能-vgpu(fedora35) |
1 |
192.168.6.234 |
z-udev |
1 |
2 |
6 |
1 |
编译(ubuntu20) |
1 |
192.168.6.235 |
z-kdev |
1 |
2 |
6 |
1 |
内核测试(fedora35) |
1 |
192.168.6.238 |
centos7-zfs |
1 |
2 |
4 |
1 |
模版(基于zfs存储卷的centos7) |
1 |
192.168.6.239 |
z-codeready |
2 |
2 |
6 |
OpenShift开发环境CodeReady |
|
1 |
192.168.6.240 |
z-devstack |
2 |
2 |
6 |
OpenStack开发环境DevStack |
|
1 |
192.168.6.241 |
z-centos6 |
1 |
2 |
6 |
模版 |
|
1 |
192.168.6.242 |
z-centos7 |
1 |
2 |
6 |
模版 |
|
1 |
192.168.6.243 |
z-centos8 |
1 |
2 |
6 |
模版 |
|
1 |
192.168.6.244 |
z-fedora35 |
1 |
2 |
6 |
模版 |
|
1 |
192.168.6.245 |
z-ubuntu18 |
1 |
2 |
6 |
模版 |
|
1 |
192.168.6.246 |
z-ubuntu20 |
1 |
2 |
6 |
模版(ubuntu 20.04) |
|
1 |
192.168.6.247 |
z-ubuntu20-rbd |
2 |
4 |
7 |
模版(ubuntu 20.04)Ceph存储 |
|
1 |
192.168.6.248 |
z-win7 |
2 |
4 |
7 |
Win7+Ceph存储 |
|
1 |
192.168.6.249 |
z-centos9-rbd |
2 |
4 |
7 |
模版(CentOS 9 Stream)Ceph存储 |
|
1 |
192.168.6.250 |
z-centos8-rbd |
2 |
4 |
7 |
模版(CentOS 8)Ceph存储 |
|
1 |
192.168.6.251 |
z-centos7-rbd |
2 |
4 |
7 |
模版(CentOS 7)Ceph存储 |
|
1 |
192.168.6.252 |
z-vdev |
2 |
4 |
6 |
1 |
fedora35(vgpu 8G) |
1 |
192.168.6.253 |
z-dev |
2 |
4 |
6 |
0 |
fedora35 |
0 |
192.168.6.254 |
dl360-ilo |
HP DL360 Gen9带外管理 |
||||
= |
= |
= |
= |
= |
= |
= |
= |
1 |
192.168.8.116 |
y-k8s-m-1 |
2 |
8 |
1 |
K8s 管控1 |
|
1 |
192.168.8.117 |
y-k8s-m-2 |
2 |
8 |
1 |
K8s 管控2 |
|
1 |
192.168.8.118 |
y-k8s-m-3 |
2 |
8 |
1 |
K8s 管控3 |
|
1 |
192.168.8.119 |
y-k8s-n-1 |
2 |
8 |
1 |
K8s node 1 |
|
1 |
192.168.8.120 |
y-k8s-n-2 |
2 |
8 |
1 |
K8s node 2 |
备注
虚拟机的内存最为关键,作为 Kubernetes集群(z-k8s) 工作节点,实践发现配置4G内存非常容易触发oom,所以目前统一改为8G,并且可能随着测试压力增大还需要调整:
<memory unit='KiB'>16777216</memory>
<currentMemory unit='KiB'>8388608</currentMemory>
当前配置改为8G,并且预留可扩展到16G
备注
保留 192.168.6.21 ~ 192.168.6.50
作为DHCP段IP,用于验证PXE以及无线网络段动态IP地址分配
主机命名规则
物理主机: 单字段命名
物理主机集群(树莓派): 主机名分为 3 段,以
-
作为分隔符第一个字段 表示服务器层次
pi
树莓派
第二字段 表示服务器节点身份
master
管控服务器worker
工作节点服务器
第三字段 表示节点序号数字
单用途虚拟机: 主机名分为 2 段,以
-
作为分隔符第一个字段 表示服务器层次(见下文),目前只有
z
第二个字段 表示用途 ,如
dev
numa
等
虚拟集群: 主机名分为 4 段,以
-
作为分隔符第一个字段 表示服务器层次,
z
表示在 HPE ProLiant DL360 Gen9服务器 物理服务器(zcloud
)上部署的第一层虚拟化;a
表示第二层
虚拟化,主要是在OpenStack之上运行虚拟机,模拟大规模 OpenStack 集群 (你也可以将这个字段理解为数据中心,今后部署多地冗灾体系)第二字段 表示集群 ,目前主要在第一层虚拟化部署集群:
b
: base 基础服务o7k
: OpenStack (模仿Kubernetes缩略方法,将中间7个字母简写为7
,所以 OpenStack 缩写成o7k
)k8s
: Kuberneteso7t
: OpenShift
第三字段 表示节点身份:
m
: 集群管控节点 (manager)n
: 集群工作节点 (node)store
: 基础服务存储data
: 基础服务数据服务:
第四字段 表示节点序号数字
网络规划
我所使用的 HPE ProLiant DL360 Gen9服务器 有2个4口网卡:
服务器主板板载
4口
Broadcom BCM5719千兆网卡FlexibleLOM Bay
4口
Intel I350千兆网卡 - 支持 Sigle Root I/O Virtualization(SR-IOV)
由于独立的 4口
Intel I350千兆网卡 支持 SR-IOV ,所以我规划:
每个Intel I350 (
igb
) 支持7个
SR-IOV 的 VF,共计可以实现32 个
网卡 (4x8
) ,分配到 Kubernetes 和 OpenStack :2块 Intel I350 (
igb
) 用于z-k8s
集群(Kubernetes): k8s运行节点(VM)z-k8s-n-1
到z-k8s-n-4
,每个node分配4个 sr-iov cni ,其余节点z-k8s-n-5
到z-k8s-n-10
则使用常规virtio-net
; 通过标签区别节点能力 (此外 NVIDIA Virtual GPU (vGPU) 也只分配2个node,以验证k8s调度)2块 Intel I350 (
igb
) 用于z-o7k
集群(OpenStack): 同样也分配4个node
绝大多数虚拟机的网络都连接在 br0
上,通过内部交换机实现互联 ( 后续学习 Open vSwitch (OVS) ),以内核虚拟交换机实现高速互联:
所有虚拟机都通过
br0
访问 Ceph 基础数据层,数据通路走内核,不经过外部交换机少量外部物理硬件(如 Raspberry Pi Cluster 以及我用笔记本模拟都KVM节点),通过 Cisco 网络 交换机访问
br0
连接的虚拟机,如 Ceph 虚拟化集群
私有云域名规划
私有云是我在一台 HPE ProLiant DL360 Gen9服务器 物理服务器( zcloud
) 上部署的云计算环境,我将这个环境作为 staging
环境来运行,所以域名设置为 staging.huatai.me
:
在最初部署环境中,为了快速完成整体架构,我采用 DNSmasq 和 iptables配置因特网共享连接(ICS) 来实现 私有云DNS服务(dnsmasq)和共享因特网(ICS)
后续不断完善迭代,我将会升级采用 BIND 重构整个DNS系统
虚拟化的层级部署
数据存储层(data)
在 zcloud
底层虚拟化上,我采用完全手工方式构建最基础的存储数据的虚拟机:
z-b-data-1
/z-b-data-2
/z-b-data-3
是通过 Open Virtual Machine Firmware(OMVF) 虚拟机pass-through读写 三星PM9A1 NVMe存储 的高性能存储虚拟机这3个虚拟机只依赖 KVM 和 Libvirt虚拟机管理器 ,并且在物理主机启动时自动启动运行,提供基础数据服务
Ceph 是最关键的存储服务: 除了
数据存储层
这3台虚拟机直接存储数据之外,其他虚拟机(包括第一层虚拟化和第二层虚拟化)的磁盘镜像全部存储在 Ceph 之中你可以将这个数据存储层 Ceph 看成类似于阿里云的
盘古
分布式存储,开天辟地: 这样所有其他虚拟机都不需要占用本地磁盘(事实上作为zcloud
主机的系统盘ssd
空间非常狭小)分布式存储提供了网络共享访问,同时提供了数据镜像容灾,这样运行的虚拟机可以在网络上不同的计算节点迁移: 例如,我可以在网络中加入我的笔记本或者台式机来模拟一个物理节点,共享访问Ceph存储,实现把虚拟机热迁移过去,从而减轻服务器的压力
在磁盘上构建 Linux LVM逻辑卷管理 LVM 卷用于存储数据 -
vg-data
(300G)etcd - 分布式kv存储 存储在
vg-data/lv-etcd
CoreDNS 采用 etcd - 分布式kv存储 存储数据
Rook - 云原生存储调度器 采用 etcd - 分布式kv存储 存储配置,在
z-k8s
中实现微型 Ceph / Cassandra / nfs服务M3 - 分布式时序数据库 采用 etcd - 分布式kv存储 存储数据,构建分布式 Prometheus监控 metrics 存储
Kubernetes 采用 etcd - 分布式kv存储 存储数据
z-b-store-1
/z-b-store-2
/z-b-store-3
是直接访问服务器上3块 2.5" SSD,基于 Gluster 的 Stratis - Linux存储系统 存储,运行 oVirt 同时提供 Ceph 的 geo-replication数据备份和恢复
近线数据存储,后续考虑实现一个容灾系统模拟
使用 企业级SSD 较好的消费级大容量SSD(2T)
z-b-arch-1
/z-b-arch-2
/z-b-arch-3
是直接访问服务器上3块 2.5" 机械硬盘,提供 Gluster 存储服务以及自动化归档备份 - 方案待定采用大容量机械硬盘(叠瓦盘)(8T),存储为主,较少修改,作为归档数据
双副本,实现基于磁盘的数据归档方案(磁带机维护成本高)
采用 Linux Bcache(块缓存) 来加速(利用SSD的部分容量)
第一层虚拟化
z-o7k
系列构建 OpenStack 集群采用 Ubuntu Linux 20.04 22.04 部署
启用 KVM嵌套虚拟化 实现第二层虚拟化
z-o3t
系列构建 oVirt 集群采用 CentOS 8 部署
启用 KVM嵌套虚拟化 实现第二层虚拟化
实现 Stratis - Linux存储系统 存储
z-k8s
系列构建 Kubernetes 集群采用 Ubuntu Linux 22.04 部署
采用 NVIDIA Virtual GPU (vGPU) 将 Nvidia Tesla P10 GPU运算卡 输出到多个工作节点虚拟机,实现分布式 Machine Learning
采用 Rook - 云原生存储调度器 来部署一个集成到Kubernetes的 Ceph 集群
第一层虚拟化的虚拟机也采用手工方式部署,部署用于构建集群的虚拟机都采用 数据存储层
的 Ceph RBD
,不使用任何本地磁盘: 虚拟机计算节点可以任意迁移。
第二层虚拟化
Kubernetes私有云
从集群稳定性和扩展性来说,推荐采用 扩展etcd节点高可用集群 部署模式:
kubernetes的管控组件和etcd分别部署在不同服务器,单节点故障影响从1/3降低到1/6
运维管理简化,拓扑清晰
etcd和apiserver都是管控平面非常消耗资源的组件,通过分离etcd部署提升了管控平面整体性能
但是,我的私有云由于资源限制,只有3台物理服务器,所以我采用了一种混合虚拟化和容器的部署架构:
管控平面服务器(kubernetes master)运行在KVM虚拟机(每个物理服务器上运行一个虚拟机)
共计3台KVM虚拟机,对外提供apiserver服务(直接通过 Libvirt虚拟机管理器 运行KVM虚拟机,简单清晰)
物理网络连接Kubernetes worker节点,管理运行在物理节点上的worker nodes
可以节约服务器占用,同时KVM虚拟机可以平滑迁移
etcd服务器运行在物理主机上
etcd是整个kubernetes集群的数据存储,不仅需要保障数据安全性,而且要保证读写性能
备注
最初我考虑采用OpenStack来运行Kubernetes管控服务器,但是OpenStack构建和运行复杂,Kubernetes依赖OpenStack则过于沉重,一旦出现OpenStack异常会导致整个Kubernetes不可用。
基础服务部署着重于稳定和简洁,依赖越少越好:并不是所有基础设施都适合云化(OpenStack)或者云原生(Kubernetes),特别是BootStrap的基础服务,使用物理裸机来运行反而更稳定更不容易出错。
Kubernetes的worker nodes直接部署在3台物理服务器上
备注
整个似有网络仅使用 3台物理服务器
。如果你缺少服务器资源,也可以采用KVM虚拟机来实践部署,即采用完全的OpenStack集群(单机或多机都可以),在OpenStack之上运行Kubernetes。
OpenStack私有云
OpenStack和Kubernetes共同部署在3台物理服务器上,底层的基础服务是共享的: