写点什么

如何在 Kubernetes 上运行数据库服务?

  • 2019-12-11
  • 本文字数:3079 字

    阅读完需:约 10 分钟

如何在 Kubernetes 上运行数据库服务?

导读: Kubernetes 已经成为了集群调度领域最炙手可热的开源项目之一。用 Kubernetes 来部署和管理 Web 应用、移动后端和 API 服务等相对容易,因为这些应用通常都是无状态应用,通过基本的 Kubernetes API 就能运行,可以在没有其他知识的情况下进行扩展并从故障中恢复。但要是用 Kubernetes 来运行有状态应用呢?比如数据库、缓存和监控系统。这就为我们带来了不小的挑战。因为这些系统需要应用领域的知识才能正确扩展、升级和重新配置,从而防止数据丢失或不可用。Leonid Mirsky 为我们阐述了如何在 Kubernetes 部署和管理有状态应用,本文以在 Kubernetes 上运行数据库为例讲解。


你在网上所能找到的许多 Kubernetes 示例,大都集中于运行无状态应用。


通常,这些都是标准的 NodeJS Express 应用或用 Flask 编写的基于 Python 的 API。


现在,在 Kubernetes 上运行这些类型的应用相对比较容易了。你拥有大规模管理和运营它们所需的一切:滚动部署、入口控制器、终止超时控制,等等。


但是,如果运行一个有状态应用,它偶尔需要在磁盘上写入数据,并确保这些数据在容器重启之间,或容器重新调度到另一个节点时仍然保持不变,又该如何做呢?


这就是事情没有那么简单的地方。幸运的是,Kubernetes 及其充满活力的社区,为如何运行这些有状态的工作负载提供了许多选择。


我们将更深入研究这些选择,但你可能会问以下这些问题……

为何在 Kubernetes 上部署有状态应用比较困难?

我们能不能在 Pod 模板上附加一个卷?这难道还不够吗?从理论上讲,你的应用现在就可以写入磁盘,但如果容器重启或移动到另一个节点的话,那么这个卷将会被重新附加到容器的新位置。


对于简单的案例来说,确实如此。但是对于 Elasticsearch、etcd、Consul 等服务来说,情况就要复杂得多了。


这些服务有一些常规 Kubernetes 部署控制器无法满足的要求。


例如,你可能需要为每个 Pod 提供可预测的 DNS 名称,以便使初始集群形成更加容易。或者,你部署的系统,可能需要确保 Pod 将按某种预定义的顺序来启动容器。


此外,你还可能希望为每个 Pod 创建并附加单独的卷,这些卷将在整个 Pod 的生命周期中与其绑定。对于常规 Pod,你只能附加一个卷,这个卷将在同一部署创建的所有 Pod 之间共享。


我们也没有提到如何操作数据库。你还需要确保制定一个计划,确定何时以及如何执行备份,或者在发生错误时如何执行恢复 / 故障转移。

运行有状态应用的可用选项

以下是一些关于如何在 Kubernetes 上部署数据库的几个选项。

1. StatefulSet

StatefulSet,是一个内置的控制器(译者注:原称 PetSet,首次出现在 Kubernetes 1.4,后在 1.5 更名为 StatefulSet),本质上类似于 Kubernetes 的部署。


最终,它将基于你将指定的 Pod 模板创建和管理一组 Pod。


主要区别在于,它为底层应用提供了以下保证:


  • 每个 Pod 都有一个稳定、唯一的网络标识符。

  • 每个 Pod 可能有一个稳定的、持久的存储卷。

  • 部署、扩展或终止都将是有序而优雅地执行。


下面是一些使用 StatefulSet 的开源数据库部署实现的示例:


  1. Kubernetes Elasticsearch Cluster,作者:Paulo Pires

  2. Consul on Kubernetes,作者:Kelsey Hightower


StatefulSet 是通用的,因此你可以使用它们来对数据库的 unique cluster formation 或主 / 从架构进行建模。


然而,最终的结果将在操作方面有所欠缺。你将需要添加其他资源或自动化,以确保能够执行定期备份或添加处理诸如故障转移等边缘情况的脚本。


