5

K8S 实战 - 09 StatefulSet 控制器

 2 years ago
source link: https://hulining.github.io/2021/03/19/kubernetes-in-action-09-statefulset/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

K8S 实战 - 09 StatefulSet 控制器

2021-03-19Kubernetes

22

  |   1.2k 字   |   5 min

本文为 K8S 实战的第九个章节。主要了解 K8S 集群中 StatefulSet 控制器相关概念及其使用方式

StatefulSet 是 Pod 资源控制器的一种实现,用于部署和扩展有状态应用的 Pod 资源,确保他们的运行顺序及每个 Pod 资源的唯一性,StatefulSet 需要为每个 Pod 维持一个唯一且固定的标识符,为其创建专有的存储卷.StatefulSet 主要有如下特性

  • 稳定且唯一的网络标识符
  • 稳定且持久的存储
  • 有序优雅的部署和扩展,删除和终止
  • 有序而自动的滚动更新

一般来说,完整可用的 StatefulSet 通常由以下三个组件组成:

  • Headless Service: 用于为资源标识符生成可解析的 DNS 资源记录
  • StatefulSet: 用于管控 Pod 资源
  • VolumeClaimTemplates: 基于静态或动态 PV 为 Pod 资源提供专有且稳定的存储

对于一个拥有 N 个副本的 StatefulSet 来说,其 Pod 对象会被有序的创建,顺序依次是 {0...N-1}, 删除则以相反的方式进行.Pod 资源的名称格式为 $(statefulset_name)-$(ordinal), 其域名后缀由相关 Headless 类型的 Service 资源给出,格式为 $(service_name).$(namespace).svc.cluster.local.

StatefulSet 控制器会为每个 VolumeClaim 模版创建一个专用的 PV, 它会从模版中指定 StorageClass 中为每个 PVC 创建 PV, 未指定 Storage 将使用默认的 StorageClass 资源。如果不支持 PV 的动态供给,就需要事先创建好满足需求的所有 PV.

StatefulSet 应用

一个完整的 StatefulSet 控制器需要由 Headless Service, StatefulSet 和 volumeClaimTemplate 组成。一般来说定义如下:

# 定义 Headless Service,暴露后端 Pod IP
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: default
labels:
app: prometheus
spec:
clusterIP: None # clusterIP 为 None
selector:
app: prometheus
ports: 9090
- port: prometheus

---
# 创建 sts 对象
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: prometheus
namespace: default
lables:
app: prometheus
spec:
serviceName: "prometheus" # 指定 headless Service 服务名称
replicas: 1 # 指定 Pod 副本数
podManagementPolicy: "Parallel" # 指定创建/删除 Pod 时的策略,可选值为 "OrderedReady"(默认),"Parallel".分别表示串行和并行(无需等待)创建/删除 Pod
updateStrategy:
type: "RollingUpdate" # 指定升级策略,与 Deployment 相同
selector:
matchLabels:
app: prometheus-pod

# Pod 模版相关内容
template:
# <Pod 相关内容>
metadata:
labels:
app: prometheus-pod
spec:

# ...

# PVC 模版相关内容
volumeClaimTemplates:
# <PVC 相关内容>
- metadata:
name: # PVC 名称,用于 Pod 内部挂载
spec:
storageClassName: # 指定 storageClass 名称
accessModes: # 指定访问模式
- ReadWriteOnce
resources: # 指定资源,一般为存储大小
requests:
storage: "500Mi"

可以看出,StatefulSet 除了需要在 spec 字段中定义 serviceName,volumeClaimTemplates 外,其它常用字段基本与 Deployment 相同

StatefulSet 中 Pod 资源的标识符

StatefulSet 控制器创建的 Pod 对象拥有固定且唯一的标识符,他们基于唯一索引,即相关 StatefulSet 名称而生成,名称格式为 <statefulset_name>-<ordinal_index>(index 从 0 开始).

这些名称会由 StatefulSet 资源相关的 headless 资源创建为 DNS 资源记录,域名格式为 $(service_name).$(namespace).svc.cluster.local.Pod 资源记录为 $(pod_name).$(service_name).$(namespace).svc.cluster.local.

Headless Service 资源借助 SRV 记录来引用真正提供服务的后端 Pod 资源的主机名称,进行指向包含 Pod IP 地址的记录条目.StatefulSet 控制器管理的 Pod 在重建后 IP 可能会变化,但它的名称标识在重建后保持不变.

StatefulSet 中 Pod 资源的存储卷

StatefulSet 控制器通过 volumeClaimTemplates 为每个 Pod 副本自动创建并关联一个 PVC 对象,它们分别绑定了一个动态供给的 PV 对象.

删除 StatefulSet 控制器的 Pod 资源,其存储卷并不会被删除,除非用户或管理员手动删除。因此,经由 StatefulSet 重建后的 Pod, 会自动关联之前的 PVC 存储卷,且之前数据依旧可用,实现数据持久化.

案例: etcd 集群

  • Service 资源清单
apiVerision: v1
kind: Service
metadata:
name: etcd
annotations:
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
spec:
clusterIP: None
selector:
app: etcd-member
ports:
- port: 2379
name: client
- port: 2380
name: peer
---
apiVersion: v1
kind: Service
metadata:
name: etcd-client
spec:
type: NodePort
selector:
app: etcd-member
ports:
- name: etcd-client
port: 2379
protocol: TCP
targetPort: 2379
  • StatefulSet 资源清单
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: etcd
labels:
app: etcd
spec:
nameService: etcd
replicas: 3
selector:
app: etcd-member
template:
metadata:
name: etcd
labels:
app: etcd-member
spec:
containers:
- name: etcd
image: "quay.io/coreos/etcd:v3.2.16"
ports:
- containerPort: 2379
name: client
- containerPort: 2380
name: peer
env:
- name: CLUSTER_SIZE
value: "3"
- name: SET_NAME
value: "etcd"
volumeMounts:
- name: data
mountPath: /var/run/etcd
command:
- "/bin/sh"
- "-ecx"
- |
IP=$(hostname -i)
PEERS=""
for i in $(seq 0 $((${CLUSTER_SIZE} -1))); do
...
done
exec etcd --name ${HOSTNAME} \
--listen-peer-urls http://${IP}:2380 \
--listen-client-urls http://${IP}:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://${HOSTNAME}.${SET_NAME}:2379 \
--initial-advertise-peer-urls http://${HOSTNAME}.${SET_NAME}:2380 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster ${PEERS} \
--initial-cluster-state new \
--data-dir /var/run/etcd/default.etcd

volumeClaimTemplates:
- metadata:
name: data
spec:
storageClassName: nfs-storageclass
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi

Recommend

  • 47
    • blog.51cto.com 5 years ago
    • Cache

    k8s之StatefulSet-jonson sun

    StatefulSet(状态集)1,什么是StatefulSet?StatefulSet又叫PetSet(之前的名称),它和RS,RC,Deployment等一样,都是pod控制器。StatefulSet是为了解决有状态服务的问题(对应于deoloyment和RS,RC,ReplicaSet都是为无状态服务而设计的)。什么是无状态服务?...

  • 12

    StatefulSet是k8s中有状态应用管理的标准实现,今天就一起来了解下其背后设计的场景与原理,从而了解其适用范围与场景 1. 基础概念 首先介绍有状态应用里面的需要考虑的一些基础的事情,然后在下一章我们再去看stateful...

  • 21

    数据持久化 Volume kubernetes中的volume提供了在容器中挂载外部存储的能力 pod需要设置卷来源(spec.volume)和挂载点(spec.containers.volumeMounts)两个信息来使用对应的Volume 官方文档:

  • 4
    • studygolang.com 4 years ago
    • Cache

    K8S 控制器模式

    Kubernetes模型通常由以下部分组成: TypeMeta TypeMeta是Kubernetes对象的最基本定义,它通过引入GKV(Group,Kind,Version)定义了一个对象的类型。 Group Kubernetes定义了非常多对象,如何归类这些...

  • 9

    DaemonSet简介DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod使用 DaemonSet 的一...

  • 4
    • jiac3366.github.io 3 years ago
    • Cache

    K8s | 控制器模型是怎样的?

    +c编程手记 Guangzhou, ChinaCRD 就是一个专门用来定义 Schema 的一个特殊的 API 对象控制循环——“ReconcileLoop”(调谐循环)或者“Sync Loop”(同步循环)被控制对象...

  • 7
    • jiac3366.github.io 3 years ago
    • Cache

    K8s | StatefulSet是什么?

    +c编程手记 Guangzhou, China18 深入理解StatefulSet(一):拓扑状态实例之间有不对等关系,以及实例对外部数据有依赖关系的应用,就被称为“有状态应用” Stateful ApplicationS...

  • 8
    • www.cnblogs.com 2 years ago
    • Cache

    k8s 中 Pod 的控制器 - ZhanLi

    k8s 中 Pod 的控制器 Pod 是 Kubernetes 集群中能够被创建和管理的最小部署单元。所以需要有工具去操作和管理它们的生命周期,这里就需要用到控制器了。 Pod 控制器由 master 的 kube-controller-manager 组...

  • 8

    一.系统环境 服务器版本 docker软件版本 Kubernetes(k8s)集群版本 CPU架构 CentOS Linux release 7.4.1708 (Core) Docker version...

  • 4

    Pod调度运⾏时,如果应⽤不需要任何稳定的标示、有序的部署、删除和扩展,则应该使⽤⼀组⽆状态副本的控制器来部署应⽤,例如 Deployment 或 ReplicaSet更适合⽆状态服务需求,⽽StatefulSet适合管理所有有状态的服务,⽐如MySQL、MongoDB集群等。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK