Ceph in Libvirt and Kubernetes

Ceph部署

Ceph的部署已经有很多文章了,大致都是用ceph-deploy这个工具实施,这里我就不累述了。我就简单记录下我在部署过程中遇到的坑。

**1. **SSH端口不是22造成的部署失败。

修改本地.ssh/config目录,加入要安装ceph集群的host即可,如下:

host ceph-mon
    Hostname 192.168.68.55
host ceph-osd1
    Hostname 192.168.68.53
host ceph-osd2
    Hostname 192.168.68.54
host ceph-mon ceph-osd1 ceph-osd2
    User root
    Port 8822

**2. **安装ceph-release

$ yum install -y centos-release-ceph-jewel

**3. **通过ceph-deploy部署不同版本的ceph,我这里用的是jewel

$ ceph-deploy install  --release jewel ceph-mon ceph-osd1 ceph-osd2

**4. **切换国内阿里ceph镜像源

export CEPH_DEPLOY_REPO_URL=http://mirrors.aliyun.com/ceph/rpm-jewel/el7/
export CEPH_DEPLOY_GPG_URL=https://mirrors.aliyun.com/ceph/keys/release.asc

**5. **配置文件

[global]
fsid = 6013f65b-1178-4d8b-b3b5-dfb52ce811a7
mon_initial_members = l-192168068053-mitaka
mon_host = 192.168.68.53
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
public network = 192.168.68.0/24
cluster network = 192.168.68.0/24
rbd_default_features = 3

这里有关rbd_default_features这个配置项,遇到个问题。由于不知道内核支持的镜像特性,所以在映射rbd的时候会报错,提示镜像特性问题。查了下,本机内核版本只支持分层,所以配置3就好了。

rbd镜像特性

  • layering: 支持分层
  • striping: 支持条带化 v2
  • exclusive-lock: 支持独占锁
  • object-map: 支持对象映射(依赖 exclusive-lock )
  • fast-diff: 快速计算差异(依赖 object-map )
  • deep-flatten: 支持快照扁平化操作
  • journaling: 支持记录 IO 操作(依赖独占锁)

Ceph 使用

**1. ** 创建存储池与配额设置

创建

ceph osd pool create {pool-name} {pg-num} [{pgp-num}] [replicated] \
        [crush-ruleset-name] [expected-num-objects]

PG_NUM
取值是强制性的,因为不能自动计算。下面是几个常用的值:
少于 5 个 OSD 时可把 pg_num 设置为 128
OSD 数量在 5 到 10 个时,可把 pg_num 设置为 512
OSD 数量在 10 到 50 个时,可把 pg_num 设置为 4096
OSD 数量大于 50 时,你得理解权衡方法、以及如何自己计算 pg_num 取值
自己计算 pg_num 取值时可借助 pgcalc 工具
随着 OSD 数量的增加,正确的 pg_num 取值变得更加重要,因为它显著地影响着集群的行为、以及出错时的数据持久性(即灾难性事件导致数据丢失的概率)。
replicated
副本个数,默认是三份

我的设置

$ ceph osd pool create instances 128
$ ceph osd pool set instances size 2
$ ceph osd pool create volumes 128
$ ceph osd pool set volumes size 2
$ ceph osd pool create kube 128
$ ceph osd pool set kube size 2

配额

ceph osd pool set-quota {pool-name} [max_objects {obj-count}] [max_bytes {bytes}]

我的设置

ceph osd pool set-quota instances max_objects 1000000
ceph osd pool set-quota volumes  max_objects 5000000
ceph osd pool set-quota kube  max_objects 5000000

**2. **创建用户

$ ceph auth get-or-create client.libvirt mon 'allow r' osd 'allow class-read class-write object_prefix rbd_children, allow rwx pool=instances, allow rwx pool=volumes' -o ceph.client.libvirt.keyring
$ ceph auth get-or-create client.kube mon 'allow r' osd 'allow class-read class-write object_prefix rbd_children, allow rwx pool=kube' -o ceph.client.kube.keyring

我这里对libvirt账号只能拥有instances和volumes池子的所有权限、kube占用只拥有kube池子所有权限

Ceph in Libvirt

**1. **生成secret

$ cat > secret.xml <
        
                client.libvirt secret
        

EOF

**2. **导入secret

$ virsh secret-define --file secret.xml

**3. **设置secret的UUID

virsh secret-set-value --secret {uuid of secret} --base64 $(ceph auth get-key client.libvirt)

4. 编辑虚拟机xml文件

    
      
      
        
        
        
      
      
        
      
      
    

5. 如果要在virt-manager上的存储池上使用Ceph,则需要定义一个pool


  ceph-volumes
  
    volumes
    
    
    
    
      
    
  

这样就可以在宿主机存储池上创建和删除rbd块了

Ceph in Libvirt and Kubernetes_第1张图片
virt-manager

6. 虚拟机镜像

因为Ceph镜像支持分层,我这里创建虚拟机镜像的时候只需要对原镜的快照做clone就行了,操作如下:

导入镜像

$ rbd import --image-format 2 Debian-Wheezy-7.11.raw instances/Debian-Wheezy-7.11.raw --name client.libvirt

raw 数据格式是使用 RBD 时的唯一可用 format 选项。从技术上讲,你可以使用 QEMU 支持的其他格式(例如 qcow2 或 vmdk),但是这样做可能会带来额外开销,而且在开启缓存模式下进行虚拟机的热迁移时会导致卷的不安全性。

快照

$ rbd snap protect  instances/Debian-Wheezy-7.11.raw@snapshot_backingfile --name client.libvirt 

克隆镜像

 $ rbd clone  instances/Debian-Wheezy-7.11.raw@snapshot_backingfile  instances/kube_ceph  --name client.libvirt

克隆完成后我们虚拟机就可以使用 instances/kube_ceph块了.

Ceph in Kubernetes

不管采用什么模式,kubelet节点都要安装ceph-common

1. 普通模式

根据K8s官方提供的rbd文件可以简单做功能测试。

  • Ceph认证

加密ceph秘钥环

grep key /etc/ceph/ceph.client.kube.keyring |awk '{printf "%s", $NF}'|base64
QVFBclU4dFlGUjhLTXhBQXRGcnFiUXN2cm1hUUU1N1ZpUmpmcUE9PQ==

secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: ceph-secret
type: "kubernetes.io/rbd"  
data:
  key: QVFBclU4dFlGUjhLTXhBQXRGcnFiUXN2cm1hUUU1N1ZpUmpmcUE9PQ==
  • 创建pod
apiVersion: v1
kind: Pod
metadata:
  name: rbd
spec:
  containers:
  - name: rbd-rw
    image: nginx:1.11.10
    volumeMounts:
    - mountPath: "/mnt/rbd"
      name: rbdpd
  nodeSelector:  
    ceph: up    #方便测试,我这里调度到label为 ceph=up的kube节点上
  volumes:
  - name: rbdpd
    rbd:
      monitors:
      - 192.168.68.57:6789
      pool: kube
      image: test
      user: kube
      secretRef:
        name: ceph-secret
      fsType: ext4

2. PersistentVolume/PersistentVolumeCliam

  • PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
  name: ceph-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  rbd:
    monitors:
      - 192.168.68.53:6789
      - 192.168.68.54:6789
      - 192.168.68.57:6789
    pool: kube
    image: magine_test
    user: kube
    secretRef:
      name: ceph-secret
    fsType: ext4
    readOnly: false
  persistentVolumeReclaimPolicy: Recycle
  • PersistentVoumeCliam
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: ceph-claim
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  • 状态
$ kubectl get pvc
NAME         STATUS    VOLUME     CAPACITY   ACCESSMODES   AGE
ceph-claim   Bound     ceph-pv1   10Gi       RWX           4h

$ kubectl get pv
NAME            CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS    CLAIM                    REASON    AGE
ceph-pv        10Gi       RWX           Recycle         Bound     default/ceph-claim                 5h

这里看到pvc就已经bound成功

  • Pod
apiVersion: v1
kind: Pod
metadata:
  name: ceph-pod
spec:
  containers:
  - name: ceph-pod
    image: nginx:1.11.10
    volumeMounts:
    - mountPath: "/mnt/rbd"
      name: ceph-pv-test
  nodeSelector:
    ceph: up
  volumes:
  - name: ceph-pv-test
    persistentVolumeClaim:
       claimName: ceph-claim

测试了下,由于accessModes采用ReadWriteMany模式,一个rbd块是可以挂载给多个Pod使用的。
目前Kubernetes对接Ceph还没发现扩展API来帮助Pod创建RBD块,所以都需要Ceph在底层创建好才能使用。
笨一点的方法是可以采用initcontainer的方式,在POD创建之前启动容器,执行命令的创建一个rdb块,操作方式留在下次文档更新。

你可能感兴趣的:(Ceph in Libvirt and Kubernetes)