本文主要记录在虚拟机中安装Ceph单节点集群的过程,其实多配置几个节点,也就是安装集群的过程。
Ceph中午文档:http://docs.ceph.org.cn/

集群规划

集群环境:

| 主机 | IP | 操作系统 | 软件 | 组件 | | —- | —- | —- | —- | —- |

| k8s-rke-node001 | 192.168.56.111 | Centos7.7.1908 | Ceph 14.2.4 | ceph_deploy、OSD、MON |

| k8s-rke-node002 | 192.168.56.112 | Centos7.7.1908 | Ceph 14.2.4 | OSD、MON |

| k8s-rke-node003 | 192.168.56.113 | Centos7.7.1908 | Ceph 14.2.4 | OSD、MON |

安装用户:chenzj

准备环境

你的管理节点必须能够通过 SSH 无密码地访问各 Ceph 节点。如果 ceph-deploy 以某个普通用户登录,那么这个用户必须有无密码使用 sudo 的权限。

设置hosts

  1. echo << EOF > /etc/hosts
  2. 192.168.56.111 k8s-rke-node001
  3. 192.168.56.112 k8s-rke-node002
  4. 192.168.56.113 k8s-rke-node003
  5. EOF

创建部署 CEPH 的用户

ceph-deploy 工具必须以普通用户登录 Ceph 节点,且此用户拥有无密码使用 sudo 的权限,因为它需要在安装软件及配置文件的过程中,不必输入密码。
在各 Ceph 节点创建新用户并设置密码。

  1. USER=chenzj
  2. useradd -G docker -d /home/$USER -m $USER
  3. echo $USER|passwd $USER --stdin >/dev/null 2>&1

确保各 Ceph 节点上新创建的用户都有 sudo 权限。

  1. sudo echo "$USER ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/$USER
  2. sudo chmod 0440 /etc/sudoers.d/$USER

允许无密码 SSH 登录

正因为 ceph-deploy 不支持输入密码,你必须在管理节点上生成 SSH 密钥并把其公钥分发到各 Ceph 节点。 ceph-deploy 会尝试给初始 monitors 生成 SSH 密钥对。
生成 SSH 密钥对,但不要用 sudoroot 用户。提示 “Enter passphrase” 时,直接回车,口令即为空:

  1. su - $USER
  2. yes|ssh-keygen -f ~/.ssh/id_rsa -t rsa -N ""

把公钥拷贝到各 Ceph 节点

  1. ssh-copy-id $USER@k8s-rke-node001
  2. ssh-copy-id $USER@k8s-rke-node002
  3. ssh-copy-id $USER@k8s-rke-node003

修改 ceph-deploy 管理节点上的 ~/.ssh/config 文件,这样 ceph-deploy 就能用你所建的用户名登录 Ceph 节点了,而无需每次执行 ceph-deploy 都要指定 --username

  1. cat << EOF >> ~/.ssh/config
  2. Host k8s-rke-node001
  3. Hostname k8s-rke-node001
  4. User $USER
  5. Host k8s-rke-node002
  6. Hostname k8s-rke-node002
  7. User $USER
  8. Host k8s-rke-node003
  9. Hostname k8s-rke-node003
  10. User $USER
  11. EOF
  12. chmod 644 ~/.ssh/config

配置时钟同步

设置SELINUX

在 CentOS 和 RHEL 上, SELinux 默认为 Enforcing 开启状态。为简化安装,我们建议把 SELinux 设置为 Permissive 或者完全禁用,也就是在加固系统配置前先确保集群的安装、配置没问题。用下列命令把 SELinux 设置为 Permissive

  1. sudo setenforce 0

设置TTY

在 CentOS 和 RHEL 上执行 ceph-deploy 命令时可能会报错。如果你的 Ceph 节点默认设置了 requiretty ,执行 sudo visudo 禁用它,并找到 Defaults requiretty 选项,把它改为 Defaults:ceph !requiretty 或者直接注释掉,这样 ceph-deploy 就可以用之前创建的用户(创建部署 Ceph 的用户 )连接了。

  1. sed -i 's/Defaults *requiretty/#Defaults requiretty/g' /etc/sudoers
  2. sed -i 's/Defaults *!visiblepw/Defaults visiblepw/g' /etc/sudoers

安装yum-plugin-priorities

确保你的包管理器安装了优先级/首选项包且已启用。

  1. sudo yum install yum-plugin-priorities -y

加载rbd模块

  1. sudo modprobe rbd

创建集群

安装 Ceph-Deploy

把 Ceph 仓库添加到 ceph-deploy 管理节点,然后安装 ceph-deploy
安装包管理工具:

  1. sudo yum install -y yum-utils curl -k -s -o /etc/yum.repos.d/epel.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo

配置yum源,注意:这里ceph使用的是nautilus版本。

  1. cat << EOF > ceph.repo[ceph-base]name=Ceph Base packagesbaseurl=https://mirrors.cloud.tencent.com/ceph/rpm-nautilus/el7/x86_64enabled=1gpgcheck=1type=rpm-mdgpgkey=https://download.ceph.com/keys/release.asc[ceph-noarch]name=Ceph noarch packagesbaseurl=https://mirrors.cloud.tencent.com/ceph/rpm-nautilus/el7/noarchenabled=1gpgcheck=1priority=1type=rpm-mdgpgkey=http://mirrors.cloud.tencent.com/ceph/keys/release.ascEOFsudo mv ceph.repo /etc/yum.repos.d/

设置环境变量,使ceph-deploy使用腾讯云源。

  1. export CEPH_DEPLOY_REPO_URL=https://mirrors.cloud.tencent.com/ceph/rpm-nautilus/el7export CEPH_DEPLOY_GPG_URL=https://mirrors.cloud.tencent.com/ceph/keys/release.asc

更新软件库并安装 ceph-deploy

  1. sudo yum update -y && sudo yum install ceph-deploy python-pip -y

创建配置目录

先在ceph-deploy管理节点上创建一个目录,用于保存 ceph-deploy 生成的配置文件和密钥对。

  1. mkdir ceph-cluster && cd ceph-cluster

创建集群

在管理节点上,进入刚创建的放置配置文件的目录,用 ceph-deploy 执行如下步骤,安装规划在k8s-rke-node001节点初始化Monitor。
1、创建集群,部署新的 monitor 节点

  1. ceph-deploy new k8s-rke-node001 \ --public-network 192.168.56.0/24 \ --cluster-network 192.168.56.0/24

注意:

  • public-network要和当前ip的网段保持对应。

2、在当前目录下用 lscat 检查 ceph-deploy 的输出,应该有一个 Ceph 配置文件、一个 monitor 密钥环和一个日志文件。

  1. -rw-r--r-- 1 root root 291 9 17 22:15 ceph.conf-rw-r--r-- 1 root root 212100 9 17 22:16 ceph-deploy-ceph.log-rw------- 1 root root 73 9 16 09:40 ceph.mon.keyring

3、如果出现异常:

  1. Traceback (most recent call last): File "/usr/bin/ceph-deploy", line 18, in <module> from ceph_deploy.cli import main File "/usr/lib/python2.7/site-packages/ceph_deploy/cli.py", line 1, in <module> import pkg_resourcesImportError: No module named pkg_resources

安装相关依赖即可:

  1. sudo yum install python-pkg-resources python-setuptools -y

4、把 Ceph 配置文件里的默认副本数从 3 改成 2 ,这样只有两个 OSD 也可以达到 active + clean 状态。把下面这行加入 [global] 段:

  1. echo "osd_pool_default_size =2[mon]mon_allow_pool_delete = truemon_max_pg_per_osd = 1024#时钟同步mon_clock_drift_allowed = 2mon_clock_drift_warn_backoff = 30" >> ceph.conf

安装 Ceph 到各节点

  1. ceph-deploy install k8s-rke-node001 k8s-rke-node002 k8s-rke-node003

此过程需要等待一段时间,因为 ceph-deploy 会 SSH 登录到各 node 上去,依次执行安装 ceph 依赖的组件包。
如果下载太慢,可以设置镜像:

  1. sudo rpm --import https://mirrors.cloud.tencent.com/ceph/keys/release.ascceph-deploy install --repo-url https://mirrors.cloud.tencent.com/ceph/rpm-nautilus k8s-rke-node001

如果还是太慢,则在每个节点配置ceph的yum源,然后通过yum安装:

  1. sudo yum -y install ceph ceph-radosgw

安装成功之后,检查每个节点的ceph版本是否一致:

  1. sudo ceph --versionceph version 14.2.4 (75f4de193b3ea58512f204623e6c5a16e6c1e1ba) nautilus (stable)

初始化 Monitor

初始化 Monitor , 获取秘钥,生产对应的 key:(服务默认端口 6789)

  1. ceph-deploy mon create-initial

完成上述操作后,当前目录里应该会出现这些密钥:

  1. ceph.client.admin.keyringceph.bootstrap-mgr.keyringceph.bootstrap-osd.keyringceph.bootstrap-mds.keyringceph.bootstrap-rgw.keyringceph.bootstrap-rbd.keyringceph.bootstrap-rbd-mirror.keyring

初始化磁盘

  1. fdisk -lsudo mkfs /dev/sdbparted /dev/sdb

创建 OSD 存储节点

列出节点所有磁盘信息:

  1. ceph-deploy disk list k8s-rke-node001ceph-deploy disk list k8s-rke-node002ceph-deploy disk list k8s-rke-node003

创建 OSD 存储节点:(服务默认端口 74053)

  1. ceph-deploy osd create k8s-rke-node001 --data /dev/sdb1ceph-deploy osd create k8s-rke-node002 --data /dev/sdb1ceph-deploy osd create k8s-rke-node003 --data /dev/sdb1

查看创建的osd:

  1. ceph-deploy osd list k8s-rke-node001ceph-deploy osd list k8s-rke-node002ceph-deploy osd list k8s-rke-node003

清除磁盘分区和内容:

  1. ceph-deploy disk zap k8s-rke-node001 /dev/sdbceph-deploy disk zap k8s-rke-node002 /dev/sdbceph-deploy disk zap k8s-rke-node003 /dev/sdb

分配 admin 配置文件

ceph-deploy 把配置文件和 admin 密钥拷贝到管理节点和 Ceph 节点,这样你每次执行 Ceph 命令行时就无需指定 monitor 地址和 ceph.client.admin.keyring 了。

  1. ceph-deploy --overwrite-conf admin k8s-rke-node001 k8s-rke-node002 k8s-rke-node003

确保你对 ceph.client.admin.keyring 有正确的操作权限。

  1. sudo chmod +r /etc/ceph/ceph.client.admin.keyring

查看集群状态

  1. ceph -s

此时出现错误,没有活跃的 mgr 服务。

部署 MGR

  1. ceph-deploy mgr create k8s-rke-node001 k8s-rke-node002 k8s-rke-node003

继续查看状态:

  1. ceph -s

此时状态 HEALTH_OK 则集群正常。

安装 Dashboard

安装 Dashboard,首先必须有 mgr
开启模块:

  1. ceph mgr module enable dashboard

创建证书:

  1. ceph dashboard create-self-signed-cert

创建密码:

  1. ceph dashboard set-login-credentials admin admin

查看服务访问:

  1. ceph mgr services

修改ceph.conf配置:

  1. [mgr]mgr modules = dashboard

推送配置文件:

  1. ceph-deploy --overwrite-conf admin k8s-rke-node001 k8s-rke-node002 k8s-rke-node003

重启服务:

  1. systemctl restart ceph\*.service ceph\*.target

可以修改访问地址:

  1. $ ceph config-key put mgr/dashboard/server_addr 34.97.202.172$ ceph config-key put mgr/dashboard/server_port 8000

清除集群

  1. $ ceph-deploy purge k8s-rke-node001 k8s-rke-node002 k8s-rke-node003$ ceph-deploy purgedata k8s-rke-node001 k8s-rke-node002 k8s-rke-node003$ ceph-deploy forgetkeys

配置调优

配置文件优化如下:

  1. [global]fsid = bf24f836-509b-4dbb-9f73-2518818a5cd2mon_initial_members = instance-template-3, instance-template-4, instance-template-5mon_host = 10.174.0.16,10.174.0.17,10.174.0.18 # 集群认证auth_cluster_required = cephx # 服务认证auth_service_required = cephx # 客户端认证auth_client_required = cephx # 如果设置了该选项,Ceph 会设置系统的 max open fds,默认值为 0max open files = 0 # 最小副本数 默认是3osd pool default size = 3 #PG 处于 degraded 状态不影响其 IO 能力,min_size 是一个PG 能接受 IO 的最小副本数osd pool default min size = 1 [mon.a]host = instance-template-3mon addr = 10.174.0.16:6789 [mon.b]host = instance-template-4mon addr = 10.174.0.17:6789 [mon.c]host = instance-template-5mon addr = 10.174.0.18:6789 [mon]mon data = /var/lib/ceph/mon/ceph-$id # monitor 间的 clock drift,默认值 0.05mon clock drift allowed = 1 # 向 monitor 报告 down 的最小 OSD 数,默认值 1mon osd min down reporters = 1 # 标记一个OSD状态为down和out之前ceph等待的秒数,默认值300mon osd down out interval = 600 [osd]# osd 数据路径osd data = /var/lib/ceph/osd/ceph-$id # 默认 pool pg,pgp 数量osd pool default pg num = 1024osd pool default pgp num = 1024 # osd 的 journal 写日志时的大小默认 5120osd journal size = 20000 # 格式化文件系统类型osd mkfs type = xfs # 格式化文件系统时附加参数osd mkfs options xfs = -f # 为 XATTRS 使用 object map,EXT4 文件系统时使用,XFS 或者 btrf 也可以使用,默认 falsefilestore xattr use omap = true # 从日志到数据盘最小同步间隔(seconds),默认值 0.1filestore min sync interval = 10 # 从日志到数据盘最大同步间隔(seconds),默认值 5filestore max sync interval = 15 # 数据盘最大接受的操作数,默认值 500filestore queue max ops = 25000 # 数据盘能够 commit 的最大字节数(bytes),默认值 100filestore queue max bytes = 10485760 # 数据盘能够 commit 的操作数,500filestore queue committing max ops = 5000 # 数据盘能够 commit 的最大字节数(bytes),默认值 100filestore queue committing max bytes = 10485760000 # 前一个子目录分裂成子目录中的文件的最大数量,默认值 2filestore split multiple = 8 # 前一个子类目录中的文件合并到父类的最小数量,默认值10filestore merge threshold = 40 # 对象文件句柄缓存大小,默认值 128filestore fd cache size = 1024 # 并发文件系统操作数,默认值 2filestore op threads = 32 # journal 一次性写入的最大字节数(bytes),默认值 1048560journal max write bytes = 1073714824 # journal一次性写入的最大记录数,默认值 100journal max write entries = 10000 # journal一次性最大在队列中的操作数,默认值 50journal queue max ops = 50000 # journal一次性最大在队列中的字节数(bytes),默认值 33554432journal queue max bytes = 10485760000 # # OSD一次可写入的最大值(MB), 默认 90osd max write size = 512 # 客户端允许在内存中的最大数据(bytes), 默认值100osd client message size cap = 2147483648 # 在 Deep Scrub 时候允许读取的字节数(bytes), 默认值524288osd deep scrub stride = 131072 # 并发文件系统操作数, 默认值 2osd op threads = 8 # OSD 密集型操作例如恢复和 Scrubbing 时的线程, 默认值1osd disk threads = 4 # 保留 OSD Map 的缓存(MB), 默认 500osd map cache size = 1024 # OSD 进程在内存中的 OSD Map 缓存(MB), 默认 50osd map cache bl size = 128 # 默认值rw,noatime,inode64, Ceph OSD xfs Mount选项osd mount options xfs = "rw,noexec,nodev,noatime,nodiratime,nobarrier" # 恢复操作优先级,取值 1-63,值越高占用资源越高, 默认值 10osd recovery op priority = 4 # 同一时间内活跃的恢复请求数, 默认值 15osd recovery max active = 10 # 一个 OSD 允许的最大 backfills 数, 默认值 10osd max backfills = 4 [client]# RBD缓存, 默认 truerbd cache = true # RBD缓存大小(bytes), 默认 335544320(320M)rbd cache size = 268435456 # 缓存为 write-back 时允许的最大 dirty 字节数(bytes),如果为0,使用 write-through,默认值为 25165824rbd cache max dirty = 134217728 # 在被刷新到存储盘前 dirty 数据存在缓存的时间(seconds), 默认值为 1rbd cache max dirty age = 5 # 该选项是为了兼容 linux-2.6.32 之前的 virtio 驱动,避免因为不发送 flush 请求,数据不回写 默认值 true # 设置该参数后,librbd 会以 writethrough 的方式执行 io,直到收到第一个 flush 请求,才切换为 writeback 方式。# rbd cache writethrough until flush = false # 最大的 Object 对象数,默认为 0,表示通过 rbd cache size 计算得到,librbd 默认以 4MB 为单位对磁盘 Image 进行逻辑切分,默认值 0# 每个 chunk 对象抽象为一个 Object;librbd 中以 Object 为单位来管理缓存,增大该值可以提升性能# rbd cache max dirty object = 2 # 开始执行回写过程的脏数据大小,不能超过 rbd_cache_max_dirty,默认值 16777216# rbd cache target dirty = 235544320 # GW 端口,默认 7480# rgw frontends = civetweb port=7480

配置完成后,需要重启加载配置文件到所有节点:

  1. ceph-deploy --overwrite-conf admin k8s-rke-node001 k8s-rke-node002 k8s-rke-node003

重启服务:

  1. systemctl restart ceph\*.service ceph\*.target

集群扩容

一个基本的集群启动并开始运行后,下一步就是扩展集群。在 k8s-rke-node004 上添加一个 OSD 守护进程和一个元数据服务器。然后分别在 k8s-rke-node002 和 k8s-rke-node003 上添加 Ceph Monitor ,以形成 Monitors 的法定人数。

添加 OSD

在 k8s-rke-node004 上添加一个 OSD:

  1. ssh k8s-rke-node004 "sudo mkdir -p /data/ceph/osd"ceph-deploy osd create --data /data/ceph/osd k8s-rke-node004

一旦你新加了 OSD , Ceph 集群就开始重均衡,把归置组迁移到新 OSD 。可以用下面的 ceph 命令观察此过程:

  1. ceph -w

你应该能看到归置组状态从 active + clean 变为 active ,还有一些降级的对象;迁移完成后又会回到 active + clean 状态( Control-C 退出)。
查看 osd 状态:

  1. ceph osd tree

