在StatefulSet中使用LocalVolume存储卷保持节点一致

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: StatefulSet是一种有状态服务,其存储卷的使用有多种方式:使用共享存储,这时在模板中定义一个volume卷,可以给多个pod共享;每个pod配置独立的存储卷,使用非共享存储(块存储)时需要这样配置,通过配置volumeClaimTemplates实现;对于StatefulSet使...

StatefulSet是一种有状态服务,其存储卷的使用有多种方式:

使用共享存储,这时在模板中定义一个volume卷,可以给多个pod共享;

每个pod配置独立的存储卷,使用非共享存储(块存储)时需要这样配置,通过配置volumeClaimTemplates实现;

对于StatefulSet使用localvolume的场景,和上述两种情况都不一样:

通过volumeClaimTemplates自动生成localvolume的controller没有提供;
localvolume本身定义了节点信息,会导致使用这个pv的pod调度到相应节点;
StatefulSet如果多个pod使用同一个localvolume,会导致多个pod调度到相同节点;

本文先通过手动创建pvc、localvolume的方式,并利用statefulset 自动生成pvc的规则,在statefulset中配置localvolume;

场景:

生成一个StatefulSet应用,每个pod定义到特定节点;StatefulSet中定义2个Pod,每个pod使用两个pvc,共需要创建4个pvc和4个localvolume;

如下图所示:

image

模板:

下面分别给出4个pv、pvc的模板,4个pv分别配置到cn-shenzhen.i-wz9gvy73m4qyk03xzg1y、cn-shenzhen.i-wz9c9m0m4oldr6mt89rd两个节点上;

pv1, pvc1:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-volume-a-1
  labels:
    alicloud-pvname: local-volume-a-1
spec:
  capacity:
    storage: 20Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-volume
  local:
    path: /local1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - cn-shenzhen.i-wz9c9m0m4oldr6mt89rd
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: local-volume-a-web-0
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: local-volume
  selector:
    matchLabels:
      alicloud-pvname: local-volume-a-1

pv2, pvc2:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-volume-a-2
  labels:
    alicloud-pvname: local-volume-a-2
spec:
  capacity:
    storage: 20Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-volume
  local:
    path: /local1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - cn-shenzhen.i-wz9gvy73m4qyk03xzg1y
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: local-volume-a-web-1
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: local-volume
  selector:
    matchLabels:
      alicloud-pvname: local-volume-a-2

pv3, pvc3:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-volume-b-1
  labels:
    alicloud-pvname: local-volume-b-1
spec:
  capacity:
    storage: 20Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-volume
  local:
    path: /local2
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - cn-shenzhen.i-wz9c9m0m4oldr6mt89rd
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: local-volume-b-web-0
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: local-volume
  selector:
    matchLabels:
      alicloud-pvname: local-volume-b-1

pv4, pvc4:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-volume-b-2
  labels:
    alicloud-pvname: local-volume-b-2
spec:
  capacity:
    storage: 20Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-volume
  local:
    path: /local2
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - cn-shenzhen.i-wz9gvy73m4qyk03xzg1y
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: local-volume-b-web-1
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: local-volume
  selector:
    matchLabels:
      alicloud-pvname: local-volume-b-2

创建上述pv pvc后,创建应用:

创建应用:

创建的时候注意pvc的名字的构成:
pvc的名字 = statefulset-name + volume-name + 序号

local-volume-a-web-0 = "local-volume-a" + "-" + "web" + "-" + "0"

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: local-volume-a
          mountPath: /data1
        - name: local-volume-b
          mountPath: /data2
  volumeClaimTemplates:
  - metadata:
      name: local-volume-a
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "local-volume"
      resources:
        requests:
          storage: 20Gi
  - metadata:
      name: local-volume-b
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "local-volume"
      resources:
        requests:
          storage: 20Gi

验证:

# kubectl get pod | grep web
web-0                              1/1     Running     0          15m
web-1                              1/1     Running     0          14m
# kubectl get pvc | grep local
local-volume-a-web-0                       Bound    local-volume-a-1         20Gi       RWO            local-volume        15m
local-volume-a-web-1                       Bound    local-volume-a-2         20Gi       RWO            local-volume        15m
local-volume-b-web-0                       Bound    local-volume-b-1         20Gi       RWO            local-volume        15m
local-volume-b-web-1                       Bound    local-volume-b-2         20Gi       RWO            local-volume        15m
# kubectl get pv | grep local
local-volume-a-1         20Gi       RWO            Retain           Bound      default/local-volume-a-web-0                       local-volume                 15m
local-volume-a-2         20Gi       RWO            Retain           Bound      default/local-volume-a-web-1                       local-volume                 17m
local-volume-b-1         20Gi       RWO            Retain           Bound      default/local-volume-b-web-0                       local-volume                 15m
local-volume-b-2         20Gi       RWO            Retain           Bound      default/local-volume-b-web-1                       local-volume                 17m

删除pod,验证新建pod调度到相同节点:

# kubectl describe pod web-0 | grep Node
Node:               cn-shenzhen.i-wz9c9m0m4oldr6mt89rd/192.168.0.12
Node-Selectors:  <none>
# kubectl delete pod web-0
pod "web-0" deleted
# kubectl get pod
NAME                               READY   STATUS      RESTARTS   AGE
web-0                              1/1     Running     0          10s
web-1                              1/1     Running     0          15m
# kubectl describe pod web-0 | grep Node
Node:               cn-shenzhen.i-wz9c9m0m4oldr6mt89rd/192.168.0.12
Node-Selectors:  <none>
相关实践学习
巧用云服务器ECS制作节日贺卡
本场景带您体验如何在一台CentOS 7操作系统的ECS实例上,通过搭建web服务器,上传源码到web容器,制作节日贺卡网页。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
6月前
|
存储 C++ 容器
set容器-set和multiset区讲解
set容器-set和multiset区讲解
58 0
|
存储 Kubernetes 网络协议
【K8S系列】深入解析StatefulSet(一)
【K8S系列】深入解析StatefulSet(一)
496 1
|
2月前
|
存储 Kubernetes 开发工具
Kerbernetes的StatefulSet与Operator
文章主要介绍了Kubernetes中StatefulSet的概念、与Operator的关系、应用场景、限制条件、Pod标识符、Pod管理策略、更新策略,并通过实战案例展示了如何使用StatefulSet部署NFS网络文件系统、etcd服务和zookeeper服务,以及如何基于Operator部署etcd。
54 0
Kerbernetes的StatefulSet与Operator
|
3月前
|
存储 Kubernetes 网络协议
在K8S中,Deployment和Statefulset有何区别?
在K8S中,Deployment和Statefulset有何区别?
|
3月前
|
存储 消息中间件 Kubernetes
在K8S中,deploy和Statefulset有何区别?
在K8S中,deploy和Statefulset有何区别?
|
Web App开发 应用服务中间件 nginx
|
6月前
|
存储 Kubernetes 网络协议
k8s学习-StatefulSet(模板、更新、扩缩容、删除等)
k8s学习-StatefulSet(模板、更新、扩缩容、删除等)
349 0
|
11月前
|
存储 Kubernetes 索引
Statefulset部署应用
Statefulset部署应用
|
11月前
|
Cloud Native Go Docker
Statefulset 实战 1
Statefulset 实战 1
|
11月前
|
Kubernetes Cloud Native 索引
Statefulset 实战 3
Statefulset 实战 3