Skip to main content

数据库是否适合容器化部署

· 5 min read
Czasg

随着 Kubernetes 的流行,越来越来的应用被打包成镜像,作为容器部署在 k8s 上。

在 k8s 中,pod 是最小的部署单位,内部可以包含多个容器镜像,每一个 pod 都具有有限的生命周期。
对于无状态服务来说,特别适合在 k8s 上运行,因为无状态服务,是具有弹性的,可以更好的应对 pod 扩缩容、重启等特性。
相反,对于有状态服务(类似数据库等),则存在一定的瓶颈限制。

先来看下 k8s 如何部署有状态服务,然后讨论下其优缺点。

DaemonSet & StatefulSet

DaemonSet 是 k8s 的控制器资源对象之一,其特点是:

1、确保每个节点仅启动一个 pod 副本,当有新节点加入集群时,自动为其增加一个 pod。

比较典型的是日志收集服务,比如:我们需要确保每个节点上起一个 logstash,以便回收节点上的服务日志。

数据库服务可以在类似场景下使用,比如给某个节点打上标签,确保某个数据库在对应节点上以 DaemonSet 类型启动,这样就可以确保该节点仅有一个 pod 副本。 最后通过 nodeport 的方式对外提供服务。 此时我们的数据库就拥有了稳定的节点 ip 和本地存储。

但是这种方式,和直接在物理机上部署的方式差别不大,主要是复用了 k8s 的管理能力。


StatefulSet 是 k8s 专为有状态服务设计的资源类型,它拥有:

1、稳定的网络标识:当服务重启,pod 绑定的 ip 不会变化,但是手动删除或者重建副本时,会重新分配 ip。 创建 headless service 时可以通过 ${serviceName-number}.${service}.${namespace} 访问指定 pod。
2、稳定的持久存储:基于 pvc 实现,每个 pod 会绑定专有的 pvc 存储。
3、有序的扩缩容:会安装顺序从 0 逐一启动或者重建,此时类似滚动更新的扩容策略不在适用。

当我们的数据库服务部署 k8s 上时,可以选择 StatefulSet 资源类型。
它的基本能力,足够支持一个有状态服务的正常运转。

性能瓶颈

数据库主要是和存储打交道,其性能瓶颈通常在磁盘IO。
那么快速的磁盘IO,将有助于提升数据库的性能和吞吐量。
比如:分别部署在 HDD 和 SSD 上的两个数据库,在相同其他条件下,SSD 上的数据库肯定拥有更高的性能。

当我们的数据库部署在 k8s 上时,可以通过挂载卷 volume(nfs、ceph)持久化数据,但是这样就不可避免的引入了网络IO,在本身的瓶颈上又补一刀。
所以当我们使用 k8s 部署数据库时,可能需要重点考虑下性能问题。

除了 nfs、ceph 之外,还有 hostpath 这类本地存储,可以忽略网络影响。 但是这需要我们的副本绑定到固定的节点上,此时就走的类似 DaemonSet 的部署路线了。


👇👇👇

本文作者: Czasg
版权声明: 转载请注明出处哦~👮‍