generated from wangchucheng/hugo-eureka-starters
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
姚泰然
committed
Sep 15, 2023
1 parent
85253a3
commit 3dd0f52
Showing
26 changed files
with
2,777 additions
and
316 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
--- | ||
title: StatefulSet使用思路梳理 | ||
description: | ||
toc: true | ||
authors: [“tryao"] | ||
tags: ["k8s"] | ||
categories: [] | ||
series: [] | ||
date: 2023-09-15T14:57:05+08:00 | ||
lastmod: 2023-09-15T14:57:05+08:00 | ||
featuredVideo: | ||
featuredImage: | ||
draft: false | ||
--- | ||
|
||
一般服务都是使用deployment部署,deploy的使用非常简单,无状态,随意调度。但是各种需要持久化数据的中间件都需要使用StatefulSet来部署,这个玩意儿实际上有点复杂。 | ||
|
||
## 最简单的方法:不要使用k8s来部署有状态应用 | ||
|
||
比如在部署kafka集群、MySQL集群时,你会发现直接用docker分别在选定节点部署,是最简单的。和传统的物理机部署并无什么区别,你要做的仅仅是将配置文件和宿主机目录挂载到容器里。 | ||
|
||
如果想要自动化,就写bash脚本,分别在各个主机运行即可,也并没有那么复杂。 | ||
|
||
容器内的服务访问容器外的服务也很简单:直接用网卡的内网ip就行。 | ||
|
||
## 不要太依赖分布式存储 | ||
|
||
第一次接触Ceph或者longhorn的时候,很容易会错误的认为分布式存储本身就可以解决高可用的问题。 | ||
|
||
比如sqlite,将它放在longhorn里,理论上pod在任意节点,都可以访问到这块pv. longhorn自带的多副本策略也可以保证数据不丢失。如果宿主机节点挂掉,k8s自动调度pod到其他结点,原来的pv也依然可用。 | ||
|
||
这一切很美好,但是有两个问题: | ||
|
||
* IO性能会变差; | ||
* **数据可能损坏** | ||
|
||
第一点是显而易见的,毕竟分布式存储是在文件系统的基础上又加了一层,肯定会影响性能。 | ||
|
||
第二点就比较蛋疼了,分布式存储保证文件的高可用是通过类似Dropbox这种文件同步的思路来进行的,**他并不理解文件的内容**,所以文件有可能会损坏是很容易理解的。 | ||
|
||
众所周知,MySQL主从的备份思路是通过binlog同步来增量进行的。当master节点宕机时,可能有一部分变更没来得及同步到slave节点,这就会造成数据**回档**的效果。但是如果是使用longhorn做同步,可能整个database都无法打开,导致数据完全损坏,这种肯定是完全无法接受的。 | ||
|
||
另外,longhorn支持s3/minio/nfs二次备份,这个卷备份可以实现完全备份。当出现宕机等问题时,你可以向前回溯这个备份,总能找到可用的完整数据。当然,这个回档的时间可能有点长。 | ||
|
||
所以,对于MySQL这种数据库,还是使用**应用层自带的副本方案**更靠谱。分布式存储只能用来存放一些不太重要的东西:比如文件之类的。甚至于,这个需求也可以使用minio之类的中间件来解决。可能像日志之类的数据比较适合使用,搞一块RWM的PV,所有应用都往里面写日志,方便集中查看应用日志,而且日志丢了一般影响也不大。 | ||
|
||
当然,如果你是在云端,使用云厂商提供的分布式存储,一般并不需要关心这个问题,我们这里主要还是讨论边缘端这种不稳定的场景。 | ||
|
||
## 利用亲和性来部署StatefulSet | ||
|
||
如果回到应用程序本身的副本方案——比如MySQL主从——那么就需要手动干涉k8s的调度。使其最终和你手动在各个节点部署的结果一致(也就是你自己用docker部署)。 | ||
|
||
首先,主从应当尽量在不同的宿主机上:如果你有两台以上宿主机的话。这个主要通过Pod反亲和性来实现:如果这个节点已经有匹配的Pod,则尽量不要还在这个节点上部署第二个sts. | ||
|
||
其次,利用节点亲和性来选择宿主机:假设你手头的宿主机配置不太一样,那就在高配置的node上加上label,然后在sts的pod上加上节点亲和,选择匹配的标签。 | ||
|
||
利用这两个方法,你可以决定pod最终被调度到哪个节点上。当然至于哪个是主哪个是从,这个仍然是随机的。如果你想保证主在某个节点,从在某个节点,那只能写两个sts,直接指定nodeName。一个sts配置2个replia,是无法实现这种需求的。 | ||
|
||
## 使用LocalPV | ||
|
||
不使用分布式存储,那就只能用LocalPV了。如果使用k3s,使用自带的local-path就行。 | ||
|
||
在sts里面指定VolumeClaimTemplate,k8s会延迟绑定PV直到Pod被调度。 | ||
|
||
对于LocalPV,k8s在调度时就会考虑到Pod和PV必须在同一个节点,这是因为StorageClass的配置里有`volumeBindingMode: WaitForFirstConsumer`,这是LocalPV的标记。在第一次创建sts时,PV还不存在,这个流程是反过来的:k8s先根据亲和性和资源需求来决定Pod在哪个节点,然后再根据PVC来动态创建PV,将PVC绑定PV,在同一个节点创建Pod然后完成挂载。 | ||
|
||
在第二次以及之后创建sts时,此时PVC/PV都已经存在,所以k8s在调度的时候就会自动将POD创建到对应的节点了。 | ||
|
||
如果是直接用k8s,那可能没有支持动态创建PV的StorageClass. 此时需要手动创建PV,其他的流程是一样的。当然最终节点只会被调度到有PV的节点:换句话说,你无须在POD中指定节点亲和性,而是在创建PV时指定节点亲和性。 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.