轻松集成系列一:如何向 KubeBlocks 添加新的数据库类型?以 Oracle MySQL 为例

KubeBlocks 可以帮助您轻松地管理各种不同类型的数据库,那么如何将一个数据库引擎添加到 KubeBlocks 呢?从这个系列开始,我们将会讲解如何通过几个非常简单的操作,把一个数据库引擎当作 KubeBlocks Add-on 添加到 KubeBlocks 进行管理。本文作为这个 Add-on 教程系列的第一篇,将以 Oracle MySQL 为例,介绍如何添加你的第一个 Add-on(点击参考完整 PR)。

Prerequisites

这个操作需要您:

  1. 会写点 Yaml (例如知道 Yaml 的缩进得几个空格)
  2. 懂点 Helm (例如 Helm 是干嘛的,Helm chart 又是什么)
  3. 玩过 K8s (例如知道有 Pod 这个东西,在 K8s 上用 Helm 装过 operator)
  4. 了解 KubeBlocks 的几个常见概念:ClusterDefinition、ClusterVersion、Cluster

Overview

本文主要介绍如何通过 KubeBlocks add-on 能力快速接入你的引擎。整个接入过程分成 3 大步:

  1. 规划集群蓝图
  2. 准备集群模板
  3. 添加 addon.yaml 文件

1. 规划集群蓝图

💡集群形态:部署一个 MySQL 8.0 单节点集群

在开始之前,我们必须先有一个集群蓝图,知道我们想要什么,想要的集群长什么样:

  1. 集群包含哪些组件
  2. 每个组件是什么形态
    a.有状态/无状态
    b.单节点/多节点

在本文中,我们要部署的集群只包含一个组件,该组件是有状态,且只有一个节点。

按照 ClusterDefinition、ClusterVersion 和 Cluster 分类,我们整理下需要的信息,如 Table 1. 所示:

Table 1. Blueprint for Oracle MySQL Cluster

名词规划
ClusterDefinition启动脚本:默认 配置文件:默认 服务端口:3306 Component 个数:1,即 MySQL
ClusterVersionImage: docker.io/mysql:8.0.34
Cluster.yaml由用户创建时指定。

2. 准备集群模板

2.1 创建 Helm chart

有两种方式可以创建 Helm chart:

Opt 1. helm create oracle-mysql

Opt 2. 直接创建一个文件夹 mkdir oracle-mysql

其主要包含以下文件内容:

> tree oracle-mysql
.
├── Chart.yaml        #  A YAML file containing information about the chart
├── templates         # A directory of templates that, when combined with values, will generate valid Kubernetes manifest files.
│   ├── NOTES.txt     # OPTIONAL: A plain text file containing short usage notes
│   ├── _helpers.tpl  # A place to put template helpers that you can re-use throughout the chart
│   ├── clusterdefinition.yaml  
│   └── clusterversion.yaml
└── values.yaml       # The default configuration values for this chart

2 directories, 6 files

(关于 Helm chart 中每个文件的作用不在此展开,可参考文档。)

我们这里着重分析template下的 Yaml 文件。

templates 目录下只有两个 Yaml 文件 clusterDefintion.yamlclusterVersion.yaml。前者描述组件拓扑,后者描述组件版本信息。

2.2 ClusterDefinition

看上去很长,接下来我们说明下各个字段的用途。

ConnectionCredential
  connectionCredential:
    username: root
    password: "$(RANDOM_PASSWD)"
    endpoint: "$(SVC_FQDN):$(SVC_PORT_mysql)"
    host: "$(SVC_FQDN)"
    port: "$(SVC_PORT_mysql)"

会创建一个 secret,其命名规则为 {clusterName}-conn-credential。它主要在其他服务访问该集群时使用,包含用户名、密码、endpoint、port 等常规信息。 (这个 secret 会先于其他资源创建,因此我们可以在其他地方引用该对象。)

$(RANDOM_PASSWD) 创建时会替换为一个随机密码。

$(SVC_PORT_mysql) 其中 mysql 为端口名,通过选择端口名来指定要暴露的端口号。这里为mysql

更多关于环境变量的说明,参看 KubeBlocks 环境变量指南

ComponentDefs
  componentDefs:
    - name: mysql-compdef       
      characterType: mysql      
      workloadType: Stateful
      service:
        ports:
          - name: mysql
            port: 3306
            targetPort: mysql
      podSpec:
        containers:
        ...       

componentDefs,即组件定义(Component Definitions),它定义了每个组件运行所需的基本信息,包括启动脚本、配置、端口等等。

这里我们只有一个 MySQL 组件。为了方便区分,我们把它命名为:mysql-compdef,表示这是 MySQL 的一个组件定义。

name [必选]

组件名称,没有特定标准,选择一个易区分有表达力的名称就行。

如果我们将拓扑、版本、和资源解耦 (就像数据库中的 table normalize), 不仅可以让每一个对象描述的信息都更清晰和聚焦, 而且还可以通过这些对象的组合来生成更丰富的集群。

因此,我们可以将 Cluster 表示为:

