01.10 「K8S 系列」 详解K8S Stateful Services

Kubernetes 是一种容器编排工具,用于管理、部署、扩展容器化应用。在k8s中管理操作的最小单位是pod,而不是直接操作容器(比如docker)。下面就是管理pod 的集中方式:

  • ReplicaSet
  • Deployments
  • StatefulSets
  • DeamonSet



Why

既然我们有了ReplicaSet, Deployments 和 DeamonSet。为什么还需要StatefulSets呢?顾名思义看的出来这是针对有状态的应用,前面三种都是针对无状态的。有状态应用常见包括MySQL、kafka等。本文我们就主要关注下K8S 中StatefulSets如何管理有状态的应用的。



StatefulSets

StatefulSets 用于管理K8S中的有状态应用。StatefulSets 中的pods用唯一标识和稳定的主机名命名。它将状态信息和其他弹性数据存储在持久卷中。该永久卷已附加到基于云的存储。它将负责维护您的应用程序状态。

在StatefulSet上下文中的持久卷声明,因此在创建StatefulSet并创建每个副本时,Kubernetes会继续为StatefulSet中的每个副本创建一个不同的磁盘。

现在,当Kubernetes启动时,可以执行复制的唯一方法是使用ReplicaSet。使用副本集,每个副本都完全相同。他们的应用程序名称末尾有随机散列。并且如果发生缩放事件(例如,按比例缩小),则会随机选择一个容器并将其删除。这些特性使ReplicaSet很难映射到有状态的应用程序。许多有状态应用程序期望其主机名是恒定的。因此,使用ReplicaSet和有状态应用程序的那些复杂性导致了StatefulSets的最终开发。Kubernetes中的StatefulSets与ReplicaSet类似,但是它增加了一些保证,使在Kubernetes内部管理状态应用程序变得更加容易。

<code>apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
serviceName: mysql
replicas: 3
template:
metadata:
labels:
app: mysql
spec:
initContainers:
- name: init-mysql
image: mysql:5.7
command:
- bash
- "-c"
- |
set -ex
# Generate mysql server-id from pod ordinal index.
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
echo [mysqld] > /mnt/conf.d/server-id.cnf
# Add an offset to avoid reserved server-id=0 value.
echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
# Copy appropriate conf.d files from config-map to emptyDir.
if [[ $ordinal -eq 0 ]]; then
cp /mnt/config-map/master.cnf /mnt/conf.d/
else
cp /mnt/config-map/slave.cnf /mnt/conf.d/
fi
volumeMounts:
- name: conf
mountPath: /mnt/conf.d
- name: config-map
mountPath: /mnt/config-map
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi/<code>

.StatefulSet的工作与Deployment相似,但是在StatefulSet中,容器的部署按顺序进行。与其一口气地部署所有容器,不如一步一步地部署它。一旦第一个Pod部署并准备就绪,则只有第二个Pod可以启动。为了获得正确的参考,这些吊舱的名称带有唯一的ID,可在其中展示唯一的身份。因此,例如,如果有3个MySQL Pod,名称将为mysql-0,mysql-1和mysql-2。并且,如果这些Pod中的任何Pod失败,则StatefulSets将部署具有相同名称的新Pod。StatefulSets需要无头服务来管理唯一身份。下图显示了StatefulSets的体系结构:


「K8S 系列」 详解K8S Stateful Services

在StatefulSet中缩放

当Kubernetes决定扩大或缩小StatefulSet时,它会以一种易于理解的方式做到这一点。例如,当您最初创建StatefulSet时,将创建第一个副本,Kubernetes将在创建第二个副本之前等待其变得正常且可用。这意味着在创建第二个副本时,您可以依赖于零索引(第一个副本)可供您连接的事实。它可以指向StatefulSet的原始成员。这使得在创建有状态应用程序时,集合点声明初始领导者和其他许多其他必要的事情变得容易得多。

同样,当您缩小比例时,Kubernetes将从最高索引处删除。因此,如果您从三个副本缩减为两个副本,则将从删除索引2处的副本开始。

结论

因此,希望可以举例说明如何在Kubernetes中部署有状态应用程序,以及如何将StatefulSets用于此类应用程序。此博客之后的下一步将是继续并建立一个StatefulSet。


分享到:


相關文章: