当前位置: 首页 > news >正文

KubeBlocks for Oracle 容器化之路

KubeBlocks for Oracle 容器化之路

引言

Oracle Data Guard

Oracle Data Guard (简称DG) 是Oracle提供的一种高可用性和灾难恢复解决方案。它提供一整套服务,用于维护、管理和监控一个或多个备用数据库,使Oracle数据库能够抵御灾难和数据损坏。DG将这些备用数据库作为生产数据库的副本进行维护。当生产数据库因计划内或计划外中断而不可用时,DG可将任一备用数据库切换至生产角色,从而最大限度地减少中断导致的停机时间。

KubeBlocks

KubeBlocks是一款支持多引擎管理的开源Operator,通过统一的代码和API集成在K8s上运行并管理多种数据库引擎,只需编写KubeBlocks的Addon即可为其添加新引擎。KubeBlocks的核心是一个K8s Operator,定义了一组CR来抽象各类数据库引擎的通用属性,并利用这些抽象来管理引擎的生命周期及日常运维操作。

容器化现状与挑战

Oracle官方在容器化方向已经做出了一些努力,提供了从11g到23ai free版本的镜像,同时还开源了官方的Oracle Database Operator。然而其在K8s上的部署和管理仍然存在一些局限性:

  1. 功能支持不完善:相较于传统物理机环境,Oracle在容器化环境中支持的功能有限,例如备份恢复、日志管理,配置变更、监控告警等功能支持并不完善。
  2. 运维复杂度高:缺乏统一的运维工具和管理界面,使得运维人员需要在多个工具之间切换,大量运维工作需要手动完成,增加了运维的复杂度。
  3. 版本支持有限:目前官方提供的镜像版本有限,且许多Feature都只针对新版本进行开发和测试验证,对仍有大量用户使用的老版本支持不足。

以Oracle 12c版本为例,尽管其在传统环境中的部署和运维已经相当成熟,但迁移到容器化环境中仍需克服诸多问题:

  1. 集群拓扑:DG集群拓扑相对复杂,涉及到Oracle和Observer多个节点之间的通信和数据同步,这在容器化环境中需要特别注意网络配置和持久化存储。
  2. 多副本管理:DG集群中通常包含一主多备多个数据库副本,副本间的数据同步,启动顺序,角色切换等各个环节都会影响集群的正常服务,在容器化环境中需要确保这些副本能够正确运行至关重要。
  3. 配置管理:传统环境中,Oracle会通过感知物理机的资源来调整配置,而在容器化环境中,老版本Oracle可能无法感知容器的资源限制,导致配置不合理。
  4. 故障转移:容器化环境中,故障转移的策略和传统环境有所不同,需要确保在容器可能发生故障的各个场景下,能够快速、准确地进行故障转移,保证服务的连续性。

针对上述现状与挑战,本文将依托KubeBlocks提供的能力,展示KubeBlocks如何解决这些使用上的痛点,并探讨Oracle数据库容器化过程中的一些细节,理解KubeBlocks以及Addon的设计思路和实现机制。

部署与运维示例

首先用一个实际操作示例,本文会展示创建一个Oracle 12c DG集群以及一些运维操作的过程,示例集群架构如下:
在这里插入图片描述

注:本文介绍的Oracle Addon基于KubeBlocks v0.9版本的API实现。

创建集群

使用kubectl apply 如下的Cluster yaml即可创建一个一主两备加上两个Observer节点的集群:

kubectl apply -f - <<EOF
apiVersion: apps.kubeblocks.io/v1alpha1
kind: Cluster
metadata:name: my-oraclelabels:helm.sh/chart: oracle-cluster-0.9.0app.kubernetes.io/name: oracle-clusterapp.kubernetes.io/instance: my-oracleapp.kubernetes.io/version: "12.2.0.1"app.kubernetes.io/managed-by: Helm
spec:clusterDefinitionRef: oracleterminationPolicy: Deletetopology: replicationaffinity:podAntiAffinity: PreferredtopologyKeys:- kubernetes.io/hostnametenancy: SharedNodecomponentSpecs:- name: oraclereplicas: 3componentDef: oracle-12cmonitor: truedisableExporter: falseserviceVersion: 12.2.0resources:limits:cpu: "2"memory: "4Gi"requests:cpu: "1"memory: "1Gi"volumeClaimTemplates:- name: dataspec:accessModes:- ReadWriteOnceresources:requests:storage: 20Gi- name: fraspec:accessModes:- ReadWriteOnceresources:requests:storage: 10Gi- name: observerreplicas: 2componentDef: oracle-observer-12cserviceVersion: 12.2.0resources:limits:cpu: "1"memory: "1Gi"requests:cpu: "0.5"memory: "0.5Gi"
EOF