C l u s t e r = C l u s t e r D e f i n i t i o n . y a m l ⋈ C l u s t e r V e r s i o n . y a m l ⋈ . . . Cluster = ClusterDefinition.yaml \Join ClusterVersion.yaml \Join ... Cluster=ClusterDefinition.yamlClusterVersion.yaml...

这个 name 就是那个 join key。

记住这个 name,后面要考的。

characterType [可选]

characterType 是一个字符串类型,用来识别这是一个什么引擎,例如mysqlpostgresqlredis是预定义的几种引擎类型。主要用于数据库连接,数据库操作时,能快速识别引擎类型,找到匹配的操作命令。

这可以是一个任意字符串,你也可以给你的引擎一个独特的名称。前期我们没有数据库引擎相关的操作,可以空缺。

workloadType [必选]

顾名思义就是 Workload 类型。K8s 提供了几个基础款:Deployment,StatefulSet 等。

Kubeblocks 在这基础上做了抽象并提供了更丰富的 Workload。比如:

  • Stateless,无状态服务
  • Stateful,有状态服务
  • Consensus,有状态服务,且有自选举能力,有角色

更深入的 Workload 介绍我们之后会单独介绍 (包括设计、实现、如何使用等)。

因为我们这里使用的是单节点的 MySQL,因此使用Stateful就足够了。

service [可选]
      service:
        ports:
          - name: mysql  # 端口名 mysql,connectionCredential 会查找这个名称找到对应的 port
            port: 3306
            targetPort: mysql

定义如何为该组件创建一个 Service,暴露哪些端口。

还记得 connectionCredential 中介绍的,集群对外暴露的 port 和 endpoint 吗?
通过 $(SVC_PORT_mysql)$ 来选择端口, mysql就是这里的 service.ports[0].namemysql。

⚠️ 注意:如果 connectionCredential 中填写了端口名,必须确保端口名有出现在这里。

podSpec

podSpec 的定义和 Kubernetes 的 podSpec 相同。

      podSpec:
        containers:
          - name: mysql-container
            imagePullPolicy: IfNotPresent
            volumeMounts:
              - mountPath: /var/lib/mysql
                name: data
            ports:
              - containerPort: 3306
                name: mysql
            env:
              - name: MYSQL_ROOT_HOST
                value: {{ .Values.auth.rootHost | default "%" | quote }}
              - name: MYSQL_ROOT_USER
                valueFrom:
                  secretKeyRef:
                    name: $(CONN_CREDENTIAL_SECRET_NAME)
                    key: username
              - name: MYSQL_ROOT_PASSWORD
                valueFrom:
                  secretKeyRef:
                    name: $(CONN_CREDENTIAL_SECRET_NAME)
                    key: password

我们这里定义了只包含一个 container 的 Pod,即 mysql-container,以及所需的环境变量、端口等常规信息。

有一点需要指出的是:$(CONN_CREDENTIAL_SECRET_NAME)是一个 placeholder,用来指代我们前文中提到的 Connection credential Secret。

我们从名为 $(CONN_CREDENTIAL_SECRET_NAME)的 secret 中获取用户名和密码作为 pod environment variable。

2.3 ClusterVersion

所有版本相关的信息都配置在 ClusterVersion.yaml 中。

我们需要为每一个 Component 需要的每一个 container 补充 image 信息。

  clusterDefinitionRef: oracle-mysql
  componentVersions:
  - componentDefRef: mysql-compdef
    versionsContext:
      containers:
      - name: mysql-container
        image: {{ .Values.image.registry | default "docker.io" }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}
        imagePullPolicy: {{ default .Values.image.pullPolicy "IfNotPresent" }}

还记得我们在 ClusterDefinition 中采用的 ComponentDef Name 吗?对,mysql-compdef

我们在这里填写该组件的每一个 container 的 image 信息。

💡写好了 ClusterDefinition 和 ClusterVersion,我们可以快速测试一下,在本地安装一下试试。

2.4 安装 Helm chart

Helm Install
helm install oracle-mysql ./path-to-your-helm-chart/oracle-mysql

成功安装后,可以看到如下信息:

NAME: oracle-mysql
LAST DEPLOYED: Wed Aug  2 20:50:33 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

2.5 创建集群

通过kbcli cluster create,就可以快速拉起一个 MySQL Cluster。

kbcli cluster create mycluster --cluster-definition oracle-mysql
Info: --cluster-version is not specified, ClusterVersion oracle-mysql-8.0.34 is applied by default
Cluster mycluster created

通过--cluster-definition 指定你的 ClusterDefinition 名字即可。

💡因为只有一个 ClusterVersion 对象关联该 ClusterDefinition。若未指定,kbcli在创建集群时,会使用该 ClusterVersion。

💡如果有多个 ClusterVersion 对象该关联 ClusterDefinition,则需要显式指定。

然后你就可以:

A. 查看集群状态

kbcli cluster list mycluster
NAME        NAMESPACE   CLUSTER-DEFINITION   VERSION               TERMINATION-POLICY   STATUS    CREATED-TIME
mycluster   default     oracle-mysql         oracle-mysql-8.0.34   Delete               Running   Aug 02,2023 20:52 UTC+0800

B. 连接集群

kbcli cluster connect mycluster
Connect to instance mycluster-mysql-compdef-0
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.34 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

C. 简单运维,例如 Scale-Up

kbcli cluster vscale mycluster --components mysql-compdef --cpu='2' --memory=2Gi

D. 简单运维,例如 Stop

Stop时会释放所有计算资源。

kbcli cluster stop mycluster

3. 添加 addon.yaml 文件

还有最后一步,你就可以通过 KubeBlocks 平台发布你的数据库集群,让更多的用户快速创建你定义的集群。

那就是添加一个 add-on 文件,成为 KubeBlocks add-on 的一员。

参考 tutorial-1-create-an-addon/oracle-mysql-addon.yaml

apiVersion: extensions.kubeblocks.io/v1alpha1
kind: Addon
metadata:
  name: tutorial-mysql
spec:
  description: 'MySQL is a widely used, open-source....'
  type: Helm
  helm:                                     
    chartsImage: registry-of-your-helm-chart
  installable:
    autoInstall: false
    
  defaultInstallValues:
    - enabled: true

我们通过 chartsImage 来配置你的 Helm chart 远端仓库地址。

4. 发布到 KubeBlocks 社区 (可选)

你可以将 Helm chart 和 addon.yaml 贡献到 KubeBlocks 社区

  • 你的 Helm chart:放在 kubeblocks/deploy 目录下。
  • 你的 addon.yaml:放在 kubeblocks/deploy/helm/templates/addons 目录下。

总结

本文以 Oracle MySQL 为例,介绍如何创建你的 add-on,并且发布到 KubeBlocks 社区。

通过简单的配置,你就可以快速创建一个 MySQL 单节点集群,并进行简单的运维。

Appendix

A.1 如何为同一个引擎配置多个版本?

我们在日常生产环境中碰到的一个常见问题就是:要支持多个版本。而在 KubeBlocks 中可以通过多个 ClusterVersion 关联同一个 ClusterDefinition 的方式来解决这个问题。

以本文中的 MySQL 为例。

1. 修改 ClusterVersion.yaml 文件,支持多个版本
apiVersion: apps.kubeblocks.io/v1alpha1
kind: ClusterVersion
metadata:
  name: oracle-mysql-8.0.32
spec:
  clusterDefinitionRef: oracle-mysql   ## 关联同一个 clusterdefinition: oracle-mysql
  componentVersions:
  - componentDefRef: mysql-compdef
    versionsContext:
      containers:
        - name: mysql-container
          image: <image-of-mysql-8.0.32>  ## 镜像地址为 8.0.32
---
apiVersion: apps.kubeblocks.io/v1alpha1
kind: ClusterVersion
metadata:
  name: oracle-mysql-8.0.18
spec:
  clusterDefinitionRef: oracle-mysql  ## 关联同一个 clusterdefinition: oracle-mysql
  componentVersions:
  - componentDefRef: mysql-compdef
    versionsContext:
      containers:
        - name: mysql-container
          image: <image-of-mysql-8.0.18> ## 镜像地址为 8.0.18
2. 创建 Cluster 时,指定版本信息
  • 创建一个 8.0.32 版本的集群
kbcli cluster create mycluster --cluster-definition oracle-mysql --cluster-version oracle-mysql-8.0.32
  • 创建一个 8.0.18 版本的集群
kbcli cluster create mycluster --cluster-definition oracle-mysql --cluster-version oracle-mysql-8.0.18

这样就可以快速为你的引擎实现多版本支持了。

A.2 kbcli 创建 Cluster 不能满足需求?

kbcli提供了一套便捷且通用的方案来创建集群。创建时会设置一些值,例如资源大小。但这并不能满足每个引擎的需求,尤其是当的集群包含多个组件,且需要选择性使用时。

你可以再用一个 Helm chart 来渲染 Cluster,或者通过 cluster.yaml文件来创建,例如:

piVersion: apps.kubeblocks.io/v1alpha1
kind: Cluster
metadata:
  name: mycluster
  namespace: default
spec:
  clusterDefinitionRef: oracle-mysql        # 指定 ClusterDefinition
  clusterVersionRef: oracle-mysql-8.0.32    # 指定 ClusterVersion
  componentSpecs:                           # 开始枚举要用的组件
  - componentDefRef: mysql-compdef          # 第一个组件,它的组件类型为:mysql-compdef
    name: mysql-comp                        # 第一个组件,名为 mysql-comp
    replicas: 1 
    resources:                              # 指定 cpu 和 memory 大小
      limits:
        cpu: "1"
        memory: 1Gi
      requests:
        cpu: "1"
        memory: 1Gi
    volumeClaimTemplates:                   # 设置 PVC 信息,这里的 name 必须和 ComponentDef 中的对应
    - name: data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 20Gi
  terminationPolicy: Delete

往期推荐

只需三步,就可以在 KubeBlocks 上集成和使用 NebulaGraph 集群啦!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值