Knative 实践:从源代码到服务的自动化部署

Stella981
• 阅读 456

通过之前的文章,相信大家已经熟悉了 Serving、Eventing 以及 Tekton。那么在实际使用中,我们往往会遇到一些复杂的场景,这时候就需要各个组件之间进行协作处理。例如我们提交源代码之后是否直接可以部署服务到 K8s 中? 这个场景对于用户来说很有吸引力。那么现在就让我们来看一下,在 Knative 中如何实现从代码到服务?

场景介绍

现在的场景是这样的:代码构建->事件驱动->服务部署。那么对应到 Knative 中,需要 Eventing、Tekton 和 Serving 一起协作来实现这个场景。

Knative 实践:从源代码到服务的自动化部署

准备

  • 部署 Knative。参考在阿里云容器服务上部署 Knative
  • 部署 Tekton。通过阿里云容器服务控制台,应用目录选择 ack-tekton-pipelines 进行安装部署 Tekton;

Knative 实践:从源代码到服务的自动化部署

  • 部署 GitHub 事件源。阿里云容器服务控制台 Knative 组件管理中选择安装 GitHub 组件,如图所示:

Knative 实践:从源代码到服务的自动化部署

从源代码到服务

Knative 实践:从源代码到服务的自动化部署

  • 修改分支代码,提交 merge request 合并到 master 分支;

  • Eventing 监听到 merge 事件,发送给 GitHub Trigger 服务;

  • GitHub Trigger 服务接收事件, 通过 Tekton 执行代码构建和并通过 deployer 执行服务部署。GitHub  Trigger 的作用就是解析 GitHub 事件的详细信息,然后转换成 Tekton 资源并且提交到 Kubernetes 中执行 Pipeline。项目地址:https://github.com/knative-sample/tekton-serving。 这个项目中有两个部分: Trigger 和 Deployer,Trigger 的作用是解析 github 事件, 并提交 PipelineRun 定义。Deployer 的作用就是更新 Service 的镜像信息。github source pull_request body 的关键内容如下:

    { "action": "closed", ... ... "merge_commit_sha": "f37cb28b1777a28cd34ea1f8df1b7ebcc6c16397", ... ... "base": { "ref": "master", ... ... }, ... ... }

  • action 表示当前的 pull request 事件细节。创建 pull request 时 action  是 opened ,关闭 pull request 时 action 就是 closed;

  • merge_commit_sha 可以获得 merge commit 的 id;

  • base.ref 可以获得 merge request 发生在哪个分支上。

本文涉及到的代码与资源文件地址:

接下来我们开始一步步搞起。

部署 Tekton 服务

我们看一下创建代码构建 Task 和 部署服务Task。

代码构建Task:

apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
  name: source-to-image
spec:
  inputs:
    resources:
      - name: git-source
        type: git
    params:
      - name: pathToContext
        description: The path to the build context, used by Kaniko - within the workspace
        default: .
      - name: pathToDockerFile
        description: The path to the dockerfile to build (relative to the context)
        default: Dockerfile
      - name: imageUrl
        description: Url of image repository
      - name: imageTag
        description: Tag to apply to the built image
        default: "latest"
  steps:
    - name: build-and-push
      image: registry.cn-hangzhou.aliyuncs.com/knative-sample/kaniko-project-executor:v0.10.0
      command:
        - /kaniko/executor
      args:
        - --dockerfile=${inputs.params.pathToDockerFile}
        - --destination=${inputs.params.imageUrl}:${inputs.params.imageTag}
        - --context=/workspace/git-source/${inputs.params.pathToContext}
      env:
      - name: DOCKER_CONFIG
        value: /builder/home/.docker

这里通过 deployer-deployer 执行服务部署,部署服务Task:

apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
  name: image-to-deploy
spec:
  inputs:
    resources:
      - name: git-source
        type: git
    params:
      - name: pathToYamlFile
        description: The path to the yaml file to deploy within the git source
      - name: imageUrl
        description: Url of image repository
      - name: imageTag
        description: Tag of the images to be used.
        default: "latest"
  steps:
    - name: deploy
      image: "registry.cn-hangzhou.aliyuncs.com/knative-sample/deployer-deployer:7620096e"
      args:
        - "--namespace=default"
        - "--serivce-name=hello-sample"
        - "--image=${inputs.params.imageUrl}:${inputs.params.imageTag}"

另外需要设置一下镜像仓库的 secret:

apiVersion: v1
kind: Secret
metadata:
  name: ack-cr-push-secret
  annotations:
    tekton.dev/docker-0: https://registry.cn-hangzhou.aliyuncs.com
type: kubernetes.io/basic-auth
stringData:
  username: <cleartext non-encoded>
  password: <cleartext non-encoded>

执行如下命令:

# Create Pipeline
kubectl apply -f tekton/pipeline/build-and-deploy-pipeline.yaml

# Create PipelineResource
kubectl apply -f tekton/resources/picalc-git.yaml

# Create image secret
kubectl apply -f tekton/image-secret.yaml

# Create task: soruce to image
kubectl apply -f tekton/tasks/source-to-image.yaml

# Create task: deploy the image to cluster
kubectl apply -f tekton/tasks/image-to-deployer.yaml

部署 Knative Serving 服务

先创建 deployer-github-trigger 服务,用于接收 GitHub 事件,并触发 Tekton Pipeline 构建任务。其中 service.yaml 如下:

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: deployer-github-trigger
spec:
  template:
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/deployer-trigger:tekton-v1_74647e3a-20190806093544
        args:
          - --trigger-config=/app/config/deployer-trigger.yaml
        volumeMounts:
        - name: config-volume 
          mountPath: /app/config
      serviceAccountName: tekton
      volumes:
        - name: config-volume 
          configMap:
            name: deployer-trigger-config
            items:
              - key: deployer-trigger.yaml
                path: deployer-trigger.yaml

这里通过 ConfigMap deployer-trigger-config, 设置 PipelineRun。deployer-github-trigger 能根据 github Event 信息获取代码仓库的最新信息但不能自动决定 PipelineRun 的定义,所以需要指定一个 PipelineRun 的模板。Trigger 通过 --trigger-config 参数指定 PipelineRun 的模板, 模板内容如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: deployer-trigger-config
  namespace: default
data:
  "deployer-trigger.yaml": |-
    apiVersion: tekton.dev/v1alpha1
    kind: PipelineRun
    metadata:
      name: tekton-kn-sample
    spec:
      pipelineRef:
        name: build-and-deploy-pipeline
      resources:
        - name: git-source
          resourceRef:
            name: eventing-tekton-serving-git
      params:
        - name: pathToContext
          value: "src"
        - name: pathToYamlFile
          value: ""
        - name: imageUrl
          value: "registry.cn-hangzhou.aliyuncs.com/knative-sample/eventing-tekton-serving-helloworld"
        - name: imageTag
          value: "1.0"
      trigger:
        type: manual
      serviceAccount: pipeline-account

执行命令如下:

# Create clusterrole
kubectl apply -f serving/clusterrole.yaml

# Create clusterrolebinding
kubectl apply -f serving/clusterrolebinding.yaml

# Create serviceaccount
kubectl apply -f serving/serviceaccount.yaml

# Create configmap
kubectl apply -f serving/configmap.yaml

# Create service
kubectl apply -f serving/service.yaml

配置 Eventing 中 GitHub 事件源

代码 merge request 会触发对应的事件,通过 Knative Eventing 获取到事件之后直接将事件发送给 deployer-github-trigger 服务。

创建 GitHub Token

创建 Personal access tokens, 用于访问 GitHub API。另外你的代码将使用它验证来自 github 的传入 webhook(secret token)。token 的名称可以任意设置。Source 需要开启 repo:public_repoadmin:repo_hook , 以便通过公共仓库触发 Event 事件,并为这些公共仓库创建 webhooks 。

下面是设置一个 "GitHubSource Sample" token 的示例。

Knative 实践:从源代码到服务的自动化部署

更新 githubsecret.yaml 内容。如果生成的是 personal_access_token_value token, 则需要设置 secretToken 如下:

apiVersion: v1
kind: Secret
metadata:
  name: githubsecret
type: Opaque
stringData:
  accessToken: personal_access_token_value
  secretToken: asdfasfdsaf

执行命令使其生效:

kubectl  apply -f eventing/githubsecret.yaml

创建 GitHub 事件源

为了接收 GitHub 产生的事件, 需要创建 GitHubSource 用于接收事件。

apiVersion: sources.eventing.knative.dev/v1alpha1
kind: GitHubSource
metadata:
  name: deployer-github-sources
spec:
  eventTypes:
  - pull_request
  ownerAndRepository: knative-sample/eventing-tekton-serving
  accessToken:
    secretKeyRef:
      name: githubsecret
      key: accessToken
  secretToken:
    secretKeyRef:
      name: githubsecret
      key: secretToken
  sink:
    apiVersion: serving.knative.dev/v1alpha1
    kind: Service
    name: deployer-github-trigger

关键字段解释:

  • 指定 github 仓库:ownerAndRepository: knative-sample/eventing-tekton-serving 表示监听 https://github.com/knative-sample/eventing-tekton-serving 仓库的事件;
  • 事件类型:eventTypes 是一个数组,这个数组中可以配置 github 事件列表;
  • 认证信息:accessToken 和 secretToken 是通过 secret 引用 github 仓库的认证信息;
  • 目标 Service:sink 字段表示接收到的事件需要发送到哪个 Service , 这里是直接发送到前面定义的 deployer-github-trigger 服务。

执行 kubectl 命令:

kubectl  apply -f eventing/github-source.yaml

如果集群中开启了 Istio 注入,需要开启 egress 访问:

kubectl  apply -f eventing/egress.yaml

deployer-github-sources 提交到 Kubernetes 之后,github source controller 会在 http://github.com/knative-sample/eventing-tekton-serving 下创建一个 webhook,回调地址就是我们的 github_receive_adapter 服务公网地址。

http://github.com/knative-sample/eventing-tekton-serving 有 pull request 发生时就会自动触发 deployer-github-trigger 的执行,deployer-github-trigger 首先编译镜像,然后更新 hello-sample service 镜像,从而完成自动化发布。

代码->镜像->服务

下面我们演示一下从代码到服务,自动化构建和部署过程:

Knative 实践:从源代码到服务的自动化部署

服务访问体验地址:http://hello-sample.default.serverless.kuberun.com

结论

从代码到服务,通过上面的示例,Knative 是否给你带来了不一样的体验?希望通过 Knative 给你带来更轻松的代码构建和服务部署,让你更专注于业务本身。欢迎对 Knative 有兴趣的一起交流。<

欢迎加入 Knative 交流群

Knative 实践:从源代码到服务的自动化部署

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Souleigh ✨ Souleigh ✨
3年前
前端性能优化 - 雅虎军规
无论是在工作中,还是在面试中,web前端性能的优化都是很重要的,那么我们进行优化需要从哪些方面入手呢?可以遵循雅虎的前端优化35条军规,这样对于优化有一个比较清晰的方向.35条军规1.尽量减少HTTP请求个数——须权衡2.使用CDN(内容分发网络)3.为文件头指定Expires或CacheControl,使内容具有缓存性。4.避免空的
Easter79 Easter79
2年前
SpringBoot自定义序列化的使用方式
场景及需求:项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串。例如:\    {        "id":1,        "name":null    },    {        "id":2,        "name":"x
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
2年前
Knative 应用在阿里云容器服务上的最佳实践
作者|元毅阿里云智能事业群高级开发工程师相信通过前面几个章节的内容,大家对Knative有了初步的体感,那么在云原生时代如何在云上玩转Knative?本篇内容就给你带来了 Knative应用在阿里云容器服务上的最佳实践。何为最佳实践,就是按照生产可用的方式部署服务,提供服务监控告警以及链路追踪。我们按照如下3个部分内容进行:
Wesley13 Wesley13
2年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Stella981 Stella981
2年前
SpringBoot自定义序列化的使用方式
场景及需求:项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串。例如:\    {        "id":1,        "name":null    },    {        "id":2,        "name":"x
Wesley13 Wesley13
2年前
Java多线程导致的的一个事物性问题
业务场景我们现在有一个类似于文件上传的功能,各个子站点接受业务,业务上传文件,各个子站点的文件需要提交到总站点保存,文件是按批次提交到总站点的,也就是说,一个批次下面约有几百个文件。      考虑到白天提交这么多文件会影响到子站点其他系统带宽,我们将分站点的文件提交到总站点这个操作过程独立出来,放到晚上来做,具体时间是晚上7:00到早上7:00。
Python进阶者 Python进阶者
4个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这