Ceph 介绍
无论是想要为云平台提供 Ceph Object Storage 或 Ceph Block Device 服务,部署一个 Ceph Filesystem 总是从设置每一个 Ceph 节点 ,网络和 Ceph 存储集群开始。一个 Ceph 存储集群至少需要一个 Ceph Monitor,Ceph Manger,和 Ceph OSD(Object Storage Daemon)。当运行 Ceph 文件系统客户端时也需要 Ceph Metadata Server。
Monitors: 一个 Ceph 监视器(ceph-mon) 维护集群状态的映射,包括监视器,管理,OSD 和 CURSH 映射。这些映射是 Ceph 守护进程之间相互协调的关键。监视器还负责管理守护进程和客户端之间的身份验证。为了保证冗余和高可用,至少需要3个监视器。
Mangers: 一个 Ceph 管理(ceph-mgr) 守护进程负责保持追踪 Ceph 集群运行时指标和当前集群状态,包括存储利用率,当前的性能指标和系统负载。Ceph 管理进程还托管基于 python 的模块来管理和公开 Ceph 集群信息,包括一个基于网页的 Ceph Dashboard 和 REST API 。为了保证高可用,至少需要2个管理节点。
Ceph OSDs: 一个 Ceph OSD(object storage daemon, ceph-osd) 存储数据,处理数据复制、恢复、重新平衡,并通过检查其他 Ceph OSD 进程的心跳来提供一些监控信息给 Ceph 监视器和管理。为了保证冗余和高可用,至少需要3个 Ceph OSDs。
MDSs: 一个 Ceph 元数据服务(MDS, ceph-mds) 存储代表 Ceph 文件系统 (例如 Ceph 快设备和 Ceph 对象存储就不使用 MDS)的元数据。Ceph 元数据服务允许 POSIX 文件系统用户执行基本的命令(像
ls,find等)而不会给 Ceph 存储集群代理极大的负载。
Ceph 将数据存储为逻辑存储池中的对象。利用 CRUSH 算法,Ceph 计算哪个放置组应该存储该对象,并进一步计算哪个 Ceph 进程节点应该存储改放置组。CRUSH 算法能使 Ceph 存储集群能够动态扩展,重新平衡和恢复。
ceph-ansible
ceph 官方提供了 ansible 的安装脚本 ceph-ansible
。将项目克隆到本地,可以看到最新的稳定版本是stable-4.0。根据集群要求准备了6台服务器。部署 OSDs 的节点需要一块额外的磁盘用作存储。ansible 的 hosts 文件如下所示:
[all]
192.168.0.10 ansible_host=192.168.0.10 ansible_user=test ansible_become=true
192.168.0.11 ansible_host=192.168.0.11 ansible_user=test ansible_become=true
192.168.0.12 ansible_host=192.168.0.12 ansible_user=test ansible_become=true
192.168.0.13 ansible_host=192.168.0.13 ansible_user=test ansible_become=true
192.168.0.14 ansible_host=192.168.0.14 ansible_user=test ansible_become=true
192.168.0.15 ansible_host=192.168.0.15 ansible_user=test ansible_become=true
[mons]
192.168.0.10
192.168.0.11
192.168.0.12
[osds]
192.168.0.13
192.168.0.14
192.168.0.15
[mgrs]
192.168.0.10
192.168.0.11这里将 192.168.0.10 作为用于执行 ansible-playbook 的节点。在这个节点上需要配置到另外5台服务器的 ssh 免密码登录(也可以在 hosts 文件中配置密码)。并安装一些依赖:
yum install -y ansible epel-release python2-pip
pip install -r requirements.txt配置 site.yml 配置文件,将没用到的 hosts 注释:
- hosts:
- mons
- osds
- mgrs配置全局变量 group_vars/all.yml:
cluster: ceph
centos_package_dependencies:
- epel-release
- libselinux-python
ceph_origin: repository
ceph_repository: community
ceph_mirror: http://mirrors.163.com/ceph
ceph_stable_key: http://mirrors.163.com/ceph/keys/release.asc
ceph_stable_repo: "{{ ceph_mirror }}/rpm-{{ ceph_stable_release }}"
ceph_stable_release: nautilus
ceph_stable: true
fetch_directory: ~/ceph-ansible-keys
monitor_interface: eth0
public_network: 192.168.0.0/24
cluster_network: "{{ public_network }}"配置 OSDs 变量,主要配置用哪个盘存储数据:
devices:
- /dev/vdb配置好可以运行 ansible-playbook -i hosts site.yml;。等待 ceph 安装完毕。安装完成后执行 ceph -s 可以看到如下输出:
cluster:
id: b358e8f9-3ffa-438b-8b38-38f9f5468d12
health: HEALTH_OK
services:
mon: 3 daemons, quorum VM_48_51_centos,VM_48_62_centos,VM_48_83_centos (age 2d)
mgr: VM_48_51_centos(active, since 2d), standbys: VM_48_83_centos
osd: 3 osds: 3 up (since 87m), 3 in (since 87m)
data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0 B
usage: 3.0 GiB used, 294 GiB / 297 GiB avail
pgs: kubernetes 配置 ceph
客户端节点配置
k8s 节点安装 ceph 客户端,注意版本要和服务端的一致。添加 ceph 的源,将以下内容写入到 /etc/yum.repo.d/ceph.repo:
[ceph]
name=Ceph noarch packages
baseurl=http://mirrors.163.com/ceph/rpm-nautilus/el7/x86_64/
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=http://mirrors.163.com/ceph/keys/release.asc再执行下列命令来安装:
yum clean all && yum makecache
yum install -y ceph-common创建 RBD pool:
ceph osd pool create kube 128授权 kube 用户:
ceph auth get-or-create client.kube mon 'allow r' osd 'allow class-read, allow rwx pool=kube' -o ceph.client.kube.keyring
ceph auth get client.kube将生成的 keyring 文件放到 k8s 节点的 /etc/ceph/ 目录下
创建 storageclass
创建 ceph secret:
ceph auth get-key client.admin | base64
ceph auth get-key client.kube | base64
kubectl apply -f ceph-kube-secret.ymlceph-kube-secret.yml
apiVersion: v1
kind: Namespace
metadata:
name: ceph
---
apiVersion: v1
kind: Secret
metadata:
name: ceph-admin-secret
namespace: ceph
type: kubernetes.io/rbd
data:
key: QVFEVGdBOWQ4bDA1TUJBQWhnamFJNHd6QzROVXJyR1J3RnlPWnc9PQ==
---
apiVersion: v1
kind: Secret
metadata:
name: ceph-kube-secret
namespace: ceph
type: kubernetes.io/rbd
data:
key: QVFBVWJ4VmRYbHNwS3hBQUxJSDdQWmxlalk5WW10Rm5DRnQwU2c9PQ==创建动态 RBD StorageClass:
kubectl apply -f ceph-kube-secret.yamlceph-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ceph-rbd
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/rbd
parameters:
monitors: 192.168.0.10:6789,192.168.0.11:6789,192.168.0.12:6789
adminId: admin
adminSecretName: ceph-admin-secret
adminSecretNamespace: ceph
pool: kube
userId: kube
userSecretName: ceph-kube-secret
fsType: xfs
imageFormat: "2"
imageFeatures: "layering"创建 pvc:
kubectl apply -f ceph-pvc.yaml -n cephceph-pvc.yaml
kind: PersistentVolumeClaim
metadata:
name: ceph-pvc
namespace: ceph
spec:
storageClassName: ceph-rbd
accessModes:
- ReadOnlyMany
resources:
requests:
storage: 1Gi查看 pvc 的状态发现一直是 pending,describe 查看 pvc 事件,发现报错:
rbd: create volume failed, err: executable file not found in $PATH结合日志查阅资料发现是在 kube-controller-manager 的 pod 容器中没有 rbd 命令。具体可以查看 github issue
可以通过安装 external-storage 插件来解决。克隆下来后路径如下:
ceph
└── rbd
└── deploy
├── non-rbac
│ └── deployment.yaml
├── rbac
│ ├── clusterrolebinding.yaml
│ ├── clusterrole.yaml
│ ├── deployment.yaml
│ ├── rolebinding.yaml
│ ├── role.yaml
│ └── serviceaccount.yaml
└── README.md由于部署 k8s 集群的时候启用了 rbac,所以我们用 rbac 目录下的部署文件。将 clusterrolebinding.yaml 和 rolebingding.yaml 的 namespace 修改为 ceph,然后部署:
kubectl apply -f rbac -n ceph等到部署完成后,修改 storageClass 的配置,把 provisioner: kubernetes.io/rbd 更改为 provisioner: ceph.com/rbd,重新部署。等待创建完成,重新部署 pvc,发现已经可以绑定了。查看 pvc 发现也已经创建了。
到 ceph 的 monitor 节点上,执行如下命令:
rbd ls -p kube
rbd info kubernetes-dynamic-pvc-10321857-9952-11e9-aac5-0a580ae9419b -p kube可以获取到 image 的详细信息,说明 ceph 确实被使用了。
创建一个 pod 进行测试,发现 pod 一直处于 container creating 的状态。
pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
test: rbd-dyn-pvc-pod
name: ceph-rbd-dyn-pv-pod2
spec:
containers:
- name: ceph-rbd-dyn-pv-busybox2
image: busybox
command: ["sleep", "60000"]
volumeMounts:
- name: ceph-dyn-rbd-vol1
mountPath: /mnt/ceph-dyn-rbd-pvc/busybox
readOnly: false
volumes:
- name: ceph-dyn-rbd-vol1
persistentVolumeClaim:
claimName: ceph-pvc查看 pod 事件,发现如下报错:
MountVolume.WaitForAttach failed for volume "pvc-ec2aa2a2-b290-11e9-998e-5254003f0e66" : rbd: map failed exit status 110, rbd output: rbd: sysfs write failed
In some cases useful info is found in syslog - try "dmesg | tail".
rbd: map failed: (110) Connection timed out在 pod 所在节点执行命令 dmesg | tail,发现如下报错:
[260542.633436] libceph: mon1 10.107.36.4:6789 feature set mismatch, my 106b84a842a42 < server's 40106b84a842a42, missing 400000000000000
[260542.638039] libceph: mon1 10.107.36.4:6789 missing required protocol features
[260552.602373] libceph: mon2 10.107.36.12:6789 feature set mismatch, my 106b84a842a42 < server's 40106b84a842a42, missing 400000000000000
[260552.606904] libceph: mon2 10.107.36.12:6789 missing required protocol features
[260562.618453] libceph: mon0 10.107.36.21:6789 feature set mismatch, my 106b84a842a42 < server's 40106b84a842a42, missing 400000000000000
[260562.623014] libceph: mon0 10.107.36.21:6789 missing required protocol features查阅资料发现这个错误和内核的特性有关,可以升级内核至4.5以上。也可以通过设置 ceph 来解决,具体可以查看 https://k2r2bai.com/2018/02/11/ceph/luminous-crush-issue/
这里通过调整 ceph 配置来解决:
ceph osd crush tunables hammerceph 配置 dashboard
启用模块:
ceph mgr enable dashboard创建证书:
ceph dashboard create-self-signed-cert重启:
ceph mgr module disable dashboard
ceph mgr module enable dashboard配置 ip,端口:
ceph config set mgr mgr/dashboard/server_addr $IP
ceph config set mgr mgr/dashboard/server_port $PORT注意 ip 是 active monitor 节点的 ip
创建用户:
ceph dashboard ac-user-create <username> <password> administrator
