存储

news/2024/10/19 10:04:12

容器中的文件在磁盘上是临时存放的,这给在容器中运行较重要的应用带来一些问题。 当容器崩溃或停止时会出现一个问题。此时容器状态未保存, 因此在容器生命周期内创建或修改的所有文件都将丢失。 在崩溃期间,kubelet 会以干净的状态重新启动容器。 当多个容器在一个 Pod 中运行并且需要共享文件时,会出现另一个问题。 跨所有容器设置和访问共享文件系统具有一定的挑战性。

Kubernetes 卷(Volume) 这一抽象概念能够解决这两个问题。

emptyDir

对于定义了 emptyDir 卷的 Pod,在 Pod 被指派到某节点时此卷会被创建。 就像其名称所表示的那样,emptyDir 卷最初是空的。尽管 Pod 中的容器挂载 emptyDir 卷的路径可能相同也可能不同,但这些容器都可以读写 emptyDir 卷中相同的文件。 当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会被永久删除。

emptyDir 配置

[root@master NFS-storageclass]# cat po-2.yaml 
apiVersion: v1
kind: Pod
metadata:name: test-pd
spec:containers:- image: registry.k8s.io/test-webservername: test-containervolumeMounts:- mountPath: /cachename: cache-volumevolumes:- name: cache-volumeemptyDir:sizeLimit: 500Mi
[root@master NFS-storageclass]# kubectl apply -f po-2.yaml 
pod/test-pd created
[root@master NFS-storageclass]# kubectl get po test-pd 
NAME      READY   STATUS    RESTARTS   AGE
test-pd   1/1     Running   0          2m2s

  

hostPath

hostPath 卷能将主机节点文件系统上的文件或目录挂载到你的 Pod 中。 虽然这不是大多数 Pod 需要的,但是它为一些应用提供了强大的逃生舱。

hostPath 的一些用法有:

  • 运行一个需要访问节点级系统组件的容器 (例如一个将系统日志传输到集中位置的容器,使用只读挂载 /var/log 来访问这些日志)
  • 让存储在主机系统上的配置文件可以被静态 Pod 以只读方式访问;与普通 Pod 不同,静态 Pod 无法访问 ConfigMap
[root@master svc]# cat ../host/po.yaml 
apiVersion: v1
kind: Pod
metadata:name: host
spec:volumes:- name: test-hosthostPath:path: /datacontainers:- name: webimage: nginximagePullPolicy: IfNotPresentvolumeMounts:- name: test-hostmountPath: /test- name: cximage: tomcat:10imagePullPolicy: IfNotPresentvolumeMounts:- name: test-hostmountPath: /chenxi
[root@master host]# kubectl exec -it host -c cx -- /bin/sh
# ls /    
bin   __cacert_entrypoint.sh  dev  home  lib64	mnt  proc  run	 srv  tmp  var
boot  chenxi		      etc  lib	 media	opt  root  sbin  sys  usr
# cd chenxi
/bin/sh: 2: cd: can't cd to chenxi
# ^[[A^[[B
/bin/sh: 3: : not found
# /bin/bash
root@host:/usr/local/tomcat# cd /chenxi/
root@host:/chenxi# echo "chenxi" > tomcat.txt
root@host:/chenxi# ls
tomcat.txt
[root@master ~]# kubectl exec -it host -c web -- /bin/bash
root@host:/# ls /test/
tomcat.txt
root@host:/# echo "nginx" >/test/nginx.txt
[root@master svc]# kubectl get po host -owide 
NAME   READY   STATUS    RESTARTS   AGE     IP              NODE     NOMINATED NODE   READINESS GATES
host   2/2     Running   0          6m52s   172.16.84.140   node-1   <none>           <none>
[root@node-1 ~]# ls /data/
nginx.txt  tomcat.txt

  nfs

