kubernetes 存储(上)

本贴最后更新于 1355 天前,其中的信息可能已经天翻地覆

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

  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    108 引用 • 54 回帖
  • NFS
    6 引用
1 操作
Leif160519 在 2020-07-12 14:59:05 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...