OpenShift 4 Hands-on Lab (5) - 用Build、Builder Trigger、Webhook构建和更新镜像

59 篇文章 2 订阅
36 篇文章 0 订阅

OpenShift 4.x HOL教程汇总
说明:本文已经在OpenShift 4.8环境中验证

构建(Build)镜像的相关概念

运行在OpenShift上应用最终必须是以容器的形式运行。在传统方式中,应用容器镜像必须由用户配置Dockerfile,然后运行docker build后才能得到。为了简化这种基于Dockerfile构建镜像的过程,OpenShift提出了构建(即Build)的概念,用它和相关对象来定义、管理镜像构建。这其中就包括非常易于使用的Source-2-Image(简称S2I)的工具,它可以根据最佳实践,直接从应用源码构建出应用容器镜像,因此S2I功能成为OpenShift优于Kubernetes的一大功能。

为了运行构建过程和管理构建,OpenShift使用了两种内部对象:BuildConfig和Build。

BuildConfig

BuildConfig是用来定义构建策略的对象,即定义做什么以及怎么做。BuildConfig支持以下四种构建策略:

  1. Dockerfile - 即直接使用Dockerfile构建出镜像。
  2. S2I - 使用S2I工具从应用源码或应用包构建出镜像。S2I的基础镜像一般也称为Builder Image,OpenShift为目前主流的开发语言(例如Java、PHP、GO、NodeJS、Python、Ruby、HTML等)都提供了对应的Builder Image。S2I会根据要部署应用源码的特点自动找到对应的Builder Image,然后将其和应用源码构建成目标容器镜像。
  3. Pipeline - 使用Jenkins或Tekon(Kubernetes原生的CI/CD功能,在OpenShift 4已经是默认CI/CD环境)的Pipeline构建出镜像。
  4. Custom - 可以定义特定的Builder Image,而不是用缺省的Builder Image。
    在OpenShift中除了可以使用YAML定义BuildConfig外还可以使用"oc new-build"命令创建一个构建的配置。

Build

还记得我们在《OpenShift 4 Hands-on Lab (1) - 部署应用》中的“部署应用代码”一节中,在使用S2I命令后用查看build的日志么?Build是用来记录每次构建运行情况的对象,每运行一次构建,OpenShift都会生成一个Build对象与之对应。在OpenShift中用以下命令可以对Build过程进行操作:

  1. oc start-build:启动一次构建过程。
  2. oc cancel-build:暂时停止一个构建运行。
    OpenShift是在一个专门的Pod中运行构建过程的。当构建过程完成后,该Pod即变成Completed的状态。其实,当我们查看Build日志的时候,看的就是这个Pod的日志。

Builder Image

运行一次构建过程的输入是BuildConfig和原始的基础镜像(即Builder Image),构建过程的输出是结果镜像。OpenShift缺省为主要的语言开发的应用提供了Builder Image,同时用户还可根据需要定制自己的Builder Image。

Build Trigger和Build Chain

我们除了可以使用上述命令手动触发运行Build外,Build还支持基于事件自动触发构建过程。OpenShift支持以下三种构建触发器(Build Trigger):

  1. Webhook:将构建对应的Webhook地址注册到Code Repository上,例如最常用的Github。当Github上的代码发生变化后,Github可以使用Webhook从远程触发启动一次构建过程。
  2. Builder Image变化:当一个Builder Image发生变化后,OpenShift可以触发构建过程,以便更新所有依赖这个Builder Image的镜像。
  3. BuildConfig:当BuildConfig被创建后,OpenShift自动触发一次构建过程,从而完成S2I过程。

在OpenShift中,由Build Trigger实现的当基础镜像变化后自动触发构建依赖它的镜像,于是在这两个镜像之间就形成了Build Chain(构建链)的关系。

触发Build,创建或更新镜像

由于在Pipeline中除了能实现Build外还可实现其它各种CI/CD功能,因此我们放在下面章节单独Pipeline介绍,而在本节我们先介绍如何配置Webhook和Build Trigger。

基于Webhook的Build Trigger

在开始之前需要确保在Github上有一个账户“MY_GITHUB”。

  1. 将https://github.com/liuxiaoyu-git/php-helloworld复制到自己的Github账号中。
  2. 在OpenShift中新建一个项目webhook-USER-ID。
$ oc new-project USER-ID-webhook
  1. 执行以下命令,创建基于PHP的php-helloworld应用
$ oc new-app php~https://github.com/MY_GITHUB/php-helloworld -n USER-ID-webhook
  1. 查看buildconifg,找到最下面,确认基于该buildconfig中只有一个build,即php-helloworld-1。然后复制“Webhook GitHub”的URL后面地址,我们把这个地址称为“WEBHOOK_URL”。
$ oc describe bc/php-helloworld -n USER-ID-webhook
Name:           php-helloworld
Namespace:      user-1-webhook
Created:        38 seconds ago
Labels:         app=php-helloworld
                app.kubernetes.io/component=php-helloworld
                app.kubernetes.io/instance=php-helloworld
Annotations:    openshift.io/generated-by=OpenShiftNewApp
Latest Version: 1
 
Strategy:       Source
URL:            https://github.com/liuxiaoyu-git/php-helloworld
From Image:     ImageStreamTag openshift/php:7.2
Output to:      ImageStreamTag php-helloworld:latest
 
Build Run Policy:       Serial
Triggered by:           Config, ImageChange
Webhook GitHub:
        URL:    		https://api.cluster-beijing-4af7.beijing-4af7.example.opentlc.com:6443/apis/build.openshift.io/v1/namespaces/user-1-webhook/buildconfigs/php-helloworld/webhooks/<secret>/github
Webhook Generic:
        URL:            https://api.cluster-beijing-4af7.beijing-4af7.example.opentlc.com:6443/apis/build.openshift.io/v1/namespaces/user-1-webhook/buildconfigs/php-helloworld/webhooks/<secret>/generic
        AllowEnv:       false
Builds History Limit:
        Successful:     5
        Failed:         5
 
Build                   Status          Duration                Creation Time
php-helloworld-1        running         running for 38s         2020-02-11 15:36:59 +0000 UTC
 
Events: <none>
  1. 执行命令查看buildconfig的配置,找到“triggers”部分中的“github”,然后用“secret”后面的字符串替换“WEBHOOK_URL”字符串中的“<secret>”区域。
$ oc get bc/php-helloworld -o yaml -n USER-ID-webhook
。。。
  triggers:
  -- github:
      secret: bhZIQnufyQZ3246OhM9Q
    type: GitHub
  -- generic:
      secret: -4UndTQhFrASVoqgNNUt
    type: Generic
  -- type: ConfigChange
  -- imageChange:
      lastTriggeredImageID: image-registry.openshift-image-registry.svc:5000/openshift/php@sha256:a5aaaae5baf98cb674ac2352429e0450591b45d3674e44c516612a9ee67282d5
    type: ImageChange
。。。
  1. 执行命令查看build,确认php-helloworld-1的“STATUS”是已经“Complate”状态。
$ oc get build -n USER-ID-webhook
NAME               TYPE     FROM          STATUS     STARTED             DURATION
php-helloworld-1   Source   Git@8cb7578   Complete   About an hour ago   1m49s
  1. 执行命令查看pod,可以看到除了一个正在运行应用的Pod外,专门负责Build的Pod(php-helloworld-1-build)已经是Completed状态。
$ oc get pod -n USER-ID-webhook
NAME                             READY   STATUS      RESTARTS   AGE
php-helloworld-1-build           0/1     Completed   0          90s
php-helloworld-967b5c6c6-z4hjs   1/1     Running     0          45s
  1. 生成route,然后访问页面。
$ oc expose svc/php-helloworld -n USER-ID-webhook -n USER-ID-webhook
route.route.openshift.io/php-helloworld exposed
$ curl http://$(oc get route php-helloworld -n USER-ID-webhook -o template='{{.spec.host}}')
Hello World !!! PHP version is 7.3.20
  1. 进入github的php-helloworld的repository,点击“Setting”标签。
  2. 在设置中进入Webhooks,然后点击“Add webhook”按钮。将WEBHOOK_URL复制到Payload URL中,并选择Content type为application/json,然后将SSL verification选为Disable,最后点击Add webhook按钮。可以看到这个webhook显示为下图“绿色”状态。
    在这里插入图片描述
  3. 在github上修改php-helloworld的index.php页面,将“Hello World”改为“Hello OpenShift”,然后提交修改。提交后,github会通过webhook在OpenShift上触发一次新的build运行。
  4. 执行以下命令,确认php-helloworld-2的“STATUS”为“Complete”状态。
$ oc get build -n USER-ID-webhook
NAME               TYPE     FROM          STATUS     STARTED             DURATION
php-helloworld-1   Source   Git@8cb7578   Complete   About an hour ago   1m32s
php-helloworld-2   Source   Git@e78c498   Complete   About an hour ago	 1m18s
  1. 再次访问route,确认页面已经更新。
$ curl http://$(oc get route php-helloworld -n USER-ID-webhook -o template='{{.spec.host}}')
Hello OpenShift !!! PHP version is 7.3.20
  1. 查看名为php-helloworld-2的build,确认“Build trigger cause”是“GitHub WebHook”。
$ oc describe build/php-helloworld-2 -n USER-ID-webhook
。。
Build trigger cause:    GitHub WebHook
Commit:                 e78c498 (change)
Author/Committer:       liuxiaoyu-git / GitHub
。。。

利用Build Trigger自动更新Image

设想你的容器镜像是多层的(如下图),其实每个相邻的下层镜像都是上层镜像的基础镜像(即Builder Image)。那么当下层的镜像发生更新后,依赖它的上层镜像需要重新构建才能使得整个镜像是最新状态,这种自动化触发构建的过程需要使用OpenShift中Builder Image类型的Build Trigger实现。
在这里插入图片描述

  1. 新建一个项目,然后执行以下命令,基于一个Docker新建一个Build。注意:我们可以从返回结果看到当运行new-build命令后,OpenShift会自动创建BuildConfig,然后在以此运行一次构建过程。在构建过程中,OpenShift先根据https://github.com/liuxiaoyu-git/welcome/blob/master/sh/Dockerfile识别出此次构建的Buider Image是名为busybox的镜像,通过“Every time “busybox:latest” changes a new build will be triggered”的说明我们可以知道OpenShift会自动在构建的Builder Image和目标镜像之间建立起Build Trigger以实现自动更新。另外,OpenShift还会创建Buider Image(即busybox)和构建的输出镜像(即ops)对应的ImageStream对象。
$ oc new-project USER-ID-build-trigger
$ oc new-build --name=ops https://github.com/liuxiaoyu-git/welcome --context-dir=sh -n USER-ID-build-trigger
--> Found container image 6d5fcfe (6 weeks old) from docker.io for "docker.io/busybox"
 
    * An image stream tag will be created as "busybox:latest" that will track the source image
    * A Docker build using source code from https://github.com/liuxiaoyu-git/welcome will be created
      * The resulting image will be pushed to image stream tag "ops:latest"
      * Every time "busybox:latest" changes a new build will be triggered
 
--> Creating resources with label build=ops ...
    imagestream.image.openshift.io "busybox" created
    imagestream.image.openshift.io "ops" created
    buildconfig.build.openshift.io "ops" created
--> Success 
  1. 执行命令查看由Builder Trigger形成的和名为busybox的ImageStream相关的build-chain(构建链)。下面说明当"busybox:latest"镜像变化后会触发“bc/ops”来更新镜像“ops:latest”。
$ oc adm build-chain busybox -n USER-ID-build-trigger
istag/busybox:latest
        bc/ops
                istag/ops:latest
  1. 执行以下命令基于另一个Docker新建另一个名为foo的Build。
$ oc new-build --name=foo https://github.com/liuxiaoyu-git/welcome --context-dir=foo -n USER-ID-build-trigger
  1. 查看BuildConfig和Build的情况,当前运行了2个构建,它们分别是根据对应的BuildConfig运行的。
$ oc get bc -n USER-ID-build-trigger
NAME   TYPE     FROM   LATEST
foo    Docker   Git    1
ops    Docker   Git    1
$ oc get build -n USER-ID-build-trigger
NAME    TYPE     FROM          STATUS     STARTED              DURATION
ops-1   Docker   Git@359ea3d   Complete   2 minutes ago        27s
foo-1   Docker   Git@359ea3d   Complete   About a minute ago   23s
  1. 执行命令查看由Builder Trigger形成的和名为busybox的ImageStream相关的build-chain。和上一次查看相比,在“ops:latest”镜像和“foo:latest”镜像之间又形成了新的build-chain关系。
$ oc adm build-chain busybox -n USER-ID-build-trigger
istag/busybox:latest
        bc/ops
                istag/ops:latest
                        bc/foo
                                istag/foo:latest
  1. 执行以下命令分别查看和名为ops、foo的ImageStream相关的build-chain。