可以看到上述Cluster中,指定了这个集群的组成部分以及一些相关定义,相信即使是之前没有了解过KubeBlocks的读者也能通过API字面表述对创建的这个集群的有一个较为直观的印象(后文会对部分关键API字段做出详细解析)。在应用后一个完整的Oracle 12c DG集群就被创建出来了,查看集群和 pod 的状态:
在这里插入图片描述
在这里插入图片描述

可以发现,observer相关的pod没有角色,而oracle相关的pod被设置成primary或者secondary。角色在KubeBlocks管理的有状态集群中非常重要,其不仅代表数据库实例之间的复制关系,也代表着KubeBlocks对这种关系的一种抽象,这种关系会直接影响KubeBlocks在各类运维操作中的行为预期。

配置变更

使用sqlplus查看Oracle参数open_cursors,发现值为300

在这里插入图片描述

使用kubectl apply应用如下OpsRequest的yaml:

kubectl apply -f - <<EOF
apiVersion: apps.kubeblocks.io/v1alpha1
kind: OpsRequest
metadata:name: my-oracle-reconfiguringnamespace: default
spec:clusterName: my-oracleforce: falsereconfigure:componentName: oracleconfigurations:- keys:- key: init.oraparameters:- key: open_cursorsvalue: '301'name: oracle-configpreConditionDeadlineSeconds: 0type: Reconfiguring
EOF

再次查看参数open_cursors,发现值成功改为301

在这里插入图片描述

Fast-Start Failover

Oracle的Fast-Start Failover特性允许在主库故障的情况下自动故障转移到备库,以便快速可靠地恢复业务。通过删除 pod 模拟节点故障,查看Oracle备节点是否自动提升为主节点。例如删除当前主节点 my-oracle-oracle-0,几秒后,my-oracle-oracle-1角色变为 primay,而my-oracle-oracle-0以secondary的角色重新加入集群。

在这里插入图片描述

在这个过程中,KubeBlocks会持续保持对Oracle的角色探测,以保证服务集群状态快速恢复并正常对外服务。

除此之外,KubeBlocks还为支持的数据库借助Chaos Mesh设计多种不同的异常场景,以验证数据库的高可用性,具体可参见:通过 Chaos Mesh 验证 KubeBlocks Addon 可用性的实践。

备份恢复

备份是保障数据的关键。在KubeBlocks中,通过预先定义的备份方法,只需应用如下yaml,即可创建一个全量备份:

kubectl apply -f - <<EOF
apiVersion: dataprotection.kubeblocks.io/v1alpha1
kind: Backup
metadata:name: my-oracle-cluster-backup
spec:backupMethod: oracle-rmanbackupPolicyName: my-oracle-oracle-backup-policydeletionPolicy: Delete
EOF

这将会调用Oracle的rman工具对当前集群进行全量备份,并将得到的备份上传到指定的存储中。

查看备份如下:

在这里插入图片描述

得到这个完整的备份后,可基于该备份恢复一个全新的集群,同样只需一个简单的yaml:

kubectl apply -f - <<EOF
apiVersion: apps.kubeblocks.io/v1alpha1
kind: OpsRequest
metadata:name: my-oracle-cluster-restore
spec:clusterName: my-oracle-restoredforce: falserestore:backupName: my-oracle-cluster-backupbackupNamespace: defaulttype: Restore
EOF

查看恢复集群的状态:

在这里插入图片描述

这样就可以完成备份恢复操作,同时还可以定义备份的频率,时间等策略。

其他运维操作

接入KubeBlocks 后,Oracle Addon还天然支持了很多其他的运维操作。除上述介绍的自动故障转移、配置变更和备份恢复之外,还支持以下运维操作:

  • Observer水平扩容,可以增加或减少Observer节点的数量
  • 垂直扩容
  • 存储扩容
  • 手动主备切换(switchover)
  • 集群重启、停止和删除
  • 小版本升级
  • 监控(配置 Prometheus exporter 采集指标)

Oracle Addon实现

这样一个完整的Addon是如何实现的呢?下面将会详细介绍部分API,帮助理解原理以及设计思路,读者可以结合这部分与运维示例一起阅读,更详细的API解读可以直接查看 KubeBlocks源码中的API注释部分。

KubeBlocks与Addon机制

KubeBlocks通过Addon机制,可以方便地扩展其功能,支持多种数据库和中间件。详细文档可以参考:KubeBlocks Addon文档

Oracle Addon

