NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

TencentHub 技术架构与 DevOps 实践揭秘(上)

  • 2019-10-29
  • 本文字数:4222 字

    阅读完需:约 14 分钟

TencentHub技术架构与DevOps实践揭秘(上)

TencentHub 是一个集 Docker 镜像、二进制文件、helmcharts 于一体的仓库存储服务。那么这一架构技术是如何基于 Kubernetes 快速实现 workflow 引擎的呢?今天将为大家分享《TencentHub 技术架构与 DevOps 落地实践揭秘》,让我们开始吧!


大家好,这次主要是给大家分享 TencentHub 技术架构和 DevOps 相关的一些东西,这两点和大家日常开发结合会比较紧密,比较接地气一点。我今天会主要分享三部分,第一,简单聊一下 TencentHub 这个产品和 DevOps 的关系,我们如何去思考建设一个 TencentHub 镜像仓库+DevOps 引擎。第二部分讲讲 TencentHub 总体的一些东西和 Docker 镜像存储在腾讯云上是如何实现的,最后是我们的 workflow 引擎:为了支撑 DevOps 工作流去设计产品以及一些具体设计/实现细节。

TencentHub 与 DevOps?

什么是 DevOps?

我相信很多人对 DevOps 已经比较熟悉了,这个概念从 2009 年大火起来到现在已经过去了接近十年的时间。直击 DevOps 的核心理念,下面这句话是我最赞同的对 DevOps 的描述:以业务敏捷为中心,去构造适应快速发布软件的工具和文化。我们做 DevOps,要去推崇 DevOps,肯定不能忘掉我们的目标是快速交付软件产品。在达到这个目标的过程当中,非常重要的落地就是我们需要工具去支撑 DevOps,所以接下来分享 TencentHub 这样一个以 DevOps 引擎为指导的工具。


什么是 TencentHub?

TencentHub 是什么?TencentHub 核心有两部分,第一,它是一个多功能的存储仓库,包含了 Docker 镜像存储功能以及 helmcharts 这样的存储,还有一些构建产物的存储等等。第二,TencentHub 是一个 DevOps 引擎,通过我们自己设计的 workflow 引擎对工作流进行编排,去帮助大家建立自己的 DevOps 流程,比如说构建、测试、审核、部署等等任务。当然,在前置环节,我们也将去对接腾讯云提供的 TGit 代码托管服务,最终给开发者提供一套完整的云上 Devops 工具解决方案。


TencentHub 技术架构

TencentHub – 总体架构

我简单介绍一下 TencentHub 的总体架构,TencentHubd 的镜像仓库存储是基于 COS 实现,因为 COS 可靠性非常高,这非常方便地给我们的镜像存储带来高可靠保证。TencentHub 核心还有一个自研 workflow 引擎,可以使用 YAML 定义 DevOps 流程,让我们的 DevOps 本身达到 Programmable,这对 Devops 的管理是很重要的。在 TencentHub 的 Devops 引擎里面,我们使用容器去实现插件机制,用来封装用户自定义的 DevOps 任务,后面会详细介绍。使用 Kubernetes 作为执行引擎,运行 DevOps 任务,目前是使用 TKE 来实现的。在 Docker 存储仓库里,我们也会加入 Docker 镜像漏洞的安全扫描,后面会做一个的简单介绍。


镜像存储

Registry Token Authentication Specification

左边这个图分为两大部分。上面是 Registry,下面是 StorageEngine。Registry 主要包含了组织、团队、成员的管理,以及一些权限的控制,同时还包括仓库 Repository 的管理,负责 Docker 镜像、文件、helmchart 的存储。我们所有存储都是使用一个仓库来管理,镜像、文件等都会放在某一个仓库下面。在最上面,我们提供了 Webhook,可以帮助用户对接自己的系统,监听仓库或者 DevOps 流程发生的一些事情。在 Registry 里面还有 Component 组件,负责 DevOps 任务的存储。下面这部分 StorageEngine,是我们去解决统一的仓库存储层的问题,它是一个我们提供出来给全球的腾讯云的机房都能使用 TencentHub 服务的机制。



TencentHub 仓库中最重要的是 Docker 镜像的存储。除了公共的镜像存储之外,TencentHub 还支持私有的镜像存储。私有镜像存储需要通过登录才能获取或者上传 Docker 镜像。如何是想登录认证呢?这是 Docker 官方的 Registry 用户认证的规范,它并没有纳入到 OCI 规范里面,只是在官方有一个文档去说明流程是什么样的,Docker 客户端也是按这个流程去实现的,所以我们只需要在 TencentHub 后端按这个流程去实现自己的授权服务就可以了。

TencentHub pull 授权流程

在我们使用 Docker 进行 push/pull 的时候,本地的 Docker 客户端会调到 containerd,检查当前这个操作是否有授权。当我们没有带上一个 Token 的时候,后端的存储服务会返回 401,并且携带一个授权服务的地址,告诉客户端去这个地方拿授权码。客户端请求授权服务获取将要进行操作的授权 Token。


获取 Token 支持两种方式,一种是 OAuth2 密码模式,你可以通过登录之后,授权服务会给你下发一个 key,它和你的密码无关系,后续的通信都是使用 Key 获取 Token。


第二种方式是 Basic Authentication 方式,很多时候我们采用的都是这种方式。TencentHub 实现的也是后者。这种方式会在 Token 客户端留下帐号密码,并不是太安全,我们后面可能会去支持 OAuth2 的密码模式。


当客户端发起一个请求到授权服务的时候,授权服务就根据当前的请求去生成一个授权的列表,封装成 Token 返回客户端,这个 Token 的格式对客户端是透明的,可用使用任意自己的格式。我们这里继续保持了选择 JWT 的格式,是因为我们把 StorageEngine 和 Registry 做了一个状态的隔离,因为我们把需要的权限都放到了 Token 里面进行封装,不需要有一个中心化的带状态的权限校验服务去连接两者。最后当 Token 拿到之后,客户端重新再去请求 Registry,重新拉取它的 Docker 镜像,或者进行数据的上传/下载之类。


这里用一个时序图简单说一下它的流程。首先可以看到,Docker 服务端首先会去访问/v2/这样的路径,客户端会根据当前是否有携带 Token 来返回一个授权的地址,我们目前返回的是hub.tencentyun.com/token这个地址,客户端就会自动访问/token的URL,带上当前的账户以及申请的权限范围。客户端申请Token完成之后,就会进入Docker镜像拉取流程。


OCI Distribution Specification

Docker 镜像是分层组织形式,每个 Docker 镜像包含多个 Layer 和一个 Config 文件,每个 Layer 包含构建一个 Docker 镜像时文件系统里面出现的差异,Config 文件里面会包含当前这个 Docker 镜像能运行的一些环境要求,例如 OS,及一些配置入口命令,导出的一些端口之类。这些文件被一个 Manifest 文件引用起来,通过它可以找到这个 Docker 镜像的所有内容。Docker 是在 V2 版本设计了这样一套规范,目前它也已经提交到 OCI 组织,成为一个 Distribution Specification 标准。


这样的设计带来很多好处。


首先,它的安全性有比较大的提高。镜像中的所有文件都是 content addressable 的设计,让我们只需要拿到最后的 Manifest 去校验,就可以发现整个数据的传输过程中是否有篡改。这在现在比较流行的区块链中都采用类似的技术,是 merkle tree 的一种实现。


第二,它可以极大减少冗余。每个构造的 Docker 镜像都不会从空白文件开始,都是从各个发行版或者是比如 CentOS 的基础镜像开始,这些基础镜像存在非常多的基础镜像 Layer 都是相同的。它通过 content addressable storage 的组织结构,不仅在客户端减少存储空间,也可以在远端仓库中减少存储所需要的空间。


最后,它对缓存是非常友好的。因为整个 Docker 镜像里面不管哪一个 Layer 有改变,都会最终影响到 Manifest 的改变,所以 Docker 镜像并不是重新修改一个 Layer,而是重新生成的,我们去做缓存的时候就可以非常方便地在不同的环境下地部署我们的缓存,只需要使用 content digest 作为 Layer 的 key 来引用 Layer 文件即可,Layer 不会修改,只会生成新的或删除老的 Layer,缓存的管理就非常简单。


distribution RESTful API

这里再简单补充一下关于 distribution 规范的一些 API。前面两个不说,主要是第三个,每个 Docker 镜像的上传都会访问到/v2/仓库名/manifests/tags|digest 地址,在这个地址上,它支持去 GET、PUT、DELETE,去实现 Docker 镜像在远端仓库的拉取/上传/删除的功能。刚才所说的 Layer、Config 文件,包括 Menifests 文件,也可以通过 V2 这个路径下面的 name+blobs+digest 去获取。更详细的规范,可以看一下 OCI 组织已经成为标准的说明,下面有个 URL。


distribution 架构

TencentHub 镜像的存储核心还是利用了 Docker 官方的 distribution 来实现的,distribution 的实现在这个图里面描述得比较清楚,最上面有 API route 层分发 URL 的规则。第二层会有一个权限控制,我们在这里做了一些改造,增加了 TencentHub 的 hubtoken 的实现。我们为什么要去实现 hubtoken,而不是用官方现在自己的 GWT 格式?


是因为 TencentHub 可能还会面临着一些私有化部署的需求,或者说一些用户在公有云上面希望有自己独立的存储仓库。但是我们上面的 Registry 和 StorageEngine 两者之间并没有中心化的授权服务,所以我们就通过在 hubtoken 里面包含了一些不同租户的身份识别信息,在上下文进行传输,所以就单独改造了这里。


在权限控制下面会有 API 协议的函数处理,一些主要的业务逻辑,都在这里实现。最终到下面 storage 的实现,它提供了一套存储的插件机制,有一个标准的存储接口,规定了文件上传、文件移动等等接口,只要去实现就可以了。我们这里也会实现 GOS,是对 COS 的简单封装,后面会做一个 GOS 简单介绍。



现在腾讯云容器服务的仓库是 CCR,还没有提到 TencentHub 上面来。CCR 有两个问题,第一是不同地域的镜像是不通的,比如说我们在广州上传一个镜像,想在硅谷拉取是拉取不到的,这是我们直接依赖了 COS 提供的分发能力,没有去对它做封装,COS 是无法跨区域访问的,所以会存在这个问题,这会带来用户体验上的不一致,基于仓库的触发器、Docker 镜像构建功能,都会受到这个问题的影响,所有基于仓库的服务都需要单独又去部署一份,维护上也带来了很大影响。所以我们就做了下面这一层。


我们在设计 global object storage 的时候,发现 distribution 协议的设计没有事务的需求,第二是我们拉取多个镜像,它对延时不太敏感,但是对吞吐量很敏感。因此,实现这个存储,我们只对 COS 做了很简单的封装,提供中心化的服务,它类似于一个 p2p 的 tracker,会去记录它所有的文件分布在哪个区域的哪个 COS 里面。比如说我们从广州上传了一个镜像,他需要在硅谷去拉取,我们通过这个 global object storage 服务,会发现它在本地是没有的。这个时候通过腾讯云内部的专线,直接去广州把它拉取过来。在拉的过程当中,它会同步写到本地的 COS 和客户端去,这样客户端也不用做很长的等待。当下一次硅谷再访问该镜像的时候,它就不会再跨区域去访问这个数据,给我们减少了很多成本,最终也给用户带来很好的体验。


2019-10-29 19:131894

评论

发布
暂无评论
发现更多内容

快速上手Apache POI

卢卡多多

POI Apache POI 9月日更

带你读AI论文丨用于细粒度分类的Transformer结构—TransFG

华为云开发者联盟

细粒度 映射 Transformer TransFG 差异性图片

世界的尽头是铁岭,互联网的尽头是它

艾小仙

MySQL + Keepalived 双主热备搭建

Se7en

一文说清BIO、NIO、AIO不同IO模型演进之路

慕枫技术笔记

后端 引航计划

三大「价值流」搞定技术型管理

蔡建斌

管理 技术管理 精益 引航计划 内容合集

手撸二叉树之二叉搜索树的最小绝对差

HelloWorld杰少

数据结构与算法 9月日更

计算机工业的生态链(三)

姬翔

9月日更

循环神经网络LSTM RNN回归:sin曲线预测

华为云开发者联盟

RNN 循环神经网络 LSTM LSTM RNN回归

什么是Spring-Cloud、需要掌握哪些知识点,Java面试常问的算法题

Java 程序员 后端

什么是事务数据库?,Java程序员面试题集大全

Java 程序员 后端

linux之chattr命令

入门小站

Linux

如何PWA构建现代离线应用程序

devpoint

Service Worker 9月日更

性能测试中标记请求参数实践

FunTester

性能测试 接口测试 压力测试 FunTester 标记参数

简单五步:给你的 Golang 应用加一个 GUI ( Electron 驱动)

baiyutang

UI 跨平台 Go 语言 GUI 9月日更

架构训练营 模块7 - 王者荣耀商城异地多活架构设计

sophiahuxh

用IoT放羊养牛,不出门也能知道它们的动向

华为云开发者联盟

物联网 华为云 iotda 畜牧业 华为云物联网平台

三面滴滴Java岗,Java程序员校招蚂蚁金服

Java 程序员 后端

HTML进阶(二)

Augus

html 9月日更

编程基础:CPU资源监控

正向成长

CPU调度

全球国家简码信息表

入门小站

工具

网络攻防学习笔记 Day132

穿过生命散发芬芳

网络模型 9月日更

三面美团、四面阿里成功斩下offer,下血本买的

Java 程序员 后端

设计模式类型

一个大红包

9月日更

测试模型中理解压力测试和负载测试

FunTester

性能测试 接口测试 压力测试 FunTester 负载测试

如何从零搭建起一支技术团队

石云升

团队管理 管理 引航计划 内容合集 9月日更

使用Git分布式控制系统,怒斩腾讯和阿里的Offer

Java 程序员 后端

网卡修改网速和buffer

耳东@Erdong

9月日更 网卡

KVM虚拟机常用管理命令

玏佾

kvm 虚拟主机

如何选择收银机主板?

双赞工控

安卓主板

三面蚂蚁惨败,面试官要求手写算法,从外包公司到今日头条offer

Java 后端

TencentHub技术架构与DevOps实践揭秘(上)_DevOps & 平台工程_彭磊_InfoQ精选文章