Ketos 笔记 -- 记 Go Hackathon 2017
纯故事 (无技术细节,可略过)
第一次参加 Hackathon,是被 Ace Tang 抓来背锅的。比赛前填表格敲定参赛项目和团队。Ace Tang 在阿里忙双 11,就由我列了一下,几乎全是日常生活中的小工具。一波 idea 筛选就是凭借 github trending 来的,docker 排第一,Ace Tang 也在负责 docker 开发,于是我们就决定写一个 docker build
在 CI 平台中的替代工具。
参赛申请提交后,与组织人员短暂寒暄,掐指一算,三周技术调研及坑位填补时间。因为团队不来自一个公司,只能借助 github 同步调研进度和文档。最初项目名字叫做 xcbuild,意味 Cross Container Building,正是想让他无痛运行在 docker container 中。中间与 Tang 每隔几天都会电话同步下或者正式会晤并交换意见,确保学习方向正确。我在公司的工作主要落在调度层,Tang 在 docker 实现上比我了解得更多,中间更多次帮我审阅文档及给出指导性意见。
比赛是在上海举行的,周五兴奋了一宿,周六早上 5点爬起赶火车。时间安排大约是,周六上午废话加寒暄,顺便打听一下伙食情况。下午开始打瞌睡,晚上通宵乱嗨,周日上午准备吹牛皮,下午开始吹牛皮,晚上打电话叫人抬我回去。粗略统计,48 小时我睡了不足 6 小时,只想说“代码使我兴奋”。
需求整理
Ketos 原名 xcbuild,因为在技术调研过程中,我们发现要解决我们的需求,我们的工作要深入到 docker build
的底层上,并将整个构建过程拆解成若干工具,由用户自由组合。Ketos 一词作为希腊神话中的海中巨怪,以及鲸鱼、鲸鱼座的词根,被用来命名该组工具套件。相对于可爱友好的 docker “蠢萌海豚”,Ketos 更具侵略性、原始性和粗犷感。
该项目 idea 来源于我最近的工作,目前在公司负责 CI 平台开发。使用 dind 的 CI 平台,对于编译任务的调度需要做一些额外的工作。并且 dind 服务作为 Job 任务运行会导致 docker build
命令完全无缓存。这个问题在国外的各大 CI 平台暴露并不严重,譬如 Go 的依赖下载,github 等源码仓库是有 CDN 通道的,而 CI 平台的使用场景通常是与工作异步进行的,略高的耗时用户完全无法感知。但若网络仅比 56K 猫快一点的话,编译耗时问题,甚至编译因网络 timeout 而失败等问题就比较严重了。而项目依赖对于有经验的开发者而言,通常首次提交依赖描述后,常年不做改动。因此如果能将每次发起编译所需踩的坑挪到发起项目时全部踩完,虽不完美,至少用户能省点心。
调研过 docker registry 的实现后,不得不说 registry 的 content addressable 设计给出了可能性及不小的启发。
再来说说 geek 们的特殊癖好。如果你写过 C,不知道 C 相对于 Go 在编译时极强的定制性是否至今仍令你回味?!
总之,在一系列文档检索之后,我们发现,docker build
命令是一个设计完美的小白用户命令,定制性差,并且扼杀了对于 geek 们的无限的想象空间。
技术调研
整个技术调研成本约为 2周 * 2人。因为我与 Tang 都对 docker build
的过程不甚了解,并且 48小时所能完成的核心功能不能过于复杂。所以项目目标确定后,先实行技术学习及调研,确定我们能做些什么。
更详细的 docker build
过程,请参考 docker 源码。逻辑上大约分为三步:
FROM
语句下载 docker 镜像到本地。docker 进程的镜像管理功能提供镜像管理服务。ADD
、COPY
以及RUN
等命令生成一个新的镜像 layer。组合所有 layer,生成新的镜像描述文件,并返回。若谈到完整的 CI 流程,还应该有一步推送新镜像到 docker registry。
总结一下,约有两个问题需要搞清楚:如何与 docker registry 通信,上传、下载并管理 docker 镜像?粗略调研了一下镜像 layer 的结构后,RUN
命令成为第二个难点。docker 自身有生成 container layer 并隔离诸多 namespace 运行用户代码的能力,也就是 docker 的核心功能,而我们什么都没有也没有时间去重写一个 runc。最重要的,根据我们的目标需求,我们要考虑如何能够给用户最高自由,并能帮助用户生成这层新的 layer。
docker registry 方面的调研确定了我们的工具将会以一个什么样的形式呈现给用户。runc 替代方案则确定了这整个项目的可行性及存在价值。由于 idea 是我提出来的,万一调研路上项目搁浅,锅要背好。于是由我负责后一项调研工作,Tang 负责前一项。
从确定项目目标并提交参赛申请,到提交申请后的两周多的时间里,我其实心里是完全没底的。因为 runc 替代方案的调研没有完成,我并不知道圈内是否已经有了该类工具,第二,我并不知道项目可行性。所有一切仅仅是凭借着我对于 CI 平台上应用 docker build
的理解驱动的。期间有无数次胆战心惊地考虑过能够令我们的项目搁浅的发现。或者 appc 到 runc 的周边已经有工具开始着手提供该类功能,或者替代 Dockerfile 中的 RUN
指令不可行,也就是意味着完成该项目需要对 docker 甚至 linux 内核提交 patch(意味着投入与产出失衡,人们会更愿意直接使用 docker build
完成工作)。
需求分析
两周的技术学习后,对于项目的可行性及难度我心里已有了些底气。中间还帮助 Tang 看了下 registry 的 api 文档。我们非常幸运,虽然 registry 的几个 go client library 有诸多深坑巨壑,但是 registry 本身的设计却让人大呼 genius。content driving 简单到不能再简单。而我们也成功地找到了一个 client 包,还是由小有名气的 heroku 提供的。
结合着新学习到的技术,重新分析下我们的需求:
registry 的设计是:
registry-url + image-name = repository
repository + tag/reference = image
image 在 registry v2 以后仅由一个到两个 manifest.json 描述,
manifest.json = image-layers + image-config
仅仅如此,这就是 docker registry 管理的所有内容。所以我们要做的就是与 registry 同步并管理 layers 和 manifest.json。
对于 RUN
语句,
仔细想想,我们的工具适用的场景是用户的本地 PC 编译以及基于 docker 的 CI 平台。在编译时,用户能够看到源码,甚至源码就是用户所写,或者编译过程已然运行在 container 里面,所以其实 namespace 并没有发挥多大作用。而编译工作是一个 one-off task,并非长时服务,所以我们认为 cgroup 也不是必须的。而我们对于 RUN
的最大需求其实只是这条语句让一段脚本运行在了一个虚假的 rootfs 里面并得到了一堆正确路径的静态文件,也即 chroot 所做的工作。
所以我们需要做的第二件事情其实是基于下载的 image 挂载或者模拟挂载为一个 union-fs,执行用户提供的命令,并找到一个技术方案让用户的命令感知到的 rootfs 为我们定义的目录。
最后一步是对于不论用户使用何种方式生成的新的 layer 目录,打包成一个 layer,并更新 image 的 manifest.json 包含该层 layer。
UI 及架构设计
临近比赛前两周,我感冒了。所以进行到这一步的时候,也就是比赛前一两天。这一步也是我们在比赛中最大的失误,直接导致了周六第一天编码过程中,工作未划清。
UI 并非是指 GUI。
由于一层 image layer 的制作极其简单,因此我们的工具核心是 xcb 命令,即 xcbuild 的缩写,该命令包含一系列子命令帮助用户从 registry 同步 image,并生成新 image 推回 registry。具体参考 xcb help
。
xcb 命令在这 48 小时中,主要实现 pull(拉取 image)、push(推送 image)和 commit(提交 layer 生成 image),以达到完整演示的目的。更多命令例如 cat-manifest(查看 image 的 manifest 描述)、put-manifest(推送 image 的 manifest)、pull-layer(拉取一层 layer 并解包)、push-layer(推送一层 layer)、has-layer 等等,则需要更多开发时间,为赛后添加。
在生成一层 image layer 过程中,被执行最多的,也即用户目前最依赖的指令是 RUN
指令。所以我们提供一个 chr 命令, 即 chroot 的缩写,该命令帮助处理 union-fs 的 layers,非侵入修改用户命令操作的文件系统根目录 rootfs 地址。具体参考 chr help
。
比赛
比赛理论上是 48小时,然而正式开始时间是周六早 9点,提交截止时间是周日 13点,即 28小时。14点开始项目汇报评审,其实是一个每组 9分钟的作品发布会。
赛前预估过我的编码能力,约为 8小时 500行 Go 代码。理想情况下,比赛中我们团队的编码能力约为 28 / 8 * 500 * 2 = 3500
行。预估 3000行代码也湛湛实现了我们的 prototype。所以到演示时项目完成度可能并不为 100%。我们遇到的第一个难题是判断在适时时裁剪代码以及违背一些编码原则加速实现。
若是开发工作不顺利(chr 这种偏近系统底层的开发工作),问题可能更多,例如最严重的踩到了之前未意料到的深坑巨壑。我们组两人在周六下午同时在自己负责的部分踩到了坑,消耗近 5小时 * 2人,几近灾难。周六晚加之身体疲劳已萌生退意,直至 23点才有显著进展。
评审过程的宣讲,语言组织能力也是一则考验。9分钟,要介绍出需求驱动、项目的价值或意义、项目的技术概述以及 UI。重中之重是这个项目的价值,答辩中简单的技术问题对于参赛的 geek 们几乎不具任何难度。而项目价值想要讲清楚,就要在赛前做好充分的调研工作,至少要网罗到评委们 50% 的技术视野。提前确定并共识一个清晰的价值也能够驱使我们团队在 28小时中保持热情。
整场 Hackathon,从入场开始,见到身边高手如云,心态不好很容易出事情。28小时的编码时间,感受下来很像一场头脑 Marathon。但是比赛进入评审阶段,大家互相交流技术,拓展视野时,实实地一场技术狂欢。庆幸我们坚持到最后。
值得一提,赛场上,我们拼了一桌 4人两队,分别取得了第一和第三。用陈的话说,“风水宝地”啊!
我们的作品:Ketos 原 Cross Container Builder (xcbuild),在 https://github.com/setekhid/ketos。
我们的团队:上海两日游,Ace Tang 和 Huitse Tai。
Ketos 笔记 -- 记 Go Hackathon 2017相关推荐
- 分层强化学习:基于选项(option)的强化学习/论文笔记 The Option-Critic Architecture 2017 AAAI
The Option-Critic Architecture 2017 AAAI 1 option option 可以看作是一种对动作的抽象. 一般来说,option可以表示为一个三元组,其中: 是这 ...
- 笔记-中项案例题-2017年上-风险管理
2017年上半年系统集成项目管理工程师考试下午真题 某政府部门为了强化文档管理,实现文档管理全部电子化,并达到文档的实时生成和同步流转的目标,使文档管理有一次突破性升级,拟建设一个新的文档管理系统.项 ...
- 笔记-中项案例题-2017年上-计算题
2017年上半年信息系统项目管理师考试下午真题 有点难度,接驳缓冲和项目缓冲的解释压根没有考过吧: 某项目细分为A.B.C.D.E.F.G.H共八个模块,而且各个模块之间的依赖关系和持续时间如下表所示 ...
- 笔记-中项案例题-2017年下-变更管理和配置管理
2017年下半年系统集成项目管理工程师考试下午真题 某公司中标一个城市的智能交通建设项目,总投资350万元,建设周期1年.在项目管理计划发布之后,柳工作为本项目的项目经理,领导项目团队按照计划与任务分 ...
- 笔记-中项案例题-2017年下-收尾管理
2017年下半年系统集成项目管理工程师考试下午真题 A公司是为保险行业提供全面的信息系统集成解决方案的系统集成企业.齐工是A公司的项目经理,目前正在负责某保险公司P公司的客户管理系统开发项目,当前该项 ...
- 传智_Springmvc+Mybatis由浅入深全套视频教程(燕青)-mybatis笔记(两天)(2017年8月5日16:09:55)
专业实习消耗了半个月,学习进度一度停滞.mybatis基本的使用不难,和hibernate相比各有优势吧,不是一个风格的框架. mybatis笔记整理如下: 笔记链接:http://download. ...
- kindel读书笔记——第二个月2017.02.22-03.21
嫌疑人X的献身 [2017/02/21, ¥9.00] 拿别人的生命来献身,其实是一种残忍. 当我看到石神自杀未遂那一段后,突然明白有些时候,生命被重新赋予后,便有了宿命.
- 【旧文集】越读者读书笔记-记于2015
#阅读心得 ##一.概述: [外链图片转存失败(img-tY4e7zEP-1566545780904)(http://upload-images.jianshu.io/upload_images/13 ...
- Kindle读书笔记——第一个月2017.01.22-02.21
1. 天才在左,疯子在右 [2017/01/21, ¥3.99] 看这本书之前以为是讲天才和疯子的共性的,结果看完才发现是讲常见心理疾病的.书中谈到的心理疾病也很常见,但是要严重到例子中那样可能却不 ...
最新文章
- 计算机word应用模块三,计算机应用基模块三.ppt
- storm自定义分组与Hbase预分区结合节省内存消耗
- windows环境给redis配置密码
- (12) Hibernate+EhCache配置二级缓存
- Android--获取当前系统时间
- ModuleNotFoundError: No module named ‘torch.utils.serialization‘
- cwyw不是有效的加载项_ADAS/AD开发09 - UDS与引导加载程序
- 又是别人家的公司!华为人才房价格曝光:1万/㎡ 带装修
- 记录一次因为懒惰而吃亏的事情
- sql server合并行_合并SQL Server复制参数化的行筛选器问题
- “迭代期内无变更”与研发心理学(承诺管理,MosCoW方法)
- Penn Treebank Tags做点小翻译 (上篇)
- Elastic 技术栈之 Logstash 基础
- Linux设备驱动开发入门之——hello驱动
- 【Python-二分法-查找重复值】
- 物理层下面的传输媒体
- 统一网关过滤器GlobalFilter、DefaultFilter、路由过滤器执行顺序
- 知道今天是星期几java_java如何判断今天是星期几
- QUIC成为了HTTP/3的标准传输协议!
- 钱币兑换(动态规划)
热门文章
- 中山大学等“双一流”官宣:博士生涨薪!大幅提高奖学金助学金标准
- 【电脑使用】如何设置没有自启项的软件开机启动
- 关于老子的五个关键思考
- ThinkPHP通过cURL的调用接口数据
- 波动方程有限差分法c语言,二维波动方程的有限差分法.pdf
- JSP自定义标签【第二章】
- Java的类和包的总结
- 泊松圆盘采样(Poisson Disk Sampling)代码实现
- 【脑肿瘤分割论文】:TransBTS: Multimodal Brain Tumor Segmentation Using Transformer
- 关于fi dd ler 手机抓包 网卡地址地址_抓包神器:tcpdump!我还真没用过