okd 安装
在本系列的前三篇文章中,我们探讨了Source-to-Image(S2I)系统的一般要求 ,并准备并测试了专门用于Go(Golang)应用程序的环境。 此S2I构建非常适合本地开发或通过代码管道维护构建器映像,但是如果您可以访问OKD或OpenShift集群(或Minishift ),则可以使用OKD BuildConfigs设置整个工作流程,不仅可以构建和维护构建器映像,还可以使用构建器映像自动创建应用程序映像和后续运行时映像。 这样,可以在下游映像更改时自动重建映像,并且可以触发OKD部署配置以重新部署从这些映像运行的应用程序。
步骤1:在OKD中生成构建器映像
与本地S2I用法一样,第一步是创建构建器映像以构建GoHelloWorld测试应用程序,我们可以重复使用该应用程序来编译其他基于Go的应用程序。 第一步,就像之前一样,将是一个Docker构建,它将从Git存储库中提取Dockerfile和S2I脚本以构建映像。 因此,这些文件必须已提交并在公共Git存储库中可用(或者您可以在本文中使用随附的GitHub存储库 )。
注意: OKD BuildConfigs不需要源Git仓库是公共的。 要使用私有存储库,您必须设置部署密钥并将这些密钥链接到构建器服务帐户。 这并不困难,但是为了简单起见,本练习将使用公共存储库。
为构建器图像创建图像流
BuildConfig将为我们创建一个生成器映像,以编译GoHelloWorld应用程序,但是首先,我们需要一个存储映像的位置。 在OKD中,该位置是图像流。
图像流及其标签就像是相关图像和图像标签的清单或清单。 它用作抽象层,即使图像发生更改,也可以使您引用图像。 将其视为引用特定图像的别名的集合,并且在图像更新时会自动指向新的图像版本。 图像流除了这些别名外什么都没有,仅是有关存储在注册表中的真实图像的元数据。
可以使用oc create imagestream <name>命令创建图像流,也可以使用oc create -f <filename>从YAML文件创建图像流。 无论哪种方式,全新的图像流都是一个小的占位符对象,直到使用手动(谁想手动执行操作?)或使用BuildConfig的图像引用填充它之前,它都是空的。
我们的golang-builder图片流如下所示:
# imageStream-golang-builder.yaml
---
apiVersion
: image.openshift.io/v1
kind
: ImageStream
metadata :
generation
: 1
name
: golang-builder
spec :
lookupPolicy :
local
: false
除了名称和(大多数)空规范外,没有任何其他内容。
注意: lookupPolicy与允许Kubernetes本地组件解析图像流引用有关,因为图像流是OKD本地的,而不是Kubernetes核心的一部分。 本主题不在本文讨论范围之内,但是您可以在OKD的文档“ 使用带有Kubernetes资源的图像流”中阅读有关它如何工作的更多信息。
为构建器图像及其后代创建图像流。
$ oc create
-f imageStream-golangBuilder.yaml
# Check the ImageStream
$ oc get imagestream golang-builder
NAME DOCKER REPO TAGS UPDATED
imagestream.image.openshift.io
/ golang-builder docker-registry.default.svc:
5000
/ golang-builder
/ golang-builder
请注意,新创建的图像流没有标签,并且从未更新过。
为构建器映像创建BuildConfig
在OKD中, BuildConfig描述了如何从特定来源构建容器映像,以及如何生成容器映像。 不要被语言所困扰,就像您可能会说要从Dockerfile构建和重新构建相同的映像一样,但实际上,您已经构建了多个映像,BuildConfig可以构建并重新构建相同的映像,但是实际上,它将创建多个图像。 (突然,图像流的原因变得更加清晰了!)
我们的构建器映像BuildConfig描述了如何构建和重新构建我们的构建器映像。 BuildConfig的核心由四个重要部分组成:
- 构建源
- 建立策略
- 建立输出
- 建立触发器
构建源 (可预测)描述了运行构建的事物的来源。 golang-builder BuildConfig描述的构建将使用我们先前创建的Dockerfile和S2I脚本,并使用Git类型的构建源克隆一个Git存储库以获取进行构建的文件。
source :
type
: Git
git :
ref
: master
uri
: https://github.com/clcollins/golang-s2i.git
生成策略描述了生成将使用生成源中的源文件执行的操作。 该golang建设者BuildConfig模仿我们在以前使用通过使用泊坞窗式构造策略来构建我们的本地制造商形象的泊坞窗构建 。
strategy :
type
: Docker
dockerStrategy
:
{
}
dockerStrategy构建类型告诉OKD从构建源指定的源中包含的Dockerfile构建Docker映像。
构建输出告诉BuildConfig如何处理生成的映像。 在这种情况下,我们指定我们在上面创建的图像流以及要赋予该图像的标签。 与本地构建一样,我们使用golang-builder:1.12对其进行标记,以作为对从父映像继承的Go版本的引用。
output :
to :
kind
: ImageStreamTag
name
: golang-builder:1.12
最后,BuildConfig定义了一组构建触发器 ,即将导致图像自动重建的事件。 对于此BuildConfig,更改BuildConfig配置或更新上游映像(golang:1.12)将触发新的构建。
triggers :
- type
: ConfigChange
- imageChange :
type
: ImageChange
使用GitHub存储库中的构建器映像BuildConfig作为参考(或仅使用该文件),创建BuildConfig YAML文件并使用它来创建BuildConfig。
$ oc create
-f buildConfig-golang-builder.yaml
# Check the BuildConfig
$ oc get
bc golang-builder
NAME TYPE FROM LATEST
golang-builder Docker Git
@ master
1
因为BuildConfig包含了“ ImageChange”触发器,所以它立即开始新的构建。 您可以检查是否使用oc get builds命令创建了构建 。
# Check the Builds
$ oc get builds
NAME TYPE FROM STATUS STARTED DURATION
golang-builder-
1 Docker Git
@ 8eff001 Complete About a minute ago 13s
在构建运行过程中以及完成后,您可以使用oc logs -f <构建名称>查看其日志,并像在本地一样查看Docker构建输出。
$ oc logs
-f golang-builder-
1 -build
Step
1
/
11 : FROM docker.io
/ golang:
1.12
---
> 7ced090ee82e
Step
2
/
11 : LABEL maintainer
"Chris Collins <collins.christopher@gmail.com>"
---
> 7ad989b765e4
Step
3
/
11 : ENV CGO_ENABLED
0 GOOS linux GOCACHE
/ tmp STI_SCRIPTS_PATH
/ usr
/ libexec
/ s2i SOURCE_DIR
/ go
/ src
/ app
---
> 2cee2ce6757d
< ...
>
如果您没有包括任何构建触发器(或没有在正确的位置放置触发器),则构建可能不会自动开始。 您可以使用oc start-build命令手动启动新的构建。
$ oc start-build golang-builder
# Or, if you want to automatically tail the build log
$ oc start-build golang-builder
--follow
构建完成后,将标记结果图像并将其推送到集成图像注册表,并使用新图像的信息更新图像流。 使用oc get imagestream命令检查图像流,以查看新标记是否存在。
$ oc get imagestream golang-builder
NAME DOCKER REPO TAGS UPDATED
golang-builder docker-registry.default.svc:
5000
/ golang-builder
/ golang-builder
1.12
33 seconds ago
步骤2:在OKD中构建应用程序映像
现在,我们已经为OKlang中创建并存储了Golang应用程序的构建器映像,我们可以使用该构建器映像来编译所有Go应用程序。 首先是我们本地构建示例中的示例GoHelloWorld应用程序。 GoHelloWorld是一个简单的Go应用,仅输出Hello World! 当它运行时。
就像在本地示例中使用s2i build命令所做的一样 ,我们可以告诉OKD使用生成器映像和S2I来构建GoHelloWorld的应用程序映像,并从GoHelloWorld GitHub存储库中的源代码编译Go二进制文件。 这可以通过带有sourceStrategy构建的BuildConfig来完成。
为应用程序图像创建图像流
首先,我们需要创建一个图像流来管理BuildConfig创建的图像。 图像流就像golang-builder图像流一样,只是名称不同。 使用oc create is或使用GitHub存储库中的YAML文件创建它。
$ oc create
-f imageStream-goHelloWorld-appimage.yaml
imagestream.image.openshift.io
/ go-hello-world-appimage created
为应用程序映像创建BuildConfig
就像我们对构建器映像BuildConfig所做的一样,此BuildConfig将使用Git source选项从GoHelloWorld存储库克隆我们的源代码。
source :
type
: Git
git :
uri
: https://github.com/clcollins/goHelloWorld.git
该BuildConfig不会使用DockerStrategy构建从Dockerfile创建映像,而是将使用sourceStrategy定义使用S2I构建映像。
strategy :
type
: Source
sourceStrategy :
from :
kind
: ImageStreamTag
name
: golang-builder:1.12
注意sourceStrategy中的from:哈希。 这告诉OKD使用我们先前为S2I构建创建的golang-builder:1.12映像。
BuildConfig将输出到我们创建的新的appimage图像流,并且我们将包括config和image-change触发器,以在有任何更新时自动启动新的构建。
output :
to :
kind
: ImageStreamTag
name
: go-hello-world-appimage:1.0
triggers :
- type
: ConfigChange
- imageChange :
type
: ImageChange
再次创建一个BuildConfig或使用GitHub存储库中的一个。
$ oc create -f buildConfig-goHelloWorld-appimage.yaml
新的构建与golang-builder的构建同时显示,并且由于指定了图像更改触发器,因此该构建将立即开始。
$ oc get builds
NAME TYPE FROM STATUS STARTED DURATION
golang-builder-
1 Docker Git
@ 8eff001 Complete
8 minutes ago 13s
go-hello-world-appimage-
1 Source Git
@ 99699a6 Running
44 seconds ago
如果要查看构建日志,请使用oc logs -f命令。 应用程序图像构建完成后,将其推送到我们指定的图像流,然后创建新的图像流标记。
$ oc get is go-hello-world-appimage
NAME DOCKER REPO TAGS UPDATED
go-hello-world-appimage docker-registry.default.svc:
5000
/ golang-builder
/ go-hello-world-appimage
1.0
10 minutes ago
成功! GoHelloWorld应用程序已从源代码克隆到新映像中,并使用我们的S2I脚本进行了编译和测试。 我们可以按原样使用映像,但是与本地S2I构建一样,我们可以做得更好,并且仅使用新的Go二进制文件创建映像。
步骤3:在OKD中构建运行时映像
现在,已经使用GoHelloWorld应用程序的已编译Go二进制文件创建了应用程序映像,当我们从本地应用程序映像中提取二进制文件并创建仅包含二进制文件的新运行时映像时,我们可以使用链构建这种方式进行模仿。
为运行时图像创建图像流
再次,第一步是为新的运行时图像创建图像流图像。
# Create the ImageStream
$ oc create
-f imageStream-goHelloWorld.yaml
imagestream.image.openshift.io
/ go-hello-world created
# Get the ImageStream
$ oc get imagestream go-hello-world
NAME DOCKER REPO TAGS UPDATED
go-hello-world docker-registry.default.svc:
5000
/ golang-builder
/ go-hello-world
连锁店
链式构建是指使用一个或多个BuildConfig来编译软件或为应用程序组装工件时,这些工件被保存并由后续的BuildConfig使用以生成运行时映像,而无需重新编译代码。
为运行时映像创建BuildConfig
运行时BuildConfig使用DockerStrategy构建从Dockerfile构建映像,这与构建器映像BuildConfig相同。 但是,这次,源不是Git源,而是Dockerfile源。
Dockerfile的来源是什么? 这是一个嵌入式Dockerfile! 我们没有在其中复制包含Dockerfile的存储库并进行构建,而是在BuildConfig中指定了Dockerfile。 这对我们的运行时Dockerfile尤其合适,因为它只有三行。
source :
type
: Dockerfile
dockerfile
: |-
FROM scratch
COPY app /app
ENTRYPOINT
[
"/app"
]
images :
- from :
kind
: ImageStreamTag
name
: go-hello-world-appimage:1.0
paths :
- sourcePath
: /go/src/app/app
destinationDir
:
"."
请注意,上面的Dockerfile源定义中的Dockerfile与本系列的第三篇文章中使用的Dockerfile相同,当我们使用通过S2I save-artifacts脚本提取的二进制文件在本地构建苗条的GoHelloWorld映像时,便使用了该文件。
其他注意事项: 临时文件是Dockerfiles中的保留字。 与其他FROM语句不同,它不定义实际图像,而是该图像的第一层将为空。 它以以下类型定义:DockerImage但没有注册表或组/命名空间/项目字符串。 在此出色的容器最佳实践参考中,了解有关此行为的更多信息。
Dockerfile源的images部分描述了将在构建中使用的工件的源。 在这种情况下,来自先前生成的appimage。 该路径小节介绍从哪里得到的二进制文件(即在/去应用图像/ src目录/ app目录,获取应用程序二进制)和保存位置(即,在构建自身的当前工作目录“ 。” )。 这使COPY应用程序/ app可以从当前工作目录中获取二进制文件,并将其添加到运行时映像中的/ app中。
注意: path是源路径对和目标路径对的数组。 列表中的每个条目都包含一个源和一个目标。 在上面的示例中,只有一个条目,因为只有一个二进制要复制。
然后,使用Docker策略来构建嵌入式Dockerfile。
strategy :
type
: Docker
dockerStrategy
:
{
}
再次将其输出到先前创建的图像流,并包含构建触发器以自动开始新的构建。
output :
to :
kind
: ImageStreamTag
name
: go-hello-world:1.0
triggers :
- type
: ConfigChange
- imageChange :
type
: ImageChange
创建一个BuildConfig YAML或使用GitHub存储库中的运行时BuildConfig。
$ oc create
-f buildConfig-goHelloWorld.yaml
buildconfig.build.openshift.io
/ go-hello-world created
如果您查看日志,您会注意到第一步是FROM scratch ,这确认我们正在将编译后的二进制文件添加到空白图像中。
$ oc logs
-f pod
/ go-hello-world-
1 -build
Step
1
/
5 : FROM scratch
---
>
Step
2
/
5 : COPY app
/ app
---
> 9e70e6c710f8
Removing intermediate container 4d0bd9cef0a7
Step
3
/
5 : ENTRYPOINT
/ app
---
> Running
in 7a2dfeba28ca
---
> d697577910fc
< ...
>
构建完成后,检查图像流标签以验证新图像是否已推送到注册表并更新了图像流。
$ oc get imagestream go-hello-world
NAME DOCKER REPO TAGS UPDATED
go-hello-world docker-registry.default.svc:
5000
/ golang-builder
/ go-hello-world
1.0
4 minutes ago
记下该图像的DOCKER REPO字符串。 下一部分将使用它来运行映像。
我们是否创建了一个很小的二进制图像?
最后,让我们验证一下我们确实仅用二进制文件构建了一个微型映像。
查看图像细节。 首先,从图像流中获取图像名称。
$ oc describe imagestream go-hello-world
Name: go-hello-world
Namespace: golang-builder
Created:
42 minutes ago
Labels:
< none
>
Annotations:
< none
>
Docker Pull Spec: docker-registry.default.svc:
5000
/ golang-builder
/ go-hello-world
Image Lookup:
local =
false
Unique Images:
1
Tags:
1
1.0
no spec tag
* docker-registry.default.svc:
5000
/ golang-builder
/ go-hello-world
@ sha256:eb11e0147a2917312f5e0e9da71109f0cb80760e945fdc1e2db6424b91bc9053
13 minutes ago
该图像在底部列出,并使用SHA哈希描述(例如, sha256:eb11e0147a2917312f5e0e9da71109f0cb80760e945fdc1e2db6424b91bc9053 ;您将有所不同)。
使用哈希获取图像的详细信息。
$ oc describe image sha256:eb11e0147a2917312f5e0e9da71109f0cb80760e945fdc1e2db6424b91bc9053
Docker Image: docker-registry.default.svc:
5000
/ golang-builder
/ go-hello-world
@ sha256:eb11e0147a2917312f5e0e9da71109f0cb80760e945fdc1e2db6424b91bc9053
Name: sha256:eb11e0147a2917312f5e0e9da71109f0cb80760e945fdc1e2db6424b91bc9053
Created:
15 minutes ago
Annotations: image.openshift.io
/
dockerLayersOrder =ascending
image.openshift.io
/
manifestBlobStored =
true
openshift.io
/ image.managed=
true
Image Size: 1.026MB
Image Created:
15 minutes ago
Author:
< none
>
Arch: amd64
Entrypoint:
/ app
Working Dir:
< none
>
User:
< none
>
Exposes Ports:
< none
>
Docker Labels: io.openshift.build.name=go-hello-world-
1
io.openshift.build.namespace=golang-builder
Environment:
PATH =
/ usr
/ local
/ sbin:
/ usr
/ local
/ bin:
/ usr
/ sbin:
/ usr
/ bin:
/ sbin:
/ bin
OPENSHIFT_BUILD_NAME =go-hello-world-
1
OPENSHIFT_BUILD_NAMESPACE =golang-builder
请注意,图像大小1.026MB正是我们想要的。 该图像是仅包含二进制文件的临时图像!
使用运行时映像运行Pod
使用我们刚刚创建的运行时映像,让我们按需创建一个pod并运行它,并验证它是否仍然有效。
这在Kubernetes / OKD中几乎从未发生过,但是我们将单独运行一个pod,仅一个pod。
$ oc run
-it go-hello-world
--image =docker-registry.default.svc:
5000
/ golang-builder
/ go-hello-world:
1.0
--restart =Never
Hello World
!
一切都按预期进行,图像运行并输出“ Hello World!”。 就像以前的本地S2I构建一样。
通过在OKD中创建此工作流程,我们可以将golang-builder S2I映像用于任何Go应用程序。 该构建器映像已就位并针对其他任何应用程序构建,并且只要上游golang:1.12映像发生更改,它将自动更新并自行重建。
通过在OKD中创建链构建策略,并使用appimage BuildConfig编译源代码并使用运行时BuildConfig创建最终映像,可以使用S2I构建自动构建新应用。 使用构建触发器,对Git存储库中源代码的任何更改都将触发整个管道的重建,从而自动重建appimage和运行时映像。
这是为任何应用程序维护更新映像的好方法。 与带有映像生成触发器的OKD deploymentConfig配合使用时,在提交新代码时将自动重新部署长时间运行的应用程序(例如,webapps)。
Source-to-Image是开发构建器映像以可重复的方式构建和编译Go应用程序的理想方法,与OKD BuildConfig配对时效果会更好。
翻译自: https://opensource.com/article/19/5/creating-source-image-build-pipeline-okd
okd 安装