前言
最近在折腾NAS和虚拟机的时候发现一个问题,部署的应用和服务太多了,有点记不住地址和端口了,所以需要一个导航页来展示这一切。
本想自己开发一个单页面应用呢,但是想到vue或react,对于前端的东西能不碰就不想碰,所以找到了一个开源的项目——flare。恰巧搭建了一个Kubernetes集群,正好练习一下。
技术点
Storage Class
什么是Storage Class
Kubernetes提供了一套可以自动创建PV的机制,即:Dynamic Provisioning。而这个机制的核心在于StorageClass这个API对象。
StorageClass对象会定义下面两部分内容:
- PV的属性。比如,存储类型,Volume的大小等。
- 创建这种PV需要用到的存储插件,即存储制备器。
有了这两个信息之后,Kubernetes就能够根据用户提交的PVC,找到一个对应的StorageClass,之后Kubernetes就会调用该StorageClass声明的存储插件,进而创建出需要的PV。
为什么用Storage Class
在一个大规模的Kubernetes集群里,可能有成千上万个PVC,这就意味着运维人员必须实现创建出这个多个PV,此外,随着项目的需要,会有新的PVC不断被提交,那么运维人员就需要不断的添加新的,满足要求的PV,否则新的Pod就会因为PVC绑定不到PV而导致创建失败。而且通过 PVC 请求到一定的存储空间也很有可能不足以满足应用对于存储设备的各种需求。
而且不同的应用程序对于存储性能的要求可能也不尽相同,比如读写速度、并发性能等,为了解决这一问题,Kubernetes 又为我们引入了一个新的资源对象:StorageClass,通过 StorageClass 的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据 StorageClass 的描述就可以非常直观的知道各种存储资源的具体特性了,这样就可以根据应用的特性去申请合适的存储资源了。
pvc是无法直接去向nfs-client-provisioner申请使用的存储空间的,这时,就需要通过SC这个资源对象去申请了,SC的根本作用就是根据pvc定义的来动态创建pv,不仅节省了我们管理员的时间,还可以封装不同类型的存储供pvc选用。
Storage Class资源
每个sc都包含以下三个重要的字段,这些字段会在sc需要动态分配pv时会使用到:
- Provisioner(供给方):提供了存储资源的存储系统。
- ReclaimPolicy:pv的回收策略,可用的值有Delete(默认)和Retiain
- Parameters(参数):存储类使用参数描述要关联到存储卷。
每个 StorageClass 都有一个制备器(Provisioner),用来决定使用哪个卷插件制备 PV。 该字段必须指定。
插件 | 内置制备器 | 配置例子 |
---|---|---|
AWSElasticBlockStore | ✓ | AWS EBS |
AzureFile | ✓ | Azure File |
AzureDisk | ✓ | Azure Disk |
CephFS | - | - |
Cinder | ✓ | OpenStack Cinder |
FC | - | - |
FlexVolume | - | - |
Flocker | ✓ | - |
GCEPersistentDisk | ✓ | GCE PD |
Glusterfs | ✓ | Glusterfs |
iSCSI | - | - |
Quobyte | ✓ | Quobyte |
NFS | - | - |
RBD | ✓ | Ceph RBD |
VsphereVolume | ✓ | vSphere |
PortworxVolume | ✓ | Portworx Volume |
ScaleIO | ✓ | ScaleIO |
StorageOS | ✓ | StorageOS |
Local | - | Local |
回收策略,由 StorageClass 动态创建的 PersistentVolume 会在类的 reclaimPolicy 字段中指定回收策略,可以是 Delete 或者 Retain。如果 StorageClass 对象被创建时没有指定 reclaimPolicy,它将默认为 Delete。
flare
轻量、快速、美观的个人导航页面,适用于 HomeLab 或其他注重私密的场景。
支持 x86 以及常见的 ARM (ARM32v6、ARM32v7、ARM64v8)设备,应用资源消耗非常低:
- CPU: < 1%
- MEM: < 30M
- Docker Image: < 10M
使用方式很简单:
- 下载Git仓库
- 使用docker启动,注意挂载
/app
目录
部署
创建Storage class
要使用 StorageClass,我们就得安装对应的自动配置程序,比如我们这里存储后端使用的是 nfs,那么我们就需要使用到一个 nfs-client 的自动配置程序,我们也叫它 Provisioner(制备器),这个程序使用我们已经配置好的 nfs 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。
- 自动创建的 PV 以${namespace}-${pvcName}-${pvName}这样的命名格式创建在 NFS 服务器上的共享数据目录中
- 而当这个 PV 被回收后会以archieved-${namespace}-${pvcName}-${pvName}这样的命名格式存在 NFS 服务器上。
注意在所有节点安装yum -y install nfs-utils
.
创建rbac权限:
1 | apiVersion: v1 |
执行yaml文件。我们新建的一个名为nfs-provisioner的ServiceAccount,然后绑定了一个名为nfs-provisioner-runner的ClusterRole,而该ClusterRole声明了一些权限,其中就包括对pv的增,删,改,查等权限,所以我们可以利用该serviceAccount来自动创建pv。
创建NFS的deployment:
1 | apiVersion: apps/v1 |
执行yaml文件,检查pod
1 | [root@master-51 ~]# kubectl get pods |
创建storage class:
1 | apiVersion: storage.k8s.io/v1 |
我们声明了一个名为statefu-nfs的sc对象,注意下面的provisioner字段对应的值一定要和上面的nfs的Deployment下面的PROVISIONER_NAME这个环境变量的值一样。
执行yaml文件,检查该资源对象。
1 | [root@master-51 ~]# kubectl get storageclass |
动态创建PVC
1 | kind: PersistentVolumeClaim |
执行yaml文件,检查是否创建了对应的PVC。
1 | [root@master-51 flare]# kubectl get pvc |
部署flare
编辑yaml文件:
1 | apiVersion: apps/v1 |
执行yaml文件,检查pod文件nfs。
1 | [root@master-51 ~]# kubectl get pods |
临时使用nodeport的方式访问:
1 | apiVersion: v1 |
之后可以考虑使用ingress或者其他方式。
访问页面,很美好:
总结
遇到的问题:
问题 1.:unexpected error getting claim reference: selfLink was empty, can’t make reference
解决 Kubernetes 1.20及以后版本禁用了 selfLink 所致。修改 /etc/kubernetes/manifests/kube-apiserver.yaml,添加 - –feature-gates=RemoveSelfLink=false 后重新部署。
问题 2.:waiting for a volume to be created, either by external provisioner “fuseim.pri/ifs” or manually created by system administrator
解决 Kubernetes 1.20及以后版本禁用了 selfLink 所致。修改 /etc/kubernetes/manifests/kube-apiserver.yaml,添加 - –feature-gates=RemoveSelfLink=false 后重新部署。