最终,使用 StatefulSet 为更复杂的有状态服务建模可能会有点笨拙的感觉,并且还不是 Kubernetes 原生的,而且,如上所述,它还将缺乏管理自动化。这就是 Operator 发挥作用之处:


StatefulSet 是 Kubernetes 提供的管理有状态应用的负载管理控制器 API。在 Pod 管理的基础上,保证 Pod 的顺序和一致性。与 Deployment 一样,StatefulSet 也是使用容器的 Spec 来创建 Pod,与之不同 StatefulSet 创建的 Pod 在生命周期中会保持持久的标记(例如 Pod Name)。简单地说,StatefulSet 是一个给 Pod 提供唯一标志的控制器,它可以保证部署和扩展的顺序。

2. Operator

如果你决定在 Kubernetes 上运行数据的原因之一,是为了统一所有应用程序组件的管理,那么 Operator 可能会提供你想要拥有的体验!


与其将应用程序放入 StatefulSet 模型中,不如编写(或者使用其他人的)自定义控制器。


作为用户,这允许你使用 Kubectl CLI 来控制有状态应用,将其作为本地 Kubernetes 资源。例如,如果你部署了 etcd Operator,那么可以使用下面的 kubectl 命令检查集群的备份状态:


kubectl get EtcdBackup example-etcd-cluster
复制代码


与 StatefulSet 相比,Operator 的主要优势在于,它们添加了一个自动化层,该层对于其操作的有状态应用是独有的。你无需担心如何在 Elasticsearch 集群中添加备份 cron,该集群使用 StatefulSet 实现。使用 Operator,你只需指定存储此备份的存储桶即可。


不幸的是,由于编写新的 Operator 除了需要了解有状态应用的细节之外,还需要了解 Kubernetes 及其 API,因此,目前可用的 Operator 并不多,而且现有的 Operator 仍然相对较新。


下面是一些 Operator 的示例,你可以自己测试概念:


  1. Prometheus operator,作者:CoreOS

  2. Elastic Search operator,作者:UPMC Enterprises


译注: Operator 是 CoreOS 推出的旨在简化复杂有状态应用管理的框架,它是一个感知应用状态的控制器,通过扩展 Kubernetes API 来自动创建、管理和配置应用实例。Operator 基于 Third Party Resources (CRD)扩展了新的应用资源,并通过控制器来保证应用处于预期状态。比如 etcd operator 通过下面的三个步骤模拟了管理 etcd 集群的行为:通过 Kubernetes API 观察集群的当前状态;分析当前状态与期望状态的差别;调用 etcd 集群管理 API 或 Kubernetes API 消除这些差别。

3. 其他

本节提到的定义较少,主要是为了说明对于特定的数据库,比如我们稍后将看到的 PostgreSQL 示例,还有其他选项可以将它们作为 Docker 容器在 Kubernetes 上部署和管理。


有时,除了 StatefulSet 或专用的 Operator 实现之外,还有其他可用的选项。


例如,Stolon 是一个“PostgreSQL 高可用性的云原生 PostgreSQL 管理器”,虽然我个人还没有机会使用它,但看到过一些帖子中提到了 Stolon。


要在 Kubernetes 上部署 Stolon,可以使用提供的 StatefulSet 定义。但是,由于 Stolon 的功能,你不需要添加自己的集群管理自动化来控制 PostgreSQL 集群。Stolon 为此提供了自己的 CLI

总结

下面是一棵快速决策树,希望它能够帮助你作出如何在 Kubernetes 上进行最佳部署和维护有状态工作负载的决策:


1.你能自己维护数据库吗?


  • 如果不能,那就忘掉本文,付钱给别人,让他帮你做这件事。

  • 如果能,那么就继续读下去。


2.你是否已经在 Kubernetes 上运行了大部分应用程序?


  • 如果没有,而是以与其他应用程序类似的方式部署数据库。根据你的方便程度,组合使用物理服务器、云实例或虚拟机。

  • 如果是,那么请接着思考以下三个问题:

  • 1). 你能为所选择的数据库找到成熟的 Operator 吗?

  • 2). 你能找到一个像 Stolon(上面提到的)这样的独立项目来使管理变得更容易吗?

  • 3). 你可以找到基于 StatefulSet 的部署吗?它是否“生产准备就绪”?


