
第1部分我们部署用于微服务的环境。 第1部分在裸机上安装Kubernetes HA(Debian)
哈,亲爱的读者,您好!
在上一篇文章中,我讨论了如何部署Kubernetes故障转移群集。 但是事实是,在Kubernetes中,部署不需要维护状态或使用数据的无状态应用程序很方便。 但是在大多数情况下,我们需要保存数据,并且在重新启动炉床时不会丢失数据。
Kubernetes将卷用于这些目的。 当我们使用Kubernetes云解决方案时,没有特别的问题。 我们只需要从Google,Amazon或其他云提供商订购所需的卷,然后在文档的指导下将收到的卷连接到Pod。
当我们处理裸机时,事情要复杂一些。 今天,我想谈谈基于ceph的使用的解决方案之一。
在此出版物中,我将告诉您:
- 如何部署Ceph分布式存储
- 使用Kubernetes时如何使用Ceph
引言
首先,我想向您解释这篇文章对谁有用。 首先,对于那些根据我的第一个出版物部署了集群以继续构建微服务架构的读者。 其次,对于那些想要自己部署ceph集群并评估其性能的人。
在本出版物中,我不会针对任何需求来讨论集群规划的主题,我只会谈论一般的原理和概念。 我不会深入研究“调优”和深度调优,有关此主题的出版物很多,包括关于Habr的出版物。 本文将具有更多介绍性,但同时,它还使您能够获得可行的解决方案,以适应将来的需求。
- 主机,主机资源,操作系统和软件版本的列表
- Ceph集群结构
- 安装前配置集群节点
- 安装ceph-deploy
- 创建一个ceph集群
- 网络设置
- 安装ceph软件包
- 监视器的安装和初始化
- 添加OSD
- 将Ceph连接到kubernetes
- 创建数据池
- 创建客户机密
- 部署ceph rbd供应商
- 创建一个存储类
- Kubernetes + Ceph韧带测试
- 物品准备中使用的材料清单
主机列表和系统要求
在撰写文章时,我使用具有此配置的虚拟机

每个都安装了Debian 9.5操作系统。 这些是测试机器,每个都有两个磁盘,第一个用于OS,第二个用于OSD cef。
我将通过ceph-deploy实用程序部署集群。 您可以在手动模式下部署ceph集群,所有步骤均在文档中进行了描述,但是本文的目的是告诉您可以多快部署ceph并开始在kubernetes中使用它。
Ceph的资源非常繁琐,尤其是RAM。 为了获得良好的速度,建议使用ssd驱动器。
您可以在官方ceph文档中阅读有关要求的更多信息。
Ceph集群结构
蒙
监视器是一个守护程序,它充当协调程序的开始,群集从该守护程序开始。 一旦我们至少有一个工作监视器,便有了一个Ceph集群。 监视器通过与其他监视器交换各种卡来存储有关群集的健康状况的信息。 客户端转向监视器,以了解向哪个OSD写入/读取数据。 部署新存储时,要做的第一件事是创建一个(或多个)监视器。 群集可以驻留在一个监视器上,但是建议制作3个或5个监视器,以避免整个系统因单个监视器的故障而损坏。 最主要的是,这些数目应该是奇数,以避免出现裂脑情况。 监视器按法定人数运行,因此,如果超过一半的监视器掉落,则会阻塞群集以防止数据不一致。
经理
Ceph Manager守护程序与Monitor守护程序一起使用以提供其他控制。
从12.x版开始,ceph-mgr守护程序已成为正常操作所必需的。
如果mgr守护程序未在运行,您将看到关于此的警告。
OSD(对象存储设备)
OSD是一个存储单元,用于存储数据本身并通过与其他OSD交换数据来处理客户端请求。 通常是磁盘。 通常,对于每个OSD,都有一个单独的OSD守护程序,该守护程序可以在安装了该磁盘的任何计算机上运行。
所有这三个守护程序都将在集群中的每台机器上运行。 因此,将监视和管理器守护程序作为服务,将OSD守护程序作为我们虚拟机的一个驱动器。
安装前配置集群节点
ceph文档指定以下工作流程:

我将从ceph01-test群集的第一个节点开始工作,它将是Admin Node,它还将包含ceph-deploy实用程序的配置文件。 为了使ceph-deploy实用程序正常运行,必须使用Admin节点通过ssh访问所有群集节点。 为了方便起见,我将在主机中写出集群的简称
10.73.88.52 ceph01-test 10.73.88.53 ceph02-test 10.73.88.54 ceph03-tset
并将密钥复制到其他主机。 我将从root执行的所有命令。
ssh-copy-id ceph02-test ssh-copy-id ceph03-test
设定文件
头颅部署安装ceph-deploy
第一步是在ceph01-test机器上安装ceph-deploy
wget -q -O- 'https://download.ceph.com/keys/release.asc' | apt-key add -
接下来,您需要选择要发布的版本。 但是这里有困难,目前用于Debian OS的ceph仅支持发光软件包。
如果要发布更新的版本,则必须使用镜像,例如
https://mirror.croit.io/debian-mimic/dists/
在所有三个节点上添加具有模拟内容的存储库
apt install curl apt-transport-https -y curl https://mirror.croit.io/keys/release.gpg > /usr/share/keyrings/croit-signing-key.gpg echo 'deb [signed-by=/usr/share/keyrings/croit-signing-key.gpg] https://mirror.croit.io/debian-mimic/ stretch main' > /etc/apt/sources.list.d/croit-ceph.list apt update apt install ceph-deploy
如果发光足以满足您的需求,那么您可以使用官方存储库
echo deb https://download.ceph.com/debian-luminous/ $(lsb_release -sc) main | tee /etc/apt/sources.list.d/ceph.list apt-transport-https apt update apt install ceph-deploy
我们还将在所有三个节点上安装NTP。
因为此建议在ceph文档中我们建议在Ceph节点上(尤其是在Ceph Monitor节点上)安装NTP,以防止时钟漂移引起问题。
apt install ntp
确保启用NTP服务。 确保每个Ceph节点使用相同的NTP服务器。 您可以在此处查看更多详细信息
创建一个ceph集群
为配置文件和ceph-deploy文件创建目录
mkdir my-cluster cd my-cluster
让我们创建一个新的集群配置,在创建时,指示集群中将有三个监视器
ceph-deploy new ceph01-test ceph02-test ceph03-test
网络设置
现在重要的是,该谈论ceph的网络了。 Ceph使用两个公共网络和一个群集网络来工作