KubeBlocks提供了一组抽象的API,用于定义和管理数据库实例。Oracle Addon则是基于这些API,为Oracle DG集群提供了一套完整的解决方案。

集群管理

Oracle Addon主要通过3个CR来定义集群纬度的生命周期管理和运维:

  • ComponentDefinition:简称CMPD,用于定义数据库集群中一个基本组成部分。在KubeBlocks管理的数据库集群中,通常会把集群中的各个基本组件称为Component。例如在Oracle DG集群中,就可以分为Oracle和Observer两个基本组件,因此需要借助两个CMPD来定义这两个组件。
  • ComponentVersion:简称CMPV,用于定义Component的具体版本,例如Oracle-12c和Oracle-19c等。
  • ClusterDefinition:简称CD,用于定义数据库集群的拓扑结构和组件之间的关系。比如在Oracle DG集群中,单机集群只需要Oracle一个组件,而主备集群则需要Oracle和Observer两个组件,因此需要借助CD来定义集群的拓扑结构。

在上述3个CR中,最重要也是最复杂的CR是CMPD,就像使用乐高积木搭建模型一样,只要有了基本的积木(Component),就可以搭建出各种复杂的模型(Cluster)。

Oracle的CMPD主要包括以下几个部分:

  • roles:定义了Oracle的角色,例如主库(Primary)和备库(Secondary)以及角色对应的读写能力。
  • service:定义了Oracle的对外提供服务的方式,可以通过roles区分只读服务和读写服务,实现读写分离。
  • systemAccounts:定义了Oracle的系统账户和初始密码,在systemAccounts中,可以自定义密码的生成策略,包括长度,复杂度等,Kubeblocks会将生成的账号密码存入到Secret中,供Oracle引用。
  • scripts:指定脚本的 ConfigMap,KubeBlocks 会将其挂载到容器中的指定目录。
  • vars: 用于引用一些跟实例相关的动态资源和信息,例如systemAccounts中定义的账号ORACLE_SYS_USER,密码ORACLE_SYS_PASSWORD,以及整个集群中Oracle所有副本的连接串ALL_ORACLE_FQDN。基于上述vars,就可以完成Oracle的TNS以及监听器等相关配置。
  • lifecycleActions:定义一些生命周期管理相关的动作,Oracle 实现了三个 Action:
    • roleProbe:用于探测副本角色
    • postProvision:用于在实例初始化完成后执行一些自定义脚本,例如Oracle主备实例都创建完成以后执行DG Broker的配置。
    • switchover:用于执行主备切换操作。
  • runtime:定义容器运行时相关的配置,包括三个容器:
    • oracle-init-container:完成Oracle的数据目录的权限设置
    • oracle:Oracle 服务运行容器
    • exporter:用于采集数据库的监控指标

除上述显式定义的容器外,KubeBlocks还会为每个Pod注入两个sidecar容器,即lorry:用于执行roleProbe等部分lifecycleActions;config-manager:用于管理配置文件和执行配置变更。

在完成上述核心配置以及一些相关配置后,一个完整的Oracle组件就定义完成了。对于Observer组件,同样按照上述方式定义即可。在两个组件都定义完成后,就可以通过CD完成整个集群的完整拓扑。

DG配置

在Oracle Addon中如何完成DG集群中主备节点间的配置呢。其中,节点自身初始化相关的逻辑都在Oracle的启动脚本中完成。一开始会先根据集群的规格,配置等信息执行一些通用的初始化操作,例如调整根据实例规格调整内核参数,设置监听,配置TNS等。接着会根据节点的角色执行不同的操作: 如果是主节点,会使用DBCA工具创建数据库,而如果是备节点,则会使用RMAN工具从主节点恢复数据库。

在主备节点都设置完成后,则会依托前文提到的postProvision这个lifecycleAction来完成主备节点间的DG Broker配置,创建并启用DG Broker的Configuration,此时Oracle这个Component就已经搭建完成了。

最后KubeBlocks会根据在CD中配置的Order创建Observer这个Component,为集群配置Fast-Start Failover(FSFO),整个集群才算创建完成。

此时集群就具备了高可用性,当主节点发生故障时,Observer会发现异常并触发Failover,将备节点提升为主节点,从而保证业务的连续性。

参数配置

