随着 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
版权声明: 转载请注明出处哦~👮