nfs 卷能将 NFS (网络文件系统) 挂载到你的 Pod 中。 不像 emptyDir 那样会在删除 Pod 的同时也会被删除,nfs 卷的内容在删除 Pod 时会被保存,卷只是被卸载。 这意味着 nfs 卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享。

[root@master ~]# cat /etc/exports
/data/kubernetes/pv1  192.168.10.0/24(rw,sync,no_root_squash,no_all_squash)
/data/kubernetes/pv2  192.168.10.0/24(rw,sync,no_root_squash,no_all_squash)
/data/kubernetes/pv3  192.168.10.0/24(rw,sync,no_root_squash,no_all_squash)
/data/kubernetes/pv4  192.168.10.0/24(rw,sync,no_root_squash,no_all_squash)
/data/kubernetes/pv5  192.168.10.0/24(rw,sync,no_root_squash,no_all_squash)
/data/kubernetes/pv6  192.168.10.0/24(rw,sync,no_root_squash,no_all_squash)
[root@master NFS-storageclass]# cat po.yaml 
apiVersion: v1
kind: Pod
metadata: name: nfs-1
spec: containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- name: webcontainerPort: 80volumeMounts:- name: nfs-volumesmountPath: /nginxvolumes:- name: nfs-volumesnfs:server: 192.168.10.29path: /data/kubernetes/pv2
[root@master NFS-storageclass]# kubectl apply -f po.yaml 
pod/nfs-1 created
[root@master NFS-storageclass]# kubectl describe pod nfs-1 
Name:             nfs-1
Namespace:        default
Priority:         0
Service Account:  default
Node:             node-1/192.168.10.30
Start Time:       Fri, 18 Oct 2024 10:02:04 +0800
Labels:           <none>
Annotations:      cni.projectcalico.org/containerID: ce2101862c7aaafc907faf6652859a564c3d63770892e2f91acf357fb245ef00cni.projectcalico.org/podIP: 172.16.84.139/32cni.projectcalico.org/podIPs: 172.16.84.139/32
Status:           Running
IP:               172.16.84.139
IPs:IP:  172.16.84.139
Containers:nginx:Container ID:   containerd://036aed08ecdce0b3aee06a5369673ae54123362fa4c43ab00b52ef0be7efb009Image:          nginxImage ID:       docker.io/library/nginx@sha256:d2eb56950b84efe34f966a2b92efb1a1a2ea53e7e93b94cdf45a27cf3cd47fc0Port:           80/TCPHost Port:      0/TCPState:          RunningStarted:      Fri, 18 Oct 2024 10:02:05 +0800Ready:          TrueRestart Count:  0Environment:    <none>Mounts:/nginx from nfs-volumes (rw)/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-b8h9m (ro)
Conditions:Type              StatusInitialized       True Ready             True ContainersReady   True PodScheduled      True 
Volumes:nfs-volumes:Type:      NFS (an NFS mount that lasts the lifetime of a pod)Server:    192.168.10.29Path:      /data/kubernetes/pv2ReadOnly:  falsekube-api-access-b8h9m:Type:                    Projected (a volume that contains injected data from multiple sources)TokenExpirationSeconds:  3607ConfigMapName:           kube-root-ca.crtConfigMapOptional:       <nil>DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300snode.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:Type    Reason     Age   From               Message----    ------     ----  ----               -------Normal  Scheduled  27s   default-scheduler  Successfully assigned default/nfs-1 to node-1Normal  Pulled     27s   kubelet            Container image "nginx" already present on machineNormal  Created    26s   kubelet            Created container nginxNormal  Started    26s   kubelet            Started container nginx
[root@master NFS-storageclass]# kubectl exec -it nfs-1  -- /bin/bash
root@nfs-1:/# ls nginx/
root@nfs-1:/# cd /nginx/
root@nfs-1:/nginx# echo "nginx" > nginx.txt 
root@nfs-1:/nginx# ls
nginx.txt
[root@master ~]# ls /data/kubernetes/pv2/
nginx.txt
[root@master ~]# cat /data/kubernetes/pv2/
cat: /data/kubernetes/pv2/: 是一个目录
[root@master ~]# cat /data/kubernetes/pv2/nginx.txt 
nginx

 Persistent Volumes

本文描述 Kubernetes 中的持久卷(Persistent Volumes)

PersistentVolume 子系统为用户和管理员提供了一组 API, 将存储如何制备的细节从其如何被使用中抽象出来。 为了实现这点,我们引入了两个新的 API 资源:PersistentVolume 和 PersistentVolumeClaim。

持久卷(PersistentVolume,PV) 是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样, 也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。

持久卷申领(PersistentVolumeClaim,PVC) 表达的是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存)。同样 PVC 申领也可以请求特定的大小和访问模式 (例如,可以挂载为 ReadWriteOnce、ReadOnlyMany、ReadWriteMany 或 ReadWriteOncePod, 请参阅访问模式)。

尽管 PersistentVolumeClaim 允许用户消耗抽象的存储资源, 常见的情况是针对不同的问题用户需要的是具有不同属性(如,性能)的 PersistentVolume 卷。 集群管理员需要能够提供不同性质的 PersistentVolume, 并且这些 PV 卷之间的差别不仅限于卷大小和访问模式,同时又不能将卷是如何实现的这些细节暴露给用户。 为了满足这类需求,就有了存储类(StorageClass) 资源。

卷和申领的生命周期 

PV 卷是集群中的资源。PVC 申领是对这些资源的请求,也被用来执行对资源的申领检查。 PV 卷和 PVC 申领之间的互动遵循如下生命周期:

制备

PV 卷的制备有两种方式:静态制备或动态制备。

静态制备

集群管理员创建若干 PV 卷。这些卷对象带有真实存储的细节信息, 并且对集群用户可用(可见)。PV 卷对象存在于 Kubernetes API 中,可供用户消费(使用)。

动态制备

如果管理员所创建的所有静态 PV 卷都无法与用户的 PersistentVolumeClaim 匹配, 集群可以尝试为该 PVC 申领动态制备一个存储卷。 这一制备操作是基于 StorageClass 来实现的:PVC 申领必须请求某个 存储类, 同时集群管理员必须已经创建并配置了该类,这样动态制备卷的动作才会发生。 如果 PVC 申领指定存储类为 "",则相当于为自身禁止使用动态制备的卷。

为了基于存储类完成动态的存储制备,集群管理员需要在 API 服务器上启用 DefaultStorageClass 准入控制器。 举例而言,可以通过保证 DefaultStorageClass 出现在 API 服务器组件的 --enable-admission-plugins 标志值中实现这点;该标志的值可以是逗号分隔的有序列表。 关于 API 服务器标志的更多信息,可以参考 kube-apiserver 文档。

绑定

用户创建一个带有特定存储容量和特定访问模式需求的 PersistentVolumeClaim 对象; 在动态制备场景下,这个 PVC 对象可能已经创建完毕。 控制平面中的控制回路监测新的 PVC 对象,寻找与之匹配的 PV 卷(如果可能的话), 并将二者绑定到一起。 如果为了新的 PVC 申领动态制备了 PV 卷,则控制回路总是将该 PV 卷绑定到这一 PVC 申领。 否则,用户总是能够获得他们所请求的资源,只是所获得的 PV 卷可能会超出所请求的配置。 一旦绑定关系建立,则 PersistentVolumeClaim 绑定就是排他性的, 无论该 PVC 申领是如何与 PV 卷建立的绑定关系。 PVC 申领与 PV 卷之间的绑定是一种一对一的映射,实现上使用 ClaimRef 来记述 PV 卷与 PVC 申领间的双向绑定关系。

如果找不到匹配的 PV 卷,PVC 申领会无限期地处于未绑定状态。 当与之匹配的 PV 卷可用时,PVC 申领会被绑定。 例如,即使某集群上制备了很多 50 Gi 大小的 PV 卷,也无法与请求 100 Gi 大小的存储的 PVC 匹配。当新的 100 Gi PV 卷被加入到集群时, 该 PVC 才有可能被绑定。