当涉及到无状态应用程序时,Kubernetes 是一个非常直观的平台。然而,在处理类似数据库的服务时,你需要更多考虑如何在 Kubernetes 上部署和管理它们。好消息和坏消息就是,都有几个选项可供选择。


作者介绍:


Leonid Mirsky,Opsfleet 的创始人,帮助初创企业将现有的基础架构迁移到 Kubernetes。


原文链接:


https://opsfleet.com/running-database-services-on-kubernetes/


2019-12-11 15:292941

评论

发布
暂无评论
发现更多内容

【一Go到底】第六天---值类型、引用类型、标识符

指剑

Go golang 10月月更

【愚公系列】2022年10月 Go教学课程 020-Go容器之数组

愚公搬代码

10月月更

pgsql数据库自动备份

衝鋒壹号

10月月更

Qt|使用QuaZip压缩包中文乱码问题解决

中国好公民st

c++ qt 10月月更

推荐一款id 生成器:Hashids

xiaoxi666

【C语言难点突破】指针的常见易错点

Geek_65222d

10月月更

Android Coder带你了解反射

子不语Any

后端 java; 10月月更

高效编程不一定意味着要疯狂写代码

宇宙之一粟

程序员 10月月更

你不知道的Java工具类库,十倍提升开发效率

一灯架构

Java java面试 10月月更

传统架构面临的挑战及上云的优势

穿过生命散发芬芳

企业上云 10月月更

在Chrome浏览器中最快速实现拾色器(颜色吸管)

茶无味的一天

前端 谷歌浏览器

Vue3入门指北(十)侦听器

Augus

Vue3 10月月更

竟然还有人说ArrayList是2倍扩容,今天带你手撕ArrayList源码

一灯架构

Java java面试 10月月更

学习编程既要追根溯源、又要紧跟时代步伐

玄兴梦影

c 编程 语法

开发者有话说|在刷怪升级的成长路上,技术人应该掌握的三个大招

迷彩

个人成长 10月月更 学会学习 学会提问 学会思考

2022-10-06:以下go语言代码输出什么?A:[1 2 3] [1 2 3] ;B:[1 2 3] [3 4 5]; C:[1 2 3] [3 4 5 6 7 8 9];D:[1 2 3] [3

福大大架构师每日一题

golang 福大大 选择题

【牛客刷题-算法】加精 _ 合并两个有序的链表 - 从思路设计、bug排除到最终实现的全过程

清风莫追

算法 链表 算法数据结构 10月月更

踩上元宇宙的风口后,消费级AR眼镜真的复兴了吗?

脑极体

Go设计模式“金旋风”——代理模式

Regan Yue

Go 设计模式 代理模式 10月月更

【牛客刷题-算法】NC141 判断是否为回文字符串

清风莫追

数据结构 算法 刷题笔记 10月月更

微信业务架构图 & 学生管理系统方案

无语

「架构实战营」

爬虫练习题(二)

张立梵

Python. 10月月更 爬虫案例

【Nacos源码之配置管理 四】DumpService如何将配置文件全部Dump到磁盘中

石臻臻的杂货铺

nacos 10月月更

【结构体内功修炼】结构体实现位段(二)

Albert Edison

C语言 结构体 10月月更 位段

【一Go到底】第七天---运算符

指剑

Go golang 10月月更

单模光缆与多模光缆,网络工程师必知的光缆类型

wljslmz

网络工程 10月月更 单模光纤 多模光纤 弱电

Collections之ArrayList源码解读(七)

知识浅谈

ArrayList 10月月更

一个 ExpressionChangedAfterItHasBeenCheckedError 错误的解决过程

汪子熙

typescript 前端开发 angular web开发 10月月更

【牛客刷题-算法】NC151 最大公约数

清风莫追

数据结构 算法 最大公约数 10月月更

HashMap高阶用法,十倍提升开发效率

一灯架构

Java java面试 10月月更

与学长共话成长,领跑毕业新未来

宇宙之一粟

校招 10月月更

如何在 Kubernetes 上运行数据库服务?_数据库_Leonid Mirsky_InfoQ精选文章