首页 >后端开发 >Golang >Kubernetes 作为数据库?关于 CRD 您需要了解的内容

Kubernetes 作为数据库?关于 CRD 您需要了解的内容

WBOY
WBOY原创
2024-07-19 12:32:22292浏览

Kubernetes as a Database? What You Need to Know About CRDs

在快速发展的云原生技术领域,Kubernetes 已成为容器化应用编排的有力工具。但在开发人员和 IT 专家中,“Kubernetes 是数据库吗?”是一个常见问题。这篇文章探讨了这个问题,并对自定义资源定义 (CRD) 进行了全面的描述,重点介绍了它们在 Kubernetes 生态系统中的使用。我们希望通过完整的代码示例和实际应用来阐明这些想法,并说明 Kubernetes 在有状态应用管理方面的适应性和强大功能。

Kubernetes 简介

Kubernetes,通常缩写为 K8s,是一个开源平台,旨在自动化应用程序容器的部署、扩展和操作。 Kubernetes 最初由 Google 开发,在充满活力的社区以及广泛的工具和扩展的支持下,已成为容器编排事实上的标准。

Kubernetes 核心概念

在深入了解 CRD 的细节以及 Kubernetes 作为数据库的问题之前,有必要了解一些核心概念:

Pod:Kubernetes 中最小的可部署单元,代表集群中正在运行的进程的单个实例。

节点:Kubernetes 中的工作机器,可以是虚拟的,也可以是物理的。

集群:由 Kubernetes master 控制的一组节点。

服务:定义一组逻辑 Pod 以及访问它们的策略的抽象。

Kubernetes 作为数据库:神话还是现实?

Kubernetes 本身不是数据库。它是一个编排平台,可以管理容器化应用程序,包括数据库。然而,由于 Kubernetes 可以用来有效地部署和管理数据库应用程序,因此经常会出现混乱。

了解自定义资源定义 (CRD)

自定义资源定义 (CRD) 扩展了 Kubernetes API,允许用户管理自己的特定于应用程序的自定义资源。此功能使 Kubernetes 具有高度可扩展性和可定制性,以适应各种用例。

什么是 CRD?

CRD 使用户能够定义行为类似于内置 Kubernetes 资源的自定义对象。例如,虽然 Kubernetes 具有 Pod、服务和部署等内置资源,但您可以创建“MySQLCluster”或“PostgreSQLBackup”等自定义资源。

创建 CRD

要创建 CRD,您需要在 YAML 文件中定义它并将其应用到您的 Kubernetes 集群。这是一个基本示例:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: myresources.example.com
spec:
  group: example.com
  versions:
    - name: v1
      served: true
      storage: true
  scope: Namespaced
  names:
    plural: myresources
    singular: myresource
    kind: MyResource
    shortNames:
      - mr

使用 kubectl apply -f myresource-crd.yaml 应用此 YAML 文件将在集群中创建自定义资源定义。

管理自定义资源

创建 CRD 后,您可以开始管理自定义资源,就像管理本机 Kubernetes 资源一样。以下是自定义资源实例的示例:

apiVersion: example.com/v1
kind: MyResource
metadata:
  name: myresource-sample
spec:
  foo: bar
  count: 10

您可以使用以下方式创建此自定义资源:

kubectl apply -f myresource-instance.yaml

将 CRD 用于有状态应用程序

自定义资源定义对于管理有状态应用程序(包括数据库)特别有用。它们允许您定义数据库集群的所需状态、备份策略和其他自​​定义行为。

示例:使用 CRD 管理 MySQL 集群

考虑一个场景,您需要使用 Kubernetes 管理 MySQL 集群。您可以定义自定义资源来表示 MySQL 集群配置:

apiVersion: example.com/v1
kind: MySQLCluster
metadata:
  name: my-mysql-cluster
spec:
  replicas: 3
  version: "5.7"
  storage:
    size: 100Gi
    class: standard

借助此 CRD,您可以使用标准 Kubernetes 命令创建、更新和删除 MySQL 集群,从而使数据库管理更加简单并与基础设施的其余部分集成。

高级 CRD 功能

CRD 提供了多种高级功能,可增强其功能以及与 Kubernetes 生态系统的集成。

验证模式

您可以为自定义资源定义验证架构,以确保仅接受有效的配置。以下是向 MySQLCluster CRD 添加验证架构的示例:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: mysqlclusters.example.com
spec:
  group: example.com
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                replicas:
                  type: integer
                  minimum: 1
                version:
                  type: string
                storage:
                  type: object
                  properties:
                    size:
                      type: string
                    class:
                      type: string
  scope: Namespaced
  names:
    plural: mysqlclusters
    singular: mysqlcluster
    kind: MySQLCluster
    shortNames:
      - mc

自定义控制器

要自动化管理自定义资源,您可以编写自定义控制器。这些控制器监视自定义资源的更改,并采取措施使实际状态与所需状态保持一致。

以下概述了如何为 MySQLCluster 资源编写控制器:

package main

import (
    "context"
    "log"

    mysqlv1 "example.com/mysql-operator/api/v1"
    "k8s.io/apimachinery/pkg/runtime"
    "k8s.io/client-go/kubernetes/scheme"
    ctrl "sigs.k8s.io/controller-runtime"
    "sigs.k8s.io/controller-runtime/pkg/client"
    "sigs.k8s.io/controller-runtime/pkg/manager"
)

type MySQLClusterReconciler struct {
    client.Client
    Scheme *runtime.Scheme
}