使用

Pod 将 PVC 申领当做存储卷来使用。集群会检视 PVC 申领,找到所绑定的卷, 并为 Pod 挂载该卷。对于支持多种访问模式的卷, 用户要在 Pod 中以卷的形式使用申领时指定期望的访问模式。

一旦用户有了申领对象并且该申领已经被绑定, 则所绑定的 PV 卷在用户仍然需要它期间一直属于该用户。 用户通过在 Pod 的 volumes 块中包含 persistentVolumeClaim 节区来调度 Pod,访问所申领的 PV 卷。 相关细节可参阅使用申领作为卷。

保护使用中的存储对象

保护使用中的存储对象(Storage Object in Use Protection) 这一功能特性的目的是确保仍被 Pod 使用的 PersistentVolumeClaim(PVC) 对象及其所绑定的 PersistentVolume(PV)对象在系统中不会被删除,因为这样做可能会引起数据丢失。

PV

[root@master pv]# cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:name: nfs-cx
spec:capacity: storage: 1GiaccessModes: ["ReadWriteOnce"]nfs:server: 192.168.10.29path: /data/kubernetes/pv3
---
apiVersion: v1
kind: PersistentVolume
metadata:name: nfs-cx-2
spec:capacity: storage: 2GiaccessModes: ["ReadWriteMany"]nfs:server: 192.168.10.29path: /data/kubernetes/pv4
[root@master pv]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                STORAGECLASS          REASON   AGE
nfs-cx                                     1Gi        RWO            Retain           Available                                                       8m20s
nfs-cx-2                                   2Gi        RWX            Retain           Available                                                       8m20s
[root@master pv]# cat pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: cx-pvc
spec:accessModes: ["ReadWriteMany"]resources:requests:storage: 2Gi [root@master pv]# kubectl get pvc
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
cx-pvc       Bound    nfs-cx-2                                   2Gi        RWX                                  9m43s[root@master pv]# cat po.yaml 
apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: myfrontendimage: nginxvolumeMounts:- mountPath: "/var/www/html"name: mypdvolumes:- name: mypdpersistentVolumeClaim:claimName: cx-pvc
[root@master pv]# kubectl describe po mypod 
Name:             mypod
Namespace:        default
Priority:         0
Service Account:  default
Node:             node-2/192.168.10.31
Start Time:       Sat, 19 Oct 2024 09:28:22 +0800
Labels:           <none>
Annotations:      cni.projectcalico.org/containerID: 59ba3be077ca2c966a44cbd16404fcf88075394125a16d4e4c32cba4a7a281e3cni.projectcalico.org/podIP: 172.16.247.40/32cni.projectcalico.org/podIPs: 172.16.247.40/32
Status:           Running
IP:               172.16.247.40
IPs:IP:  172.16.247.40
Containers:myfrontend:Container ID:   containerd://3817af539efa8fd11e1f082cfb57d315ecfb48db14ed951c9e124c0901ba58dfImage:          nginxImage ID:       docker.io/library/nginx@sha256:28402db69fec7c17e179ea87882667f1e054391138f77ffaf0c3eb388efc3ffbPort:           <none>Host Port:      <none>State:          RunningStarted:      Sat, 19 Oct 2024 09:28:53 +0800Ready:          TrueRestart Count:  0Environment:    <none>Mounts:/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-vv7kt (ro)/var/www/html from mypd (rw)
Conditions:Type              StatusInitialized       True Ready             True ContainersReady   True PodScheduled      True 
Volumes:mypd:Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)ClaimName:  cx-pvcReadOnly:   falsekube-api-access-vv7kt:Type:                    Projected (a volume that contains injected data from multiple sources)TokenExpirationSeconds:  3607ConfigMapName:           kube-root-ca.crtConfigMapOptional:       <nil>DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300snode.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:Type    Reason     Age    From               Message----    ------     ----   ----               -------Normal  Scheduled  5m24s  default-scheduler  Successfully assigned default/mypod to node-2Normal  Pulling    5m22s  kubelet            Pulling image "nginx"Normal  Pulled     4m53s  kubelet            Successfully pulled image "nginx" in 28.407s (28.408s including waiting)Normal  Created    4m53s  kubelet            Created container myfrontendNormal  Started    4m53s  kubelet            Started container myfrontend

  存储类: https://www.cnblogs.com/rdchenxi/p/17113820.html

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/73351.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Linux系统命令3

1、df 查看磁盘使用情况Filesystem:代表该文件系统时哪个分区,所以列出的是设备名称。 1K-blocks:说明下面的数字单位是1KB,可利用-h或-m来改变单位大小,也可以用-B来设置。 Used:已经使用的空间大小。Available:剩余的空间大小。 Use%:磁盘使用率。如果使用率在90%以上…

线性表学习1

线性结构 若结构是非空有限集,则有且仅有一个开始结点和一个终端结点,并且除了首尾节点外所有结点都最多只有一个直接前趋和一个直接后继。 可表示为:(a1,a2,a3,...) 特点:只有一个首结点和尾结点 本质特征:除首尾结点外,其他结点只有一个直接前驱和一个直 接后继。 简言…

学习 gradle 基础

简介 Gradle 的优势一款最新的,功能最强大的构建工具,用它逼格更高 使用 Groovy 或者 Kotlin 代替 XML,使用程序代替传统的 XML 配置,项目构建更灵活 丰富的第三方插件,让你随心所欲使用 完善 Android,Java 开发技术体系下载和安装 官网地址 https://services.gradle.org…

AutoResetEvent双向信号(生产者和消费者)例子

AutoResetEvent是一个非常有用的线程同步机制,尤其是在处理生产者和消费者问题的时候,尤其适用。本随笔记录下生产者和消费者一对一问题的两种写法并进行代码执行逻辑的分析,来加深对AutoResetEvent的理解。 写法一:internal class Program {public static AutoResetEvent …

数据采集和融合技术作业1

作业① 1)用requests和BeautifulSoup库方法定向爬取给定网址的数据,屏幕打印爬取的大学排名信息。 a、主要代码解析 该函数从获取的JSON数据中提取前 num 名大学的信息,并将这些信息存储到 ulist 列表中,同时格式化输出这些大学的排名信息 def printUnivList(ulist, html, …

沃顿商学院商业人工智能笔记-六-

沃顿商学院商业人工智能笔记(六) P46:12_简介.zh_en - GPT中英字幕课程资源 - BV1Ju4y157dK 嗨,我是迈克尔罗伯茨。我是威廉H罗伯茨教授。 我是宾夕法尼亚大学沃顿商学院的金融学劳伦斯教授。 在这一系列视频中,我们将讨论金融、机器学习。以及人工智能。因此,当我想到金…

沃顿商学院商业人工智能笔记-九-

沃顿商学院商业人工智能笔记(九) P82:19_更广泛的隐私和伦理问题.zh_en - GPT中英字幕课程资源 - BV1Ju4y157dK 所以让我们讨论一下关于使用数据科学和人工智能的一些更广泛的问题。一般来说,在工作场所管理人际关系。这些是伦理问题,也是隐私问题。 所以让我们谈谈这些问…

沃顿商学院商业人工智能笔记-三-

沃顿商学院商业人工智能笔记(三) P123:22_AI的风险.zh_en - GPT中英字幕课程资源 - BV1Ju4y157dK 在这次讲座中,我们将讨论AI的一些风险。我将以一个简单的统计风险开始,它有重要的管理意义。 然后我会谈论社会和伦理风险。 所以我想讨论的第一个风险是过拟合风险。 现在,…