k8sday13数据存储(1.5/2)

目录

二、高级核心存储

1、PV

1.1配置文件

①、访问模式(accessModes)

②、回收策略(persistentVolumeReclaimPolicy)

③、存储类别

④、状态(Status)

1.2创建测试

①、准备NFS环境

②、创建PV

③、验证

2、PVC

1.1配置文件

1.2绑定引用测试

①、创建PVC

②、测试绑定

③、创建Pod准备测试

④、测试链路打通

3、注意事项

PV和PVC未绑定检查步骤

1、容量(Capacity)

2、访问模式(AccessModes)

3、可用状态(Status)

4、StorageClassName 必须完全一致

4、生命周期

①、资源供应

②、资源绑定

③、资源使用

④、资源释放

⑤、资源回收

5、补充动态供给


二、高级核心存储

​ 之前学过NFS提供存储配置,我们知道要进行存储数据要求用户会自己搭建NFS服务器,会在YAML文件中配置NFS,这显然对于用户来说,要求过高,而且k8s支持的存储系统类型多,要求用户熟知每个存储系统那是不现实的,所以k8s提出高级核心存储的概念(主要包含PV和PVC),二者通过连接绑定,最终实现用户只需要提出Pod的存储要求,而其底层实现由对应的管理员实现。如图:

1、PV

集群级资源,独立于 Pod 生命周期。可由管理员静态提前创建,也可通过 StorageClass 让系统自动动态供给。

1.1配置文件

以下给出一个NFS 类型的 PV 示例,供集群管理员提前“静态”创建,

  # persistent-volume-nfs.yaml
  # 应用侧只需在 PVC 中声明相同 storageClassName 即可绑定。
  apiVersion: v1
  kind: PersistentVolume        # 声明资源类型是 PV
  metadata:
    name: pv-nfs-share          # PV 对象在集群中的名称,可自定义
    # 由于 PV 是集群级资源,所以没有 namespace 的概念
    labels:
      app: nfs-pv-demo          # 可按需添加 label,方便选择器匹配
  spec:
    capacity:
      storage: 2Gi              # 声明的容量,PVC 申请量需 ≤ 该值
    accessModes:                # 访问模式
      - ReadWriteMany           # 允许多节点同时读写
    persistentVolumeReclaimPolicy: Retain     # 回收策略
    storageClassName: nfs-slow  # 必须与下方对应 PVC 的 storageClassName 一致
    mountOptions:
      - nfsvers=4.1             # 挂载参数,按需调整
      - noatime
    nfs:                        # 存储类型
      server: 192.168.10.5      # NFS 服务器 IP 或域名
      path: /data/nfs/share     # NFS 导出的共享目录
①、访问模式(accessModes)

用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:

  • ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载

  • ReadOnlyMany(ROX):只读权限,可以被多个节点挂载

  • ReadWriteMany(RWX):读写权限,可以被多个节点挂载

需要注意的是,底层不同的存储类型可能支持的访问模式不同

②、回收策略(persistentVolumeReclaimPolicy)

当 PV 不再被使用了之后,对其的处理方式。目前支持三种策略:

  • Retain(保留):PVC 删除后仅解除绑定,数据仍在,需要管理员手工清理数据

  • Recycle(回收):清除 PV 中的数据,已废弃,不推荐使用

  • Delete(删除):与 PV 相连的后端存储完成 volume 的删除操作,当然这常见于云服务商的存储服务

需要注意的是,底层不同的存储类型可能支持的访问模式不同

③、存储类别

PV可通过storageClassName参数指定一个存储类别

  • 具有了特定类别的PV只能与请求了改特定类别的PVC绑定

  • 没有指定类别的PV只能与不请求任何类别的PVC绑定

④、状态(Status)

一个PV的生命周期内,可能会有4个状态阶段:

  • Available(可用):未被任何PVC绑定

  • Bound(已绑定):PV已经和PVC绑定

  • Released(已释放):PV和PVC已解绑,PVC被删除,但是资源未被集群重新声明

  • Failed(失败):PV自动回收失败

