写点什么

Knative 系列(二):兵马未动粮草先行之 Build 篇

  • 2019-06-11
  • 本文字数:3686 字

    阅读完需:约 12 分钟

Knative系列(二):兵马未动粮草先行之Build篇

在该系列的第一篇文章中,主要介绍了Knative的基本概念及诞生背景,并提到 Knative 主要由 Build、Serving 和 Eventing 三大核心组件组成,本文将重点 Build 的使用方法。



具体来说,Build 提供源码到容器镜像的构建能力;Serving 提供 Serverless 应用或函数的部署能力,并通过 istio 实现服务管理,同时提供了容器扩缩容能力;Eventing:提供事件触发通道。


Knative 的这三个组件提供了一套完善的 Serverless 方案,让开发者可以只关心自己的代码。提交代码以后,Build 会将源码构建成镜像,Serving 会自动实现应用部署,Eventing 提供事件触发入口,接下来就可以访问到最新应用了。对使用者来说,从源码直接到应用,省去了中间复杂的环节。


Build 完全基于 Kubernetes,设计非常灵活,用户可以利用 Build 定制构建流程,虽然官方文档宣称现在 Knaitve 还不能提供完整的 CI/CD 方案,但是利用 Build 的灵活性完全可以实现 CI 平台搭建,这部分内容会在后面的实现中着重介绍。


本文,我们把 Build 组件拆开揉碎,全面分享给读者。如果现在手头刚好有一个K8s集群,可以跟着文档尝试操作,整个过程甚至不需要占用一杯咖啡的时间。

Build 组件安装

Build 可以作为一个独立组件单独安装,只需要在 K8s 的集群中执行以下命令即可:


   kubectl apply --filename https://github.com/knative/build/releases/download/v0.6.0/build.yaml
复制代码


执行成功以后,可以通过以下命令查看:


kubectl get pods --namespace knative-build
复制代码


可以看到,在 knative-build 的 namespace 下,新增了两个容器 build-controller 和 build-webhook,build-controller 是 Build 核心模块,其基本业务流程是监控自己创建的 CRD 资源从而实现构建,build-webhook 和大多数的 webhook 功能一样,通过 webhook 的方式对自己的 api 进行校验。



到这里恭喜你,Build 组件已经安装成功了,接下来就可以利用它来进行构建。

build 和 buildtemplate

构建之前,我们需要先了解两个概念:build 和 buildtemplate。这里的 build 不是 knative 的 Buid 组件,而是 Build 组件通过 CRD 定义的一个资源文件,build 通过自己定义资源文件去控制构建流程,所以说,Build 完全基于 K8s 生态,只要有 K8s 集群就可以完成构建而不需要依赖其他外部组件,同时,yaml 定义的资源文件也可以很轻易的移植到其他集群上去。


为了方便理解,我们先看一个 build 的 yaml 文件:


apiVersion: build.knative.dev/v1alpha1kind: Buildmetadata:  name: kaniko-buildspec:  serviceAccountName: build-bot   //如果源码或者仓库为公开可以不用创建serviceAccount  source:    git:      url: https://github.com/my-user/my-repo   //你的源码仓库地址      revision: master                          //你的源码分支地址  template:    name: kaniko                                    arguments:    - name: IMAGE      value: us.gcr.io/my-project/my-app         //构建成功以后镜像存放的镜像仓库地址
复制代码


以下是其中的几个关键配置:


serviceAccountName需要先创建一个serviceAccount资源,里边包含了构建过程中拉取代码或者pull/push镜像的认证信息,如果你的代码和镜像都放在一个公开的仓库里则可以不用定义这个资源。
sourcesource中指定了你的代码源,revision是代码的分支
template使用的buildtemplate的名称,也是由build定义的一个CRD资源


如果想在自己的代码仓库尝试用 build 进行构建,只需要修改上面蓝色的部分即可。看起来,build.yaml 非常简单,而且在 yaml 中也没有看到关于构建过程的体现,是因为在这个 build.yaml 里定义了一个 buildtemplate,buildtemplate 中定义了实际构建过程中的 steps(关于 steps 的内容我们稍后会讲到),当我有多个代码库,或者代码库下有多个分支,抑或是代码想用不同的方式去构建,每次都要定义一个完整的 build 文件就显得非常麻烦,这个时候利用 buildtemplate 可以定义很多构建模板,然后只需要像上面的 build.yaml 一样简单指定代码仓库即可。那么,buildtemplate 是必须的么?当然不是,我们可以直接把 steps 写在 buid.yaml 里,但是 buildtemplate 极大的提高了 build 的灵活性和可移植、可重用性。为了方便快速实现构建,knative 的 build-template 代码库中已经预置了大量的 buildtemplate,包括bazelbuildpackskaniko等近十个模板,这里我们先用 Kaniko 的 build-template 体验一下 build 的构建过程。


