Knative 的 Serving(服务)组件是解决如何从容器到 URL 的,而 Build 组件是解决如何从源代码到容器的。Build resource 允许您定义如何编译代码和构建容器,而不是指向预构建的容器镜像。这确保了在将代码发送到容器镜像库之前以一致的方式编译和打包代码。在本章中将会向你介绍一些新的组件:

  • Build

  • Build Template

  • Service Account

Service Account(服务账户)

在开始配置构建之前,你首先会面临一个紧迫的问题:如何在构建时获得需要验证的服务?如何从私有的 Git 仓库拉取代码和如何把容器镜像推到 Docker Hub 里面?为此,你可以利用两个 Kubernetes 原生组件的组合:Secret 和 Service Account 。Secret 可以让你安全地存储这些经过身份验证的请求所需的凭据,Service Account 可以让你灵活地为多个构建提供和维护凭据,而无需每次构建新应用程序时手动配置它们。

在 Example 3-1 中,首先创建一个 Secret ,命名为 dockerhub-account,里面包含需要使用的凭据。当然,可以像应用其他 YAML 一样应用它,如 Example 3-2 所示。

Example 3-1. knative-build-demo/secret.yaml




  
  1. apiVersion: v1

  2. kind: Secret

  3. metadata:

  4. name: dockerhub-account

  5. annotations:

  6. build.knative.dev/docker-0: https://index.docker.io/v1/

  7. type: kubernetes.io/basic-auth

  8. data:

  9. # 'echo -n "username" | base64'

  10. username: dXNlcm5hbWUK

  11. # 'echo -n "password" | base64'

  12. password: cGFzc3dvcmQK

Example 3-2. kubectl apply




  
  1. kubectl apply -f knative-build-demo/secret.yaml

首先要注意的是, usernamepassword 在传递给 Kubernetes 时都是 base64 编码的。还注意到,使用 basic-auth 根据 Docker Hub 进行身份验证,这意味着将使用用户名和密码进行身份验证,而不是类似于 access token(访问令牌)的东西。此外,Knative 还附带了开箱即用的 ssh-auth,这允许使用 SSH 私钥从私有 Git 存储库中拉取代码。

除了将 Secret 命名为 dockerhub-account 之外,还对 Secret 进行了注解。Annotation(注解)是说明连接到特定主机时使用哪些凭据的一种方式。在 Example 3-3 中,定义了连接到 Docker Hub 时使用的基于身份的验证凭证集。

我的凭据安全吗?

一旦创建了名为 dockerhub-account 的 Secret,接下来必须创建要运行应用程序的 Service Account ,以便它能够访问 Kubernetes 中的凭据。配置很简单,如 Example 3-3 所示。

Example 3-3. knative-build-demo/serviceaccount.yaml




  
  1. apiVersion: v1

  2. kind: ServiceAccount

  3. metadata:

  4. name: build-bot

  5. secrets:

  6. - name: dockerhub-account

示例中创建了一个名为 build-bot 的 ServiceAccount ,允许它访问 dockerhub-accountSecret 。在示例中当推送容器镜像时,Knative 使用这些凭证对 Docker Hub 进行身份验证。

The Build Resource(构建资源)

首先从 Hello World 应用程序开始。这是一个简单的 Go 应用程序,它监听端口8080并以 “Hello from Knative!” 作为 HTTP GET 请求的回应。代码如 Example 3-4 所示。

Example 3-4. knative-helloworld/app.go




  
  1. package main


  2. import (

  3. "fmt"

  4. "log"

  5. "net/http"

  6. )


  7. func handlePost(rw http.ResponseWriter, req *http.Request) {

  8. fmt.Fprintf(rw, "%s", "Hello from Knative!")

  9. }


  10. func main() {

  11. log.Print("Starting server on port 8080...")

  12. http.HandleFunc("/", handlePost)

  13. log.Fatal(http.ListenAndServe(":8080", nil))

  14. }

然后编写一个 Dockerfile 来构建代码和容器,如 Example 3-5 所示。

Example 3-5. knative-helloworld/Dockerfle




  
  1. FROM golang


  2. ADD . /knative-build-demo

  3. WORKDIR /knative-build-demo


  4. RUN go build


  5. ENTRYPOINT ./knative-build-demo

  6. EXPOSE 8080

在前面的第2章中,你已经在本地构建了容器并手动将其推送到容器镜像库。然而,Knative 为在 Kubernetes 集群中使用 Build 来完成这些步骤提供了一种更好的方式。与 Configuration (配置)和 Route(路由)一样,Build 也可以简单地作为 Kubernetes 自定义资源(CRD)来通过 YAML 定义的方式实现。在深入研究每个组件之前,先来看一看 Example 3-6 ,看看 Build 的配置是什么样的。

Example 3-6. knative-build-demo/service.yaml




  
  1. apiVersion: serving.knative.dev/v1alpha1

  2. kind: Service

  3. metadata:

  4. name: knative-build-demo

  5. namespace: default

  6. spec:

  7. runLatest:

  8. configuration:

  9. build:

  10. serviceAccountName: build-bot

  11. source:

  12. git:

  13. url: https://github.com/gswk/knative-helloworld.git

  14. revision: master

  15. template:

  16. name: kaniko

  17. arguments:

  18. - name: IMAGE

  19. value: docker.io/gswk/knative-build-demo:latest

  20. revisionTemplate:

  21. spec:

  22. container:

  23. image: docker.io/gswk/knative-build-demo:latest

在构建步骤之前,你还会看到定义源代码位置的源代码部分。目前,Knative 发布了三个代码源选项:

  • git:Git 仓库,可以选择使用参数来定义分支、标记或提交 SHA 。

  • gcs:位于谷歌云存储中的存档文件。

  • 自定义:任意容器镜像仓库。这允许用户编写自己的源代码,只要将源代码放在 /work space 目录中即可。

只需要安装一个额外的组件,即 Build Template(构建模板)。将会在 “Build template” 一节中向你更深入地介绍这些内容,但是现在,先将继续使用在 YAML 中定义的方式,在本例中是 Kaniko Build Template 如 Example 3-7 所示。

Example 3-7. Install the Kaniko Build Template




  
  1. kubectl apply -f https://

  2. raw.githubusercontent.com/knative/build-templates/master/kaniko/kaniko.yaml

通过应用模板,可以像在 Serving 示例中那样部署服务,配置如 Example 3-8 所示。

Example 3-8. Deploy our application




  
  1. kubectl apply -f knative-build-demo/service.yaml

然后,该构建将运行以下步骤:

  1. 从 gswk/knative-helloworld 的 GitHub repo 中拉取代码。

  2. 在 repo 中使用 Kaniko Build Template (下一节将详细描述)。

  3. 使用前面设置的 “build-bot” Service Account 将容器推送到 gswk/knative-build-demo 上的 Docker Hub。

  4. 使用新构建的容器部署应用程序。

Build Template(构建模板)

在 Example 3-6 中,使用了一个 Build Template ,但从未真正解释过 Build Template 是什么或它做什么。简单来说,Build Template 是可共享的、封装的、参数化的构建步骤集合。目前,Knative 已经支持多个 Build Template ,包括:

  • Kaniko

  • Jib

  • Buildpack

虽然这并不是可用模板的完整列表,但是可以轻松地集成 Knative 社区开发的新模板。安装 Build Template 和应用 YAML 文件安装 Service(服务)、Route(路由)或 Build configuration(构建配置)一样简单:




  
  1. kubectl apply -f https://raw.githubusercontent.com/knative/

  2. build-templates/master/kaniko/kaniko.yaml

然后可以像其他configura配置一样应用 Example 3-6 来部署应用程序,同时向它发送请求,就像在第2章中所做的那样:




  
  1. kubectl apply -f knative-build-demo/service.yml


  2. $ curl -H "Host: knative-build-demo.default.example.com"

  3. http://$KNATIVE_INGRESS

在 Example 3-9 中继续使用 Kaniko 作为参考来进一步观察 Build Template 。

Example 3-9. https://github.com/knative/build-templates/blob/master/kaniko/kaniko.yaml




  
  1. apiVersion: build.knative.dev/v1alpha1

  2. kind: BuildTemplate

  3. metadata:

  4. name: kaniko

  5. spec:

  6. parameters:

  7. - name: IMAGE

  8. description: The name of the image to push

  9. - name: DOCKERFILE

  10. description: Path to the Dockerfile to build.

  11. default: /workspace/Dockerfile

  12. steps:

  13. - name: build-and-push

  14. image: gcr.io/kaniko-project/executor

  15. args:

  16. - --dockerfile=${DOCKERFILE}

  17. - --destination=${IMAGE}

Build Template 的 steps 部分具有与 Build 完全相同的语法,只是使用命名变量进行模板化。实际上,除了用变量替换路径之外, steps 部分看起来非常类似于 Example 3-6 的模板部分。parameters 部分在 Build Template 所期望的参数周围放置了一些结构。Kaniko Build Template 需要一个定义在何处推送容器镜像的 IMAGE 参数,但是有一个可选的 DOCKERFILE 参数,如果没有定义该参数,则提供一个默认值。

结论

Knative 中的 Build 在部署应用程序时删除了许多手动步骤。此外,Build Template 提供了一些构建代码和删除手动管理组件数量的好方法。随着时间的推移,可能会有越来越多的 Build Template 被构建并与 Knative 社区共享,这可能是最值得关注的事情之一。

我们已经花了很多时间来构建和运行应用程序,但是 serverless 的最大承诺之一是,它可以使您的服务轻松地连接到事件源。在下一章中,将研究 Knative 的 Eventing(事件)组件以及开箱即用的所有可用事件源。

点击阅读原文跳转到 Web 浏览可以查看文中链接。

相关阅读推荐

Knative:重新定义Serverless

Google 开源的 Serverless 平台 knative 简介

Knative:精简代码之道

基于Kubernetes和Istio的Serverless框架Knative解析之Autoscaler

Knative 入门系列3:Build 介绍-LMLPHP

加入 ServiceMesher 社区

本文分享自微信公众号 - 伪架构师(fake-architect)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

04-07 15:25