前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >有状态容器实践:k8s集成ceph分布式存储

有状态容器实践:k8s集成ceph分布式存储

作者头像
yuanyi928
发布2018-04-02 15:47:44
3.7K0
发布2018-04-02 15:47:44
举报
文章被收录于专栏:EAWorldEAWorld

大家好,今天由我为大家介绍一下我们对于k8s与ceph集成的预研成果。对于k8s与ceph,我们也了解有限,有些理解不对的地方,还请大家指正。

今天将基于以上6点内容来分享。如果大家有任何问题,也欢迎在微课堂之后在群中直接提出,大家共同探讨。

总结了一下,产生存储痛点的原因大致有以下几个:

•默认情况下,容器产生的数据只存于内存中,容器一销毁,数据也随之丢失

•Docker可通过-v参数,将一个本地目录挂载至容器,但存在不能跨越主机的问题,无法在集群中应用•Docker还可以通过各种存储插件支持将各种类型的存储做为后端存储,但也存在无法跨主机集群应用的问题

•Docker+k8s一起的时候,存储的问题更突显。

k8s的Pod是不稳定的,随时可能会因为重新调度而在某台机器上销毁,而在另一台机器上新建,持久化存储必须跟得上这种调度,随时准备随容器一起进行迁移。

Torus是一种针对容器集群量身打造的存储系统,可以为通过Kubernetes编排和管理的容器集群提供可靠可扩展的存储。

这是继etcd、rkt、flannel,以及CoreOSLinux之后CoreOS发布的另一个开源产品。

Torus的产品特性:

1.扩展性:与etcd类似,Torus也是一种构建块,可以实现包括分布式块设备( Distributedblock device)或大型对象存储在内不同类型的存储。Torus使用G o语言编写并使用gRPC协议,用户可以方便地用任何语言创建Torus客户端。

2.易用性:专门针对集群和Kubernetes等集群流程平台(Clusterorchestration platform)设计的Torus可用简单的方法部署和运维,并可随时缩放。

3.准确性:Torus使用etcd分布式键值数据库存储并检索文件或对象元数据。etc d为必须快速可靠执行的分布式系统核心运作提供了一个坚实、经得起考验的 基础。

4.缩放性:Torus目前可缩放至数百个节点,并可将多个共用磁盘以单一存储池 的方式使用。

虽然Torus的特性看起来很美,可以毕竟它还太年轻,成熟稳定需要一定的时间。目前我们只是保持持续的关注。

第二种则是Flocker,目前也是很火热的个项目。Flocker提供了开源容器数据卷管理系统。它提供了数据迁移的工具,从而解决了有状态服务的容器化难题。尤其适用于数据库这样的容器。通常,容器的数据卷与单个server绑定,Flocker数据卷,则可以随容器迁移而迁移。Flocker为实现有状态的微服务提供了便利。上图是它的架构示意图,它要求每个节点上都必须要安装它的flockerplugin, 然后由flockercontrol进行统一调度,最终实现数据与容器同步迁移。

如上图所示,展示了存储随容器迁移的过程:

1.当容器发生迁移时,flocker可以保证容器所挂载的数据卷也会跟着同步迁移

2.迁移要求各个主机上都需要安装flockerplugin

3.原理其实是在其它主机上将容器启动的时候,将数据卷重新挂载其上。因此,单个容器迁移时,服务存在一定的中断,但这个过程一般很短

flocker其实是我们比较心仪的方式。但是因为系统的限制,目前没有办法安装。我们同样对它保持着高度的关注。

最后介绍的这第三种方案,则是比较常规的方案,基于k8s本身的能力以及第三方的插件来实现,当然还必须后端有对应的存储进行支持。k8s的pv可以向容器提供持久存储。它需要先于Pod创建,然后在pod创建的时候,绑定给它。也可以不使用pv, 直接在声明pod的时候,使用mountpoint属性声明需要使用的持久卷。pv与mountpoint都支持多种类型的存储,基本上涵盖了目前的主流方式

以上就是一个nfs类型的pv的声明文件,将它保存成yaml文件,使用kubectlcraete–fxxx.yaml 这种方式就可以创建一个pv。在pv中,可以定义它的名称,可以定义它的容量,也可以定义它的访问方式。