1.2创建测试
①、准备NFS环境
  # 获取已有节点,找到control-plane容器记下输出容器内 IP( INTERNAL-IP )例如 172.18.0.4 
  kubectl get node -o wide
  ​
  # 进入控制面(control-plane)容器
  docker exec -it my-multi-node-cluster1-control-plane bash
  ​
  # ---- 容器内执行 ------
  # 更新并安装NFS服务(如果你已经安装过了就不用这一步了)
  apt update && apt install -y nfs-kernel-server
  ​
  # 创建共享目录
  mkdir /tmp/logs/{pv1,pv2,pv3} -pv
  # 把共享目录权限改成 “任何人可读可写可执行”
  chmod 777 /tmp/logs
  # 向 /etc/exports 追加一行 导出规则
  # 当然也可以手动进入 /etc/exports 然后编辑添加规则
  # 建议使用精准的网络白名单
  # 如172.18.0.0/24 只允许这一网段访问;写成 * 就是全网放通,风险高
  echo "/tmp/logs 172.18.0.0/24(rw,sync,no_subtree_check,no_root_squash)" > /etc/exports
  # 重新加载 /etc/exports 并立即生效
  exportfs -rav 
  # 重启 NFS 服务进程
  systemctl restart nfs-kernel-server
  # 如果不可用systemctl,可改为:
  service nfs-kernel-server restart
  ​
  # 退出控制面容器
  exit
②、创建PV
  # pv-nfs.yaml
  apiVersion: v1
  kind: PersistentVolume        # 声明资源类型是 PV
  metadata:
    name: pv1-nfs               # PV 对象在集群中的名称,可自定义
    # 由于 PV 是集群级资源,所以没有 namespace 的概念
    labels:
      app: pv1          # 可按需添加 label,方便选择器匹配
  spec:
    capacity:
      storage: 1Gi              # 声明的容量,PVC 申请量需 ≤ 该值
    accessModes:                # 访问模式
      - ReadWriteMany           # 允许多节点同时读写
    persistentVolumeReclaimPolicy: Retain     # 回收策略
    nfs:                        # 存储类型
      server: 172.18.0.4        # NFS 服务器 IP 或域名
      path: /tmp/logs/pv1       # NFS 导出的共享目录
    storageClassName: nfs-static         # 存储类别
  ---
  ​
  apiVersion: v1
  kind: PersistentVolume        # 声明资源类型是 PV
  metadata:
    name: pv2-nfs               # PV 对象在集群中的名称,可自定义
    # 由于 PV 是集群级资源,所以没有 namespace 的概念
    labels:
      app: pv2          # 可按需添加 label,方便选择器匹配
  spec:
    capacity:
      storage: 2Gi              # 声明的容量,PVC 申请量需 ≤ 该值
    accessModes:                # 访问模式
      - ReadWriteMany           # 允许多节点同时读写
    persistentVolumeReclaimPolicy: Retain     # 回收策略
    nfs:                        # 存储类型
      server: 172.18.0.4        # NFS 服务器 IP 或域名
      path: /tmp/logs/pv2       # NFS 导出的共享目录
    storageClassName: nfs-static         # 存储类别
  ---
  ​
  apiVersion: v1
  kind: PersistentVolume        # 声明资源类型是 PV
  metadata:
    name: pv3-nfs               # PV 对象在集群中的名称,可自定义
    # 由于 PV 是集群级资源,所以没有 namespace 的概念
    labels:
      app: pv3         # 可按需添加 label,方便选择器匹配
  spec:
    capacity:
      storage: 3Gi              # 声明的容量,PVC 申请量需 ≤ 该值
    accessModes:                # 访问模式
      - ReadWriteMany           # 允许多节点同时读写
    persistentVolumeReclaimPolicy: Retain     # 回收策略
    nfs:                        # 存储类型
      server: 172.18.0.4        # NFS 服务器 IP 或域名
      path: /tmp/logs/pv3       # NFS 导出的共享目录
    storageClassName: nfs-static         # 存储类别
③、验证
  # 创建PV
  kubectl create -f pv-nfs.yaml
  ​
  # 查看PV
  kubectl get pv -o wide

2、PVC

命名空间级资源,由用户/应用开发者创建。Kubernetes 的调度器负责把合适的 PV 绑定到这个 PVC 上。Pod 通过挂载 PVC,从而间接使用 PV

