王鹏(Tad) 分布式实验室
先介绍一下背景
随着光音业务规模的上升,线上业务产品的数量及服务器的采购量也越来越大。当达到一定数量级后,就不能使用常规的维护方法来解决这些问题。
以前,一旦业务量上去,我们就不得不停下手头的开发工作,部署业务所需要的环境及线上调试,到最后,只有特别熟悉业务和代码的同事才能胜任此工作。为了解决这些问题,我们从前年开始就关注了LXC,并试着小规模地使用了一段时间,但是由于LXC本身存在一系列的问题,比如内核版本的限制及二次开发困难,没能大规模地推广。
后来随着Docker的发展及火热,我们也接触到了CoreOS,它的AB分区升级特性特别吸引人。使用后才发现,跟宣传写的不一样,还是需要重启服务器才能升级内核的,但是总的来说,结合Fleet的使用,可以动态地把业务迁到其它服务器,来达到平滑升级的目的,因此还是非常不错的。
我是从开发转到基础平台维护岗位的,所以希望用开发的方式来解决运维的问题,并想通过改变运维的方式的来加快业务研发的速度。但是真正专职做平台开发后,才意识到搭建整个运维体系是多么困难的事。
所以,为了更快地构建我们的平台,业务的选型首选开源框架,然后再它的基础上,根据业务的需要做二次开发。借着Google的名气以及相对完善的生态圈,我们最终选择了Kubernetes + CoreOS + Docker,做为整个平台编排调度的基础。
我们每次采购机器,一般都是几百个节点,所以整个平台的部署就非常头疼,特别是CoreOS和Kubernetes,必须借助***才能安装和更新,让人非常不爽。前期的大部分时间都浪费在这上面了!
于是,写了一个简单的Yoo-Installer工具来解决这些问题,现在分享给大家。
由于想呈现最简单便捷的安装方式,结果没把握好时间,这次的分享准备不足,所以你们可以多提问,我多分享一些采过的坑。
项目代码我放到GitHub(https://github.com/Goyoo/yoo-installer)上了,代码还在不断完善中,如果有问题,可以直接在上面提Issue。另外,我们组的一个同事赵文来也贡献Kubernetes-client 的Nodejs版本,一并分享给大家:https://github.com/Goyoo/node-Kubernetes-client,希望能跟大家一起打造美好的Docker生态圈。
它共分为DHCP Service、TFTP Service、HTTP Service,其中HTTP Service 里包括了CoreOS的引导,安装到硬盘,Kubernetes的安装及其它服务脚本的初始化。
PXE引导
收到DHCP广播,获取IP
使用TFTP进行通信,传输CoreOS的基础IMGAGE
在内存启动CoreOS系统
系统启动成功后,下载脚本,执行安装Kubernetes及其它相关服务。
服务器的IP。在安装服务器前,应该确定好服务器的IP,因为IP在后面的安装是一个非常重要的变量。比如etcd的service IP,Kubernetes的Master IP都需要写入到配置里的。
我们是这样做的:我们的服务器是高密度刀片服务器,都配有管理模块。通过一些简单的API调用,就可以得到所有的网卡mac信息,与KVM的IP保持一定的逻辑关系,这样就可以保证服务器的IP有序,便于日后的管理与维护。(可以参考Yoo-installer项目的app/utils/IPMI/dhcpMacList.js,通过这段代码得到dhcpd所需要的配置格式,直接使用即可)。
在Yoo-Installer里,我分了6个菜单,适合四种使用场景。
分别对应于官方的CoreOS集群架构
Docker Dev Environment on Laptop
Small Cluster
Easy Development/Testing Cluster
Production Cluster with Central Services
参考:CoreOS Cluster Architectures(https://coreos.com/os/docs/latest/cluster-architectures.html)
第一种,就是开发环境的方式。我们在开发时,可以使用这种方式来开发。
开发测试集群。这种方式的优点是不用额外部署etcd服务,需要几个节点来测试,就加入几个,非常灵活。但是不是高可用的架构。因为如果etcd死了,整体集群就不能工作了。所以,非常适合开发测试使用。
线上生产环境集群架构。这种基本上就可以做到高可用了。不同服务资源之间可以使用Meta信息进行标识。
这些代码是如何实现的呢
主要是通过cloud-config-url参数的设置来改变不同的启动脚本,如cloud-config-url=http://192.168.1.10/config/develop-etcd/pxe.yml。
注意,这里面有一个技巧。默认的话,CoreOS是没有密码的。有时安装时会出现一些问题,我会在启动参数里加上coreos.autologin标记,这样引导后,就可以直接进入系统,然后查找问题了。
详见代码:https://github.com/Goyoo/yoo-installer/blob/master/app/tftp/pxelinux.cfg/default。
这样,我们就能顺利启动系统了。
启动后,我们需要安装系统到硬盘,下载并安装Kubernetes,并初始化一些系统环境等等。
这样是怎么做的呢?
先看代码
这里我们在cloud-config-url
里自定义了一个服务,叫setup.service
。等系统启动后,会下载相应的脚本:pxe.sh。
详见代码(https://github.com/Goyoo/yoo-installer/blob/master/app/views/script/pxe.ejs)。
脚本分为几个部分:
同步系统时间,新机器可能时钟有问题,这样会导致CoreOS不能正常安装,
硬盘分区,这个要根据自己的机器情况进行处理。
系统的安装。
离线下载已经准备好的Kubernetes,并放到相应的系统目录里。
其它脚本。
通知Yoo-Installer已经安装完成并重启。
那么,我们对于Kubernetes是如何自动处理的呢。
在CoreOS里,有一个Cloud-init文件,在每次系统启动时,它便会自动执行。我们利用了这个文件,自动搭建了Kubernetes的服务。
比如这个Central的YAML文件。
hostname: 配置后,方便识别。
ssh_authorized_keys: 可以设置一个跳板机的key,方便管理。
update: CoreOS版本更新策略及更新版本设置。
Fleet: Fleet的服务。
units: 具体的systemd units文件配置,这里面包括了etcd、Fleet、Flannel、Docker、kube api server、kube controller manage、kube scheduler、kube-register等服务的配置。
我们也可以直接写文件,比如DNS的配置,『search localhost』 ,我在coreos-init里就没找到对应的功能配置key,只有写文件了。
服务器不建议用DHCP动态分配IP,就算是MAC绑死的也不好。我们出过一次故障,DHCP服务异常,导致业务网络中断。
关于cloud-init文件, CoreOS 提供了coreos-cloudinit的方法,可以做validate 。如果自己修改了init文件,最好检验一下,不然只有重启后才能发现问题。
coreos-cloudinit不加validate参数,还可以执行,像写文件之类的操作,直接就可以看到结果。
关于CoreOS自动下载更新。像我们这样自建机房的,最郁闷了,不像一些国外的公有云那么方便,直接可以下载更新。怎么做呢?首先,你要有个***,然后通过专门设置update 的service,加上ALL_PROXY,就可以自动更新了!
为了更便捷的使用Yoo-Installer,我计划做二个版本,一个是VM版本的,下载后,直接可以用,另一个是Docker版本的。由时准备不足,没有做完,但是因为我自己也需用,所以我会继续完善!
这里要吐个嘈。我在封装DHCPD时,因为桥接的问题,Docker里面的广播根本发不出来。如果您有高招,请告诉我,我会请你吃饭哦~
对于Yoo-Installer,为了便于使用,我们专门做了一个UI,功能还不丰富,希望大家能积极提意见,欢迎PR。