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

本文为普元云计算架构设计群的微课堂原创分享,转载需注明出处:EAII企业架构创新研究院。

如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群 姓名 公司 职位 微信号”。


0?wx_fmt=jpeg


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


0?wx_fmt=jpeg


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


0?wx_fmt=jpeg


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


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


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


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


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


0?wx_fmt=jpeg


0?wx_fmt=jpeg


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的特性看起来很美,可以毕竟它还太年轻,成熟稳定需要一定的时间。目前我们只是保持持续的关注。


0?wx_fmt=jpeg


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


0?wx_fmt=jpeg


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


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


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


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


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


0?wx_fmt=jpeg


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


0?wx_fmt=jpeg


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


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


0?wx_fmt=jpeg


0?wx_fmt=jpeg


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


0?wx_fmt=jpeg


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


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


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


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


0?wx_fmt=jpeg


0?wx_fmt=jpeg


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


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


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


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


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


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


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


0?wx_fmt=jpeg


CEPH整体架构


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


•rados之上提供了librados与cephfs


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


•librados之上有radosgw与rbd


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


•rbd则提供块存储能力


0?wx_fmt=jpeg


ceph组成


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


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


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


•Ceph Monitor 提供了集群管理


0?wx_fmt=jpeg


ceph的概念


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


•再由PG映射到OSD set


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


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


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


0?wx_fmt=jpeg


0?wx_fmt=jpeg


安装规划


•安装目标:搭建一套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调用


0?wx_fmt=jpeg


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


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


0?wx_fmt=jpeg



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参数进行证书忽略。


0?wx_fmt=jpeg


安装准备(所有节点)


在各个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节点与其它节点建立互信,是为了减少在安装过程中密码的输入。


0?wx_fmt=jpeg


安装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


0?wx_fmt=jpeg


创建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的权重都是一样的。


0?wx_fmt=jpeg


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


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


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


0?wx_fmt=jpeg


0?wx_fmt=jpeg


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系统还是利大于弊。它的轻量,低污染,系统双分区滚动升级等都是我们最看重的特性。


0?wx_fmt=jpeg


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


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


    modproberbd


再看一下加载的结果:


    core@ck68 ~ $ lsmod |greprbd

    rbd 65536

    libceph 204800 1 rbd


自动开始加载krbd:


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

         rbd


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


0?wx_fmt=jpeg


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


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


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


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

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


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


0?wx_fmt=jpeg


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


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


0?wx_fmt=jpeg


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块存储


0?wx_fmt=jpeg


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


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


0?wx_fmt=jpeg


关于作者:

秦双春

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


640?wx_fmt=jpeg


关于EAII

EAII(Enterprise Architecture Innovation Institute)企业架构创新研究院,致力于软件架构创新与实践,加速企业数字化转型。


eaworld项目(微信号:eaworld,长按二维码关注)

640?wx_fmt=jpeg

eaworld是EAII的官方微信账号。


阅读原文,下载课件↓↓↓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值