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

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 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>
相关实践学习
使用ACS算力快速搭建生成式会话应用
阿里云容器计算服务 ACS(Container Compute Service)以Kubernetes为使用界面,采用Serverless形态提供弹性的算力资源,使您轻松高效运行容器应用。本文将指导您如何通过ACS控制台及ACS集群证书在ACS集群中快速部署并公开一个容器化生成式AI会话应用,并监控应用的运行情况。
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
消息中间件 Kubernetes 网络协议
K8S 性能优化 - OS sysctl 调优
K8S 性能优化 - OS sysctl 调优
|
Kubernetes 搜索推荐 数据安全/隐私保护
Containerd ctr、crictl、nerdctl 实战
Containerd ctr、crictl、nerdctl 实战
4345 1
|
存储 Kubernetes 数据可视化
|
Kubernetes Cloud Native 微服务
微服务实践之使用 kube-vip 搭建高可用 Kubernetes 集群
微服务实践之使用 kube-vip 搭建高可用 Kubernetes 集群
542 3
|
存储 Kubernetes API
k8s学习-ConfigMap(创建、使用、更新、删除等)
k8s学习-ConfigMap(创建、使用、更新、删除等)
3481 0
|
10月前
|
存储 Kubernetes 调度
【赵渝强老师】K8s的有状态控制器StatefulSet
在Kubernetes中,StatefulSets用于部署有状态应用程序,提供持久存储和唯一标识符。与Deployment不同,StatefulSets确保Pod的标识符在重新调度后保持不变,适用于需要稳定网络标识符和持久存储的场景。本文介绍了StatefulSets的创建、扩容与缩容、更新与回滚等操作,并提供了具体示例和视频讲解。
362 0
|
存储 Kubernetes 应用服务中间件
大白话说明白K8S的PV / PVC / StorageClass(理论+实践)
本文主要通过大白话说明白PV、PVC的概念和原理,再说说StorageClass的作用,最后通过实践加深理解。
大白话说明白K8S的PV / PVC / StorageClass(理论+实践)
|
Kubernetes Perl 容器
在 Kubernetes 中重启 pod 的 3 种方法
【4月更文挑战第25天】
8346 1
在 Kubernetes 中重启 pod 的 3 种方法
|
负载均衡 Kubernetes 混合部署
k8s 中externalTrafficPolicy应用场景和实践
在Kubernetes(K8s)中,`externalTrafficPolicy` 是一个用于控制服务的外部流量的策略。这个字段可以在 `Service` 的定义中设置,其主要作用是决定服务对外部请求的负载均衡行为。具体来说,`externalTrafficPolicy` 有两个可选值: 1. `Cluster`: 默认值。当设置为 `Cluster` 时,服务将负载均衡流量到所有的 Pod,无论这些 Pod 是否在同一节点上。这意味着即使请求来自于同一节点的多个 Pod,流量也可能被负载均衡到不同的节点上。 ```yaml apiVersion: v1 kind: Se
1351 1
|
Kubernetes 关系型数据库 API
Zalando Postgres Operator 快速上手
Zalando Postgres Operator 快速上手
685 0