$ oc adm build-chain ops -n USER-ID-build-trigger
istag/ops:latest
        bc/foo
                istag/foo:latest
$ oc adm build-chain foo -n USER-ID-build-trigger
istag/foo:latest
  1. 查看BuildConfig中的Trigger。可以看到每个BuildConfig包括4种Trigger,其中目前只有“TYPE”为“image”的有对应的Trigger。
$ oc set triggers bc/foo -n USER-ID-build-trigger
NAME              TYPE     VALUE       AUTO
buildconfigs/foo  config               true
buildconfigs/foo  image    ops:latest  true
buildconfigs/foo  webhook  <secret>
buildconfigs/foo  github   <secret>
$ oc set triggers bc/ops -n USER-ID-build-trigger
NAME              TYPE     VALUE           AUTO
buildconfigs/ops  config                   true
buildconfigs/ops  image    busybox:latest  true
buildconfigs/ops  webhook  <secret>
buildconfigs/ops  github   <secret>
  1. 针对ops,再运行一次新的build。
$ oc start-build bc/ops -n USER-ID-build-trigger
build.build.openshift.io/ops-2 started
  1. 执行以下命令会发现有4个构建的记录,这是因为在ops-2完成构建后会根据build-chain自动触发执行foo-2的构建。
$ watch oc get build -n USER-ID-build-trigger
NAME    TYPE     FROM          STATUS     STARTED          DURATION
ops-1   Docker   Git@359ea3d   Complete   12 minutes ago   27s
foo-1   Docker   Git@359ea3d   Complete   11 minutes ago   23s
ops-2   Docker   Git@359ea3d   Complete   4 minutes ago    27s
foo-2   Docker   Git@359ea3d   Complete   3 minutes ago    23s
  1. 执行以下命令,删除build-chain在foo和ops之间的Trigger。
$ oc set triggers bc/foo --from-image=ops:latest --remove -n USER-ID-build-trigger
buildconfig.build.openshift.io/foo triggers updated
  1. 再次查看Build Chain,发现ops:latest后不再有foo的BuildConfig过程
$ oc adm build-chain busybox -n USER-ID-build-trigger
istag/busybox:latest
        bc/ops
                istag/ops:latest
  1. 再次新运行一次ops的build,然后查看确认只有5个build记录。这是因为我们在上一步删除foo和ops之间的Build Trigger,因此新构建ops-3不会自动触发foo-3的构建了。
$ oc start-build bc/ops -n USER-ID-build-trigger
build.build.openshift.io/ops-3 started
$ watch oc get build -n USER-ID-build-trigger
NAME    TYPE     FROM          STATUS     STARTED          DURATION
ops-1   Docker   Git@359ea3d   Complete   29 minutes ago   27s
foo-1   Docker   Git@359ea3d   Complete   27 minutes ago   23s
ops-2   Docker   Git@359ea3d   Complete   20 minutes ago   27s
foo-2   Docker   Git@359ea3d   Complete   20 minutes ago   23s
ops-3   Docker   Git@359ea3d   Complete   47 seconds ago   27s
  1. 执行以下命令,重新恢复foo和ops之间的Build Chain。
$ oc set triggers bc/foo --from-image=ops:latest --remove=false -n USER-ID-build-trigger
buildconfig.build.openshift.io/foo triggers updated
  1. 再次新运行一次ops的build,然后查看确认有8个build记录。不但有ops-4和foo-4,还有上面因为Build Chain断掉后缺少的foo-3。
$ oc start-build bc/ops -n USER-ID-build-trigger
build.build.openshift.io/ops-4 started
$ watch oc get build -n USER-ID-build-trigger
NAME    TYPE     FROM          STATUS     STARTED              DURATION
ops-1   Docker   Git@359ea3d   Complete   43 minutes ago       27s
foo-1   Docker   Git@359ea3d   Complete   42 minutes ago       23s
ops-2   Docker   Git@359ea3d   Complete   35 minutes ago       27s
foo-2   Docker   Git@359ea3d   Complete   34 minutes ago       23s
ops-3   Docker   Git@359ea3d   Complete   15 minutes ago       27s
foo-3   Docker   Git@359ea3d   Complete   9 minutes ago        19s
ops-4   Docker   Git@359ea3d   Complete   About a minute ago   28s
foo-4   Docker   Git@359ea3d   Complete   51 seconds ago       24s
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值