从公共网络图中可以看到,这是用户和应用程序级别,而群集网络是通过其复制数据的网络。
非常需要将这两个网络彼此分开。 同样,网络速度群集网络至少需要10 Gb。
当然,您可以将所有内容保留在同一网络上。 但是,这充满了这样的事实:一旦OSD之间的复制量增加,例如,当新的OSD(磁盘)下降或添加时,网络负载就会非常大。 因此,基础架构的速度和稳定性将在很大程度上取决于ceph使用的网络。
不幸的是,我的虚拟化群集没有单独的网络,我将使用一个公共的网段。
集群的网络配置是通过配置文件完成的,该文件是我们使用上一个命令生成的。
/my-cluster# cat ceph.conf [global] fsid = 2e0d92b0-e803-475e-9060-0871b63b6e7f mon_initial_members = ceph01-test, ceph02-test, ceph03-test mon_host = 10.73.88.52,10.73.88.53,10.73.88.54 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx
如我们所见,cef部署没有为我们创建默认的网络设置,因此我将public network = {public-network / netmask}参数添加到配置的global部分。 我的网络是10.73.0.0/16,所以添加我的配置后将如下所示
[global] fsid = 2e0d92b0-e803-475e-9060-0871b63b6e7f mon_initial_members = ceph01-test, ceph02-test, ceph03-test mon_host = 10.73.88.52,10.73.88.53,10.73.88.54 public network = 10.73.0.0/16 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx
如果要将群集网络与公共网络分开,请添加参数cluster network = {cluster-network / netmask}
您可以在文档中阅读有关网络的更多信息。
安装ceph软件包
使用ceph-deploy,我们在三个节点上安装了所需的所有ceph软件包。
为此,请在ceph01-test上执行
如果版本是模仿的
ceph-deploy install --release mimic ceph01-test ceph02-test ceph03-test
如果版本发光
ceph-deploy install --release luminous ceph01-test ceph02-test ceph03-test
等到一切都建立好。
监视器的安装和初始化
安装完所有软件包后,我们将创建并启动集群的监视器。
C ceph01-test执行以下操作
ceph-deploy mon create-initial
在此过程中将创建监视器,将启动守护程序,而ceph-deploy将检查仲裁。
现在,将配置分散在群集节点上。
ceph-deploy admin ceph01-test ceph02-test ceph03-test
并检查我们集群的状态,如果您正确执行了所有操作,则该状态应为
HEALTH_OK
~/my-cluster# ceph status cluster: id: 2e0d92b0-e803-475e-9060-0871b63b6e7f health: HEALTH_OK services: mon: 3 daemons, quorum ceph01-test,ceph02-test,ceph03-test mgr: no daemons active osd: 0 osds: 0 up, 0 in data: pools: 0 pools, 0 pgs objects: 0 objects, 0 B usage: 0 B used, 0 B / 0 B avail pgs:
创建mgr
ceph-deploy mgr create ceph01-test ceph02-test ceph03-test
并再次检查状态
ceph -s
应该出现一行
mgr: ceph01-test(active), standbys: ceph02-test, ceph03-test
我们将配置写入集群中的所有主机
ceph-deploy admin ceph01-test ceph02-test ceph03-test
添加OSD
目前,我们有一个正常工作的集群,但是它还没有用于存储信息的磁盘(在ceph术语中为osd)。
可以使用以下命令添加OSD(一般视图)
ceph-deploy osd create --data {device} {ceph-node}
在我的测试平台上,disk / dev / sdb分配在osd下,因此在我的情况下,命令如下
ceph-deploy osd create --data /dev/sdb ceph01-test ceph-deploy osd create --data /dev/sdb ceph02-test ceph-deploy osd create --data /dev/sdb ceph03-test
检查所有OSD是否都在工作。
ceph -s
结论
cluster: id: 2e0d92b0-e803-475e-9060-0871b63b6e7f health: HEALTH_OK services: mon: 3 daemons, quorum ceph01-test,ceph02-test,ceph03-test mgr: ceph01-test(active) osd: 3 osds: 3 up, 3 in
您也可以尝试一些有用的OSD命令。
ceph osd df ID CLASS WEIGHT REWEIGHT SIZE USE AVAIL %USE VAR PGS 0 hdd 0.00490 1.00000 5.0 GiB 1.0 GiB 4.0 GiB 20.05 1.00 0 1 hdd 0.00490 1.00000 5.0 GiB 1.0 GiB 4.0 GiB 20.05 1.00 0 2 hdd 0.00490 1.00000 5.0 GiB 1.0 GiB 4.0 GiB 20.05 1.00 0 TOTAL 15 GiB 3.0 GiB 12 GiB 20.05
和
ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.01469 root default -3 0.00490 host ceph01-test 0 hdd 0.00490 osd.0 up 1.00000 1.00000 -5 0.00490 host ceph02-test 1 hdd 0.00490 osd.1 up 1.00000 1.00000 -7 0.00490 host ceph03-test 2 hdd 0.00490 osd.2 up 1.00000 1.00000
如果一切正常,那么我们有一个正常工作的ceph集群。 在下一部分中,我将告诉您如何在kubernetes中使用ceph
将Ceph连接到kubernetes
不幸的是,我将无法在本文中详细描述Kubernetes卷的操作,因此,我将尝试将其放在一个段落中。
Kubernetes使用存储类来处理数据的数据量,每个存储类都有自己的配置程序,您可以将其视为处理不同数据存储量的一种“驱动程序”。 支持kubernetes的完整列表可以在官方文档中找到。
Kubernetes本身也支持使用rbd,但是官方的kube-controller-manager映像未安装rbd客户端,因此您需要使用其他映像。
还应注意,以rbd创建的卷(pvc)只能是ReadWriteOnce(RWO),这意味着您只能将创建的卷挂载到一个炉床上。
为了使我们的集群能够使用ceph卷,我们需要:
在Ceph集群中:
- 在ceph集群中创建数据池
- 创建一个客户端并访问数据池的密钥
- 获取ceph管理员机密
为了使我们的集群能够使用ceph卷,我们需要:
在Ceph集群中:
- 在ceph集群中创建数据池
- 创建一个客户端并访问数据池的密钥
- 获取ceph管理员机密
在Kubernetes集群中:
- 创建ceph管理员密码和ceph客户端密钥
- 安装ceph rbd提供程序或将kube-controller-manager映像更改为支持rbd的映像
- 使用Ceph客户端密钥创建秘密
- 创建存储类
- 在kubernetes工人笔记上安装ceph-common
创建数据池
在ceph集群中,为kubernetes卷创建一个池
ceph osd pool create kube 8 8
在这里,我将做一个小小的解释,最后的数字8 8是pg和pgs的数字。 这些值取决于ceph集群的大小。 有一些特殊的计算器可以计算pg和pg的数量,例如ceph的官方数据
首先,我建议默认情况下保留它,如果将来可以增加此数量(只能从Nautilus版本中减少)。
为数据池创建客户端
为新池创建一个客户端
ceph auth add client.kube mon 'allow r' osd 'allow rwx pool=kube'
我们将为客户提供一个密钥,将来我们将需要它来创建一个秘密的kubernetes。
ceph auth get-key client.kube AQDd5aldka5KJRAAkpWTQYUMQi+5dfGDqSyxkg==
获取管理员密钥
并获得管理员密钥
ceph auth get client.admin 2>&1 |grep "key = " |awk '{print $3'} AQAv+Itdx4DwKBAAKVhWRS3+eEPqV3Xrnlg9KA==
在ceph集群上,所有工作都已完成,现在我们需要去一台可以访问kubernetes集群的机器
我将在第一篇出版物中使用我部署的集群的master01-test(10.73.71.25)。
创建客户机密
使用我们收到的客户令牌创建文件(不要忘记用您的令牌替换它)
echo AQDd5aldka5KJRAAkpWTQYUMQi+5dfGDqSyxkg== > /tmp/key.client
并创建一个我们将来使用的秘密
kubectl create secret generic ceph-secret --from-file=/tmp/key.client --namespace=kube-system --type=kubernetes.io/rbd
创建管理员机密
使用管理员令牌创建文件(不要忘记将其替换为令牌)
echo AQAv+Itdx4DwKBAAKVhWRS3+eEPqV3Xrnlg9KA== > /tmp/key.admin
之后,创建管理员密码
kubectl create secret generic ceph-admin-secret --from-file=/tmp/key.admin --namespace=kube-system --type=kubernetes.io/rbd
检查机密是否已创建
kubectl get secret -n kube-system | grep ceph ceph-admin-secret kubernetes.io/rbd 1 8m31s ceph-secret kubernetes.io/rbd 1 7m32s
方法首先部署ceph rbd Provisioner
我们从github克隆了kubernetes-incubator / external-storage存储库,它拥有与ceph存储库成为kubernetes集群好友所需的一切。
git clone https://github.com/kubernetes-incubator/external-storage.git cd external-storage/ceph/rbd/deploy/ NAMESPACE=kube-system sed -r -i "s/namespace: [^ ]+/namespace: $NAMESPACE/g" ./rbac/clusterrolebinding.yaml ./rbac/rolebinding.yaml
kubectl -n $NAMESPACE apply -f ./rbac
结论
clusterrole.rbac.authorization.k8s.io/rbd-provisioner created clusterrolebinding.rbac.authorization.k8s.io/rbd-provisioner created deployment.extensions/rbd-provisioner created role.rbac.authorization.k8s.io/rbd-provisioner created rolebinding.rbac.authorization.k8s.io/rbd-provisioner created serviceaccount/rbd-provisioner created
方法二:替换kube-controller-manager映像
官方的kube-controller-manager映像中没有rbd支持,因此我们需要更改controller-manager映像。
为此,在每个Kubernetes向导上,您需要编辑kube-controller-manager.yaml文件,并将图像替换为gcr.io/google_containers/hyperkube:v1.15.2。 请注意与您的Kubernetes集群版本匹配的映像版本。
vim /etc/kubernetes/manifests/kube-controller-manager.yaml
之后,您将需要重新启动kube-controller-manager
ubectl get pods -A | grep manager kube-system kube-controller-manager-master01-test 1/1 Running 0 5m54s kube-system kube-controller-manager-master02-test 1/1 Running 0 5m54s kube-system kube-controller-manager-master03-test 1/1 Running 9111 103d
Pod应该自动更新,但是如果由于某种原因没有发生,可以通过删除手动重新创建。
kubectl delete pod -n kube-system kube-controller-manager-master01-test kubectl delete pod -n kube-system kube-controller-manager-master02-test kubectl delete pod -n kube-system kube-controller-manager-master03-test
检查一切正常
kubectl describe pod -n kube-system kube-controller-manager-master02-test | grep Image: Image: gcr.io/google_containers/hyperkube:v1.15.2
--
创建一个存储类
方法一-如果使用预配器ceph.com/rbd
创建一个带有我们存储类描述的yaml文件。 另外,下面使用的所有文件都可以下载到我在ceph目录中的存储库中
cat <<EOF >./storage-class.yaml kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: ceph-rbd provisioner: ceph.com/rbd parameters: monitors: 10.73.88.52:6789, 10.73.88.53:6789, 10.73.88.54:6789 pool: kube adminId: admin adminSecretNamespace: kube-system adminSecretName: ceph-admin-secret userId: kube userSecretNamespace: kube-system userSecretName: ceph-secret imageFormat: "2" imageFeatures: layering EOF
并将他嵌入我们的集群中
kubectl apply -f storage-class.yaml
检查一切正常
kubectl get sc NAME PROVISIONER AGE ceph-rbd ceph.com/rbd 7s
方法二-如果您使用了预配器kubernetes.io/rbd
创建存储类
cat <<EOF >./storage-class-hyperkube.yaml kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: ceph-rbd provisioner: kubernetes.io/rbd allowVolumeExpansion: true parameters: monitors: 10.73.88.52:6789, 10.73.88.53:6789, 10.73.88.54:6789 pool: kube adminId: admin adminSecretNamespace: kube-system adminSecretName: ceph-admin-secret userId: kube userSecretNamespace: kube-system userSecretName: ceph-secret imageFormat: "2" imageFeatures: layering EOF
并将他嵌入我们的集群中
kubectl apply -f storage-class-hyperkube.yaml storageclass.storage.k8s.io/ceph-rbd created
检查一切正常
kubectl get sc NAME PROVISIONER AGE ceph-rbd kubernetes.io/rbd 107s
Kubernetes + Ceph韧带测试
在测试ceph + kubernetes之前,必须在集群的每个工作代码上安装ceph-common软件包。
apt install curl apt-transport-https -y curl https://mirror.croit.io/keys/release.gpg > /usr/share/keyrings/croit-signing-key.gpg echo 'deb [signed-by=/usr/share/keyrings/croit-signing-key.gpg] https://mirror.croit.io/debian-mimic/ stretch main' > /etc/apt/sources.list.d/croit-ceph.list apt update apt install ceph-common
创建一个Yaml文件PersistentVolumeClaim
cat <<EOF >./claim.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: claim1 spec: accessModes: - ReadWriteOnce storageClassName: ceph-rbd resources: requests: storage: 1Gi EOF
杀了他
kubectl apply -f claim.yaml
检查是否已创建PersistentVolumeClaim。
bectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE claim1 Bound pvc-d1e47825-289c-4201-acb8-033e62a3fe81 1Gi RWO ceph-rbd 44m
并且还自动创建了PersistentVolume。
kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-d1e47825-289c-4201-acb8-033e62a3fe81 1Gi RWO Delete Bound default/claim1 ceph-rbd 37m
让我们创建一个测试容器,在其中将创建的pvc包含在/ mnt目录中。 使用文本“ Hello World!”运行此文件/mnt/test.txt。
cat <<EOF >./create-file-pod.yaml kind: Pod apiVersion: v1 metadata: name: create-file-pod spec: containers: - name: test-pod image: gcr.io/google_containers/busybox:1.24 command: - "/bin/sh" args: - "-c" - "echo Hello world! > /mnt/test.txt && exit 0 || exit 1" volumeMounts: - name: pvc mountPath: "/mnt" restartPolicy: "Never" volumes: - name: pvc persistentVolumeClaim: claimName: claim1 EOF
我们将杀死他并确认他已完成任务
kubectl apply -f create-file-pod.yaml kubectl get pods -w
让我们等待状态
create-file-pod 0/1 Completed 0 16s
让我们创建另一个,将其连接到该卷,但已经在/ mnt / test中,然后确保由第一个卷创建的文件到位
cat <<EOF >./test-pod.yaml kind: Pod apiVersion: v1 metadata: name: test-pod spec: containers: - name: test-pod image: gcr.io/google_containers/busybox:1.24 command: - "/bin/sh" args: - "-c" - "sleep 600" volumeMounts: - name: pvc mountPath: "/mnt/test" restartPolicy: "Never" volumes: - name: pvc persistentVolumeClaim: claimName: claim1 EOF
运行kubectl get po -w并等待直到pod运行
之后,让我们进入该目录并检查该卷是否已连接以及我们在/ mnt / test目录中的文件
kubectl exec test-pod -ti sh cat /mnt/test/test.txt Helo world!
感谢您阅读到最后。 抱歉,发布延迟。
我已经准备好回答个人信息或个人资料中指示的社交网络中的所有问题。
在下一个小型出版物中,我将告诉您如何基于创建的ceph集群,然后根据第一个出版物中的计划来部署S3存储。
出版材料