K8S和Docker的持久化机制 – 优雅地使用存储系统

Docker持久卷和读写层

Docker容器中的文件保存在 镜像的读写层中 或者 挂载的存储系统中
以下说明Docker中容器的保存位置

容器的目录挂载实际是 容器中看到的目录 对应 存储系统中的真实目录
即docker inspect结果中,可以看到Destination –> Source的映射

"Mounts": [
    {
        "Type": "volume",
        "Name": "mysql-volume",
        "Source": "/var/lib/docker/volumes/mysql-volume/_data",
        "Destination": "/var/lib/mysql",
        "Driver": "local",
        "Mode": "z",
        "RW": true,
        "Propagation": ""
    }
]

挂载目录的写操作写入持久卷

创建持久卷test-volume

docker volume create test-volume

启动一个nginx容器,将容器的/data目录挂载到持久卷中

docker run -d --name nginx-server -v test-volume:/data -p 80:80 nginx:latest

进入容器,分别在容器中的/data目录和根目录写入新文件

docker exec -it nginx-server /bin/bash
cd / && touch not-bound.txt && echo 'not-bound-file' > not-bound.txt
cd /data && touch bound.txt && echo 'bound-file' > bound.txt
exit

删除容器,使用相同挂载路径重启新容器

docker stop nginx-server && docker rm nginx-server
docker run -d --name nginx-server -v test-volume:/data -p 80:80 nginx:latest

只有挂载目录的内容被保存在持久卷中,其他数据随着容器删除均丢失

cd / && cat not-bound.txt
cd /data && cat bound.txt

查看volume列表

docker volume ls

清空容器未挂载volume

volume docker volume prune

删除volume

docker volume rm test-volume

非挂载目录写操作写入读写层

创建持久卷test-rw-volume

docker volume create test-rw-volume

启动一个nginx容器,将容器的/data目录挂载到持久卷中

docker run --name test-rw-server -d -v test-rw-volume:/data -p 80:80 nginx:latest

进入容器,将文件写在非挂载目录

docker exec -it test-rw-server /bin/bash
touch write.txt && echo 'aaa' > write.txt
exit

查看容器的读写层写操作变化记录

docker diff test-rw-server

提交镜像后,重新运行一个新容器,可以发现容器中已经包含写入的文件,说明 commit操作将容器的所有非挂载目录的写操作写入了镜像

docker commit docker commit -m "test rw" test-rw-server
docker run --name test-rw-restore -d -p 81:80 nginx:latest
docker exec -it test-rw-restore /bin/bash
cat write.txt

K8S持久卷详解

K8S可控制容器启动时持久卷的分配和挂载,持久卷方式有以下几种
emptydir Pod启动时k8s分配挂载点,pod停止时卷删除,数据不保留
hostpath 挂载在本机的固定目录上,与主机紧耦合,主机宕机时数据无法访问
存储系统 如云厂商提供的云存储,自行搭建的NFS系统等
PV/PVC PVC声明访问的容量和权限,PV负责真实挂载

NFS的安装、挂载和使用

在将要共享存储的主机192.168.0.53上安装并启动nfs

apt-get install -y nfs-kernel-server nfs-common rpcbind
sudo systemctl start nfs-kernel-server.service

配置共享存储系统实际指向的的本机路径、允许挂载的其他主机地址网段、数据落盘策略:写内存同步写硬盘、以root身份访问、允许大于1024端口访问(insecure解决报错 MountVolume.SetUp failed for volume "wp-pv" : mount failed: exit status 32)重启nfs生效

vim /etc/exports
/nfsDir  192.168.*.*(rw,sync,no_root_squash,insecure)
sudo systemctl restart nfs-server

查看启动后的nfs状态

sudo systemctl status nfs-server
showmount -e

测试查看挂载,结束后取消挂载

sudo mount -t nfs 192.168.0.53:/nfsDir .
df -h
sudo umount .

PV、PVC和StorageClass

PersitentVolumeClaim是请求存储属性的声明,相当于接口,供开发人员使用屏蔽底层实现
PersitentVolume是请求存储系统属性的实现,向真实的存储系统请求资源挂载,由运维人员分配
StorageClass支持PV根据模板的动态申请挂载,如StatefulSet中的volumeClaimTemplates

PV、PVC的手动分配绑定

wp-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: wp-pv
spec:
  capacity:
    storage: 4Gi
  volumeMode: Filesystem                   # 挂载目录模式
  accessModes:
    - ReadWriteMany                        # 卷可被多个主机同时挂载,数据共享
  persistentVolumeReclaimPolicy: Retain    # 删除PVC或PV后数据不被删除
  storageClassName: wp-class               # 用于和PVC绑定使用
  nfs:
    path: /nfsDir                          # nfs源目录
    server: 192.168.0.53                   # nfs服务器地址

wp-pv-claim.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
spec:
  accessModes:
    - ReadWriteMany                        # 可被多个POD共享,访问权限为可读可写
  resources:
    requests:
      storage: 2Gi                         # 启动容量2G
    limits:
      storage: 4Gi                         # 最大容量不超过4G
  storageClassName: wp-class               # 用于和pv绑定

发布PV和PVC

kubectl apply -f wp-pv.yaml
Kubectl apply -f wp-pv-claim.yaml

查看持久卷分配和绑定情况

Kubectl get pv
kubectl describe pv wp-pv
Kubectl get pvc
kubectl describe pvc wp-pv-claim

StorageClass支持的动态分配(待续)

参考资料

ubuntu nfs文档

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

©2018-2024 Howell版权所有 备案号:冀ICP备19000576号