Kubernetes 中存储使用介绍(PV、PVC和StorageClass)

简介: 在 Kubernetes 中的应用,都是以 Pod 的形式运行的,当我们要是在 Kubernetes 上运行一些需要存放数据的应用时,便需要关注应用存放的数据是否安全可靠。因为 Pod 是有生命周期的,那么也就是说当 Pod 被删除或重启后,Pod 里面所运行的数据也会随之消失。

Kubernetes 中存储使用介绍



一、基本介绍


1.Volume 类型

2.PV 和 PVC 绑定条件

3.StorageClass


二、使用介绍


1.创建 PV

2.创建 PVC

3.创建 StorageClass


一、基本介绍



在 Kubernetes 中的应用,都是以 Pod 的形式运行的,当我们要是在 Kubernetes 上运行一些需要存放数据的应用时,便需要关注应用存放的数据是否安全可靠。因为 Pod 是有生命周期的,那么也就是说当 Pod 被删除或重启后,Pod 里面所运行的数据也会随之消失。


因此,K8s 引入了 Volume(数据卷)的概念,使我们可以通过挂载的方式,将 Pod 内所需要存放的数据,挂载到宿主机的目录中。这样,我们便可以防止 Pod 内所运行的数据因为 Pod 的删除/重启而丢失。


1.Volume 类型


  • emptyDir:临时目录,用于 Pod 内多容器共享目录,并不适用于需要保存数据的应用,因为 emptyDir 和 Pod 的生命周期相同。
  • hostPath:主机目录,可以保证运行应用的数据不被丢失,但是需要将 Pod 每次都调度到同一台主机上。
  • nfs:共享目录,可以保证运行应用的数据不被丢失。


以上三种是较为常见的数据卷,同时,我们还可以通过配置 PV、PVC、StorageClass 来保证数据的持久化存储。


PV 的全称: PersistentVolume(持久化卷),是对底层共享存储的一种抽象,将共享存储定义为一种资源,它属于集群级别资源,不属于任何命名空间。PV 由管理员进行创建和配置,与共享存储的具体实现直接相关。


PVC 的全称: PersistentVolumeClaim(持久化卷声明),用来描述 Pod 对于 PV 存储的要求,以此来分配到合适的 PV 上。


Pod、PV、PVC 关系: 一个 Pod 可以挂载 n 个 PVC,同样一个 PVC 也可以给 n 个 Pod 提供服务。但是,一个 PVC 只能绑定一个 PV,一个 PV 只能对应一种后端存储。


image.png


2.PV 和 PVC 绑定条件


  1. PV 的存储大小和权限需要满足 PVC 所提供的要求;
  2. PV 和 PVC 的 StorageClassName 需要相同(如果没有指定 StorageClassName,则默认为空)


注意: 要是当我们创建的 Pod 挂载的 PVC 没有和 PV 绑定成功,那么 Pod 将会一直处于 Pending 状态。


3.StorageClass


Kubernetes 提供了一种能够自动管理 PV 的机制,叫做 StorageClass(可以说是 PV 的模板,能够自动的创建 PV)


二、使用介绍



准备工作:


[root@k8s-master01 ~]# yum -y install nfs-utils rpcbind
[root@k8s-master01 ~]# echo "/app *(rw,sync,no_root_squash)" > /etc/exports
[root@k8s-master01 ~]# mkdir /app
[root@k8s-master01 ~]# systemctl start rpcbind nfs


1.创建 PV


[root@k8s-master01 ~]# vim test-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs
spec:
  capacity:
    storage: 2Gi            # 存储容量为 2Gi
  accessModes:
  - ReadWriteOnce
  nfs:
    path: /app
    server: 192.168.1.1
[root@k8s-master01 ~]# kubectl create -f test-pv.yaml


image.png


Access Modes 访问模式:


image.png


  • 需要注意的是,accessModes 只能针对于块存储来做限制,‘像 NFS 这类的文件系统是支持这样配置的,但是限制不了。


Reclaim Policy 回收策略:


  • Delete(删除):当 PVC 被删除时,PV 同样会被删除。
  • Retain(保留):当 PVC 被删除时,PV 并不会被删除,需要手动进行删除。
  • Recycle(回收):当 PVC 被删除时,PV 上的数据也会随之删除,以便和新的 PVC 进行绑定(已被遗弃)


2.创建 PVC


1)创建


[root@k8s-master01 ~]# cat <<END > test-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
END
[root@k8s-master01 ~]# kubectl create -f test-pvc.yaml


  • 上面 PVC 的配置表示:希望被分配到一个具有 2Gi 空间的磁盘,并且只允许我一个 PVC 进行读写。


2)查看


[root@k8s-master01 ~]# kubectl get pv,pvc


image.png


PV,PVC 绑定状态:


image.png


3)创建 Pod


[root@k8s-master01 ~]# cat <<END > test-web.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-web
spec:
  containers:
  - name: nginx
    image: nginx:1.21.0
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html
    persistentVolumeClaim:
      claimName: test-pvc
END
[root@k8s-master01 ~]# kubectl create -f test-web.yaml


  • 这里需要注意,Pod 所运行在的主机,需要安装 nfs-utils 包,不然挂载 NFS 时会出现问题。


验证: 在挂载目录下创建个 index.html 文件,查看是否挂载成功(尽量不要挂载有用的目录,因为挂载后会进行覆盖)


[root@k8s-master01 ~]# echo "Hello" > /app/index.html


image.png


3.创建 StorageClass


1)创建 RBAC 授权文件


[root@k8s-master01 ~]# cat <<END > external-storage-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-clusterrole
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
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-clusterrole
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  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
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io
END
[root@k8s-master01 ~]# kubectl create -f external-storage-rbac.yaml


2)创建 Deployment 文件


[root@k8s-master01 ~]# cat <<END > external-storage-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  namespace: default
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: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: tianya/nfs
            - name: NFS_SERVER
              value: 192.168.1.1
            - name: NFS_PATH
              value: /app
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.1.1
            path: /app
END
[root@k8s-master01 ~]# kubectl create -f external-storage-deploy.yaml


3)创建 StorageClass 资源文件


[root@k8s-master01 ~]# cat <<END > external-storage-class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client-storageclass
provisioner: tianya/nfs
END
[root@k8s-master01 ~]# kubectl create -f external-storage-class.yaml


  • 上面的 provisioner 配置要和 Deployment 里的 PROVISIONER_NAME 变量值相同。


4)验证


[root@k8s-master01 ~]# cat <<END > test-storage-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-storage-pvc
spec:
  storageclassName: nfs-client-storageclass
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 4Gi
END
[root@k8s-master01 ~]# cat <<END > test-storage-pvc.yaml


问题: 创建完 PVC 后,一直处于 Pending 状态,通过查看 PVC 信息发现,输出:waiting for a volume to be created, either by external provisioner "tianya/nfs" or manually created by system administrator 报错。


原因是因为: 在 Kubernetes 的 1.20 以上版本,默认禁用了 SelfLink 功能。但是由于 nfs-client-privisioner 服务需要依赖此功能。所以,需要在 apiserver 的配置文件中开启此功能。


[root@k8s-master01 ~]# vim /etc/systemd/system/kube-apiserver.service


  • 增加:--feature-gates=RemoveSelfLink=false 配置。


查看:


image.png


创建 Pod,并挂载新的 PVC 进行验证:


[root@k8s-master01 ~]# cat <<END > test-storage-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-web
spec:
  containers:
  - name: test-web
    image: nginx:1.21.0
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html
    persistentVolumeClaim:
      claimName: test-storage-pvc
END
[root@k8s-master01 ~]# kubectl create -f test-storage-pod.yaml   


image.png


  • 上面的 /app/default-test-storage-pvc-pvc-dcc38edd-72a5-4d50-8199-0d277c9ba3f9/ 是 StorageClass 自动创建的 PV 目录。


相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
6月前
|
存储 运维 Kubernetes
容器数据保护:基于容器服务 Kubernetes 版(ACK)备份中心实现K8s存储卷一键备份与恢复
阿里云ACK备份中心提供一站式容器化业务灾备及迁移方案,减少数据丢失风险,确保业务稳定运行。
|
6月前
|
存储 监控 对象存储
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
139 0
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
|
7月前
|
存储 监控 对象存储
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
113 1
|
8月前
|
存储 Kubernetes 安全
k8s存储类型:emptyDir、hostPath、nfs、pvc及存储类storageclass的静态/动态创建pv
Kubernetes提供了多种存储类型,满足不同的应用需求。`emptyDir`和 `hostPath`适用于临时和宿主机存储需求,`nfs`适用于共享存储,`PersistentVolumeClaim`和 `StorageClass`实现了持久存储的灵活管理。通过理解和配置这些存储类型,可以有效提升Kubernetes集群的存储管理能力。
316 13
|
4月前
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
ACK One 的多集群应用分发,可以最小成本地结合您已有的单集群 CD 系统,无需对原先应用资源 YAML 进行修改,即可快速构建成多集群的 CD 系统,并同时获得强大的多集群资源调度和分发的能力。
143 9
|
4月前
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
本文介绍如何利用阿里云的分布式云容器平台ACK One的多集群应用分发功能,结合云效CD能力,快速将单集群CD系统升级为多集群CD系统。通过增加分发策略(PropagationPolicy)和差异化策略(OverridePolicy),并修改单集群kubeconfig为舰队kubeconfig,可实现无损改造。该方案具备多地域多集群智能资源调度、重调度及故障迁移等能力,帮助用户提升业务效率与可靠性。
|
6月前
|
存储 Kubernetes 监控
K8s集群实战:使用kubeadm和kuboard部署Kubernetes集群
总之,使用kubeadm和kuboard部署K8s集群就像回归童年一样,简单又有趣。不要忘记,技术是为人服务的,用K8s集群操控云端资源,我们不过是想在复杂的世界找寻简单。尽管部署过程可能遇到困难,但朝着简化复杂的目标,我们就能找到意义和乐趣。希望你也能利用这些工具,找到你的乐趣,满足你的需求。
580 33
|
6月前
|
Kubernetes 开发者 Docker
集群部署:使用Rancher部署Kubernetes集群。
以上就是使用 Rancher 部署 Kubernetes 集群的流程。使用 Rancher 和 Kubernetes,开发者可以受益于灵活性和可扩展性,允许他们在多种环境中运行多种应用,同时利用自动化工具使工作负载更加高效。
328 19
|
6月前
|
人工智能 分布式计算 调度
打破资源边界、告别资源浪费:ACK One 多集群Spark和AI作业调度
ACK One多集群Spark作业调度,可以帮助您在不影响集群中正在运行的在线业务的前提下,打破资源边界,根据各集群实际剩余资源来进行调度,最大化您多集群中闲置资源的利用率。
|
9月前
|
Prometheus Kubernetes 监控
OpenAI故障复盘 - 阿里云容器服务与可观测产品如何保障大规模K8s集群稳定性
聚焦近日OpenAI的大规模K8s集群故障,介绍阿里云容器服务与可观测团队在大规模K8s场景下我们的建设与沉淀。以及分享对类似故障问题的应对方案:包括在K8s和Prometheus的高可用架构设计方面、事前事后的稳定性保障体系方面。

推荐镜像

更多