Kaniko 是 Google 推出的构建工具,它基于 Dockerfile 进行构建但是却不需要 docker daemon,我们先来看一下 Kaniko 的 buildtemplate 是什么样子。


apiVersion: build.knative.dev/v1alpha1kind: BuildTemplatemetadata:  name: kanikospec:  parameters:  - name: IMAGE    description: The name of the image to push  - name: DOCKERFILE    description: Path to the Dockerfile to build.    default: /workspace/Dockerfile  steps:  - name: build-and-push    image: gcr.io/kaniko-project/executor    args:    - --dockerfile=${DOCKERFILE}    - --destination=${IMAGE}    env:    - name: DOCKER_CONFIG      value: /builder/home/.docker
复制代码


buildtempate 中也有几个关键配置:


steps定义构建的步骤
builderbuilders就是每个steps中定义的image,每个step中必须要定义一个builder,builder是steps具体的执行者,后续在到build的实现中我们可以看到为什么每个step一定要去指定一个image


kaniko 的 buildtemplate 十分简单,只有一个 step,然后传入两个参数 DOCKERFILE 和 IMAGE 即可,DOCKERFILE 是工程中 dockerfile 所在的文件路径,IMAGE 是要推送的镜像仓库地址。


这两个文件都准备好以后你只需要执行以下两条命令,一切顺利的话一段时间时候以后,你就可以在你的镜像仓库里看到你刚刚构建好的镜像了。


kubectl create -f kaniko.yamlkubectl create -f build.yaml
复制代码


如果只是想体验一次 Build 带来的基于原生 K8S 的快捷构建,到这里你的体验之旅就已经结束了,如果想问到底执行完以后发生了什么,那就再花点时间看看到底发生了什么?

Build 构建实现

在上述步骤创建完 build.yaml 以后执行


kubectl get pod
复制代码


我们发现多出了一个 pod,用 describe 查看 POD 可以看到以下信息:


Name:               kaniko-build-pod-a4f897Namespace:          defaultControlled By:      Build/kaniko-buildInit Containers:build-step-credential-initializer:Image:          gcr.io/knative-releases/github.com/knative/build/cmd/creds-init@sha256:101f537b53b895b28b84ac3c74ede7d250845e24c51c26516873d8ccb23168ce    .......    build-step-git-source-0:      Image:         gcr.io/knative-releases/github.com/knative/build/cmd/git-init@sha256:ce2c17308e9cb81992be153861c359a0c9e5f69c501a490633c8fe54ec992d53      Args:        -url        https://github.com/lihua871205/2048.git        -revision        master    ......    build-step-build-and-push:      Image:         gcr.io/kaniko-project/executor      Args:        --dockerfile=/workspace/Dockerfile        --destination=swr.cn-north-1.myhuaweicloud.com/l00283074/sample:latest    ......
复制代码


POD 里边包含三个 Init Containers:build-step-credential-initializer, build-step-git-source-0 以及 build-step-build-and-push


  • build-step-credential-initializer:如果 git 和 docker 需要认证的对 git 和 docker 进行认证

  • build-step-git-source-0:负责将代码拉取到 workspace 下

  • build-step-build-and-push:是用户自己定义的构建 step,它负责将源码构建成镜像


从这里,我们可能已经猜到 build 的构建实现,利用 Init Containers 的特性,build 先将 source 中的配置生成一个默认的 build-step-git-source-0 接下来再将用户 step 中配置的信息依次解析成多个 Init Containers,当 POD 运行的时候会依次执行所有的 Init Containers 从而实现代码获取,源码构建的流程。这也回答了上面的两个问题:


1、为什么每个 step 都要有一个 builder?这是 Init Containers 的特性决定的,即使是 Source 这个步骤其实也是使用了 Build-Controller 内置的一个镜像;


