网站首页 > 技术文章 正文
本文内容主要源自https://itnext.io/variations-on-imagestreams-in-openshift-4-f8ee5e8be633一文。
ImageStream基本概念
容器镜像存储在镜像注册表中(如Docker Hub、Quay.io),我们可以从那里手动pull出来单独运行,也可以在Kubernetes集群中运行。Kubernetes没有内置的镜像注册表,然而这在企业环境中又是通常是需要的。Red Hat OpenShift 提供了一个开箱即用的集成注册表来填补这一空白,并引入了一个名为ImageStream的新的Kubernetes资源,以“Kubernetes-native方式”管理镜像。
ImageStreams 是为了支持不同用途而设计的。但在一开始,某些参数可能会让人感到困惑。本文将对于OpenShift中的镜像管理的基本概念。
技术上来说,ImageStream只是一个包含元数据的Kubernetes资源。除了管理内部的镜像--通常是在OpenShift集群中构建的--ImageStreams可以指向外部注册表中的图像。在这种情况下,它们只是一个额外的抽象层,提供了一些额外的功能(例如轮询更新、缓存)。由于 ImageStream 可以有两种不同的行为方式,如果我们区分它们是指向内部图像还是指向外部图像,就更容易理解它们。
Internal Image 和 External Image
Internal Image 和 Internal Image Registry
首先,下面是关于存储在Internal Registry中的Image的一些注意事项:
1. 对于内部图像,ImageStreams和内部注册表是紧密耦合的。例如,myproject命名空间中的myimage-internal
ImageStream被映射到image-registry.openshift-image-registry.svc:5000/myproject/myimage-internal
repository。
2. 如果我们运行一个新的构建,其中output指定的是ImageStream类型,那么图像将被存储在OpenShift内部注册表中。(【引用#1】如果Build的output指定的是DockerImage类型,那么OpenShift会使用push操作将Image推送到标准的Docker Registry,缺省是DockerHub)。另外同理适用于指定Builder Image的来源。
3. 如果我们使用Push方法手动向Internal Image Registry推送一个Image,OpenShift会自动创建一个匹配的ImageStream并指向这个Internal Image Registry中的Image。主要注意的是我们必须有推送Image所到Namespace的编辑权限。
5. 如果我们删除了ImageStream,在内部注册表中保存的Image存储也会被删除。
6. 为了保持注册表的使用空间,你需要定期[Prune Images](https://docs.openshift.com/container-platform/4.3/applications/pruning-objects.html#pruning-images_pruning-objects)。在这个过程中,那些在Build或Deployment中被使用到的内部Image会自动保留。
External Image
在OpenShift之外的External Registry保存了外部Image。ImageStream和External Registry、以及其上的外部Image的关系如下:
1. 我们可以用 oc import-image 或 oc tag 命令创建一个指向外部图像的 ImageStream,或者直接用 yaml 创建一个 ImageStream。
2. 一个ImageStream中的标签可以指向来自完全不同的注册库和存储库的Image。通过这种有效的方法可以将相关的外部Image关联起来,但Image可存储在不同的Registry存储库中。
3. 作为一个抽象层,ImageStreams隐藏了Image的实际来源。当构建和部署引用一个ImageStream时,我们可以通过修改ImageStream中的URL来改变正在使用的Image,而不是逐一编辑OpenShift的每个构建和部署。
4. 当创建或更新Image时,ImageStream 通过其唯一的 sha256 ID(而非Tag)来引用图像。这使得当外部注册表变化标签的时候,其使用的Image可保持稳定性。
5. ImageStreams 可以定期(15 分钟)监控外部标记是否发生变化(通过--scheduled=true)。
6. 我们可以在内部注册表中缓存外部Image(通过--reference-policy=local)。这真的很有用,因为它可以使部署更加快速,并且不受外部注册表可用性的影响。
7. 另一个重要的功能--无论是内部还是外部映像--是在ImageStream更新时自动触发相关的BuildConfigs和DeploymentConfigs的能力。这个行为可以在这些资源上设置(参见 imageChangeParams.automatic=true),通常是启用的。
确定ImageStream指向的目标和方式
我们可以把OpenShift的ImageStream看成是一个指向Image的指针(当然还有一些其它元数据),ImageStream指向的Image目标可以是多种不同类型的目标,它们包括:
1. 指向一个external image
2. 通过pullthrough 指向一个被缓存的external image
3. 总是使用一个external image的URL
4. 指向一个internal image
5. 指向另一个ImageStream
指向External Image
我们可以用以下oc的import-image命令或tag命令创建一个存放在myproject下的ImageStream,并让它指向外部Image,这个外部Image就是docker.io/balazsszeti/hello:sleeper。
$ oc import-image myproject/myimage-ref-source:mytag --from="docker.io/balazsszeti/hello:sleeper" --confirm
$ oc tag docker.io/balazsszeti/hello:sleeper myproject/myimage-ref-source:mytag
然后我们可以查看这个ImageStream和ImageStreamTag的详细信息。
$ oc get is myimage-ref-source -oyaml
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
annotations:
openshift.io/image.dockerRepositoryCheck: "2020-04-12T08:18:25Z"
creationTimestamp: "2020-04-12T08:18:25Z"
generation: 1
name: myimage-ref-source
namespace: myproject
resourceVersion: "2844402"
selfLink: /apis/image.openshift.io/v1/namespaces/myproject/imagestreams/myimage-ref-source
uid: 2e541461-7c96-11ea-8ba8-0a580a81000f
spec:
lookupPolicy:
local: false
tags:
- from:
kind: DockerImage
name: docker.io/balazsszeti/hello:sleeper
importPolicy: {}
name: mytag
referencePolicy:
type: Source
status:
dockerImageRepository: image-registry.openshift-image-registry.svc:5000/myproject/myimage-ref-source
publicDockerImageRepository: default-route-openshift-image-registry.apps.cluster-beijing-78c7.beijing-78c7.example.opentlc.com/myproject/myimage-ref-source
tags:
- items:
- created: "2020-04-12T08:18:25Z"
dockerImageReference: docker.io/balazsszeti/hello@sha256:42957024b43e121a210a1b3a8a44f497233a2385f7ef48227a6866afdb9b8e1b
generation: 1
image: sha256:42957024b43e121a210a1b3a8a44f497233a2385f7ef48227a6866afdb9b8e1b
tag: mytag
$ oc get istag
NAME IMAGE REF UPDATED
myimage-ref-source:mytag docker.io/balazsszeti/hello@sha256:42957024b43e121a210a1b3a8a44f497233a2385f7ef48227a6866afdb9b8e1b 10 minutes ago
1. 名为mytag的ImageSteamTag指向的是DockerImage类型的External Image,外部镜像URL(名称+Tag)是docker.io/balazsszeti/hello:sleeper。
2. 这个ImageSteam的mytag实际指向的外部Image是由dockerImageReference所指的sha256 ID,即下面的字符串。在生成ImageStreamTag的时候,OpenShift是使用了docker.io/balazsszeti/hello:sleeper获得的该Image的sha256 ID。这样当在build或deployment命令中引用ImageStreamTag来创建Pod的时候,实际上使用的是用sha256 ID代表的Image。
docker.io/balazsszeti/hello@sha256:42957024b43e121a210a1b3a8a44f497233a2385f7ef48227a6866afdb9b8e1b
3. 每次通过ImageSteamTag使用Image的时候使用的是source类型的referencePolicy,即直接从source访问Image。因此如果当时网络不通,则无法访问该Image。
4. 当生成ImageSteamTag指向sha256 ID后,修改升级外部镜像的tag就不再影响ImageSteamTag了,也就是说即便把外部镜像从“docker.io/balazsszeti/hello:sleeper”改为“docker.io/balazsszeti/hello:sleeper-v1”,只要sha256 ID没有变化,OpenShift的ImageSteamTag就可以继续使用该外部镜像。
5. 当外部镜像发生变化后需要自动更新ImageSteamTag对应的sha256 ID,那么可以使用oc tag或oc import-image命令的“--scheduled=true”参数,它会在YAML中设置“importPolicy: {scheduled: true}”。
6. ImageStream是OpenShift扩展的对象,因此OpenShift的Build、DeploymentConfig等对象可以直接使用它。如果需要在Kubernetes的RC、Pod等对象使用ImageStream,可执行以下的命令启动ImageStream的本地名称查询功能。该命令将把ImageStream的Imagestream. spec.lookupPolicy.local设为true。
$ oc set image-lookup IMAGESTREAM
以下是一个例子:如果为名为hello的ImageStream启用了本地名称查询功能,那么在pod或其他资源中使用“--image=hello”就可以访问到ImageSteamTag指向的Image,无而来自上游Image Registry。如果没有启动本地名称查询功能,那么使用“--image=hello”访问Image的时候会出问题,例如下面的“ErrImagePull”错误。
$ oc import-image myproject/hello:latest --from="openshift/hello-openshift:latest" --confirm
$ oc run hello --image=hello
$ oc get pod -w
NAME READY STATUS RESTARTS AGE
hello-1-deploy 0/1 ContainerCreating 0 4s
hello-1-mnnmz 0/1 Pending 0 0s
hello-1-mnnmz 0/1 ContainerCreating 0 0s
hello-1-deploy 1/1 Running 0 9s
hello-1-mnnmz 0/1 ContainerCreating 0 7s
hello-1-mnnmz 0/1 ErrImagePull 0 8s
下面在使用了“set image-lookup”后就可通过“--image=hello”使用该镜像了。
$ oc delete dc hello
$ oc set image-lookup hello
$ oc run hello --image=hello
$ oc get pod -w
NAME READY STATUS RESTARTS AGE
hello-1-vxcph 0/1 Pending 0 0s
hello-1-vxcph 0/1 ContainerCreating 0 0s
hello-1-deploy 1/1 Running 0 9s
hello-1-vxcph 0/1 ContainerCreating 0 7s
hello-1-vxcph 1/1 Running 0 9s
hello-1-deploy 0/1 Completed 0 18s
hello-1-deploy 0/1 Completed 0 18s
通过pullthrough指向External Image
为了让ImageStream使用pullthrough特性,我们可以在oc import-image或oc tag命令中通过“--reference-policy=local”参数。
$ oc import-image myproject/myimage-ref-local:mytag --from="docker.io/balazsszeti/hello:sleeper" --confirm --reference-policy=local
$ oc tag docker.io/balazsszeti/hello:sleeper myproject/myimage-ref-local:mytag --reference-policy=local
“--reference-policy=local”参数会将ImageStream的referencePolicy.local设置成true。
。。。
referencePolicy:
type: Local
。。。
当StreamImage使用的是pullthrough方式指向External Image时候,那么:
1. 根据Image生成Pod的时候会使用Internal Registry上的已经被pulled through的Image。例如:
image-registry.openshift-image-registry.svc:5000/myproject/myimage-ref-local@sha256:42957024b43e121a210a1b3a8a44f497233a2385f7ef48227a6866afdb9b8e1b
2. 当Image第一次被使用的时后,它会先从External Registry被获取到然后缓存到Internal Registry缓存中。所以在第一次使用Image的时后还不会脱机工作,但一旦缓存后,就再也不需要联系外部注册表了。即使将映像从外部注册表中删除,它也会保留在Internal Registry缓存中。
3. 和“指向External Image”一节样,当External Image的Tag变化后,并且如果sha256 ID还有效,那么不会影响继续使用ImageStreamTag访问镜像,而且Internal Registry的Image缓存也不会更新。当使用手动更新或使用“--scheduled=true”定时更新,更新后的External Image会更新至内部缓存的Image。
4. 由于Pod是采用Internal Registry sha256 ID获取被缓存的Image,因此如果缓存Image没有被清除,那么Pod就可以被rollback。
每次通过External Image的URL地址获取镜像
通过使用oc tag命令的--reference=true参数可创建一个ImageStream。在通过它运行Pod的时候,OpenShift不会直接使用ImageStreamTag的sha256 ID来找到对应的Image,而是每次都是通过指定的External Image名称和对应的Tag去找那个对应特定的Image。下面我们对比使用--reference=true参数和--reference=false(缺省情况)的区别。
1. 首先使用--reference=true参数创建一个ImageStream,然后查看是否有ImageStreamTag对象。可以看到当使用--reference=true参数的时候,OpenShift并不会为之创建与ImageStream对应的ImageStreamTag,当然就没有Image的sha256 ID了。此时OpenShift每次都要通过解析External Image的URL地址(即docker.io/openshift/hello-openshift:latest)解析实际使用的Image(其实最终还要解析到Image的sha256 ID)。因此这种情况是每次都做一次外部镜像地址的全解析。
$ oc tag docker.io/openshift/hello-openshift:latest myproject/hello-1:latest --reference=true
$ oc get istag hello-1:latest
Error from server (NotFound): imagestreamtags.image.openshift.io "hello-1:latest" not found
2. 首先使用--reference=false参数创建一个ImageStream,然后查看是否有ImageStreamTag对象。可以看到当使用--reference=false参数的时候,OpenShift会为之创建与ImageStream对应的ImageStreamTag。OpenShift以后实际上是通过ImageStreamTag中记录的sha256 ID定位该Image的,因此从External Image的URL地址解析到Image的sha256 ID过程OpenShift只做一次。
$ oc tag docker.io/openshift/hello-openshift:latest myproject/hello-2:latest --reference=false
$ oc get istag hello-2:latest
$ oc get istag hello-2:latest
NAME IMAGE REF UPDATED
hello-2:latest docker.io/openshift/hello-openshift@sha256:aaea76ff622d2f8bcb32e538e7b3cd0ef6d291953f3e7c9f556c1ba5baf47e2e 5 seconds ago
当我们使用--reference=false的ImageStream的时候,具有以下特性:
1. 在这种情况下由于没有ImageSteamTag的sha256 ID,因此Pod每次都要使用以下External Image的URL找到该Image。
docker.io/openshift/hello-openshift:latest
2. 在这种情况下即便使用了--reference-policy=local选项,也无法使用缓存,因此不能离线运行。
3. 由于每次OpenShift都通过External Image的URL找到所用Tag对应的Image来运行Pod,因此当External Image的Tag升级后,OpenShift可以立即感知出来这种变化,并用新的Tag对应的Image生成Pod。在--reference=false的时候,应配合Pod的“imagePullPolicy: Always”参数一起使用,以让Pod每次都pull到最新的Image。
4. 在这种情况时,Pod直接使用的是External Image URL获取的Image,而不是用ImageStream配置中的Internal Registry URL(即image-registry.openshift-image-registry.svc:5000/myproject/myimage-reference:mytag)获取Image。
5. 由于Pod是直接通过External Image的URL获得Image,例如docker.io/openshift/hello-openshift:latest,因此即便rollback,Pod获取到的Image可能会没有变化,因此rollback就不会奏效。
Internal Image
通过OpenShift的build生成的Image会推送到 Internal Registry上,OpenShift同时会为其生成ImageStream。
$ oc new-build --to='myimage-internal:mytag' --strategy=docker --binary=true --name=myimage-internal
$ oc start-build myimage-internal --from-dir=. --follow
$ oc get is myimage-internal
NAME IMAGE REPOSITORY TAGS UPDATED
myimage-internal default-route-openshift-image-registry.apps.cluster-beijing-78c7.beijing-78c7.example.opentlc.com/myproject/myimage-internal
使用这种方式的ImageStream有以下特性:
1. 同使用pullthrough方式相同,Pod使用的是Internal Registry和sha256 ID的组合方式访问到Image。
image-registry.openshift-image-registry.svc:5000/myproject/myimage-internal@sha256:ff3b3c5e3d09bf93e2a05ece04235f4ea8212f36b617161d8f11f374a14aeb74
2. 由于Image就在OpenShift的internal registry中,因此可以离线访问到。
3. 当通过build过程更新了Image的Tag后,Pod会使用更新后的Image。
4. 其它特性和上面介绍的pullthrough的情况相同。
猜你喜欢
- 2024-11-23 轻量图片查看器-imageGlass
- 2024-11-23 「正点原子FPGA连载」第十八章Linux内核移植
- 2024-11-23 图片处理工具,FocusOn Image Viewer软件体验
- 2024-11-23 深入分析ImageMagick的Shell注入漏洞
- 2024-11-23 一键部署!markdown-to-image:将 Markdown 转为海报的编辑器!
- 2024-11-23 手机误删照片怎么恢复?这款免费照片恢复App你值得拥有
- 2024-11-23 Image Enhance Pro for Mac(图像处理工具)中文版
- 2024-11-23 WiseImage Pro——为AutoCAD开发的插件工具推荐
- 2024-11-23 使用ImageJ进行运动粒子分析
- 2024-11-23 动感映像插件Imagemotion for mac
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-