访问方式有三种: 单节点可读可写(ReadWriteOnce),多节点只读(ReadOnlyMany),多节点可读可写(ReadWriteMany)。也可以定义它们的回收策略,回收策略是指当容器销毁时,对其所挂载的卷的处理方式。处理方式目前也有三种:保持数据(Retain), 清除数据(Recycle), 删除卷(Delete).当前,只有NFS和HostPath的存储可以支持清除数据(Recycle),而删除卷一般需要有底层IAAS的支持才能实现。

我们最终选择了k8s+cephrbd的方式来构建我们的容器存储。这有一部分的原因是因为需要k8s必须跑在coreos上造成的。关于为什么我们的k8s集群必须跑在coreos之上,这个我们后面会有说明。

•没有选择最新的Torus,因为它太年轻,不够成熟

•也没有选择flocker,因为无法在coreos系统上安装

•我们选择了比较保守的插件+对应后端存储的方案。

最终的选择:k8s+cephrbd。选择ceph,是因为它的稳定与高效,而且目前与k8s的集成也结合得比较好。

下面来介绍一下ceph,相信其实一大部分人都已经认识了它

•Ceph是一种为优秀的性能、可靠性和可扩展性而设计的统一的分布式文件系统

•在2004年由Sage Weil开发,并于2006年基于开源协议开源了Ceph

•ceph同时支持文件存储,块存储,对象存储

•ceph具有高扩展性、高可靠性、高性能的优点,这三个特点也是企业级存储需要的

•Ceph其使用最多的是最成熟的Ceph RBD(块存储),其次是Ceph RADOS

•十年的历史,成千上万的用户,是现代云平台存储的首选

CEPH整体架构

•ceph的底层是自已开发的rados

•rados之上提供了librados与cephfs

•app可以直接使用librados(源码级集成)

•librados之上有radosgw与rbd

•radosgw对外提供restapi,封装librados的能力(api级集成)

•rbd则提供块存储能力

ceph组成

•Ceph Client 是 Ceph文件系统的用户

•Ceph Metadata Daemon 提供了元数据服务器

•Ceph Object Storage Daemon 提供了实际存储(对数据和元数据两者)

•Ceph Monitor 提供了集群管理

ceph的概念

•用户文件作为Object先映射到PG(Placement Group)

•再由PG映射到OSD set

•每个Pool有多个PG,每个Object通过计算hash值并取模得到它所对应的PG

•PG再映射到一组OSD,第一个OSD是Primary,剩下的都是Replicas

•从PG分配到OSD使用了一种伪随机算法CRUSH

安装规划

•安装目标:搭建一套ceph块存储的功能验证环境

•ceph采用的版本是当前最新的 10.2.1

•共4个节点,1个专门用来安装(只安装ceph-deploy),其它3个均为ceph的工作节点(ceph-osd)。3个工作节点中选择1个做为ceph管理节点(ceph-monitor)。因为只需要搭建ceph块存储,不需要元数据服务节点(mds)

•节点底层系统为centos7.1

•节点均为虚拟机,配置为4c4G,配置80G硬盘

•节点均有两块网卡,内网(10.16.16.0/24),外网(10.15.15.0/24)

•ceph的client节点由k8s的工作节点充当

•如图所示,ceph-60为Ceploy-Deploy节点,ceph-61即是osd节点,也是monitor节点。cehp-62与ceph-63则为单纯的osd节点。

•61,62,63均是通过60进行远程安装

•61,62,63上的osd均受61的monitor管理

•外部的ceph-client通过61进行连接与api调用

首先,我们需要将各节点的系统centos7的内核升级。因为centos7.1默认的内核版本为3.10.0-123,如果要用来安装ceph, 推荐内核至少升级到 3.18, 因为内核 3.18以后对krdb添加了一个重要特性: discard,这个特性可以根据块内文件的删除同步改变块的真实大小,从而节省磁盘空间。

同时,内核升级过程中,也可以把systemd的版本从218升级至219以上,避免执行cephminitor节点初始化的时候,出现的上述安装错误。

centos7 内核升级具体步骤

1. 最新的内核可以在这里看到: https://www.kernel.org/

2. 升级至指定版本内核,请自行下载对应版本的rpm包进行安装

3. 自动升级至最新版本内核

rpm--import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org。

rpm-Uvhhttp://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm

yum--enablerepo=elrepo-kernel install kernel-ml-develkernel-ml –y

4. 更新完成之后,查看当前内核版本: uname-r,会发现还是老内核,新内核需要重启之后才能生效

5. 查看默认启动顺序:awk-F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg

6. 设置默认启动项: grub2-set-default 0

7.重启系统,切换至新的内核:reboot

导入证书的时候,可能会出现: curl: (60) Peer‘s Certificate has expired.这样的证书错误。解决办法:直接使用wgethttps://www.elrepo.org/RPM-GPG-KEY-elrepo.org 将证书文件下载到本地,然后在本地执行导入。由于wget也是由curl发出http请求,我们下载的时候要加上--no-check-certificate参数进行证书忽略。

安装准备(所有节点)

在各个node节点创建ceph用户,并将它添加至sudo用户组,并修改各主机名

在各个node节点上安装openssh-server

在ceph-deploy节点上,生成ssh密钥,并将公钥发送至所有的node节点,使它可以免密码ssh登陆

在4个节点中添加ceph的安装源

[ceph-noarch]

name=Cephnoarch packages

baseurl=http://ceph.com/rpm-infernalis/el7/noarch

enabled=1

gpgcheck=0

type=rpm-md

gpgkey=https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/release.asc

在4个节点中修改 /etc/hosts

10.15.15.60ceph-60

10.15.15.61ceph-61

10.15.15.62ceph-62

10.15.15.63ceph-63

生成ssh密钥,并将公钥发送至所有的node节点,可以使用ssh-keygen与 ssh-copy-id工具。让deploy节点与其它节点建立互信,是为了减少在安装过程中密码的输入。

安装ceph:

1. 安装 ceph-deploy: yum update && yum install ceph-deploy

2. 创建ceph的cluster, 并设置ceph-61为ceph的 monitor: sudoceph-deploy new ceph-61

3. 修改ceph.conf文件,添加clueter network与public network

cluster network =10.16.16.0/24

public network =10.15.15.0/24

4. 在60上生成一个 ~/.ssh/config文件,内容如下

Host ceph-61

Hostname ceph-61

User ceph

Host ceph-62

Hostname ceph-62

User ceph

Host ceph-63

Hostname ceph-63

User ceph

5. 在60上为61,62,63安装cpeh

sudoceph-deploy install ceph-61 ceph-62 ceph-63

6. 在60上执行cephmon的初始化,并设置61为cephmonitor节点

ceph-deploy --overwrite-confmon create-initial

sudoceph-deploy admin ceph-61

创建OSD节点

1. 在三个节点上分别创建目录,例如在61上创建两个目录: sudomkdir -p /opt/ceph/osd61-1 /opt/ceph/osd61-2,三节点两个两个目录,总共创建6个目录

2.为这些目录设置所有权,所有权归 ceph:ceph: chown -R ceph:ceph /opt/ceph/osd61-1 /opt/ceph/osd61-23.创建osd: sudo ceph-deploy osdprepare ceph-61:/opt/ceph/osd61-1 ceph-61:/opt/ceph/osd61-24.激活osd: sudo ceph-deploy osdactivate ceph-61:/opt/ceph/osd61-1 ceph-61:/opt/ceph/osd61-25.查看 ceph的状态

上图中是我们安装好之后,运行cephosddump显示的结果。

可以看出,我们一共创建了6个osd,每个osd的权重都是一样的。

上面可以看到,我们的ceph状态是正常的,有6个osd,6个都是启用的,处于pg中。这样,我们的ceph块存储就安装好了。

我们总共有三个节点,我在每个节点上创建了两个目录作为osd的数据存储目录,共有6个osd。

ceph中因为有了ceph-deploy这个工具,安装起来还是很轻松的。

CoreOS是一个基于Linux,systemd和Docker的小型操作系统。它借鉴了Google的Chrome OS,特别是其对数千服务器的分布式管理,CoreOS项目是Google ChromeOS代码的一个fork版本,目前已成为一个超级精简的服务器操作系统,进化速度堪比ChromeOS。

我们没有使用传统的centos,redhat 或 ubuntu之类的操作系统,而是大胆地采用了coreos做为kubernetes底层的操作系统,是因为它有如下优点:

占用内存少。比典型的服务器版本Linux少占40%的内存,资源利用率高

可靠,高速,及时的补丁更新,可以系统双分区滚动整体更新

所有应用都安装在容器中,对系统依赖低

默认支持docker

专为大规模部署设计,轻量稳定且高效

多个云平台支持,支持目前EC2、Rackspace、GCE等云服务提供商

但是同样,有得就有失,它也有一些不足与限制:

没有包管理

没有编译器,也没有python,perl之类的解释器

很多目录都是只读的,不能像传统linux系统那样来修改配置

总体比较而言,coreos系统还是利大于弊。它的轻量,低污染,系统双分区滚动升级等都是我们最看重的特性。

要想执行ceph的块存储挂载,必须加载必要的内核模块。krbd是cephrbd依赖的一个内核模块,它默认已经安装在coreos系统之中了,但是默认是不启用的。

我们需要把它加载进系统:

modproberbd

再看一下加载的结果:

core@ck68 ~ $ lsmod |greprbd

rbd 65536

libceph 204800 1 rbd

自动开始加载krbd:

创建文件/etc/modules-load.d/rbd.conf,文件内容只需要写上需要加载的模块名称即可:

rbd

下次重启之后,系统就会自动将rbd模块加载进来了

要想kubernates可以正常执行rbd挂载,必要的条件就是要在系统中有可以正常执行的rbd命令

这在其它系统上很好解决,coentos7上执行yum install ceph-common就行,在其它系统上问题也不大

但在coreos中,这是个比较大的问题。因为coreos上没有包管理器,也没有gcc之类的编译器,要想直接安装在coreos上是没可能的

通过查阅大量的国外资料,我们最终找到了办法:用容器来实现这个命令

制作 common-ceph的 image,将ceph-common安装在容器内部,这里我们的镜像名称就叫 ceph-common

在k8s的各个工作节点上,创建/opt/bin/rbd文件,内容如下:

上面示例了一个的含有rbd卷的rc声明文件。在创建这个rc之前,必须要先在ceph中创建对应的块,还有必须要把ceph的证书文件拷贝至cephclient节点的对应位置。

证书还有另外一方式可以避免拷贝文件,那需要先在k8s中创建对应的secret, 然后在rc中声明使用这个secret。在使用 kubectl创建rc的时候,会出一个警告,这只是客户端对文件的一个校验,确定文件没有问题的话,可以添加--validate=false 来忽略这个警告,直接创建rc

rc创建成功了,但是pod却迟迟没有running。查看pod对应节点的kubelet的日志,发现了rbd: map failed executable file notfound in $PATH 的问题:

不是在系统的/opt/bin目录下放了rbd的可执行脚本吗?为什么会找不到呢?在coreos系统中,默认帮我们扩展了PATH的目录,将/opt/bin自动添加至了PATH中。

这样,直接放在/opt/bin之下的可执行文件是可以直接调用的。

rbd可以不加路径,在终端中的任何目录下直接被调用,添加正确的参数,可以手动成功对rbd进行挂载。

经过多天的排查,最终找到了原因所在,问题出在systemd上。所有通过systemd启动的服务,使用的PATH环境变量不是系统中通过传统方式声明的。它的PATH环境变量,必须通过systemd的方式进行指定。

解决办法

修改/etc/systemd/system.conf文件,在最后添加如下内容:

DefaultEnvironment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin"

然后执行配置重新加载,并重启kubelet服务

systemctl daemon-reload

systemctl restart kubelet

经验证,配置添加之后,问题解决,可随着pod的创建与删除正常挂载与卸载对应的rbd块存储

目前,我们还仅对coreos上的k8s与ceph的分布式块存储进了预研与验证,还缺少对其性能的严格测试。而且目前据我们的验证来看,ceph块存储还不太合适用来做为容器的共享存储使用,还需要进一步验证,或寻找其它的方案。数据的安全也是需要考虑的方面。期待与大家一起来共同探讨这些方面的问题,共同进步。

今天的分享就到此结束,谢谢大家的捧场~

关于作者:

秦双春

现任普元云计算架构师。曾在PDM,云计算,数据备份,移动互联相关领域公司工作,10年IT工作经验。曾任上海科企软件桌面虚拟化产品的核心工程师,主导过爱数TxCloud云柜的设计与开发,主导过万达信息的食安管理与追溯平台的移动平台开发。国内云计算的早期实践者,开源技术爱好者,容器技术专家。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 EAWorld 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档