func (r *MySQLClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    var mysqlCluster mysqlv1.MySQLCluster
    if err := r.Get(ctx, req.NamespacedName, &mysqlCluster); err != nil {
        return ctrl.Result{}, client.IgnoreNotFound(err)
    }

    // Reconciliation logic goes here

    return ctrl.Result{}, nil
}

func main() {
    mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
        Scheme: scheme.Scheme,
    })
    if err != nil {
        log.Fatalf("unable to start manager: %v", err)
    }

    if err := (&MySQLClusterReconciler{
        Client: mgr.GetClient(),
        Scheme: mgr.GetScheme(),
    }).SetupWithManager(mgr); err != nil {
        log.Fatalf("unable to create controller: %v", err)
    }

    if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
        log.Fatalf("unable to run manager: %v", err)
    }
}

版本控制

CRD 支持版本控制,允许您管理自定义资源的不同版本并在它们之间顺利迁移。这对于保持向后兼容性和随着时间的推移不断发展 API 至关重要。

案例研究:数据库的 Kubernetes Operator

Kubernetes Operators leverage CRDs and custom controllers to automate the management of complex stateful applications like databases. Let's explore a real-world example: the MySQL Operator.

The MySQL Operator

The MySQL Operator simplifies the deployment and management of MySQL clusters on Kubernetes. It uses CRDs to define the desired state of the MySQL cluster and custom controllers to handle tasks like provisioning, scaling, and backups.

Defining the MySQLCluster CRD

The MySQL Operator starts by defining a CRD for the MySQLCluster resource, as shown earlier. This CRD includes fields for specifying the number of replicas, MySQL version, storage requirements, and more.

Writing the MySQLCluster Controller

The controller for the MySQLCluster resource continuously watches for changes to MySQLCluster objects and reconciles the actual state with the desired state. For example, if the number of replicas is increased, the controller will create new MySQL instances and configure them to join the cluster.

Code Example: Scaling a MySQL Cluster

Here’s a simplified version of the controller logic for scaling a MySQL cluster:

func (r *MySQLClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    var mysqlCluster mysqlv1.MySQLCluster
    if err := r.Get(ctx, req.NamespacedName, &mysqlCluster); err != nil {
        return ctrl.Result{}, client.IgnoreNotFound(err)
    }

    // Fetch the current number of MySQL pods
    var pods corev1.PodList
    if err := r.List(ctx, &pods, client.InNamespace(req.Namespace), client.MatchingLabels{
        "app":  "mysql",
        "role": "master",
    }); err != nil {
        return ctrl.Result{}, err
    }

    currentReplicas := len(pods.Items)
    desiredReplicas := mysqlCluster.Spec.Replicas

    if currentReplicas < desiredReplicas {
        // Scale up
        for i := currentReplicas; i < desiredReplicas; i++ {
            newPod := corev1.Pod{
                ObjectMeta: metav1.ObjectMeta{
                    Name:      fmt.Sprintf("mysql-%d", i),
                    Namespace: req.Namespace,
                    Labels: map[string

]string{
                        "app":  "mysql",
                        "role": "master",
                    },
                },
                Spec: corev1.PodSpec{
                    Containers: []corev1.Container{
                        {
                            Name:  "mysql",
                            Image: "mysql:5.7",
                            Ports: []corev1.ContainerPort{
                                {
                                    ContainerPort: 3306,
                                },
                            },
                        },
                    },
                },
            }
            if err := r.Create(ctx, &newPod); err != nil {
                return ctrl.Result{}, err
            }
        }
    } else if currentReplicas > desiredReplicas {
        // Scale down
        for i := desiredReplicas; i < currentReplicas; i++ {
            podName := fmt.Sprintf("mysql-%d", i)
            pod := &corev1.Pod{
                ObjectMeta: metav1.ObjectMeta{
                    Name:      podName,
                    Namespace: req.Namespace,
                },
            }
            if err := r.Delete(ctx, pod); err != nil {
                return ctrl.Result{}, err
            }
        }
    }

    return ctrl.Result{}, nil
}

Benefits of Using Kubernetes Operators

Kubernetes Operators, built on CRDs and custom controllers, provide several benefits for managing stateful applications:

Automation: Operators automate routine tasks such as scaling, backups, and failover, reducing the operational burden on administrators.

Consistency: By encapsulating best practices and operational knowledge, Operators ensure that applications are managed consistently and reliably.

Extensibility: Operators can be extended to support custom requirements and integrate with other tools and systems.

Conclusion

Although Kubernetes is not a database in and of itself, it offers a strong framework for installing and administering database applications. A strong addition to the Kubernetes API, bespoke Resource Definitions (CRDs) allow users to design and manage bespoke resources that are suited to their particular requirements.

You may build Kubernetes Operators that automate the administration of intricate stateful applications, such as databases, by utilizing CRDs and custom controllers. This method offers more flexibility and customization, improves consistency, and streamlines processes.

This article has covered the foundations of CRDs, shown comprehensive code examples, and shown how stateful applications may be efficiently managed with CRDs. To fully utilize Kubernetes, you must comprehend and make use of CRDs, regardless of whether you are implementing databases or other sophisticated services on this potent orchestration platform.

As Kubernetes develops further, its adaptability to a variety of use cases and needs is ensured by its expansion through CRDs and Operators. Keep investigating and experimenting with these functionalities as you progress with Kubernetes to open up new avenues for your infrastructure and apps.

以上是Kubernetes 作为数据库?关于 CRD 您需要了解的内容的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn