关于 Nutanix 的 CSI 体积插件背后的存储设备

本篇文章是作为2019年Kubernetes讲解日历的第二十五天,即12月15日的一部分而发布的。
这篇文章的内容基于本日期时点的信息(Nutanix CSI Plugin 1.x系列)。因此,请注意如果未来提供了新版本,则可能与该说明存在矛盾。
首先
就个人而言,我觉得Kubernetes中的存储,尤其是在本地环境中的存储问题,同负载均衡器的问题一样令人困扰。
在使用和运维Kubernetes的人群中,有些人可能不太关心Kubernetes底层的计算资源和存储资源,因为这些事情都由另一个团队负责。
然而,在本地运营基础架构,不仅仅是Kubernetes,显然无法避免从较低层次的计算和存储资源管理中脱身。
最近,Rook和Longhorn等产品成为了讨论的热点,它们是可用于本地的Kubernetes存储解决方案。但是今天我们要介绍的是一个不太为人所知的CSI Volume插件,它涉及一些私有化产品的讨论。
提供CSI卷插件,使Nutanix存储可以在包括Karbon的Kubernetes中使用。
Nutanix和Karbon是什么?
有些人可能会对推出本地虚拟化产品的公司为什么选择Kubernetes感到困惑,而在容器和Kubernetes领域的人们可能会说,我根本没听说过Nutanix之类的公司。所以,让我们首先简要复习一下这方面的一些内容。
Karbon是什么意思?
Nutanix是一种专有的HCI(超融合基础架构)产品,但其上运行着可管理的Kubernetes(更准确地说是CNCF分类中的Certified Kubernetes – Hosted),如果拥有Nutanix,可以无需特殊许可证等条件使用,并附带支持。
虽然有点旧,但请参阅去年的Kubernetes Advent Calendar 2018中关于Nutanix的本地托管Kubernetes服务“Karbon”的详细信息。
Nutanix是什么?
Nutanix最初是解决在本地环境中管理基础设施的复杂性和无法扩展的问题。它使用通用的x86服务器和软件定义的分布式架构,提供设计为容错的虚拟化基础设施,具有高可扩展性和基于集群技术的高可用性和容错性。此外,它还像公共云一样通过软件将底层抽象化,并且通过仪表板和API实现所有管理,从而提供便利性和价值。
Nutanix的CSI Volume插件是什么?

通过Nutanix的Karbon和CSI的Volume Plugin,提供的Software Defined分布式存储可以充分利用HCI的特性,并解决传统本地Kubernetes存储的问题。
为了与本次Advent Calendar的主旨不太相符,不再只谈论过于专有的产品。因此,接下来将以任何人都可以免费使用的Nutanix Community Edition为基础进行讨论。
关于Nutanix Community Edition的介绍,虽然有点过时,但可以参考这里的【2016年版】Nutanix CE再入門+最新情報(その1:ハイパーコンバージドインフラとNutanix CEの概要)。
CSI Volume Plugin后面的存储概述。
我想稍微提到一下 Nutanix 的 CSI Volume Plugin 对于 Kubernetes 容器所使用的存储本身的功能。在过去,对于 Kubernetes 的使用而言,数据持久化功能是由 Kubernetes 进行抽象化处理的,Kubernetes 的用户不需要关心存储本身的功能或存储内部的实现细节。然而,对于那些在本地环境中使用 Kubernetes 来进行有状态容器操作的用户来说,他们可能希望了解存储的可靠性、功能和性能等方面。
通过CSI Volume Plugin访问的存储是由Nutanix的分布式SDS(软件定义存储)提供的。Nutanix的核心架构包括Nutanix的创始成员之一,他曾在Google设计过Google的文件系统,并将公共云架构设计和思想引入企业世界的目标。
关于特征部分,有以下几个方面。
-
- ストレージへのデータの書き込み時、自動的に1つ以上複製を作成する
-
- 障害等で定義されたデータの複製数を下回った場合、自動でそれを検知し即座に複製から復元する
-
- SSD、HDDで構成されるストレージにおけるデータの階層化を自動で行う
-
- データの実体をメタデータで管理することでCoR(Copy on Redirect)を用いてクローンやスナップショットが一瞬で作成ができる
- その他、圧縮、重複排除、イレージャーコーディング、レプリケーションの機能、など
通过利用Nutanix HCI一直以来的特点,在存储不足的情况下,可以通过一键方式添加节点(这里的节点指的是构成Nutanix集群的节点,不是Kubernetes的节点),从而自动扩展具有高可用性的存储空间,而无需系统停机。
换句话说,已经在虚拟化世界中有充分实绩的存储将可稳定地提供给Kubernetes上的Pod。
CSI Volume Plugin的概述
您可以在以下位置获取Nutanix的CSI Volume插件:https://github.com/nutanix/csi-plugin(如果使用Karbon,则在部署Kubernetes集群时会自动部署,但在非Nutanix环境中,您需要从此处获取插件并进行部署)。
这个CSI Volume Plugin不仅可以在Karbon上的Kubernetes Pod中使用,还可以在非Nutanix环境下配置的Kubernetes Pod中提供存储,并支持通过PVC动态提供存储。此外,这个CSI Volume Plugin可以利用Nutanix的存储功能为Pod提供块级和文件级存储。
引用自《CSI VOLUME DRIVER 1.1》文档:
Kubernetes 是一个开源平台,可以协调在主机集群中部署、扩展和运维应用程序容器。Nutanix 托管的虚拟机(VM)或裸金属服务器组成了一个主机集群。Nutanix 支持使用 CSI Volume Driver 动态配置 PersistentVolumeClaims (PVC),该驱动程序在 Kubernetes pod 中运行。管理员需要配置一个存储类来进行持久性卷的配置。
该卷配置程序会监听已配置的存储类的 PVC 请求,然后为该请求创建一个 PersistentVolume (PV)。