1.1配置文件
  # PVC 示例
  # 功能:向集群申请一块 3 GiB 的 NFS 存储,用于 Pod 挂载
  apiVersion: v1
  kind: PersistentVolumeClaim # 声明资源类型是 PVC
  metadata:
    name: pvc-logs            # PVC 在集群里的名字,Pod 通过这个名字引用
    namespace: default        # PVC 是命名空间级资源,按需改成自己的 ns
  spec:
    accessModes:
      - ReadWriteMany         # 必须与目标 PV 的 accessModes 完全一致
    resources:                # 请求空间
      requests:
        storage: 3Gi          # 申请的容量。只要 ≤ PV 的 capacity.storage 即可
    storageClassName: nfs-rwo # 存储类别
      # 1. 如果集群里给 NFS 手动创建的 PV 写了 storageClassName: nfs-rwo,
      #    这里就要写同样的值,才能匹配到该 PV(静态绑定)。
      # 2. 如果想走动态供给(StorageClass + NFS provisioner),
      #    则 storageClassName 指向对应的 StorageClass 名称即可;
      #    留空或写 "" 会落到集群的「默认 StorageClass」。
    # volumeName: pv-nfs-001  # 可选字段,强制绑定到某一台特定 PV
                              # 写死后即使其他 PV 更匹配也不会变,一般不建议用
    # selector:               # 可选,用 label 做更灵活的选择
    #   matchLabels:
    #     app: nfs-pv-demo

PVC的存储类别、访问模式、回收策略都与PV相同

1.2绑定引用测试
①、创建PVC
 # pvc-nfs.yaml
  apiVersion: v1
  kind: PersistentVolumeClaim # 声明资源类型是 PVC
  metadata:
    name: pvc1-nfs            # PVC 在集群里的名字,Pod 通过这个名字引用
    namespace: default        # PVC 是命名空间级资源,按需改成自己的 ns
  spec:
    accessModes:
      - ReadWriteMany         # 必须与目标 PV 的 accessModes 完全一致
    resources:                # 请求空间
      requests:
        storage: 1Gi          # 申请的容量。只要 ≤ PV 的 capacity.storage 即可
    storageClassName: nfs-static         # 存储类别
  ---
  ​
  apiVersion: v1
  kind: PersistentVolumeClaim # 声明资源类型是 PVC
  metadata:
    name: pvc2-nfs            # PVC 在集群里的名字,Pod 通过这个名字引用
    namespace: default        # PVC 是命名空间级资源,按需改成自己的 ns
  spec:
    accessModes:
      - ReadWriteMany         # 必须与目标 PV 的 accessModes 完全一致
    resources:                # 请求空间
      requests:
        storage: 1Gi          # 申请的容量。只要 ≤ PV 的 capacity.storage 即可
    storageClassName: nfs-static         # 存储类别
  ---
  ​
  apiVersion: v1
  kind: PersistentVolumeClaim # 声明资源类型是 PVC
  metadata:
    name: pvc3-nfs            # PVC 在集群里的名字,Pod 通过这个名字引用
    namespace: default        # PVC 是命名空间级资源,按需改成自己的 ns
  spec:
    accessModes:
      - ReadWriteMany         # 必须与目标 PV 的 accessModes 完全一致
    resources:                # 请求空间
      requests:
        storage: 4Gi          # 申请的容量。只要 ≤ PV 的 capacity.storage 即可
        # 当前第三个pvc的申请容量,超过所有pv的容量,所以无法绑定
    storageClassName: nfs-static         # 存储类别
②、测试绑定
  # 创建PVC
  kubectl create -f pvc-nfs.yaml
  ​
  # 查看PVC
  kubectl get pvc -o wide
  # 查看PV绑定情况
  kubectl get pv -o wide

如图:

③、创建Pod准备测试
  # 提供一个 Pod 准备进行 PVC → PV → NFS 链路打通测试
  apiVersion: v1
  kind: Pod
  metadata:
    name: test-pvc-mount        # Pod 名称,可随意改
  spec:
    containers:
    - name: nginx
      image: nginx:1.24.0
      ports:
      - containerPort: 80
      volumeMounts:
      - name: html              # 与 volumes.name 对应
        mountPath: /usr/share/nginx/html   # 容器内挂载点
    volumes:
    - name: html
      persistentVolumeClaim:
        claimName: pvc1-nfs     # 必须和已存在的 PVC 名字一致
    restartPolicy: Never        # 测试用,跑完即停;生产可用 Always
