Docker和Kubernetes中使用Ceph RBD卷的原理分析

2023-10-20 13:40

本文主要是介绍Docker和Kubernetes中使用Ceph RBD卷的原理分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Docker 或者 Kubernetes 中使用 Ceph RBD 块设备,相比于在宿主机中,是否会对性能造成额外损失?带着这些疑问对相关技术进行原理分析。

Linux中的Mount绑定传播

参考文档:

  1. Shared Subtrees ;
  2. Mount namespaces and shared subtrees ;
  3. Mount namespaces, mount propagation, and unbindable mounts 。

Linux的Mount绑定关系

Linux Mount 命名空间通过隔离文件系统挂载点对隔离文件系统提供支持,它是历史上第一个 Linux Namespace ,所以它的标识位比较特殊,就是 CLONE_NEWNS 。隔离后,不同 Mount Namespace 中的文件结构发生变化也互不影响。你可以通过 /proc/[pid]/mounts 查看到所有挂载在当前 Namespace 中的文件系统,还可以通过 /proc/[pid]/mountstats 看到 Mount Namespace 中文件设备的统计信息,包括挂载文件的名字、文件系统类型、挂载位置等等。

进程在创建 Mount Namespace 时,会把当前的文件结构复制给新的 Namespace 。新 Namespace 中的所有 Mount 操作都只影响自身的文件系统,而对外界不会产生任何影响。这样做非常严格地实现了隔离,但是某些情况可能并不适用。比如父节点 Namespace 中的进程挂载了一张 CD-ROM ,这时子节点 Namespace 拷贝的目录结构就无法自动挂载上这张 CD-ROM ,因为这种操作会影响到父节点的文件系统。

2006 年引入的挂载传播( Mount Propagation )解决了这个问题,挂载传播定义了挂载对象( Mount Object )之间的关系,系统用这些关系决定任何挂载对象中的挂载事件如何传播到其他挂载对象(参考自: http://www.ibm.com/developerworks/library/l-mount-namespaces/ )。所谓传播事件,是指由一个挂载对象的状态变化导致的其它挂载对象的挂载与解除挂载动作的事件。

  • 共享关系( Share Relationship )。如果两个挂载对象具有共享关系,那么一个挂载对象中的挂载事件会传播到另一个挂载对象,反之亦然。
  • 从属关系( Slave Relationship )。如果两个挂载对象形成从属关系,那么一个挂载对象中的挂载事件会传播到另一个挂载对象,但是反过来不行;在这种关系中,从属对象是事件的接收者。

一个挂载状态可能为如下的其中一种:

  • 共享挂载( Shared
  • 从属挂载( Slave
  • 共享 / 从属挂载( Shared And Slave
  • 私有挂载( Private
  • 不可绑定挂载( Unbindable

传播事件的挂载对象称为共享挂载( Shared Mount );接收传播事件的挂载对象称为从属挂载( Slave Mount )。既不传播也不接收传播事件的挂载对象称为私有挂载( Private Mount )。另一种特殊的挂载对象称为不可绑定的挂载( Unbindable Mount ),它们与私有挂载相似,但是不允许执行绑定挂载,即创建 Mount Namespace 时这块文件对象不可被复制。

共享挂载的应用场景非常明显,就是为了文件数据的共享所必须存在的一种挂载方式;从属挂载更大的意义在于某些“只读”场景;私有挂载其实就是纯粹的隔离,作为一个独立的个体而存在;不可绑定挂载则有助于防止没有必要的文件拷贝,如某个用户数据目录,当根目录被递归式的复制时,用户目录无论从隐私还是实际用途考虑都需要有一个不可被复制的选项。

  • 默认情况下,所有挂载都是私有的。设置为共享挂载的命令如下:
$ mount --make-shared <mount-object>

从共享挂载克隆的挂载对象也是共享的挂载;它们相互传播挂载事件。

  • 设置为从属挂载的命令如下:
$ mount --make-slave <shared-mount-object>

从从属挂载克隆的挂载对象也是从属的挂载,它也从属于原来的从属挂载的主挂载对象。

  • 将一个从属挂载对象设置为共享 / 从属挂载,可以执行如下命令或者将其移动到一个共享挂载对象下:
$ mount --make-shared <slave-mount-object>
  • 如果你想把修改过的挂载对象重新标记为私有的,可以执行如下命令:
$ mount --make-private <mount-object>
  • 通过执行以下命令,可以将挂载对象标记为不可绑定的:
$ mount --make-unbindable <mount-object>

Linux的Mount绑定测试

  • 查看本机块设备:
$ lsblk
NAME            MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda               8:0    0 222.6G  0 disk 
├─sda1            8:1    0   200M  0 part /boot
└─sda2            8:2    0 222.4G  0 part ├─centos-root 253:0    0 122.4G  0 lvm  /└─centos-home 253:1    0   100G  0 lvm  /home
  • 创建和绑定目录:
$ mkdir /opt/tmp /mnt/tmp /mnt/tmp1 /mnt/tmp2
$ mount --bind /opt/tmp /mnt/tmp
$ mount --bind /mnt/tmp1 /mnt/tmp2
  • 查看绑定目录的详细信息:
$ cat /proc/self/mountinfo | grep /mnt/tmp
549 40 253:0 /opt/tmp /mnt/tmp rw,relatime shared:1 - xfs /dev/mapper/centos-root rw,seclabel,attr2,inode64,noquota
583 40 253:0 /mnt/tmp1 /mnt/tmp2 rw,relatime shared:1 - xfs /dev/mapper/centos-root rw,seclabel,attr2,inode64,noquota

可以看到两个绑定目录都是共享的,且共享 ID 1 ,父目录在 253:0 设备上。

在Docker中使用数据卷的主要方式

参考文档:

  1. Manage data in Docker ;
  2. Use bind mounts 。
  • Docker 支持的挂载模式:

  • 创建一个数据卷(卷挂载):
$ docker run --rm -it -v /data1 centos:7 bash
# Or
$ docker run --rm -it -v data1:/data1 centos:7 bash
# Or
$ docker run --rm -it --mount target=/data1 centos:7 bash
# Or
$ docker run --rm -it --mount type=volume,target=/data1 centos:7 bash
# Or
$ docker run --rm -it --mount type=volume,source=data1,target=/data1 centos:7 bash$ docker ps | awk 'NR==2 {print $1}' | xargs -i docker inspect -f '{{.State.Pid}}' {} | xargs -i cat /proc/{}/mountinfo | grep data
1029 1011 253:0 /var/lib/docker/volumes/239be79a64f7fa6ec815b1d9f2a7773a678ee5c8c1150f03ca81b0d5177b36a0/_data /data1 rw,relatime master:1 - xfs /dev/mapper/centos-root rw,seclabel,attr2,inode64,noquota
  • 映射一个外部卷(绑定挂载):
$ docker run --rm -it -v /opt:/data2 centos:7 bash
# Or
$ docker run --rm -it --mount type=bind,source=/opt,target=/data2 centos:7 bash$ docker ps | awk 'NR==2 {print $1}' | xargs -i docker inspect -f '{{.State.Pid}}' {} | xargs -i cat /proc/{}/mountinfo | grep data
1029 1011 253:0 /opt /data2 rw,relatime - xfs /dev/mapper/centos-root rw,seclabel,attr2,inode64,noquota
  • 使用数据型容器(卷挂载):
$ docker create --name vc -v /data1 centos:7
$ docker run --rm -it --volumes-from vc centos:7 bash$ docker ps | awk 'NR==2 {print $1}' | xargs -i docker inspect -f '{{.State.Pid}}' {} | xargs -i cat /proc/{}/mountinfo | grep data
1029 1011 253:0 /var/lib/docker/volumes/fe71f2d0ef18beb92cab7b99afcc5f501e47ed18224463e8c1aa1e8733003803/_data /data1 rw,relatime master:1 - xfs /dev/mapper/centos-root rw,seclabel,attr2,inode64,noquota
  • 带打包数据的容器(卷挂载):

编辑 Dockerfile

FROM busybox:latest
ADD htdocs /usr/local/apache2/htdocs
VOLUME /usr/local/apache2/htdocs

创建容器

$ mkdir htdocs
$ echo `date` > htdocs/test.txt
$ docker build -t volume-test .$ docker create --name vc2 -v /data1 volume-test
$ docker run --rm -it --volumes-from vc2 volume-test sh
/ # cat /proc/self/mountinfo  | grep htdocs
1034 1011 253:0 /var/lib/docker/volumes/54f47af60b8fb25602f022dcd8ad5b3e1a93a2d20c1045184a70391d9bed69b6/_data /usr/local/apache2/htdocs rw,relatime master:1 - xfs /dev/mapper/centos-root rw,seclabel,attr2,inode64,noquota$ docker ps | awk 'NR==2 {print $1}' | xargs -i docker inspect -f '{{.State.Pid}}' {} | xargs -i cat /proc/{}/mountinfo | grep htdocs
1034 1011 253:0 /var/lib/docker/volumes/54f47af60b8fb25602f022dcd8ad5b3e1a93a2d20c1045184a70391d9bed69b6/_data /usr/local/apache2/htdocs rw,relatime master:1 - xfs /dev/mapper/centos-root rw,seclabel,attr2,inode64,noquota
  • 使用临时外部卷(临时挂载):
$ docker run --rm -it --mount type=tmpfs,target=/data1 centos:7 bash$ docker ps | awk 'NR==2 {print $1}' | xargs -i docker inspect -f '{{.State.Pid}}' {} | xargs -i cat /proc/{}/mountinfo | grep data
1029 1011 0:160 / /data1 rw,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,seclabel

在Docker中使用块设备的相关测试

  • 在容器内通过绑定挂载使用宿主机的块设备,只能使用已经在宿主机格式化和挂载好的目录:
$ docker run --rm -it -v /data1 -v /opt:/data2 centos:7 bash
[root@4282b3df2417 /]# mount | grep data
/dev/sdb1 on /data2 type xfs (rw,relatime,attr2,inode64,noquota)
/dev/sda1 on /data1 type xfs (rw,relatime,attr2,inode64,noquota)$ docker inspect 4282b3df2417 | grep -i pid "Pid": 12797,"PidMode": "","PidsLimit": 0,$ cat /proc/12797/mounts | grep data
/dev/sdb1 /data2 xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/sda1 /data1 xfs rw,relatime,attr2,inode64,noquota 0 0
  • 在容器内通过共享设备使用块设备,可以读写,但是不能挂载:
$ docker run --rm -it --device /dev/sdc:/dev/sdc centos:7 bash[root@55423f5eaeea /]# mkfs -t minix /dev/sdc
21856 inodes
65535 blocks
Firstdatazone=696 (696)
Zonesize=1024
Maxsize=268966912[root@55423f5eaeea /]# mknod /dev/sdd b 8 48
[root@55423f5eaeea /]# mkfs -t minix /dev/sdd
mkfs.minix: cannot open /dev/sdd: Operation not permitted[root@55423f5eaeea /]# rm /dev/sdc
rm: remove block special file '/dev/sdc'? y[root@55423f5eaeea /]# mknod /dev/sdc b 8 32
[root@55423f5eaeea /]# mkfs -t minix /dev/sdc
21856 inodes
65535 blocks
Firstdatazone=696 (696)
Zonesize=1024
Maxsize=268966912[root@55423f5eaeea /]# mount /dev/sdc mnt/
[root@55423f5eaeea /]# mount: permission denied[root@55423f5eaeea /]# dd if=/dev/sdc of=/dev/null bs=512 count=10
10+0 records in
10+0 records out
5120 bytes (5.1 kB) copied, 0.000664491 s, 7.7 MB/s[root@55423f5eaeea /]# dd if=/dev/zero of=/dev/sdc bs=512 count=10
10+0 records in
10+0 records out
5120 bytes (5.1 kB) copied, 0.00124138 s, 4.1 MB/s
  • 在容器内通过特权模式使用块设备,可以读写和挂载:
$ docker run --rm -it --privileged=true centos:7 bash[root@b5c40e199476 /]# mount /dev/sdc mnt
[root@b5c40e199476 /]# mkfs -t minix /dev/sdc
mount: unknown filesystem type 'minix'[root@b5c40e199476 /]# yum install -y xfsprogs[root@b5c40e199476 /]# mkfs.xfs /dev/sdc -f
meta-data=/dev/sdc               isize=512    agcount=4, agsize=6553600 blks=                       sectsz=512   attr=2, projid32bit=1=                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=26214400, imaxpct=25=                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=12800, version=2=                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0[root@b5c40e199476 /]# mount /dev/sdc mnt
[root@b5c40e199476 /]# df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay          30G   19G   12G  62% /
tmpfs           910M     0  910M   0% /dev
tmpfs           910M     0  910M   0% /sys/fs/cgroup
/dev/sda1        30G   19G   12G  62% /etc/hosts
shm              64M     0   64M   0% /dev/shm
/dev/sdc        100G   33M  100G   1% /mnt[root@b5c40e199476 /]# echo `date` > /mnt/time.txt
[root@b5c40e199476 /]# cat /mnt/time.txt 
Wed Mar 6 12:23:05 UTC 2019

Kubernetes中的块设备使用和实现

  • 查看 kublet 初始化根目录 /var/lib/kubelet 时的源码,可以看到 kubelet 使用 syscall.MS_SHARED|syscall.MS_REC 标志,该目录下下所有的 Mount 都默认共享(相当于执行 mount --make-rshared /var/lib/kubelet ):
// pkg/kubelet/kubelet.go
// setupDataDirs creates:
// 1.  the root directory
// 2.  the pods directory
// 3.  the plugins directory
// 4.  the pod-resources directory
func (kl *Kubelet) setupDataDirs() error {
...if err := kl.mounter.MakeRShared(kl.getRootDir()); err != nil {return fmt.Errorf("error configuring root directory: %v", err)}
...
}// pkg/util/mount/nsenter_mount.go
func (n *NsenterMounter) MakeRShared(path string) error {return doMakeRShared(path, hostProcMountinfoPath)
}// pkg/util/mount/mount_linux.go
// doMakeRShared is common implementation of MakeRShared on Linux. It checks if
// path is shared and bind-mounts it as rshared if needed. mountCmd and
// mountArgs are expected to contain mount-like command, doMakeRShared will add
// '--bind <path> <path>' and '--make-rshared <path>' to mountArgs.
func doMakeRShared(path string, mountInfoFilename string) error {shared, err := isShared(path, mountInfoFilename)if err != nil {return err}if shared {klog.V(4).Infof("Directory %s is already on a shared mount", path)return nil}klog.V(2).Infof("Bind-mounting %q with shared mount propagation", path)// mount --bind /var/lib/kubelet /var/lib/kubeletif err := syscall.Mount(path, path, "" /*fstype*/, syscall.MS_BIND, "" /*data*/); err != nil {return fmt.Errorf("failed to bind-mount %s: %v", path, err)}// mount --make-rshared /var/lib/kubeletif err := syscall.Mount(path, path, "" /*fstype*/, syscall.MS_SHARED|syscall.MS_REC, "" /*data*/); err != nil {return fmt.Errorf("failed to make %s rshared: %v", path, err)}return nil
}
  • 创建一个使用 PVC 创建 RBD Pod
$ echo 'apiVersion: v1
kind: Pod
metadata:name: nginx-test
spec:containers:- name: nginximage: nginx:latestvolumeMounts:- name: nginx-test-vol1mountPath: /data/readOnly: falsevolumes:- name: nginx-test-vol1persistentVolumeClaim:claimName: nginx-test-vol1-claim' | kubectl create -f -
pod/nginx-test created
  • 查看 PVC 的状态:
$ kubectl get pvc
NAME                    STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
nginx-test-vol1-claim   Bound    pvc-d6f6b6f8-446c-11e9-bbd8-6c92bf74be54   10Gi       RWO            ceph-rbd       114s$ kubectl describe pvc nginx-test-vol1-claim
Name:          nginx-test-vol1-claim
Namespace:     default
StorageClass:  ceph-rbd
Status:        Bound
Volume:        pvc-d6f6b6f8-446c-11e9-bbd8-6c92bf74be54
Labels:        <none>
Annotations:   pv.kubernetes.io/bind-completed: yespv.kubernetes.io/bound-by-controller: yesvolume.beta.kubernetes.io/storage-provisioner: kubernetes.io/rbd
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      10Gi
Access Modes:  RWO
VolumeMode:    Filesystem
Events:Type       Reason                 Age    From                         Message----       ------                 ----   ----                         -------Normal     ProvisioningSucceeded  6m36s  persistentvolume-controller  Successfully provisioned volume pvc-d6f6b6f8-446c-11e9-bbd8-6c92bf74be54 using kubernetes.io/rbd
Mounted By:  nginx-test
  • 查看 PV 的状态:
$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                           STORAGECLASS   REASON   AGE
pvc-d6f6b6f8-446c-11e9-bbd8-6c92bf74be54   10Gi       RWO            Delete           Bound    default/nginx-test-vol1-claim   ceph-rbd                105s$ kubectl describe pv pvc-d6f6b6f8-446c-11e9-bbd8-6c92bf74be54
Name:            pvc-d6f6b6f8-446c-11e9-bbd8-6c92bf74be54
Labels:          <none>
Annotations:     kubernetes.io/createdby: rbd-dynamic-provisionerpv.kubernetes.io/bound-by-controller: yespv.kubernetes.io/provisioned-by: kubernetes.io/rbd
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    ceph-rbd
Status:          Bound
Claim:           default/nginx-test-vol1-claim
Reclaim Policy:  Delete
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        10Gi
Node Affinity:   <none>
Message:         
Source:Type:          RBD (a Rados Block Device mount on the host that shares a pod's lifetime)CephMonitors:  [172.29.201.125:6789 172.29.201.126:6789 172.29.201.201:6789]RBDImage:      kubernetes-dynamic-pvc-db7fcd29-446c-11e9-af81-6c92bf74be54FSType:        RBDPool:       k8sRadosUser:     k8sKeyring:       /etc/ceph/keyringSecretRef:     &SecretReference{Name:ceph-k8s-secret,Namespace:,}ReadOnly:      false
Events:            <none>
  • 查看创建和映射的 RBD
$ rbd ls -p k8s
kubernetes-dynamic-pvc-db7fcd29-446c-11e9-af81-6c92bf74be54$ lsblk | grep rbd0
rbd0            252:0    0    10G  0 disk /var/lib/kubelet/pods/18a8fb7b-446d-11e9-bbd8-6c92bf74be54/volumes/kubernetes.io~rbd/pvc-d6f6b6f8-446c-11e9-bbd8-6c92bf74be54
  • 查看 RBD 的挂载信息:
$ cat /proc/self/mountinfo | grep rbd0
313 40 252:0 / /var/lib/kubelet/plugins/kubernetes.io/rbd/mounts/k8s-image-kubernetes-dynamic-pvc-db7fcd29-446c-11e9-af81-6c92bf74be54 rw,relatime shared:262 - ext4 /dev/rbd0 rw,seclabel,stripe=1024,data=ordered
318 40 252:0 / /var/lib/kubelet/pods/18a8fb7b-446d-11e9-bbd8-6c92bf74be54/volumes/kubernetes.io~rbd/pvc-d6f6b6f8-446c-11e9-bbd8-6c92bf74be54 rw,relatime shared:262 - ext4 /dev/rbd0 rw,seclabel,stripe=1024,data=ordered

可以看到 RBD 被挂载在两个位置,一个是 Pod Volume 目录,还有一个是 RBD 插件目录,而且这两个目录都是 shared:262 ,说明这两个目录是被绑定的。

  • 查看 RBD 挂载目录的位置:
$ cat /proc/self/mountinfo | grep "^40 "
40 0 253:0 / / rw,relatime shared:1 - xfs /dev/mapper/centos-root rw,seclabel,attr2,inode64,noquota

可以看到 RBD 挂载在 253:0 设备上,这是宿主机的根目录所挂载的位置。

  • 查看 Pod 挂载的卷目录:
$ cat /proc/self/mountinfo | grep 18a8fb7b-446d-11e9-bbd8-6c92bf74be54
303 40 0:56 / /var/lib/kubelet/pods/18a8fb7b-446d-11e9-bbd8-6c92bf74be54/volumes/kubernetes.io~secret/default-token-zn95h rw,relatime shared:233 - tmpfs tmpfs rw,seclabel
318 40 252:0 / /var/lib/kubelet/pods/18a8fb7b-446d-11e9-bbd8-6c92bf74be54/volumes/kubernetes.io~rbd/pvc-d6f6b6f8-446c-11e9-bbd8-6c92bf74be54 rw,relatime shared:262 - ext4 /dev/rbd0 rw,seclabel,stripe=1024,data=ordered$ cat /proc/self/mountinfo | grep shared:233
303 40 0:56 / /var/lib/kubelet/pods/18a8fb7b-446d-11e9-bbd8-6c92bf74be54/volumes/kubernetes.io~secret/default-token-zn95h rw,relatime shared:233 - tmpfs tmpfs rw,seclabel

可以看到 Pod 挂载了两个卷,除了之前的 RBD ,还有就是一个存放 Secret 的卷。

  • 查看 Pod Docker 容器中挂载目录:
$ docker inspect $(docker ps | grep nginx_nginx-test | awk '{print $1}') | grep Mounts -A33"Mounts": [{"Type": "bind","Source": "/var/lib/kubelet/pods/18a8fb7b-446d-11e9-bbd8-6c92bf74be54/volumes/kubernetes.io~rbd/pvc-d6f6b6f8-446c-11e9-bbd8-6c92bf74be54","Destination": "/data","Mode": "Z","RW": true,"Propagation": "rprivate"},{"Type": "bind","Source": "/var/lib/kubelet/pods/18a8fb7b-446d-11e9-bbd8-6c92bf74be54/volumes/kubernetes.io~secret/default-token-zn95h","Destination": "/var/run/secrets/kubernetes.io/serviceaccount","Mode": "ro,Z","RW": false,"Propagation": "rprivate"},{"Type": "bind","Source": "/var/lib/kubelet/pods/18a8fb7b-446d-11e9-bbd8-6c92bf74be54/etc-hosts","Destination": "/etc/hosts","Mode": "Z","RW": true,"Propagation": "rprivate"},{"Type": "bind","Source": "/var/lib/kubelet/pods/18a8fb7b-446d-11e9-bbd8-6c92bf74be54/containers/nginx/190cc168","Destination": "/dev/termination-log","Mode": "Z","RW": true,"Propagation": "rprivate"}],

可以看到 Docker 的这些卷最后都是通过 Bind 挂载的,而且 Mount 广播使用的是 rprivate 属性。

  • 看看 Pod 的容器内 Mount 情况:
$ docker exec -it $(docker ps | grep nginx_nginx-test | awk '{print $1}') df -h
Filesystem               Size  Used Avail Use% Mounted on
overlay                  123G  4.7G  118G   4% /
tmpfs                     64M     0   64M   0% /dev
tmpfs                    189G     0  189G   0% /sys/fs/cgroup
/dev/rbd0                9.8G   37M  9.7G   1% /data
/dev/mapper/centos-root  123G  4.7G  118G   4% /etc/hosts
shm                       64M     0   64M   0% /dev/shm
tmpfs                    189G   12K  189G   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                    189G     0  189G   0% /proc/acpi
tmpfs                    189G     0  189G   0% /proc/scsi
tmpfs                    189G     0  189G   0% /sys/firmware$ docker exec -it $(docker ps | grep nginx_nginx-test | awk '{print $1}') cat /proc/self/mountinfo | grep -e rbd -e serviceaccount
617 599 252:0 / /data rw,relatime - ext4 /dev/rbd0 rw,seclabel,stripe=1024,data=ordered
623 599 0:56 / /run/secrets/kubernetes.io/serviceaccount ro,relatime - tmpfs tmpfs rw,seclabel

可以看到 Pod 的容器内的确主要挂载了 RBD Secret 两个目录。

分析总结

  1. Docker 中,无论使用哪种方式使用数据卷,实际上都是利用的 Linux 的的 mount --bind 绑定挂载功能实现。
  2. Kubernetes 中使用 RBD 卷时,首先通过 rbd map 到宿主机并进行格式化,然后 mount 到宿主机目录,最后把这个宿主机目录 mount --bind 到容器的指定目录中使用。

根据原理分析可以初步推断:在宿主机中测试 RBD 读写性能和在 Docker Kubernetes 中分别测试的性能没有本质区别, Docker Kubernetes 本身不会对 RBD 性能造成影响(之后我又使用Fio对其进行完整的性能测试,和这个结论也是一致的)。

这篇关于Docker和Kubernetes中使用Ceph RBD卷的原理分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/247460

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma