kubernetes重要概念(Kubernetes系列二十一)
kubernetes重要概念(Kubernetes系列二十一)这个问题的解决方案是在 Kubernetes 集群使用共享存储系统。如 NFS、aws EFS。hostPath 卷只在单节点集群中工作正常。但不是在多节点集群中。因为在 deployment/replicaSet下的 pods 将在所有节点上使用 /var/local/data 目录,并期望所有节点包含相同的数据。但这是不可能的,因为它们是不同的节点。hostPath Volume#poddefinitionfilewithavolumeapiVersion:v1 kind:Pod metadata: name:webserver spec: containers: -image:nginx:latest name:nginx-container volumeMounts: -mountPath:/usr/share/nginx/html name:test-volvolumes: -n
Kubernetes 系列(二十一)深入 Kubernetes | Storage深入了解 Kubernetes 存储
卷Kubernetes卷是一个目录,它包含了Pod内容器可访问的数据。卷提供了一种插件机制来连接临时容器和其他地方的持久数据存储。
在本文中你将了解到:
卷的种类hostpath 类型的卷将 /var/local/data 目录作为卷从主机挂载到 pod 的 nginx 容器的 /usr/share/nginx/html 位置。
hostPath Volume
#poddefinitionfilewithavolumeapiVersion:v1
kind:Pod
metadata:
name:webserver
spec:
containers:
-image:nginx:latest
name:nginx-container
volumeMounts:
-mountPath:/usr/share/nginx/html
name:test-volvolumes:
-name:test-vol
hostPath:
path:/var/local/data
type:DirectoryOrCreate
任何由 nginx-container 在 /usr/share/nginx/html 位置写入的数据将被持久化在主机目录:/var/local/data。如果pod终止,数据将在 /var/local/data 位置保持安全。
在前面,使用了来自主机机器的一个目录作为卷。它被称为 hostPath 卷。但是有一个重要的事实要记住, hostPath 卷不建议用于生产级应用程序。
hostPath 卷只在单节点集群中工作正常。但不是在多节点集群中。因为在 deployment/replicaSet下的 pods 将在所有节点上使用 /var/local/data 目录,并期望所有节点包含相同的数据。但这是不可能的,因为它们是不同的节点。
这个问题的解决方案是在 Kubernetes 集群使用共享存储系统。如 NFS、aws EFS。
Kubernetes 还支持多种类型的标准存储解决方案,如NFS、glusterFS,或公有云解决方案,如AWS EBS、AWS EFS、Azure磁盘或文件、谷歌的持久磁盘等。
NFS 共享作为卷使用 nfs 共享目录创建一个卷,并将其关联到一个pod。使用NFS,数据可以在pods之间共享,尽管它们运行在不同的工作节点或可用分区中。
#PoddefinitonwithnfssharedirectoryapiVersion:v1
kind:Pod
metadata:
name:webserver
spec:
containers:
-image:nginx:latest
name:nginx-container
volumeMounts:
-mountPath:/usr/share/nginx/html
name:test-vol
volumes:
-name:test-vol
nfs:
server:10.3.97.250#nfsserveripordns
path:/var/local/nfs-share#nfssharedirectory
使用 AWS EBS 卷
使用AWS-CLI创建一个卷,并记录“VolumeId”,以便将该卷附加到一个pod。
awsec2create-volume\
--availability-zoneap-northeast-1d\
--size10\
--volume-typegp2\
--query"VolumeId"--outputtext
#PoddefinitionwithnodeaffinityapiVersion:v1
kind:Pod
metadata:
name:webserver
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
-matchExpressions:
-key:topology.Kubernetes.io/zone
operator:In
values:
-ap-northeast-1d
containers:
-image:nginx:latest
name:nginx-container
volumeMounts:
-mountPath:/usr/share/nginx/html
name:test-volume
volumes:
-name:test-volume
awsElasticBlockStore:#ThisAWSEBSVolumemustalreadyexist
volumeID:"vol-0b067ed35227a1bff"#Volume-id
fsType:ext4
由于EBS卷创建在“ap-northeast-1d”AZ中,所以要将卷挂载到pod上,pod应该位于同一个AZ中。这就是使用节点关联将pod部署在与EBS卷位于同一AZ中的节点上的原因。
ConfigMap 作为卷现有的 configmap 可以作为一个卷注入到pods中。
#Pod-definitionwithconfigmapmountedasavolumeintothepodapiVersion:v1
kind:Pod
metadata:
name:web-server
spec:
containers:
-name:wordpress
image:wordpress
volumeMounts:
-name:config-volume
mountPath:/etc/config#Directorywherefileswillbemounted
volumes:
-name:config-volume
configMap:
name:user-config
Secret 作为卷
现有的 secret 可以作为一个卷注入到 pod 中。
#Pod-definitionwithsecretmountedasavolumeintothepodapiVersion:v1
kind:Pod
metadata:
name:frontend
spec:
containers:
-name:wordpress
image:wordpress
volumeMounts:
-name:secret-vol01
mountPath:/etc/secret#files-mountedinthislocation
readOnly:true
volumes:
-name:secret-vol01
secret:
secretName:app-secret
持久卷(PV)
持久卷是管理员在集群中放置的一块存储。它是集群中的资源,就像节点是集群中的一样。持久卷是一个卷插件,它的生命周期独立于使用持久卷的任何独立pod。
持久卷要求(pvc)一个PersistentVolumeClaim (PVC)是一个用户对存储的请求。它类似于Pod。Pods消耗节点资源,pvc 消耗 pv 资源。总之,PV 是由 PVC 请求使用的,PV和PVC之间是一对一的关系。PVC通过指定持久卷所需的最小大小和访问模式来配置。
如果匹配的卷不存在,PVC将无限期地保持未绑定状态。只要有匹配的PV可用,请求将被绑定。
创建 PV
>kubectlcreate-f<pv-manifest-file>.yaml#PVusinghostdirectoryapiVersion:v1
kind:PersistentVolume
metadata:
name:pv-volume01
labels:
storage-tier:standard
spec:
capacity:
storage:50Mi
accessModes:
-ReadWriteMany
persistentVolumeReclaimPolicy:Retain
hostPath:
path:/var/local/data#PVusingNFS-SharedirectoryapiVersion:v1
kind:PersistentVolume
metadata:
name:pv-nfsspec:
capacity:
storage:20Gi
accessModes:
-ReadWriteOnce
nfs:
path:/var/nfs_server/kubernetes_data
server:10.25.96.6#IPorDNSofnfsserver
Capacity — PV 拥有特定的存储容量。这是使用PV的 capacity 属性设置的。
accessModes — 访问模式
ReadWriteOnce — 卷可以被单个节点挂载为读写状态.
ReadWriteOnly — 卷可以被多个节点挂载为只读。
ReadWriteMany — 许多节点可以将卷挂载为读写状态。
ReadWriteOncePod — 卷可以被一个 Pod 挂载为读写状态。
persistentVolumeReclaimPolicy —
Retain — 关联pod终止后,卷将被保留。
Delete — 关联pod终止后,卷将被删除。
Recycle — 卷将被回收以备将来使用。
目前只有NFS和HostPath支持回收。AWS EBS卷、GCE PD卷、Azure Disk卷、Cinder卷支持删除。
volume type —
支持很多卷类型,如hostPath nfs aws ebs azureDisk和更多。
创建 PVC#PVCwithoutselectorapiVersion:v1
kind:PersistentVolumeClaim
metadata:
name:myclaim
spec:
accessModes:
-ReadWriteMany
resources:
requests:
storage:50Mi#PVCwithselectorapiVersion:v1
kind:PersistentVolumeClaim
metadata:
name:myclaim
spec:
accessModes:
-ReadWriteMany
resources:
requests:
storage:70Mi
selector:
matchLabels:
storage-tier:standard
accessModes — 同 PV
resources —在这个字段中,pod 可以请求特定大小的存储资源。
selector —带有 selector 选择器的请求,尝试匹配现有的、未被使用的和可用的PV。PVC与选择器总是请求 拥有matchLabels和accessModes精确匹配彼此的 PV。
绑定用户使用请求的特定存储量和特定访问模式创建一个PersistentVolumeClaim。主节点中的控制回路总是监视新的PVCs,找到匹配的PV(如果可能的话),并将它们绑定在一起。
绑定规则:
● accessMode PV和PVC的accessMode必须匹配。
● PVC要求的存储容量必须等于或小于PV的存储容量。相等的匹配总是会获得优先级。但如果没有精确的匹配,那么PVC将请求拥有一个比PVC所要求的更大的存储容量的PV。
50Gi PV将匹配一个请求50Gi 的 PVC。50Gi PV将匹配一个请求40Gi 的 PVC(如果没有精确的匹配存在) 50Gi PV将无法匹配一个请求100Gi 的 PVC
● 配置了 selector 的PVC总是请求匹配标签和accessModes 以及存储容量匹配标准保持上述相同的 PV。
PV binding with PVC- Image-1
PV binding with PVC- Image-2
PV 和 PVC 相关命令:#ForcreatingPVandPVChost~$kubectlcreate-f<file-name>.yaml
host~$kubectlcreate-fpv.yaml
host~$kubectlcreate-fpvc.yaml
#ForlistingPVandPVChost~$kubectlgetpv
host~$kubectlgetpvc
#ForviewingdetailsofPVandPVChost~$kubectldescribepv<pv-name>
host~$kubectldescribepvc<pvc-name>
#FordeletingPVandPVC(PVCshouldbedeletedfirst)host~$kubectldeletepvc<pvc-name>
host~$kubectldeletepv<pv-name>
阶段(Phase)
PV将处于以下阶段之一:
Available — 一个空闲的资源,还没有被请求绑定。
Bound — 卷已经绑定到一个请求
Released — 声明已被删除,但资源尚未回收。
Failed — 卷的自动回收失败。
使用 PVC 作为卷Pods可以通过使用声明作为一个卷来访问存储。声明必须与使用声明的Pod 位于同一个命名空间。集群在Pod的命名空间中找到声明,并搜索合适的匹配并绑定它们。
#UsageofPVCasaVolumesapiVersion:v1
kind:Pod
metadata:
name:web-server
spec:
containers:
-name:nginx-webserver
image:nginx
volumeMounts:
-name:webserver-vol01
mountPath:"/usr/share/nginx/html"
volumes:
-name:webserver-vol01
persistentVolumeClaim:
claimName:myclaim
O 概述- PV、PVC和PVC作为一个卷
apiVersion:v1
kind:PersistentVolume
metadata:
name:pv-volume01
spec:
capacity:
storage:50Mi
accessModes:
-ReadWriteMany
persistentVolumeReclaimPolicy:Retain
hostPath:
path:/var/local/data---
apiVersion:v1
kind:PersistentVolumeClaim
metadata:
name:myclaim
spec:
accessModes:
-ReadWriteMany
resources:
requests:
storage:50MiapiVersion:v1
kind:Pod
metadata:
name:web-server
spec:
containers:
-name:nginx-webserver
image:nginx
volumeMounts:
-name:webserver-vol01
mountPath:"/usr/share/nginx/html"
volumes:
-name:webserver-vol01
persistentVolumeClaim:
claimName:myclaim
动态配置 (provisioning)
到目前为止,PV都是我们自己从现有的存储中创建出来的。这就是所谓的静态配置。但是想象一下我们使用AWS-EBS作为存储解决方案的生产环境。当pod需要存储时,我们需要在AWS上手动供应EBS卷,然后通过使用该EBS卷配置PV。
如果在pod需要时自动配置卷,这将会更方便,因为这是 storage class 进入image 的地方。通过 storage class,我们可以在AWS上动态提供一个EBS卷,并在声明请求时将其附加到pods上。
Storage Class一个Kubernetes StorageClass是一个Kubernetes存储机制,它允许我们在Kubernetes集群中动态地提供持久卷(PV)。使用 storage class,pod可以根据需要动态请求特定类型的存储。
Dynamic Provisioning 动态配置
每个StorageClass都包含字段:provisioner、parameters 和reclaimPolicy,当需要动态供应属于该类的持久卷时,将使用这些字段。
AWS EBS卷的 storage class (使用内部 provisioner)
apiVersion:storage.k8s.io/v1
kind:StorageClass
metadata:
name:gp2-standard
provisioner:kubernetes.io/aws-ebs#Internal-provisioner
parameters:
type:gp2
reclaimPolicy:Retain
volumeBindingMode:Immediate
一个StorageClass对象包含一个 provisioner,它决定将使用哪个卷插件来供应PV。Kubernetes提供internal 和 external provisioner。Internal provisioners 也被称为“In-tree”卷插件,这意味着它们的代码是Kubernetes核心代码的一部分,并与Kubernetes核心二进制文件一起导入。我们还可以指定并运行一个 external provisioner,它被定义为容器存储接口(CSI)。
parameters: 底层存储系统的属性。
reclaimPolicy: 可以是 Delete 或 Retain。默认是 Delete
volumeBindingMode: 可以是 Immediate 或 WaitForFirstConsumer
Immediate — PVC 创建后立即提供PV。WaitForFirstConsumer— 将延迟 PV 的供应,直到使用PVC的Pod被创建。
SAWS EBS卷的 storage class (使用CSI)
apiVersion:storage.k8s.io/v1
kind:StorageClass
metadata:
name:ebs-sc
provisioner:ebs.csi.aws.com#EBSCSIasprovisioner
volumeBindingMode:WaitForFirstConsumer
存储类不仅动态地提供PV,而且允许我们使用底层存储系统的不同参数创建不同类型的存储类。例如对于AWS EBS,有各种类型的EBS卷(gp2、gp3、io1、io2等)。此外,还可以进行各种配置,例如,为EBS卷启用加密、指定最小IOPS和最小吞吐量。
具有不同参数的存储类示例-
apiVersion:storage.k8s.io/v1
kind:StorageClass
metadata:
name:gp2-standard
provisioner:ebs.csi.aws.com
parameters:
type:gp2
volumeBindingMode:Immediate
reclaimPolicy:RetainapiVersion:storage.k8s.io/v1
kind:StorageClass
metadata:
name:io2-encrypted
provisioner:ebs.csi.aws.com
parameters:
type:io2
iopsPerGB:"3000"
encrypted:"true"
volumeBindingMode:WaitForFirstConsumer
reclaimPolicy:Delete
现在,我们将测试EBS卷的动态配置。遵循以下步骤-
根据下面的清单文件,创建 storageclass
kcreate-fhttps://raw.githubusercontent.com/shamimice03/AWS_EKS-EBS_CSI/main/Demo-storageClass.yaml
apiVersion:storage.k8s.io/v1
kind:StorageClass
metadata:
name:gp2-encrypted
annotations:
storageclass.kubernetes.io/is-default-class:"true"#MakethisstorageClassasDefault
provisioner:ebs.csi.aws.com#AmazonEBSCSIdriver
parameters:
type:gp2
encrypted:'true'#EBSvolumeswillalwaysbeencryptedbydefault
volumeBindingMode:WaitForFirstConsumer
reclaimPolicy:Delete
mountOptions:
-debug
依次创建一个持久卷声明(PVC),并将PVC作为一个卷附加到一个 pod 中。
使用下面的清单文件:
kubectlcreate-fhttps://raw.githubusercontent.com/shamimice03/AWS_EKS-EBS_CSI/main/pvc-pod.yaml
---
#PVCdefinition
apiVersion:v1
kind:PersistentVolumeClaim
metadata:
name:ebs-claim-01
spec:
storageClassName:gp2-encrypted
accessModes:
-ReadWriteOnce
resources:
requests:
storage:10Gi
---
#PoddefinitionwithPVCasaVolume
apiVersion:v1
kind:Pod
metadata:
name:webserver
spec:
containers:
-name:nginx-container
image:nginx:latest
volumeMounts:
-mountPath:"/usr/share/nginx/html"
name:test-volume
volumes:
-name:test-volume
persistentVolumeClaim:
claimName:ebs-claim-01
Verification 验证
现在,验证我们之前部署的Storage-Class、PVC和Pods是否如我们预期的那样工作。
>kubectlgetstorageclass
>kubectlgetpvc
>kubectlgetpods