④、测试链路打通
  # 1. 应用文件,部署 Pod
  kubectl apply -f pod-test-pvc.yaml
  ​
  # 2. 验证部署成功
  kubectl get pod test-pvc-mount -w
  ​
  # 3. 进入 Pod 写文件
  kubectl exec -it test-pvc-mount -- sh -c 'echo "hello from pod" > /usr/share/nginx/html/index.html'
  ​
  # 4. 在 NFS 服务器或任何节点验证
  # 注意 my-multi-node-cluster1-control-plane 是我的 NFS 服务器名称,记得改为你自己的
  docker exec -it my-multi-node-cluster1-control-plane bash
  cat /tmp/logs/pv1/index.html
  # 应输出:hello from pod
  ​
  # 5. 清理
  kubectl delete -f pod-test-pvc.yaml

测试结果如下:

说明PVC → PV → NFS 链路打通,用户对于 Pod 的数据操作,实际存储在了与 Pod 连接的 PV,与 PV 绑定的 PVC 的存储系统之中,即 :用户→Pod→ PVC → PV → NFS(底层存储系统)

3、注意事项

PV和PVC未绑定检查步骤
1、容量(Capacity)

PVC 申请的 storage 必须 ≤ PV 声明的 capacity.storage,否则不会绑定。

  kubectl get pv,pvc -o wide
2、访问模式(AccessModes)

PVC 的 accessModes 必须是 PV 声明的访问模式的子集。例:PV 只有 RWO,PVC 却要求 RWX,就会一直 Pending

  kubectl describe pvc <pvc-name>
3、可用状态(Status)

PV 必须是 Available;如果已被别的 PVC 绑走,就会是 Bound。• 若 PV 是 Released(前一个 PVC 被删但 reclaimPolicy=Retain),需要手动把它重新设为 Available

4、StorageClassName 必须完全一致

• 如果 PV 写了 storageClassName: nfs-rwo,PVC 必须也写 storageClassName: nfs-rwo。• 如果 PV 的 storageClassName: ""(空串),PVC 也必须写 storageClassName: "",不能省略。

  kubectl get pv <pv-name> -o jsonpath='{.spec.storageClassName}'
  kubectl get pvc <pvc-name> -o jsonpath='{.spec.storageClassName}'
资源YAML 里 不写 storageClassName 字段时,实际值说明
PV""(空字符串)明确等于空串,不会被当成任何 StorageClass,只能与同样为 "" 的 PVC 匹配。
PVC集群中 标记为 default 的 StorageClass(通常是 standard如果集群设置了 default StorageClass,PVC 会自动填上它的名字;如果没有 default,则也为 ""
  • PVC 没写 ⇒ 自动落到 standard

  • PV 也没写 ⇒ 等于 ""(空串)

    可能会导致二者无法匹配绑定

4、生命周期

PV和PVC遵循类似的生命周期:

①、资源供应
  • PV已创建,未绑定待使用

②、资源绑定
  • PV和对应的PVC绑定,如果找不到应绑定的PV,PVC会一直处于Pending状态,一旦绑定,PVC独占PV

③、资源使用
  • Pod使用PVC

④、资源释放
  • PVC使用完PV后,释放PV,PV处于Released状态

⑤、资源回收
  • 通过提前设定的回收策略回收PV,只有PV存储空间回收完成,才能提供给新的PVC绑定

5、补充动态供给

上方所讲的是静态供给策略,用户将需要的资源要求发送给PVC来进行PV的匹配,如果有符合的就绑定,没有就不绑定,如用户要2.88GI,现在有的PV只有3GI且没有和其他的PVC绑定,这个3GI的PV就会和2.88GI的PVC绑定,但是如果这时候又有用户要0.18GI,当前没有和他匹配的PV,就不会进行绑定。

​ 现在所讲的动态供给策略就是对静态供给的一种优化,因为静态补给是我们管理员已经提前创建好了PV,但不一定是用户所需要的,所以可能导致PV和PVC不绑定,即使满足绑定要求,也不一定是最好的,如3GI的PV和2.88GI的PVC绑定。而动态供给是用户提出需求给PVC,PVC和云供应商在集群内的抽象(存储类)沟通,这时候按照请求来“定制”一个PV,使之绑定。

精简总结:静态PV是管理员提前创建好的,动态PV是等提出需求后按照需求创建的

StorageClass 是 Kubernetes 用来 “抽象并自动化持久存储供给(Provisioning)” 的一组对象。一句话:告诉集群“我需要什么类型、什么性能、多少副本的存储”,集群就按这个模板自动给你创建 PV。

存储类核心功能说明
动态供给PVC(PersistentVolumeClaim)一旦声明 StorageClass,集群会自动创建匹配的 PV,无需管理员手工建 PV。
参数模板存储类型、IOPS、副本数、加密、磁盘格式等全部写在 StorageClass 里,PVC 只需引用名字。
回收策略可指定 PV 释放后 Delete / Retain / Recycle 的行为。

提供一个简单StorageClass的示例:

  apiVersion: storage.k8s.io/v1
  kind: StorageClass
  metadata:
    name: sc-test                      # PVC 通过这个名字引用(可自定义)
  provisioner: kubernetes.io/aws-ebs   # 底层存储驱动
  parameters:
    type: gp3                          # AWS EBS 的 gp3 SSD
    iops: "3000"
    encrypted: "true"
  reclaimPolicy: Delete                # PVC 删除后自动回收 EBS

常见命令:

  # 查看集群有哪些 StorageClass
  kubectl get sc
  ​
  # 查看详情
  kubectl describe sc <你的存储类名称>
  ​
  # 设置默认 StorageClass
  kubectl patch sc fast-ssd -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
常见云厂商provisioner 示例
AWSkubernetes.io/aws-ebs
GCPkubernetes.io/gce-pd
Azurekubernetes.io/azure-disk / azurefile
阿里云diskplugin.csi.alibabacloud.com
腾讯云com.tencent.cloud.csi.cbs
本地rancher.io/local-path, openebs.io/local, rook-ceph.rbd.csi.ceph.com

想使用动态供给还需要我们完成k8s集群安全机制的学习,进行授权管理等等,所以现在就不演示

### Date类型数据格式及其编程处理 #### SCL中字符串日期转换为DATE类型 在TIA博途SCL编程环境中,可以利用特定函数实现字符串到`DATE`类型的转换。对于形如‘20181220’这样的字符串表示的日期,通过解析各个组成部分并构建相应的`DATE`对象完成转换操作[^1]。 ```scl // 假设输入字符串为 sDate='20181220' STRING(8) sYear := SUBSTR(sDate, 1, 4); STRING(2) sMonth := SUBSTR(sDate, 5, 2); STRING(2) sDay := SUBSTR(sDate, 7, 2); INT nYear,nMonth,nDay; nYear:= INT#sYear; nMonth:= INT#sMonth; nDay:= INT#sDay; DATE dResult := DATE(nYear, nMonth, nDay); // 构建DATE变量 ``` #### Java向Oracle数据库插入DATE类型数据 当涉及到Java应用程序与Oracle数据库交互时,通常会遇到需要将字符串形式的时间戳转化为适合存储于表单内的`DATE`字段的情况。此时可借助`SimpleDateFormat`类来进行格式化和解析工作[^2]。 ```java import java.text.SimpleDateFormat; import java.util.Date; String dateStr = "2023-09-15"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { Date day = sdf.parse(dateStr); } catch (Exception e) { System.out.println(e.getMessage()); } ``` #### Python中Object转Date类型 针对Python环境下,尤其是数据分析场景下常见的Pandas库应用场合,有时需确保DataFrame内某列的数据被正确认定为时间序列而非泛型的对象(Object),这有助于后续更高效地执行基于时间段的操作以及可视化展示等任务[^3]。 ```python import pandas as pd df = pd.DataFrame({'dates': ['2023/01/01', '2023/02/01']}) df['dates'] = pd.to_datetime(df['dates']) print(type(df.iloc[0]['dates'])) # 输出:<class 'pandas._libs.tslibs.timestamps.Timestamp'> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值