目录
前言
最初尝试Kubernetes直接部署云计算相关组件, 但是要在Docker中完成自动配置很麻烦, 再者follower无法做到动态扩容, 比如Hadoop中新增的Datanode容器, NameNode容器是无法感知的。节点的存储与网络通信也存在一定问题。
BlueData
Bluedata在《Big Data and Container Orchestration with Kubernetes (K8s)》中提到了自己产品BlueData EPIC未来在Kubernetes上的发展。
Bluedata设置了StateFulSet的EPIC Controller, 提供了REST和Web UI支持, 且在其Pod上安装Kubectl从而控制Kubernetes以增加新容器, 完成Cloudera或其他镜像的部署, 具体可参见以下视频中的演示。
如视频中展示, 计算节点以StatefulSet和对应的Service拓展, PersistVolume由cePersistentDisk中配置gke完成存储部署。鉴于BlueData仍然处于开发测试中, 自研违背搭建云环境的初衷过于花费时间, 本作者更加青睐于下面的第二种方式来搭建有状态的云计算服务。
loicmathieu/docker-cdh
这是github上的一个开源docker项目loicmathieu/docker-cdh, 通过所需install所需cloudera组件, 并且预先准备好相关配置, 即可直接搭建出容器化的云计算环境, 作者也通过实践在Kubernetes上成功依据此项目搭建出了HDFS + MR + Pig + Hive + Spark + Flume的实验环境, 并且datanode部分可自动拓展, 部署yaml如下:
- cloudera.yaml: https://down.windawings.com/kubernetes/loicmathieu/cloudera.yaml
- cloudera-ingress.yaml: https://down.windawings.com/kubernetes/loicmathieu/ingress-cloudera.yaml
具体能做什么可参考loicmathieu/docker-cdh中的说明, yaml中的镜像和nfs的ip等需要做替换, 这里不再赘述。虽然部署结果还算满意, 但是和apache spot的实验环境有一定区别, 未来组件的拓展性也很差, 需要把Dockerfile全部重写; 而且因为新加组件需要额外配置, 所以Kubernetes的ConfigMap需求也会变得更大, 且可能因新组件的配置难以同步, 要么在DN节点配置kubectl可动态更改ConfigMap, 要么使用Puppet, Chef或Ansible之类的工具向Master节点注册自己, 这样做也很麻烦。最后选择重写Dockerfile, 并尝试在Kubernetes中配置Cloudera Master和Clouder Agent来搭建出更自定义的云计算环境, 并且享受Cloudera带来的集成上的遍历, ConfigMap也只需要管理Cloudera即可。
部署
其实与其说是部署, 不如说是错误日志记录合适一些, 因为没有拓展出REST或者别的API, 只是单纯地使用Dockerfile完成镜像配置和Kubernetes的部署相结合, 实际遇到的问题主要来源于Docker和Cloudera的适配。具体内容其实看yaml配置和Dockerfile内容就明白了, 先放上配置再说明部署过程中遇到的麻烦。
- Dockerfile: https://github.com/windawings/spot-docker
- cloudera.yaml: https://down.windawings.com/kubernetes/cloudera/cloudera.yaml
- cloudera-ingress.yaml: https://down.windawings.com/kubernetes/cloudera/ingress-cloudera.yaml
日志
部署在5月初就已经做好了, 但当时没有对错误一一做笔记, 所以如今想起什么就补充。
- Cloudera自带了Supervisor, 如果
pip install supervisor
Cloudera Agent会报错说无法运行supervisord - 不知道为什么Kubernetes中对CPU和内存做了limit后, 即使设置此前CPU或内存的最大值, 容器会无法正常启动, 只好暂时不做设置
- Kubernetes启动容器后会刷新一遍容器的Environment, 而此时开机脚本是读取不到这个新环境内容的(我做出了很多努力, 都无法获取到新环境配置信息……), 最后采取设置Kubernetes的hostname, 故意使其和对应Service的name相同, 从而达成访问Service与Master相连通的方式(因为实在不想使用Pod的部署模式, 力求以Service通信, 以StatefulSet或Deployment完成节点部署), 这里之所以需要读取新环境配置是为了让Cloudera Master服务可见, 因为Cloudera Master以Deployment部署, 其Pod会分配一个Deployment的
name-[随机字符]
的取名形式, 需要获取到后设置hosts
和hostname
为master-svc, 完成容器重启后使其服务可被Cloudera Agent发现(其实完全可以用正则匹配到这个随机码然后替换完成重启, 但因为尝试以开机启动脚本读取新环境配置浪费太多时间, 而且考虑可能有更改hostname的需要, 所以选择了配置Deployment.spec.template.spec.hostname
与Service.metadata.name
相同的取巧方式完成部署) - PersistVolume需要配置哪些运行目录暂时未知, 这个部分难以让Cloudera进行管理, 算是目前自定义云环境中比较尴尬的部分。也就是说需要自己知道各个组件需要做持久化的路径, 将其以PersistVolume存储到容器生命周期之外。目前仅对Cloudera组件的parcel压缩包进行了本地NFS挂载和存储, HDFS算是可以自己配置nn, dn这些内容的位置, zk的myid和日志等, 这个部分暂时没有好的动态做持久化分配的点子, 也不可能直接挂载根目录或者挂载一个过大的位置
- 目前仍然卡在Cloudera分法检验完agent的parcel之后, 配置角色时hue的数据库连接失败上(其他都能成功, 似乎是其python的某个xml模块有报错), 这个需要更改master的Dockerfile引入缺失配置, 暂时未解决