K8s 数据管理

k8s-cert



前言

与 Docker 类似,也是通过 Volume 为容器提供存储。一般地,我们会将应用服务分为有状态和无状态,对于 K8s 中容器和 Pod 来说,其生命周期是短暂的,因为他们随时可能被销毁和创建。容器销毁时,其内部文件系统中的数据也会被删除。

如何解决这个问题?K8s 提供了 Volume 数据卷,Volume 的生命周期独立于容器,它不会因为容器的销毁而销毁。当 Volume 被 mount 到 Pod 中时,Pod 中的所有容器都可以访问这个 Volume。K8s 支持多种 backend 类型,如 emptyDir、hostPath、GCE Persistent Disk 等。

一、Volume

1.1 emptyDir

1.1.1 基本概念

从字面意思来看,它似乎表示一个空目录,其实它就是 Host 上的一个空目录(即卷最初是空的),而且是最基础的 Volume 类型。需要注意的是:当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会被永久删除。但如果只是容器被销毁,而 Pod 还在的情况下,这个 Volume 是不受影响的。

1.1.2 应用案例

Pod 中的所有容器都可以共享 Volume,它们可以指定各自的 mount 路径。

vim emptyDir.yml
apiVersion: v1
kind: Pod
metadata:
  name: pro-dev
spec:
  containers:
  - image: busybox
    name: pro
    volumeMounts:
    - mountPath: /pro_dir
      name: shared-volume
    args:
    - /bin/sh
    - -c
    - echo "hello world" > /pro_dir/hello; sleep 30000
  - image: busybox
    name: dev
    volumeMounts:
    - mountPath: /dev_dir
      name: shared-volume
    args:
    - /bin/sh
    - -c
    - cat /dev_dir/hello; sleep 30000
  volumes:
  - name: shared-volume
    emptyDir: {}

该案例中 Pod 有两个容器 pro 和 dev,它们共享一个 volume,pro 负责往 volume 写数据,dev 则是从 volume 中读取数据。

整体流程就是:

  • 定义了一个 emptyDir 类型的 Volume - - > shared-volume;
  • pro 容器将 shared-volume mount 到 /pro_dir 目录下;
  • pro 将数据写入 /pro_dir/hello 文件里;
  • dev 容器将 shared-volume mount 到 /dev_dir 目录下;
  • dev 通过 cat 从文件 hello 读取数据。

开始创建 Pod:

kubectl apply -f emptyDir.yml

image-20221230100359487

查看 dev 输出日志:

kubectl logs pro-dev dev

image-20221230100552490

从日志可看到 dev 成功读到了 pro 写入的数据,验证了同个 Pod 中的多个容器共享了 emptyDir Volume。

emptyDir 是 Docker Host 文件系统里的目录,其效果相当于执行了 docker run -v /pro_dirdocker run -v /dev_dir。通过 docker inspect 来查看文件 Mount 情况。

docker inspect k8s_pro_pro-dev_default_479982fc-0a53-45e8-806c-38994e3f6f08_0

image-20221230101749720

docker inspect k8s_dev_pro-dev_default_479982fc-0a53-45e8-806c-38994e3f6f08_0

image-20221230101849704

看看 Host 是否有 Source 文件:

image-20221230102308120

可看到,shared-volume 已经被创建于 Host 中,且两个容器都 Mount 到了同一个目录,因此,/var/lib/kubelet/pods/479982fc-0a53-45e8-806c-38994e3f6f08/volumes/kubernetes.io~empty-dir/shared-volume/ 就是 emptyDir 在 Host 上的实际路径。

由此可看出,emptyDir 能够很方便地为 Pod 中的容器提供共享存储,不需要额外的配置。但 emptyDir 不具备持久性,只要 Pod 被销毁,那 emptyDir 也就会被销毁。因此,emptyDir 只适用于临时共享存储的场景。

1.2 hostPath

1.2.1 基本概念

hostPath Volume 的作用就是将 Docker Host 文件系统中已经存在的目录 mount 给 Pod 的容器,但大部分应用都不会使用 hostPath Volume,因为这会增加 Pod 与节点的耦合,限制了 Pod 的使用。不过那些需要访问 k8s 或 Docker 的内部数据的应用则需要使用到 hostPath

1.2.2 应用案例

有哪些典型的应用案例呢?比如 kube-apiserver、kube-controller-manager 就是这样的应用,我们可以查看一下 kube-apiserver 的 Pod 配置。

kubectl edit pod kube-apiserver-k8s-master --namespace=kube-system

image-20221230104301893

上图中定义了三个 hostPath:ca-certs、etc-pki 和 k8s-certs,他们分别对应了 Host 目录下的 /etc/ssl/certs/etc/pki/etc/kubernetes/pki。如果 Pod 被销毁了,hostPath 对应的目录还是会保留,相比于 emptyDir 来说持久性更强,但如果 Host 崩溃,hostPath 也就无法访问了。

1.3 外部 Storage Provider

当然,K8s 也可以使用主流的分布式存储,如 Ceph、GlusterFS 等,如使用 Ceph 分布式存储。

apiVersion: v1
kind: Pod
metadata:
  name: Ceph-Storage
spec:
  containers:
    - image: busybox
      name: Ceph-Storage
      mountPath: /test-ceph
  volumes:
    - name: ceph-volume
      cephfs:
        path: /home/data/cephfs
        monitors: "192.168.56.190:6789"
        secretFile: "/etc/ceph/admin.secret"

这种外部分布式存储的特点就是:它们不依赖于 K8s,Volume 的底层基础设施由独立的存储系统管理,与 K8s 集群是分离,数据持久化后,即使整个 K8s 集群崩溃了,持久化的数据也不会受到影响。

二、Persistent Volume

2.1 基本概念

尽管 Volume 已经为 K8s 提供了更好的数据持久化方案,但在存储管理上任然是欠缺的,尤其是在大规模集群环境下,需要考虑到效率和安全性问题。K8s 给出的解决方案就是 PersistentVolume,PVPersistentVolumeClaim,PVC

2.1.1 PersistentVolume

持久卷(PersistentVolume,PV)是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样, 也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。

2.1.2 PersistentVolumeClaim

持久卷申领(PersistentVolumeClaim,PVC)表达的是用户对存储的请求。概念上与 Pod 类似。Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存);同样 PVC 申领也可以请求特定的大小和访问模式 (例如,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载)。

有了 PersistentVolumeClaim,用户只需要告诉 K8s 需要什么样的存储资源,而不必真正关心真正的空间是从哪里分配、如何访问底层信息等。

2.2 NFS PersistentVolume

K8s 支持多种类型的 PersistentVolume,比如 Ceph、AWS EBS、NFS 等,我们就通过 NFS 来实验 PersistentVolume

1、安装 NFS

在 K8s-Master 上部署 NFS

# 安装工具/服务
yum -y install rpcbind
yum -y install nfs-utils

# 启动服务
systemctl start nfs-server
systemctl enable nfs-server
systemctl start rpcbind
systemctl enable rpcbind

# 编辑共享文件
vim /etc/exports
/home/data/app 192.168.56.0/24(rw,no_root_squash,sync)

# 创建共享目录
mkdir -p /home/data/app

# 重启NFS
systemctl restart nfs-server

查看 NFS 共享目录

image-20221230170957898

2、K8s 创建 PV 对象

vim pv-test.yml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-test
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: nfs
  nfs:
    path: /home/data/app
    server: 192.168.56.160

参数说明

capacity: 指定PV的容量为1GB
accessModes: 指定访问模式为ReadWriteOnce,支持三种访问模式
             ReadWriteOnce: 表示PV能以读写模式mount到单个节点
             ReadOnlyMany: 表示PV能以只读模式mount到多个节点
             ReadWriteMany: 表示PV能以读写模式mount到多个节点
persistentVolumeReclaimPolicy: 指定PV回收策略为Recycle,支持三种回收策略
             Retain: 表示需要管理员手动回收
             Recycle: 表示清除PV中的数据,相当于 rm -rf
             Delete: 表示删除Storage Provide 上对应的存储资源
storageClassName: 指定PV的class为NFS,相当于为PV设置了一个分类,PVC可以指定class申请相应class的PV
nfs.path: NFSf服务的共享目录
nfs.server: NFS服务IP地址

创建 PV 对象

kubectl apply -f pv-test.yml

查看 PV 资源

kubectl get pv

image-20221230173207185

上图中,STATUS 状态为 Available,表示该 PV 资源已经就绪,可以被 PVC 申请。

3、创建 PVC

对于 PVC 来说,只需要指定 PV 的容量、访问模式和 class 即可。

vim pvc-test.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-test
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs
  selector:
    matchLabels:
      pv: pv-test

# selector标签选择器,选择pv资源的标签:pv-test

创建 PVC 对象

kubectl apply -f pvc-test.yml

查看 PVC 资源

image-20221230180255467

从输出结果来看,PVC 已经 Bound 到 PV 了,申请成功。

image-20221230180521984

4、Pod 中使用存储

PVC 申请成功后,接下来就可以在 Pod 中使用存储了,配置 Pod 文件。

vim pod-test.yml
apiVersion: v1
kind: Pod
metadata:
  name: pod-test
spec:
  containers:
    - name: pod-test
      image: busybox
      args:
      - /bin/sh
      - -c
      - sleep 30000
      volumeMounts:
      - mountPath: "/mydata"
        name: mydata
  volumes:
    - name: mydata
      persistentVolumeClaim:
        claimName: pvc-test

其实就与普通的 Volume 格式类似,在 volume 中通过 persistentVolumeClaim 指定使用 pvc-test 申请的 Volume。

创建 Pod

kubectl apply -f pod-test.yml

查看 Pod 状态

image-20230102001214287

5、验证

Pod pod-test 容器中创建一个测试文件testfile,看看 NFS 共享文件中是否数据同步。

image-20230102003109834

在 NFS 共享目录中创建一个测试文件,在去 Pod 对应容器中看看是否有刚刚创建的 helloWrld

image-20230102003913619

如果都同步了,证明 Pod 共享了 NFS 的资源。

image-20230102003406954

从实验结果来看,Pod 中创建的文件同步到了 NFS 共享目录,同样,在 NFS 共享目录中创建的文件也同步到了 Pod 中了。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云计算-Security

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值