12月22日更新:
我在另一篇文章中发布了关于如何使用Kubernetes外部的CSI卷插件将Nutanix存储用作持久卷的内容。
Nutanix 的 CSI 卷插件的行为
由于时间限制,我们无法介绍如何从非Nutanix环境的Kubernetes中使用,但可以参考Karbon的工作原理。总的来说,这是一个符合CSI标准的插件,所以它没有什么特别之处,只会按照CSI的正常规范进行操作。
为了简单地演示它的行为,我们将尝试部署一个WordPress。
通过CSI Volume Plugin对PVC发出Volume的请求。


为了进行简单的演示,本次我们将把Service、PersistentVolumeClaim和Deployment全部放在一个yaml文件中,并尝试应用这样一个yaml文件。
此外,在应用以下两个yaml文件之前,我们将先创建一个名为mysql-pass的Secret,其中包含kubectl create secret generic mysql-pass –from-literal=password=[YOUR-PASSWORD]的命令。
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
然后,我也尝试将WordPress的主要yaml文件应用到上面的设置中。
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: NodePort
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim


在命令行上,看起来如下所示。
~/Documents/01_docs/demo/yaml ❯ kubectl get pv,pvc,sc,pods -n default
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-4648134d-1f48-11ea-831c-506b8df55666 20Gi RWO Delete Bound default/mysql-pv-claim default-storageclass 35m
persistentvolume/pvc-55199cfd-1e24-11ea-831c-506b8df55666 10Gi RWO Delete Bound ntnx-system/prometheus-k8s-db-prometheus-k8s-0 default-storageclass 35h
persistentvolume/pvc-94facb9c-1f48-11ea-831c-506b8df55666 20Gi RWO Delete Bound default/wp-pv-claim default-storageclass 33m
persistentvolume/pvc-c476f529-1e23-11ea-831c-506b8df55666 20Gi RWO Delete Bound ntnx-system/elasticsearch-logging-data-elasticsearch-logging-0 default-storageclass 35h
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/mysql-pv-claim Bound pvc-4648134d-1f48-11ea-831c-506b8df55666 20Gi RWO default-storageclass 35m
persistentvolumeclaim/wp-pv-claim Bound pvc-94facb9c-1f48-11ea-831c-506b8df55666 20Gi RWO default-storageclass 33m
NAME PROVISIONER AGE
storageclass.storage.k8s.io/default-storageclass (default) com.nutanix.csi 35h
NAME READY STATUS RESTARTS AGE
pod/wordpress-76b5d9f5c8-djv5p 1/1 Running 0 33m
pod/wordpress-mysql-66594fb556-vg64r 1/1 Running 0 35m
删除Pod导致删除了通过PVC请求的Volume。
最后,我们将清洁这个Pod。由于使用了默认的Delete回收策略的StorageClass,删除这两个Pod将使PVC请求的Volume恢复到原始状态。

由于Karbon的插件中默认可用的Kibana LogTrail在追踪日志时数量庞大,所以我提取了以下的部分内容。
Dec 16 00:28:18
karbon-ce-milk02-4e3adb-k8s-master-0 kube-apiserver-karbon-ce-milk02-4e3adb-k8s-master-0: I1215 15:28:18.284180
1 wrap.go:47] DELETE /api/v1/persistentvolumes/pvc-94facb9c-1f48-11ea-831c-506b8df55666: (12.0125ms) 200 [csi-provisioner/v0.0.0 (linux/amd64) kubernetes/$Format 172.16.10.43:54884]
Dec 16 00:28:27
karbon-ce-milk02-4e3adb-k8s-master-0 kube-apiserver-karbon-ce-milk02-4e3adb-k8s-master-0: I1215 15:28:27.208092
1 wrap.go:47] DELETE /api/v1/persistentvolumes/pvc-4648134d-1f48-11ea-831c-506b8df55666: (7.042595ms) 200 [csi-provisioner/v0.0.0 (linux/amd64) kubernetes/$Format 172.16.10.43:54884]


总结
Nutanix的CSI Volume插件为Kubernetes上的Pod提供了基于公共云思想的高扩展性、可用性和容错性,并且已经在Nutanix作为虚拟化基础设施存储方面获得了良好的成果。
通过这个CSI Volume插件,您可以无缝地利用Nutanix存储来处理在Kubernetes上的Pod发出的存储请求和删除操作,不仅可以操作Kubernetes上的pv和pvc,也可以操作Nutanix的存储。
虽然Nutanix是一个私有产品,但也有可以免费使用的Community Edition,并且Karbon也可以在其中运行,所以(虽然安装Community Edition需要一些麻烦…),如果您希望在本地虚拟化基础设施和Kubernetes上运行,但更关心Kubernetes的搭建有多麻烦的话,对Nutanix的CSI卷插件感兴趣的人可以试试看。
明天(或者说,已经变成了今天),Kubernetes Advent Calendar 2019的第二篇,第16天的帖子是由@yukirii的朋友发布的。