K8s存储:volumes配置管理
文章目录一、emptyDir卷二、hostpath卷1.基本示例2.结合nfs三、PersistentVolume(持久卷,简称PV)四、statefulset控制器及与pv、pvc的结合一、emptyDir卷当 Pod 指定到某个节点上时,首先创建的是一个 emptyDir 卷,并且只要 Pod 在该节点上运行,卷就一直存在。 就像它的名称表示的那样,卷最初是空的。 尽管 Pod 中的容器挂载
一、emptyDir卷
当 Pod 指定到某个节点上时,首先创建的是一个 emptyDir 卷,并且只要 Pod 在该节点上运行,卷就一直存在。 就像它的名称表示的那样,卷最初是空的。 尽管 Pod 中的容器挂载 emptyDir 卷的路径可能相同也可能不同,但是这些容器都可以读写 emptyDir 卷中相同的文件。 当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会永久删除。
vim emptydir.yaml:
apiVersion: v1
kind: Pod
metadata:
name: vol1
spec:
containers:
- image: busyboxplus
name: vm1
stdin: true
tty: true
volumeMounts:
- mountPath: /cache
name: cache-volume
- name: vm2
image: myapp:v1
volumeMounts:
- mountPath: /usr/share/nginx/html
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
medium: Memory % 表示写入的所有文件都在容器的内存空间中
sizeLimit: 100Mi % 设置配额,当超过该配额之后,pod将会处于驱离状态
注意:同一个pod内的不同容器共享一个存储,一个网络
注意:当消耗的内存超过指定配额时,该pod将会被kubelet evict掉
二、hostpath卷
hostPath 卷能将主机节点文件系统上的文件或目录挂载到您的 Pod 中。 虽然这不是大多数 Pod 需要的,但是它为一些应用程序提供了强大的逃生舱。
1.基本示例
vim hostpath.yaml:
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: myapp:v1
name: vm1
volumeMounts:
- mountPath: /usr/share/nginx/html
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /webdata
type: DirectoryOrCreate %如果没有/webdata目录则创建
注意:当删除pod时,真实主机上的/webdata目录并不会被删除(逃生舱)
2.结合nfs
首先要搭建一台nfs服务器,最终达到的效果是:pod调度到哪个节点上,则远端nfs服务器上的指定目录就会挂载到该节点上的pod内。注意:要确保被调度的节点上装有nfs-utils工具:
yum install -y nfs-utils
在调度节点上编辑nfs.yaml文件:
vim nfs.yaml:
apiVersion: v1
kind: Pod
metadata:
name: nfs-pd
spec:
containers:
- image: myapp:v1
name: vm1
volumeMounts:
- mountPath: /usr/share/nginx/html
name: test-volume
volumes:
- name: test-volume
nfs:
server: 10.4.17.201 % nfs服务器
path: /nfsdata
三、PersistentVolume(持久卷,简称PV)
是集群内,由管理员提供的网络存储的一部分。就像集群中的节点一样,PV也是集群中的一种资源。它也像Volume一样,是一种volume插件,但是它的生命周期却是和使用它的Pod相互独立的。PV这个API对象,捕获了诸如NFS、ISCSI、或其他云存储系统的实现细节。
vim pv1.yaml:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce %该volume只能被单个节点以读写的方式映射
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 10.4.17.201
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany %该volume可以被多个节点以只读方式映射
persistentVolumeReclaimPolicy: Recycle %回收策略:回收,自动删除卷中数据
storageClassName: nfs
nfs:
path: /nfsdata/pv2
server: 10.4.17.201
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv3
spec:
capacity:
storage: 20Gi
volumeMode: Filesystem
accessModes:
- ReadOnlyMany %该volume可以被多个节点以读写的方式映射
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfsdata/pv3
server: 10.4.17.201
PersistentVolumeClaim(持久卷声明,简称PVC)是用户的一种存储请求。它和Pod类似,Pod消耗Node资源,而PVC消耗PV资源。Pod能够请求特定的资源(如CPU和内存。PVC能够请求指定的大小和访问的模式(可以被映射为一次读写或者多次只读。PVC与PV的绑定是一对一的映射。没找到匹配的PV,那么PVC会无限期得处于unbound未绑定状态。匹配条件主要是下图三个:
其中,已有pv的内存大小不能低于pvc所申请的容量。
有两种PV提供的方式:静态和动态。
静态PV:集群管理员创建多个PV,它们携带着真实存储的详细信息,这些存储对于集群用户是可用的。它们存在于Kubernetes API中,并可用于存储使用。
动态PV:当管理员创建的静态PV都不匹配用户的PVC时,集群可能会尝试专门地供给volume给PVC。这种供给基于StorageClass。
创建pvc:
vim pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
spec:
storageClassName: nfs
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc2
spec:
storageClassName: nfs
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- image: myapp:v1
name: nginx
volumeMounts:
- mountPath: /usr/share/nginx/html
name: nfs-pv
volumes:
- name: nfs-pv
persistentVolumeClaim:
claimName: pvc1
---
apiVersion: v1
kind: Pod
metadata:
name: test-pod-2
spec:
containers:
- image: myapp:v1
name: nginx
volumeMounts:
- mountPath: /usr/share/nginx/html
name: nfs-pv-2
volumes:
- name: nfs-pv
persistentVolumeClaim:
claimName: pvc2
删除完某个pvc后,相应的资源将会被回收再利用:
StorageClass提供了一种描述存储类(class)的方法,不同的class可能会映射到不同的服务质量等级和备份策略或其他策略等。每个 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段, 这些字段会在StorageClass需要动态分配PersistentVolume 时会使用到。
NFS Client Provisioner是一个automatic provisioner,使用NFS作为存储,自动创建PV和对应的PVC,本身不提供NFS存储,需要外部先有一套NFS存储服务。
PV以 {namespace}-{pvcName}-{pvName}的命名格式提供(在NFS服务器上)
PV回收的时候以 archieved-{namespace}-{pvcName}-{pvName} 的命名格式(在NFS服务器上)
vim nfs-client-provisioner.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner % 默认default,我们为了结构化的清晰可以将其改为自己创建的新的namespace:nfs-client-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: nfs-client-provisioner:v4.0.0 %这个镜像最好提前下载好放到harbor私有仓库中,因位这个时国外镜像,联网下载起来很慢
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 10.4.17.201 %nfs服务端地址
- name: NFS_PATH %nfs目录
value: /nfsdata
volumes:
- name: nfs-client-root
nfs:
server: 10.4.17.201 %nfs服务端地址
path: /nfsdata %nfs目录
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
archiveOnDelete: "true" %打包备份,删除Pod的时候pv和pvc目录还会在
默认的 StorageClass 将被用于动态的为没有特定 storage class 需求的 PersistentVolumeClaims 配置存储:(只能有一个默认StorageClass)如果没有默认StorageClass,PVC 也没有指定storageClassName 的值,那么意味着它只能够跟 storageClassName 也是“”的 PV 进行绑定。因此可以通过打补丁的方式指定默认的storageClassName
四、statefulset控制器及与pv、pvc的结合
StatefulSet将应用状态抽象成了两种情况:
拓扑状态:应用实例必须按照某种顺序启动。新创建的Pod必须和原来Pod的网络标识一样
存储状态:应用的多个实例分别绑定了不同存储数据。
StatefulSet给所有的Pod进行了编号,编号规则是:(statefulset名称)-(序号),从0开始。
Pod被删除后重建,重建Pod的网络标识也不会改变,Pod的拓扑状态按照Pod的“名字+编号”的方式固定下来,并且为每个Pod提供了一个固定且唯一的访问入口,即Pod对应的DNS记录。
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx-svc"
replicas: 3 %副本数,可任意指定
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: myapp:v1
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
storageClassName: managed-nfs-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
注意:需要回收pod时需要更改yaml文件中的副本数为0,需要创建时同样更改副本数即可,而不是直接delete -f,此时存储并不会删除,再创建pod时网络标识不会发生变化,而且不会再为其分配新的存储,而是把原先分配给其的存储再分配给该pod,当然,原先的pv和pvc也不会消失。这就是持久化惟一性存储。
更多推荐
所有评论(0)