添加 Monitor

Ceph 存储集群需要至少一个 Monitor 才能运行。为达到高可用,典型的 Ceph 存储集群会运行多个 Monitors,这样在单个 Monitor 失败时不会影响 Ceph 存储集群的可用性。Ceph 使用 PASOX 算法,此算法要求有多半 monitors(即 1 、 2:3 、 3:4 、 3:5 、 4:6 等 )形成法定人数。
k8s-rke-node002 和 k8s-rke-node003 上添加 Ceph Monitor

  1. ceph-deploy mon add k8s-rke-node002ceph-deploy mon add k8s-rke-node003

新增 Monitor 后,Ceph 会自动开始同步并形成法定人数。你可以用下面的命令检查法定人数状态:

  1. ceph quorum_status --format json-pretty
  • 请确保ntp时钟同步

    添加 MDS

    如果需要使用 Cephfs,则需要创建 MDS: ``` ceph-deploy mds create k8s-rke-node001
  1. > 注意:
  2. > 当前生产环境下的 Ceph 只能运行一个元数据服务器。
  3. 查看服务状态:

$ netstat -lnputActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name…tcp 0 0 0.0.0.0:6805 0.0.0.0:* LISTEN 71047/ceph-mds

  1. ## 添加 RGW
  2. 添加 RGW 支持使用 Object Storage 存储:(服务端 7480)

ceph-deploy rgw create k8s-rke-node001

  1. 可以更改该节点 ceph.conf 内服务端口:

[client]rgw frontends = civetweb port=80

  1. 浏览器访问:[http://192.168.56.111:7480](http://192.168.56.111:7480)
  2. # 使用
  3. ## CephFS
  4. 查看 pool 存储池:

ceph osd pool ls

  1. 创建 pool 名为 test_data pg 32

ceph osd pool create test_data 32

  1. > pg 数量:
  2. > 创建pool 通常在创建pool之前,需要覆盖默认的 pg_num,官方推荐: 若少于 5 OSD 设置 pg_num 128 5~10 OSD,设置 pg_num 512 10~50 OSD,设置 pg_num 4096 超过 50 OSD,可以参考 pgcalc 计算。

Total PGs = (Total_number_of_OSD * 100) / max_replication_count

  1. 创建 pool 名为 test_metadata pg 32

ceph osd pool create test_metadata 32

  1. 创建名为 data fs

$ ceph fs new data test_metadata test_datanew fs with metadata pool 10 and data pool 9

  1. 查看 cephfs 列表:

$ ceph fs lsname: data, metadata pool: test_metadata, data pools: [test_data ]

  1. 安装 ceph-fuse 进行挂载文件系统的支持:

sudo yum install -y ceph-fuse

  1. 挂载:

$ mkdir /data$ ceph-fuse -m 192.168.1.121:6789,192.168.1.122:6789,192.168.1.123:6789 /data$ df -hFilesystem Size Used Avail Use% Mounted on…ceph-fuse 47G 0 47G 0% /data

  1. 可以使用 mount 进行挂载:

$ mount -t ceph -o name=admin,secret=ceph auth get-key client.admin,rw 192.168.1.121:6789,192.168.1.122:6789,192.168.1.123:6789:/ /data

  1. 可能会超时:

$ mount -vvvv -t ceph -o name=admin,secret=ceph auth get-key client.admin,rw 192.168.1.121:6789,192.168.1.122:6789,192.168.1.123:6789:/ /data parsing options: rw,name=admin,secret=xxxmount error 110 = Connection timed outmount error 110 = Connection timed out

  1. 通过如下方式解决:

$ ceph osd crush tunables hammer$ ceph osd crush reweight-all

  1. 删除 pool

ceph osd pool rm test_data test_data —yes-i-really-really-mean-it

  1. 如出现如下错误:

$ ceph osd pool rm test_data test_data —yes-i-really-really-mean-itError EPERM: WARNING: this will PERMANENTLY DESTROY all data stored in pool data. If you are ABSOLUTELY CERTAIN that is what you want, pass the pool name twice, followed by —yes-i-really-really-mean-it.

  1. 请添加配置:

[mon]…mon_allow_pool_delete = true

  1. 重启服务:

systemctl restart ceph*.service ceph*.target

  1. 然后再进行删除。
  2. ## RBD
  3. 使用 RBD 存储,加载模块:

$ modprobe rbd$ modinfo rbdfilename: /lib/modules/4.4.197-1.el7.elrepo.x86_64/kernel/drivers/block/rbd.kolicense: GPLdescription: RADOS Block Device (RBD) driverauthor: Jeff Garzik jeff@garzik.orgauthor: Yehuda Sadeh yehuda@hq.newdream.netauthor: Sage Weil sage@newdream.netauthor: Alex Elder elder@inktank.comsrcversion: 6B2F83CD15A20F9CDD5DDF0depends: libcephretpoline: Yintree: Yvermagic: 4.4.197-1.el7.elrepo.x86_64 SMP mod_unload modversionsparm: single_major:Use a single major number for all rbd devices (default: false) (bool)

  1. 查看存储池:

$ ceph osd lspools7 rbd8 k8s9 test_data10 test_metadata

  1. 查看某个存储池中的镜像:

rbd list k8s

  1. 查看各个存储池使用情况:

$ rados dfPOOL_NAME USED OBJECTS CLONES COPIES MISSING_ON_PRIMARY UNFOUND DEGRADED RD_OPS RD WR_OPS WR USED COMPR UNDER COMPRk8s 48 GiB 5235 0 15705 0 0 0 3331022 180 GiB 52592993 533 GiB 0 B 0 Brbd 192 KiB 3 0 9 0 0 0 2100 16 MiB 522 360 MiB 0 B 0 Btest_data 0 B 0 0 0 0 0 0 0 0 B 0 0 B 0 B 0 Btest_metadata 1.5 MiB 22 0 66 0 0 0 0 0 B 45 13 KiB 0 B 0 Btest_rbd 192 KiB 3 0 9 0 0 0 608 1.8 MiB 235 23 MiB 0 B 0 Btotal_objects 5263total_used 51 GiBtotal_avail 1.4 TiBtotal_space 1.5 TiB

  1. 创建名为 test_rbd Pool

ceph osd pool create test_rbd 70

  1. 初始化 rbd pool 块:

rbd pool init test_rbd

  1. 创建 rbd,名为 rbd1 大小为 10GB

rbd create test_rbd/rbd1 —size 10240# rbd create test_rbd/rbd1 —size 10240 —image-format 2 —object-size 22# rbd create test_rbd/rbd1 —size 1024 —image-feature layering

  1. 说明:
  2. - 默认创建 image 时,没有任何模式也就是 --image-format 1
  3. - 如果 --image-format 2,则支持 RBD分层(layering),是实现 COW Copy-On-Write)的前提。
  4. - 如果 --object-size 2416MB 则设置 Object 的大小,默认值 224MB
  5. 查看池中的 image

$ rbd ls test_rbdrbd1 $ rbd info test_rbd/rbd1rbd image ‘rbd1’: size 10 GiB in 2560 objects order 22 (4 MiB objects) snapshot_count: 0 id: 51e6e345fdee6 block_name_prefix: rbd_data.51e6e345fdee6 format: 2 features: layering, exclusive-lock, object-map, fast-diff, deep-flatten op_features: flags: create_timestamp: Mon Feb 3 20:48:14 2020 access_timestamp: Mon Feb 3 20:48:14 2020 modify_timestamp: Mon Feb 3 20:48:14 2020

  1. 改写镜像大小:

$ rbd resize test_rbd/rbd1 —size 20480Resizing image: 100% complete…done. $ rbd info test_rbd/rbd1rbd image ‘rbd1’: size 20 GiB in 5120 objects order 22 (4 MiB objects) snapshot_count: 0 id: 51e6e345fdee6 block_name_prefix: rbd_data.51e6e345fdee6 format: 2 features: layering, exclusive-lock, object-map, fast-diff, deep-flatten op_features: flags: create_timestamp: Mon Feb 3 20:48:14 2020 access_timestamp: Mon Feb 3 20:48:14 2020 modify_timestamp: Mon Feb 3 20:48:14 2020

  1. 映射到物理机:

$ rbd map test_rbd/rbd1/dev/rbd0 # 卸载# rbd unmap test_rbd/rbd1

  1. 如出现如下提示:

$ rbd map test_rbd/rbd1rbd: sysfs write failedRBD image feature set mismatch. You can disable features unsupported by the kernel with “rbd feature disable test_rbd/rbd1 object-map fast-diff deep-flatten”.In some cases useful info is found in syslog - try “dmesg | tail”.rbd: map failed: (6) No such device or address

  1. 表示当前系统不支持 feature。<br />RBD支持的特性,及具体BIT值的计算如下:
  2. |
  3. 属性
  4. | 功能
  5. | BIT
  6. |
  7. | --- | --- | --- |
  8. |
  9. layering
  10. | 支持分层
  11. | 1
  12. |
  13. |
  14. striping
  15. | 支持条带化v2
  16. | 2
  17. |
  18. |
  19. exclusive-lock
  20. | 支持独占锁
  21. | 4
  22. |
  23. |
  24. object-map
  25. | 支持对象映射(依赖 exclusive-lock
  26. | 8
  27. |
  28. |
  29. fast-diff
  30. | 快速计算差异(依赖 object-map
  31. | 16
  32. |
  33. |
  34. deep-flatten
  35. | 支持快照扁平化操作
  36. | 32
  37. |
  38. |
  39. journaling
  40. | 支持记录 IO 操作(依赖独占锁)
  41. | 64
  42. |
  43. 而实际上 Centos 7 3.10 内核只支持 layering 所以我们要手动关闭一些 features,然后重新 map;如果想要一劳永逸,可以在 ceph.conf 中加入 rbd_default_features = 1 来设置默认 features(数值仅是 layering 对应的 bit 码所对应的整数值)。<br />禁用内核不支持的 feature

$ rbd feature disable test_rbd/rbd1 object-map fast-diff deep-flatten exclusive-lock

  1. 如果还想一劳永逸,那么就在执行创建rbd镜像命令的服务器中,修改Ceph配置文件/etc/ceph/ceph.conf,在global section下,增加

rbd_default_features = 1

  1. 如果还无法进行映射通过 info 指令查看是否还有其他的 featires,然后 disable 后重试即可。

$ rbd info test_rbd/rbd1rbd image ‘rbd1’: size 20 GiB in 5120 objects order 22 (4 MiB objects) snapshot_count: 0 id: 51e6e345fdee6 block_name_prefix: rbd_data.51e6e345fdee6 format: 2 features: layering, exclusive-lock op_features: flags: create_timestamp: Mon Feb 3 20:48:14 2020 access_timestamp: Mon Feb 3 20:48:14 2020 modify_timestamp: Mon Feb 3 20:48:14 2020

  1. 查看映射列表:

$ rbd showmappedid pool namespace image snap device0 test_rbd rbd1 - /dev/rbd0

  1. 格式化 xfs 格式:

sudo mkfs.xfs /dev/rbd0

  1. 挂载磁盘:

sudo mount /dev/rbd0 /mnt $ df -hTFilesystem 1K-blocks Used Available Use% Mounted on…/dev/rbd0 xfs 20G 55M 20G 1% /mnt

  1. RBD 扩容时,则需要重新执行格式化并进行挂载:(此时数据会丢失)

$ sudo umount /mnt$ sudo mkfs.xfs /dev/rbd0 -f$ rbd resize test_rbd/rbd1 —size 20480$ sudo mount /dev/rbd0 /mnt

  1. 进入磁盘,创建测试文件:

$ cd /mnt$ sudo dd if=/dev/zero of=/mnt/file bs=10M count=1 oflag=direct记录了1+0 的读入记录了1+0 的写出10485760字节(10 MB)已复制,0.0783636 秒,134 MB/秒$ lsfile$ df -h /mnt文件系统 容量 已用 可用 已用% 挂载点/dev/rbd0 20G 43M 20G 1% /mnt

  1. 删除 RBD:

sudo umount /mntsudo rbd unmap test_rbd/rbd1sudo rbd rm test_rbd/rbd1

  1. ## k8s
  2. 创建一个rbd镜像:

rbd create foobar -s 1024 -p k8s #在k8s pool中创建名为foobar的image,大小为1024MB

  1. 这时候,不要手动不要挂载!
  2. ### RBD用作volume

apiVersion: v1kind: Podmetadata: name: rbdspec: containers: - image: gcr.io/nginx name: rbd-rw volumeMounts: - name: rbdpd mountPath: /mnt/rbd volumes: - name: rbdpd rbd: monitors: - ‘1.2.3.4:6789’ pool: k8s image: foobar fsType: ext4 readOnly: false user: admin keyring: /etc/ceph/ceph.client.admin.keyring

  1. Pod启动后,可以看到文件系统由k8s做好并挂载到了容器里。我们将/etc/hosts文件拷贝到/mnt/rbd/目录去。

kubectl exec rbd — df -h|grep rbdkubectl exec rbd — cp /etc/hosts /mnt/rbd/kubectl exec rbd — cat /mnt/rbd/hosts

  1. 然后将Pod删除、重新挂载foobar image。<br />前面Pod要求各node上都要有keyring文件,很不方便也不安全。新的Pod我使用推荐的做法:secret(虽然也安全不到哪里)<br />先创建一个secret

apiVersion: v1kind: Secretmetadata: name: ceph-secrettype: “kubernetes.io/rbd” data: key: QVFCXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX9PQ==

  1. 在新的PodRef这个secret

apiVersion: v1kind: Podmetadata: name: rbd3spec: containers: - image: gcr.io/nginx name: rbd-rw volumeMounts: - name: rbdpd mountPath: /mnt/rbd volumes: - name: rbdpd rbd: monitors: - ‘1.2.3.4:6789’ pool: k8s image: foobar fsType: ext4 readOnly: false user: admin secretRef: name: ceph-secret

  1. 再来看看前面写到image上的文件还在不在。

kubectl exec rbd3 — cat /mnt/rbd/hosts

  1. ### RBD用作PV/PVC
  2. 先在k8s pool里创建一个名为pv image

rbd image create pv -s 1024 -p k8s

  1. 再创建一个PV,使用上面创建的image pv

apiVersion: v1kind: PersistentVolumemetadata: name: ceph-rbd-pvspec: capacity: storage: 1Gi accessModes: - ReadWriteOnce rbd: monitors: - ‘1.2.3.4:6789’ pool: k8s image: pv user: admin secretRef: name: ceph-secret fsType: ext4 readOnly: false persistentVolumeReclaimPolicy: Recycle

  1. 看下现在pv的状态,还是 Available

kubectl get pv|grep rbdceph-rbd-pv 1Gi RWO Recycle Available

  1. 创建一个PVC,要求一块1G的存储。

apiVersion: v1kind: PersistentVolumeClaimmetadata: name: ceph-rbd-pv-claimspec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi

  1. 因为上面已经创建满足要求的PV了,可以看到pvcpv的状态都已经是Bound了。

kubectl get pvc|grep rbdceph-rbd-pv-claim Bound pvc-bdaf8358-5dc6-11e8-a37d-ecf4bbdeea94 1Gi RWO fast 10s# kubectl get pv|grep ceph-rbd-pvceph-rbd-pv 1Gi RWO Recycle Bound 12m

  1. ### RBD用作storage class
  2. 先创建一个SC

kind: StorageClassapiVersion: storage.k8s.io/v1metadata: name: fastprovisioner: kubernetes.io/rbdparameters: monitors: 172.25.60.3:6789 adminId: admin adminSecretName: ceph-secret adminSecretNamespace: resource-quota pool: k8s userId: admin userSecretName: ceph-secret fsType: ext4 imageFormat: “2” imageFeatures: “layering”

  1. pvc中需要指定其storageClassName为上面创建的scname

kind: PersistentVolumeClaimapiVersion: v1metadata: name: rbd-pvc-pod-pvcspec: accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: storage: 8Gi storageClassName: fast

  1. RBD只支持 ReadWriteOnce ReadOnlyAll,不支持ReadWriteAll。注意这两者的区别点是,不同nodes之间是否可以同时挂载。同一个node上,即使是ReadWriteOnce,也可以同时挂载到2个容器上的。

apiVersion: v1kind: Podmetadata: labels: test: rbd-pvc-pod name: ceph-rbd-sc-pod2spec: containers: - name: ceph-rbd-sc-nginx image: gcr.io/nginx volumeMounts: - name: ceph-rbd-vol1 mountPath: /mnt/ceph-rbd-pvc/nginx readOnly: false volumes: - name: ceph-rbd-vol1 persistentVolumeClaim: claimName: rbd-pvc-pod-pvc

  1. 如果是多副本的应用怎么办呢?可以用StatefulSet

apiVersion: apps/v1kind: StatefulSetmetadata: name: nginxspec: selector: matchLabels: app: nginx serviceName: “nginx” replicas: 3 template: metadata: labels: app: nginx spec: terminationGracePeriodSeconds: 10 containers: - name: nginx image: gcr.io/nginx volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: [ “ReadWriteOnce” ] storageClassName: “fast” resources: requests: storage: 8Gi

  1. 此时去看PVC,可以看到创建了3PVC

kubectl get pvc|grep wwwwww-nginx-0 Bound pvc-05f10f64-58df-11e8-8bd4-ecf4bbdeea94 8Gi RWO fast 6dwww-nginx-1 Bound pvc-0e1768f3-58df-11e8-8bd4-ecf4bbdeea94 8Gi RWO fast 6dwww-nginx-2 Bound pvc-17347e8e-58df-11e8-8bd4-ecf4bbdeea94 8Gi RWO fast 6d# kubectl get pv|grep wwwpvc-05f10f64-58df-11e8-8bd4-ecf4bbdeea94 8Gi RWO Delete Bound dex/www-nginx-0 fast 6dpvc-0e1768f3-58df-11e8-8bd4-ecf4bbdeea94 8Gi RWO Delete Bound dex/www-nginx-1 fast 6dpvc-17347e8e-58df-11e8-8bd4-ecf4bbdeea94 8Gi RWO Delete Bound dex/www-nginx-2 fast 6d

``` 但注意不要用Deployment。因为,如果Deployment的副本数是1,那么还是可以用的,跟Pod一致;但如果副本数 >1 ,此时创建deployment后会发现,只启动了1个Pod,其他Pod都在ContainerCreating状态。过一段时间describe pod可以看到,等volume等很久都没等到。

参考文章