Leif160519的blog Leif160519的blog

——————

目录
kubernetes存储(上)
/    

kubernetes存储(上)

1.为什么需要存储卷

容器部署过程中一般有以下三种数据:

  • 启动时需要的初始数据,可以是配置文件
  • 启动过程中产生的临时数据,该临时数据需要多个容器间共享
  • 启动过程中产生的持久化数据

image.png

2.数据卷概述

  • Kubernetes中的Volume提供了在容器中挂载外部存储的能力
  • Pod需要设置卷来源(spec.volume)和挂载点(spec.containers.volumeMounts)两个信息后才可以使用相应的Volume

官方给出了k8s支持的所有卷类型,点击查看:Volumes | Kubernetes

image.png

存储分为以下几类:
本地:hostPath,emptyDir
网络:nfs,cephfs,rbd,glusterfs
公有云:awsElasticBlockStore,azureDisk
k8s本身存储:secret,configMap,downwardAPI

3.临时存储卷:emptyDir

创建一个空卷,挂载到Pod中的容器。Pod删除该卷也会被删除。

应用场景:Pod中容器之间数据共享

pod实现:网络共享(infra container),存储共享(emptyDir)

示例程序emptyDir.yaml

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: write
    image: centos
    command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;done"]
    volumeMounts:
      - name: data
        mountPath: /data
  - name: read
    image: centos
    command: ["bash","-c","tail -f /data/hello"]
    volumeMounts:
      - name: data
        mountPath: /data

  volumes:
  - name: data
    emptyDir: {}

卷挂载是针对容器的,故volumeMounts要与container同级

yaml应用完成后,k8s会在宿主机创建一个空目录,路径在/var/lib/kubelet/pods/<pod-id>/volumes/kubernetes.io~empty-dir/data/,所有的文件都会挂载在这个空目录中,下面介绍查找方法:

  • 1.查看pod在哪个节点上
kubectl get pod -o wide

image.png

  • 2.去node1执行:
docker ps | grep my-pod

image.png

  • 3.找到pod-id:37a7c719-31b6-4a4f-bfa0

  • 4.接着去目录下查看执行结果:

cd /var/lib/kubelet/pods/37a7c719-31b6-4a4f-bfa0-acacea1fac22/volumes/kubernetes.io~empty-dir/data

可以发现文件夹下产生了一个hello文件.文件内容可以直接cat查看或者通过kubectl查看:kubectl logs -f my-pod read

4.节点存储卷:hostPath

挂载Node文件系统上文件或者目录到Pod中的容器。

应用场景:Pod中容器需要访问宿主机文件

示例:hostPath.yaml
将宿主机/tmp目录挂载到pod的/data目录中

apiVersion: v1
kind: Pod
metadata:
  name: my-pod2
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 36000
    volumeMounts:
    - name: data
      mountPath: /data

  volumes:
  - name: data
    hostPath:
      path: /tmp
      type: Directory

挂载的目录为当前节点宿主机目录,不是其他节点的也不是远程存储的目录

image.png

image.png

5. 网络存储卷:NFS

示例程序nfs.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:
      - name: wwwroot
        nfs:
          server: 192.168.0.6
          path: /data/nfs

在nfs服务器上新建一个index.html,内容为123:

echo 123 > index.html

选择一个pod,exec进去看看:

image.png

以上说明,nfs挂载没问题!其他两个pod中也会有同样的index.html

访问pod的ip:

image.png

6.持久卷

持久卷对上述配置磁盘(nfs)的角色进行划分,并且抽象出来两个资源:

  • PersistentVolume(PV):对存储资源创建和使用的抽象,使得存储作为集群中的资源管理
    1.静态
    2.动态

  • PersistentVolumeClaim(PVC):让用户不需要关心具体的Volume实现细节

解决的痛点:专人做专事,运维只负责提供存储空间,用户不需要关心怎么实现,直接用配置好的存储即可。

pv与pvc一一对应,用户申请一块容量,会匹配一个pv,该pv会与这个pvc绑定

示例:

image.png

作为开发者,需要关注前两个yaml,先写部署的镜像信息,再指定数据卷类型(pvc)(左图),然后再指定需要的容量和访问模式(中间图),它们通过pvc的名称关联;这两块一般写在同一个yaml中(左图和中图);右图一般是运维人员提前准备好的pv,里面包含了卷的来源,访问模式和大小

6.1 PV静态供给

原理图:

image.png

解释:中间部分为运维人员准备的一些存储池,存储池中有很多的pv,当开发者在k8s中申请一块存储时,执行完yaml之后,pvc会自动查找与其定义的访问模式或者容量相匹配的pv并与之绑定,只有绑定了pv成功申请了存储之后,pod才会显示running状态,否则一直显示pending状态

注意pv与pvc一一对应并且绑定

总结:
PVC与PV:

  • 一对一的关系
  • PV可以是多个后端存储
  • PV一般都是k8s运维创建(存储池)

示例

  • my-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: www
      mountPath: /usr/share/nginx/html
  volumes:
    - name: www
      persistentVolumeClaim:
        claimName: my-pvc

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

  • my-pvc.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /data/nfs
    server: 192.168.0.6

效果
image.png

补充:
Kubernetes支持持久卷的存储插件:
https://kubernetes.io/docs/concepts/storage/persistent-volumes/

PV与PVC匹配:
1、访问模式(三种访问方式: ReadWriteOnce(RWO), ReadOnlyMany(ROX), ReadWriteMany(RWX))
2、存储容量(PVC如果没有找到精确对应的PV时,会根据就近PV匹配)

6.2 PV动态供给

当pvc去申请容量时,它会根据存储类自动创建pv,pvc申请多大空间,pv就会创建多大空间

image.png

  • Dynamic Provisioning机制工作的核心在于StorageClass的API对象。
  • StorageClass声明存储插件,用于自动创建PV。

Kubernetes支持动态供给的存储插件:
https://kubernetes.io/docs/concepts/storage/storage-classes/

由此可见,k8s并不支持nfs的pv动态供给,故需要安装插件让其支持,插件地址为:
https://github.com/kubernetes-incubator/external-storage

动态供给-NFS

image.png

下载安装存储插件:点击下载

image.png

注意:deployment.yml中的nfs地址需要手动更改!!!路径不存在会自动创建。

cd nfs-client
kubectl apply -f .

image.png

示例

  • my-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: www
      mountPath: /usr/share/nginx/html
  volumes:
    - name: www
      persistentVolumeClaim:
        claimName: my-pvc

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  storageClassName: "managed-nfs-storage"  # 指定存储类
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

image.png


“The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time.” – Tom Cargill

标  题kubernetes存储(上)
作  者Leif160519
出  处https://github.icu/articles/2020/07/11/1594471383567.html
关于博主:坐标南京,运维工程师,如有问题探讨可以直接下方留言。
声援博主:如果您觉得文章对您有帮助,可以评论、订阅、收藏。您的鼓励是博主的最大动力!