KubeBlocks 为了方便对各种数据库的参数进行管理,定义了参数配置相关的API:

  • 参数模板:定义一个参数模板, 这个模板中可以定义具体的参数数值,也可以根据Go Template和KubeBlocks提供的内置函数配置参数的计算规则,从而根据实例规格动态计算出最适合的参数值,
  • ConfigConstraint:即参数的约束,参数的约束主要包含三部分:
    • 支持的配置文件格式:例如 yaml, toml, ini 等。
    • 参数的类型和取值范围: KubeBlocks使用CUE文件来描述参数的类型和取值范围。
    • 参数的生效范围:参数可以被划分为动态参数、静态参数和不可变参数。动态参数可以被修改并立即生效,静态参数需要重启实例才能生效,不可变参数一旦设置就不能被修改。

Oracle主要使用pfile和spfile来配置数据库参数,为了方便用户进行配置,Oracle Addon将pfile中的部分参数设置到KubeBlocks的参数模板中,在实例启动后,会根据这个动态渲染出的pfile再生成spfile。

备份恢复

备份恢复是数据库运维中的重要环节,KubeBlocks为各种数据库提供了灵活的备份相关API以实现不同的备份恢复机制,包括全量备份、增量备份、基于时间点恢复等。Addon只需实现以下两个API:

  • BackupPolicyTemplate:即备份策略的模板,用于定义指定组件的备份策略,创建数据库集群时会根据该模板生成集群的备份策略。包括备份方法,默认备份调度周期,默认的备份目标。
  • ActionSet:定义不同数据库使用的具体备份方法,可以在这个API中实现实际的备份行为。

以Oracle Addon中实现的全量备份为例,定义了一个名为oracle-rman的ActionSet,该ActionSet的backupType为Full,表示这是一个全量备份。接着定义了一个名为oracle-backup-policy-template的BackupPolicyTemplate,该模板指定了使用oracle-rman ActionSet进行全量备份,并通过Cron表达式设置了默认的备份调度周期。借助这些定义,KubeBlocks能够自动化地执行备份,并将这些备份上传到指定的存储位置,这些目的存储位置可以是本地存储,也可以是云存储服务,如AWS S3等。

总结展望

在K8s环境中想要稳定高效地运行Oracle集群不是一件简单的事,但是KubeBlocks为其提供了一条见解且行之有效的路径。本文详细介绍了基于KubeBlocks这个Operator支持Oracle Addon的细节,并介绍了其支持的功能和优势,目前,KubBlocks for Oracle 已经上线 KubeBlocks 企业版,欢迎感兴趣的读者申请体验。

之后我们会持续优化迭代KubBlocks for Oracle,以支持更多功能并提升稳定性,同时还会增加支持的Oracle版本,使KubBlocks for Oracle成为更多企业级用户的不二之选。

http://www.dtcms.com/a/351712.html

相关文章:

  • 高校党建系统设计与实现(代码+数据库+LW)
  • 从零开始的 Docker 之旅
  • HIVE的高频面试UDTF函数
  • 【软考论文】论面向对象建模方法(动态、静态)
  • 无人机倾斜摄影农田航线规划
  • HTML应用指南:利用GET请求获取中国银行人民币存款利率数据
  • SciPy科学计算与应用:SciPy线性代数模块入门-矩阵运算与应用
  • 精确位置定位,AR交互助力高效作业流程​
  • 余承东:鸿蒙智行累计交付突破90万辆
  • 机器人视频感知架构深度解析:7条技术法则,打造低延迟实时感知与交互
  • 【ROS2】 忽略局域网多机通信导致数据接收的bug
  • 天气查询小程序项目报告
  • iOS 审核 4.3a【二进制加固】
  • Spring MVC 全解析:从核心原理到 SSM 整合实战 (附完整源码)
  • leetcode-python-383赎金信
  • 深度学习----由手写数字识别案例来认识PyTorch框架
  • 构建AI智能体:十四、从“计算”到“洞察”:AI大模型如何让时间序列数据“开口说话”
  • version GLIBCXX_3.4.30‘ not found (required by cmake)
  • JVM线上调优参数配置指南
  • 今日分享:C++ string 类模拟实现
  • 深度学习之第四课卷积神经网络CNN(一)
  • 不卡顿、不掉线!稳定可靠的体育赛事直播系统源码解析
  • 【Chrome】更新后白屏无法显示问题
  • 【力扣】面试经典150题总结04-区间/栈
  • python 自学笔记13 numpy数组规整
  • 智能驾驶机器学习知识总结
  • 越过千万生死线,鸿蒙直面商业化考验
  • ME_INFORECORD_MAINTAIN_MULTI,创建采购单信息记录,报错ME 816 系统错误(方法PROCESS_CONDITION中错误)
  • Feign 调用为服务报 `HardCodedTarget(type=xxxClient, name=xxxfile, url=http://file)`异常
  • 关于C#中运算符的简单说明