2、为什么 build 非常灵活?用户可根据自己的场景,自己定制构建镜像,Build 只提供构建流程,但是不提供构建实现,这也是为什么当前有这么多 buildtemplate 的原因。我们再回顾下 Build 的基本流程:


总结

Knative 的 Build 利用 init container 实现了一个基于 K8s 生态的构建流程,用户可以自己定制构建场景,或者利用丰富的 build-template 实现构建,它可以作为一个独立的组件减少 K8s 构建的烦恼,更重要的是可以嵌入到 serving 中(偷偷预告一下后面的章节会讲到 build 如何和 serving 集成到一起)形成完整的 Serverless 生态,只有通过 Build 快捷地将源码变成镜像,才能让 serving 有源源不断的“粮草”大展身手。


相关文章:《Knative 系列(一):基本概念和原理解读》


2019-06-11 08:408922

评论 2 条评论

发布
用户头像
Proposal: Knative Build deprecation in favor of Tekton Pipelines #614

https://github.com/knative/build/issues/614
2019-06-11 13:11
回复
用户头像
专业
2019-06-11 12:31
回复
没有更多了
发现更多内容

Java开发最佳实践手册全网独一份,vue视频教程百度网盘,正式加入字节跳动

Java 程序员 后端

Java开发入门与实战!极客学院和黑马程序员,Java高级工程师系列学习路线介绍

Java 程序员 后端

Java开发究竟该如何学习,年末阿里百度等大厂技术面试题汇总,程序员翻身之路

Java 程序员 后端

Java开发经典实战!自学java教程百度云盘,阿里程序员的Java之路

Java 程序员 后端

Java开发经验谈,linux视频教程百度网盘,逆袭面经分享

Java 程序员 后端

Java开发者跳槽面试,尚硅谷java课程,netty框架面试题

Java 程序员 后端

Java开发从零开始,牛客网java选择题库,程序员Javaweb源码

Java 程序员 后端

Java开发经验的有效总结,以商品超卖为例讲解Redis分布式锁

Java 程序员 后端

第1周作业

波波

「架构实战营」

Java开发自学教程!尚学堂java,我被面试官绝地反杀了

Java 程序员 后端

云栖收官:想跟远道而来的朋友们说

阿里巴巴云原生

云原生 云栖大会 收官 致谢

Java开发视频教程,linux使用教程,BIO和NIO有啥区别

Java 程序员 后端

Java开发还不会这些,极客学院和黑马,进阶学习工作最全指南

Java 程序员 后端

Java开发工程师笔试题目,图灵学院vip百度云盘,阿里P8大牛手把手教你

Java 程序员 后端

Java开发者应该会哪些东西才不会被公司淘汰,美团Java面试

Java 程序员 后端

Java开发者跳槽指,牛客网算法初级班,春招我借这份PDF的复习思路

Java 程序员 后端

Java开发自学技巧!极客学院百度云资源,2021最新Java笔试题目

Java 程序员 后端

Java开发面试基础,牛客网客户端,【面试总结】

Java 程序员 后端

Java开发你需要了解的那些事,Java线程池基础入门和简单实践以及使用技巧

Java 程序员 后端

Java开发面经分享,springboot项目案例百度云,实战篇

Java 程序员 后端

模块一作业

忘记喝水的猫

架构训练营

Java开发核心知识笔记共2100页,如何保证Redis与数据库的双写一致性

Java 程序员 后端

模块一作业

心怀架构

Java开发实战讲解,牛客网面试经验,Java高级知识图谱

Java 程序员 后端

Java开发岗还不会这些问题,想拿高工资

Java 程序员 后端

Java开发面试基础,java架构师全套百度网盘,Java基础面试重点

Java 程序员 后端

Java开发前景怎么样,java全套教程百度云,linux基础入门教程

Java 程序员 后端

Java开发教程,极客时间架构师训练营,面试流程4轮技术面+1轮HR

Java 程序员 后端

Java开发还会吃香吗,Java微服务架构从入门到精通

Java 程序员 后端

Java开发面试题!牛客网java开发高频面试题,让我成功在寒冬中站稳脚步

Java 程序员 后端

Java开发实战讲解,牛客网面试经验,Java编程入门教材

Java 程序员 后端

Knative系列(二):兵马未动粮草先行之Build篇_文化 & 方法_华为云原生团队_InfoQ精选文章