ThankNeko's Blog ThankNeko's Blog
首页
  • 操作系统

    • Linux基础
    • Linux服务
    • WindowsServer笔记
    • Ansible笔记
    • Shell笔记
  • 容器服务

    • Docker笔记
    • Kubernetes笔记
    • Git笔记
  • 数据库服务

    • MySQL笔记
    • ELK笔记
    • Redis笔记
  • 监控服务

    • Zabbix笔记
  • Web服务

    • Nginx笔记
    • Tomcat笔记
  • 数据处理

    • Kettle笔记
  • Python笔记
  • Bootstrap笔记
  • C笔记
  • C++笔记
  • Arduino笔记
  • 分类
  • 标签
  • 归档
  • 随笔
  • 关于
GitHub (opens new window)

Hoshinozora

尽人事,听天命。
首页
  • 操作系统

    • Linux基础
    • Linux服务
    • WindowsServer笔记
    • Ansible笔记
    • Shell笔记
  • 容器服务

    • Docker笔记
    • Kubernetes笔记
    • Git笔记
  • 数据库服务

    • MySQL笔记
    • ELK笔记
    • Redis笔记
  • 监控服务

    • Zabbix笔记
  • Web服务

    • Nginx笔记
    • Tomcat笔记
  • 数据处理

    • Kettle笔记
  • Python笔记
  • Bootstrap笔记
  • C笔记
  • C++笔记
  • Arduino笔记
  • 分类
  • 标签
  • 归档
  • 随笔
  • 关于
GitHub (opens new window)
  • 操作系统

  • 虚拟化服务

    • Docker笔记

    • Kubernetes笔记

      • Kubernetes介绍
      • Kubernetes部署
      • K8S资源与标签
      • Pod资源详解
      • Kubectl命令
      • 控制器资源配置
      • Service资源配置
      • Ingress资源配置
      • configMap资源配置
      • Volume资源配置
        • 存储卷资源介绍
          • 存储卷介绍
          • 存储卷分类
          • pause容器
          • 容器化应用配置方式
        • Volume存储卷使用
          • 存储卷声明
          • 存储卷挂载
          • 使用例子
        • 存储管理资源介绍
          • 介绍
          • PV
          • PVC
          • StorageClass
          • Provisioner
        • 存储管理实践
          • PV/PVC使用
          • StorageClass使用
      • Volume资源配置
    • Jenkins笔记

    • K3S笔记

  • 数据库服务

  • 监控服务

  • Web服务

  • 数据处理

  • Ops
  • 虚拟化服务
  • Kubernetes笔记
Hoshinozora
2023-12-20
目录

Volume资源配置

# 存储卷资源介绍

# 存储卷介绍

由于Pod或Node是可能故障的,而故障会导致Pod的重构,也就会导致Pod内的数据被清除。所以对于需要持久存储的服务,就不应当将保存数据到Pod内,而是应该保存到Pod之外。

我们可以将数据存储到Node之内,但对于一个多Node的集群来说,我们应该将数据存储到网络共享存储之上,比如NFS服务。

# 存储卷分类

  • emptyDir (临时存储)

    • Pod删除时,其中的临时数据也会被删除。临时数据可以存储到内存,也可以存储到硬盘。
  • hostPath (主机存储)

    • 将数据存储到本地,Pod删除时,数据卷中保存的数据仍然保留在本地中。
  • 网络存储

    • 使用网络存储首先需要保证节点级可以正常使用目标网络存储服务。
    • 传统网络存储如nfs、cifs、ISCSI等,分布式存储如glusterfs、rbd、cephfs等,云存储如EBS、AzureDisk等。

# pause容器

每个Pod都对应了一个pause容器,pause是每个Pod的底层基础容器。Pod中的容器都共享着其所属pause的网络名称空间和存储卷。

这也是Pod中的容器可以使用同一个网络名称空间、同样的存储卷的原因。

# 容器化应用配置方式

  1. 自定义命令行参数,containers.command、containers.args。
  2. 将配置文件直接写死进镜像,极不推荐,违背了容器的弹性特性。
  3. 环境变量传入配置(推荐),containers.env。需要通过entrypoint脚本来预处理环境变量,将环境变量的配置信息,写入配置文件中。
  4. 存储卷,将配置文件直接放在存储卷中,然后挂载到容器中应用程序的配置文件所在的路径。

# Volume存储卷使用

# 存储卷声明

# pod.spec.volumes <[]object>

  • 用于定义容器中会用到的Pod的存储卷。

# volumes.name <string>

  • 存储卷名(必选),用于使用时调用。

# volumes.emptyDir <object>

  • 用于定义临时存储卷,定义Pod临时存储方式。
  • medium <string> - 媒介类型,为空表示使用磁盘作为存储媒介(默认),Memory表示使用内存作为存储媒介。
  • sizeLimit <string> - 大小限制,限制磁盘或内存的使用大小。

# volumes.gitRepo <object>

  • 用于定义Git仓库存储卷。
    • 需要Pod的宿主机安装了git能够正常使用Git命令。
    • 它是基于emptyDir工作的,它会将Git仓库中的数据下载到本地数据卷中。当Pod销毁时,其数据卷中的数据也会被销毁。
    • 它是单向的,本地的修改不会同步到Git仓库中,且并非实时的,仓库数据以Pod启动时的仓库数据为准,不会更新,当然如果需要,可以使用辅助容器去同步。
  • directory <string> - 目标目录,指定作为存储卷的仓库的目录,"." 表示仓库根目录。
  • repository <string> - 仓库URL(必选),指定作为存储卷的仓库URL。
  • revision <string> - 版本,指定作为存储卷的仓库的版本。

# volumes.hostPath <object>

  • 定义主机路径存储卷。将Pod所在宿主机的文件系统目录作为存储卷,映射为Pod中容器的目录。Pod被删除时,存储卷也不会被删除,数据依然存在。

  • <string> - 主机路径(必选),指定作为存储卷的宿主机的文件/目录路径,如果目标是软链接,则会跟随到真实路径。

  • type <string> - 存储卷类型

    • DirectoryOrCreate - 存储卷是一个目录,如果已存在则直接使用,如果不存在则创建它再使用。
    • Directory - 存储卷是一个目录,且必须已存在。
    • FileOrCreate - 存储卷是一个文件,如果已存在则直接使用,如果不存在则创建它再使用。
    • File - 存储卷是一个文件,且必须已存在。
    • Socket - 存储卷是一个Socket文件,且必须已存在。
    • CharDevice - 存储卷是一个字符设备文件,且必须已存在。
    • BlockDevice - 存储卷是一个块设备文件,且必须已存在。

# volumes.nfs <object>

  • 用于NFS存储卷。

    • 需要有一个NFS服务器。

      yum install -y nfs-utils
      mkdir -p /nfs && echo "/nfs *(rw,sync)" > /etc/exports
      systemctl start nfs && systemctl enable nfs
      netstat -lntup | grep 2049
      
      1
      2
      3
      4
    • 需要Pod的宿主机能够正常挂载NFS类型文件系统,也就是需要可以正常使用mount -t nfs命令,安装nfs-utils即可。

  • server <string> - NFS服务器(必选),指定NFS服务器的主机名或IP。

  • path <string> - NFS目录路径(必选),指定用于存储卷的NFS路径,例如"/data"目录就是挂载NFS存储卷中的"/data"目录。

  • readOnly <boolean> - 是否只读,指定NFS目录是否只读 (默认为读写,也就是False)。

# volumes.configMap <object>

  • 定义configMap配置文件存储卷,这种存储卷如果引用的configMap配置发生变动,会同步映射到存储卷中来。
  • name <string> - configMap资源名,指定将被引用为配置文件存储卷的configMap资源的名称。会将数据转化为文件,每个键值对为一个文件,键为文件名,值为文件内容。
  • items <[]object> - 指定要挂载的数据,用于只引用部分数据到数据卷,不指定则默认是configMap资源下的数据全都挂载。
    • key <string> - 键名(必选),指定要挂载的数据的键名。
    • mode <integer> - 文件权限,指定挂载的文件的权限。
    • path <string> - 文件路径,指定挂载的文件的路径,能够以数据卷的根为起始点,向下指定路径。但无法使用”..“指定到数据卷之外。
  • optional <boolean> - 可选,指定Pod创建时configMap是否必须存在。

# volumes.secret <object>

  • 定义secret存储卷。

# 存储卷挂载

# pod.spec.containers.volumeMounts <[]object>

  • 用于指定挂载Pod中的存储卷到容器中,该配置无法在容器运行后动态更新。

# volumeMounts.name <string>

  • 挂载的存储卷(必选),指定挂载用的存储卷名称。

# volumeMounts.mountPath <string>

  • 目标挂载路径(必选),指定用于挂载的目标路径。

# 使用例子

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
    - name: nginx
      image: nginx:latest
      imagePullPolicy: IfNotPresent
      volumeMounts:
        - name: nfs-html-volume
          mountPath: /usr/share/nginx/html
  volumes:
    - name: nfs-html-volume
      nfs:
        server: 192.168.10.100
        path: /nfs/html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 存储管理资源介绍

# 介绍

K8S的存储系统从基础到高级大致分为三个层次:Volume,PV(Persistent Volume)和动态存储供应。

直接在Pod配置中定义的存储卷就叫做Volume,Volume是Pod的附属品,它们之间属于一种静态绑定关系,我们无法单独创建一个Volume,因为它不是一个独立的K8S资源对象。

而**PV(Persistent Volume)是集群之中的一块网络存储,PV跟Volume类似,但独立于Pod之外是一个K8S资源对象,所以我们可以单独创建一个PV。它不和Pod直接发生关系,而是通过PVC(Persistent Volume Claim)**来实现动态绑定。Pod定义里指定的是PVC,然后PVC会根据Pod的要求自动绑定合适的PV给Pod使用。

PVC只有绑定了PV之后才能被Pod使用。K8S会不断地查看当前每一个PVC,是不是处于Bound状态。如果不是则会遍历所有PV,只要有合适的PV,就会将其进行绑定。

但随着集群规模变大,运维需要创建的PV将变得非常多,基本无法靠人工完成,此时就可能出现Pod因为PVC绑定不到PV而启动失败。为了解决这个问题,K8S提供了**动态存储供应(dynamic provisioning)**机制,来动态创建PV,这个机制的核心概念就是StorageClass。

PV、PVC让存储资源的使用变得可控,能够合理规划磁盘资源的使用,从而保障系统的稳定性、可靠性,不会出现磁盘使用超支的情况。StorageClass则用于自动化创建PV,减少人工的工作量。

# PV

PV是对K8S存储资源的抽象,一个PV对应一个存储卷,定义一个PV内容包括了存储类型、存储大小和访问模式等。PV一般由运维人员创建和配置,供容器申请使用。

# PVC

PVC用于描述对PV存储资源的一个申请,请求信息包含存储大小、访问模式等。创建PV后,Pod就可以通过PVC向PV申请磁盘空间了。类似于某个应用程序向操作系统申请1G的磁盘使用空间。

PVC 创建成功之后,Pod 就可以以挂载存储卷(Volume)的方式使用PVC的存储资源了。Pod在使用PVC时必须与PVC在同一个Namespace下。

# StorageClass

K8S有两种存储资源的供应模式:静态模式和动态模式,资源供应的最终目的就是将适合的PV与PVC绑定:

  • 静态模式:管理员预先创建许多各种各样的PV,等待PVC申请使用。
  • 动态模式:管理员无须预先创建PV,而是通过StorageClass自动完成PV的创建以及与PVC的绑定。

StorageClass就是动态模式,根据PVC的需求动态创建合适的PV资源,从而实现存储卷的按需创建。通过storageClass自动创建的PV会在对应的存储目录上创建一个PV用的目录,用来提供数据读写。

一般某个商业性的应用程序,会用到大量的Pod,如果每个Pod都需要使用存储资源,那么就需要人工时不时的去创建PV,这也是个麻烦事儿。解决方法就是使用动态模式:当Pod通过PVC申请存储资源时,直接通过StorageClass去动态的创建对应大小的PV,然后与PVC绑定,此时PV和PVC基本就是一对一的关系。

StorageClass资源对象的定义主要包括:名称、Provisioner、存储的相关参数配置、回收策略。StorageClass一旦被创建,则无法修改,只能删除重新创建。

# Provisioner

Provisioner是存储插件或者说存储驱动,比如NFS插件、CephFS插件等。在创建PVC时需要指定StorageClass,PVC选择到对应的StorageClass后,与其关联的Provisioner组件就会动态的创建PV资源。

PV和PVC的生命周期包括4个阶段:资源供应(Provisioning)、资源绑定(Binding)、资源使用(Using)、资源回收(Reclaiming)。而Provisioner就是用于进行资源供应的。

# 存储管理实践

# PV/PVC使用

# PV配置编写

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-html-pv
  # 需要定义标签用于被PVC选择
  labels:
    pv: nfs-html-pv
spec:
  # 声明PV卷大小
  capacity:
    storage: 1Gi
  # 指定访问模式
  accessModes:
    - ReadWriteMany
  # 指定PV回收策略
  persistentVolumeReclaimPolicy: Retain
  # nfs配置
  nfs:
    server: 192.168.10.100
    # 指定NFS上的存储路径,必须是已存在的路径
    path: /nfs/html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  • accessModes (访问模式)
    • ReadWriteOnce - 可被一个节点读写挂载。
    • ReadOnlyMany - 可被多个节点只读挂载。
    • ReadWriteMany - 可被多个节点读写挂载。
  • persistentVolumeReclaimPolicy (PV回收策略)
    • Recycle - 删除PVC时删除PV以及其中的数据。
    • Retain - 删除PVC时保留PV以及其中的数据,需要管理员手工清理数据 (默认)。

# PVC配置编写

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-html-pvc
spec:
  # 声明请求的资源
  resources:
    requests:
      storage: 100Mi
  accessModes:
    - ReadWriteMany
  # 通过selector查找PV
  selector:
    matchLabels:
      pv: nfs-html-pv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# Pod配置编写

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
    - name: nginx
      image: nginx:latest
      imagePullPolicy: IfNotPresent
      volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
  volumes:
    - name: html
      persistentVolumeClaim:
        claimName: nfs-html-pvc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# StorageClass使用

# 安装Provisioner

使用StorageClass之前我们需要先安装对应的存储插件,nfs的存储插件为nfs-subdir-external-provisioner。

# 下载nfs-subdir-external-provisioner,下载Source code
https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/releases/

# 解压下载的包
tar -xvf nfs-subdir-external-provisioner-nfs-subdir-external-provisioner-*.tar.gz

# 创建命名空间存储该驱动
kubectl create namespace nfs-provisioner

# 修改相关配置
cd nfs-subdir-external-provisioner-nfs-subdir-external-provisioner-*/deploy/

# 修改镜像源/NFS服务器地址/共享目录配置
sed -ri.bak -e "s#registry\.k8s\.io/sig-storage#registry.cn-shenzhen.aliyuncs.com/xiaohh-docker#" -e "s#10\.3\.243\.101#192.168.10.100#" -e "s#/ifs/kubernetes#/nfs#" deployment.yaml

# 修改命名空间
sed -i 's/namespace: default/namespace: nfs-provisioner/g' $(grep -rl 'namespace: default' ./)

# 安装动态供给
kubectl get all -o wide -n nfs-provisioner

# 查看安装结果
kubectl get all -n nfs-provisioner

# 查看动态供应存储类名称
kubectl get storageclass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# StorageClass配置编写

# 安装nfs-subdir-external-provisioner的时候会创建一个storageClass,需要另外的可以自己写

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-html-storage
  annotations:
    # 是否设置为默认storageClass
    storageclass.kubernetes.io/is-default-class: "false"
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
  # 删除时数据处理方式
  archiveOnDelete: "false"
  # 指定NFS存储卷目录路径,目录不能已存在,需要删除再添加StorageClass
  # 也可以使用变量,如:"${.PVC.namespace}/${.PVC.name}/${.PVC.annotations.nfs.io/storage-path}"
  pathPattern: html
mountOptions:
  # 访问文件时不更新文件inode中的时间戳,高并发环境可提高性能
  - noatime
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • archiveOnDelete
    • false - 删除PVC时,删除PV以及其中的数据。
    • true - 删除PVC时,保留PV以及其中的数据。

# PVC配置编写

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-html-pvc
spec:
  # 指定使用的storageClass名称
  storageClassName: nfs-html-storage
  # 声明请求的资源
  resources:
    requests:
      storage: 10Mi
  accessModes:
    - ReadWriteMany
1
2
3
4
5
6
7
8
9
10
11
12
13

# Pod配置编写

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
    - name: nginx
      image: nginx:latest
      imagePullPolicy: IfNotPresent
      volumeMounts:
        - name: nfs
          mountPath: /usr/share/nginx/html
  volumes:
    - name: nfs
      persistentVolumeClaim:
        claimName: nfs-html-pvc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#Linux#DevOps#Kubernetes#容器编排#Volume#存储卷#存储管理#配置清单
configMap资源配置
Volume资源配置

← configMap资源配置 Volume资源配置→

最近更新
01
二〇二五年四月十七日随笔
04-17
02
二〇二五年四月十六日随笔
04-16
03
二〇二五年四月九日随笔
04-09
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Hoshinozora | MIT License
湘ICP备2022022820号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式