Kubernetes 是数据库吗?五分钟讲解 CRD
如今,当你谈到容器化应用时,Kubernetes 通常会被提及作为其编排器。诚然,Kubernetes 非常适合管理服务器上的容器,并确保它们持续运行。但如今,Kubernetes 的作用远不止于此。
Kubernetes 允许您根据自己的逻辑扩展其功能。您可以基于 Kubernetes 中现有的机制,构建前所未有的开发工具——自定义资源定义 (CRD)。
支持我们🙏
我们知道 Kubernetes 的使用并非易事。正因如此,我们创建了 Cyclops,一个真正面向开发者的 Kubernetes 平台。它抽象化了 Kubernetes 的复杂性,并通过 UI 部署和管理您的应用。由于其平台特性,UI 本身高度可定制——您可以根据自己的需求进行更改。
我们正在将 Cyclops 开发为一个开源项目。如果您有兴趣尝试一下,可以参考我们代码库中的快速入门指南。如果您喜欢,请给我们一个 star ⭐ 来表示您的支持。

Kubernetes 组件
在深入探讨 CRD 之前,让我们先回顾一下 Kubernetes 控制平面组件,特别是 Kubernetes API 及其 ETCD 数据库。我们之前针对每个组件撰写了一篇博文,欢迎随时查看以了解更多详细信息。
您可能会使用命令行工具kubectl与 Kubernetes 集群通信。此工具允许您在 Kubernetes 集群中创建、读取和删除资源。当我说“与 Kubernetes 集群通信”时,我的意思是向 API 发出请求。Kubernetes API 是我们作为用户唯一会交互的组件。
每次我们创建或更新 K8s 资源时,Kubernetes API 都会将其存储在其数据库中etcd
。etcd是一个分布式键值存储,用于存储所有资源配置,例如部署、服务等。etcd 的一个巧妙功能是etcd
,您可以订阅数据库中某些键的更改,而其他 Kubernetes 机制也会使用这些数据。
当我们创建一个新的 K8s 资源时会发生什么?让我们通过创建一个服务来了解整个流程。要创建它,我们需要一个名为service.yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
并将其应用到集群kubectl
:
kubectl apply -f service.yaml
service/my-service created
kubectl
读取我们的文件并向 Kubernetes API 创建请求。API 随后会确保我们的服务配置有效(例如,所有必需字段均已存在、字段类型正确等),并将其存储到 etcd。现在,我们etcd
可以利用watch
之前提到的功能,将新创建的服务通知给控制器。
CRD 及其创建方法
基本流程介绍完毕后,我们现在可以扩展它了。我们可以将验证、存储和监视资源的相同流程应用于自定义对象。为了定义这些对象,我们将使用 Kubernetes 的自定义资源定义 (CRD)。
CRD 可以是一个 YAML 文件,其中包含我们新对象的架构——我们的自定义对象有哪些字段,以及如何验证它们。它将指导 Kubernetes API 如何处理新类型的资源。
假设您的公司从事水果业务,并委托您自动将苹果部署到 Kubernetes 集群。当然,这个例子与实际场景无关,只是为了说明您可以随意扩展 Kubernetes API。
苹果的颜色可以是green
、red
或yellow
,每个苹果都有其重量。让我们创建一个 YAML 来在 Kubernetes API 上反映这一点:
# apple-crd.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: apples.my-fruit.com
spec:
group: my-fruit.com
names:
kind: Apple
listKind: ApplesList
plural: apples
singular: apple
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
properties:
color:
enum:
- green
- red
- yellow
type: string
weightInGrams:
type: integer
type: object
type: object
served: true
storage: true
v1alpha1
我们为版本定义了两个属性.properties.spec
:
color
(可以采用 中的一个值enum
)weightInGrams
要告诉 Kubernetes API 有一种新类型的对象,我们只需将前一个文件应用到集群即可:
kubectl apply -f apple-crd.yaml
customresourcedefinition.apiextensions.k8s.io/apples.my-fruit.com created
Kubernetes API 现在已经准备好接收Apples
、验证它们并将它们存储到etcd
。
不要相信我的话,您可以创建一个满足上述 CRD 模式的 Kubernetes 对象:
# green-apple.yaml
apiVersion: my-fruit.com/v1alpha1
kind: Apple
metadata:
name: green-apple
spec:
color: green
weightInGrams: 200
并将其应用到集群:
kubectl apply -f green-apple.yaml
apple.my-fruit.com/green-apple created
现在,您的集群可以处理多一种类型的资源,并且您可以在同一个 Kubernetes 集群内存储和处理自定义数据。这是一个完全有效的命令:
kubectl get apples
NAME AGE
green-apple 6s
那么我可以将 Kubernetes 用作数据库吗?
现在我们知道我们可以在 Kubernetes 数据库中存储任何类型的对象并通过 K8s API 进行管理,我们应该对滥用这个概念的程度划定界限。
显然,你的应用程序数据(例如示例中的水果)在谈到 CRD 时会落入滥用的范畴。你应该针对这种情况开发独立的 API 并使用单独的数据库。
如果您需要对象可访问,kubectl
并且对象的 API 是声明式的,那么 CRD 非常适合。此外,扩展 Kubernetes API 的另一个很好的用例是实现Kubernetes Operator 模式,更多内容请见后续博客文章 😄
另一方面,如果您决定采用 CRD 路线,那么您将非常依赖 K8s API 如何处理资源,并且您可能会因为其 API 组和命名空间而受到限制。
Kubernetes CRD 是一款强大的工具,可以帮助您构建新的开发者平台和工具。Cyclops 的开发工作基于 CRD,欢迎随时访问我们的代码库进行查看。
鏂囩珷鏉ユ簮锛�https://dev.to/cyclops-ui/is-kubernetes-a-database-crds-explained-in-三分钟-361d