什么是ImageStream
ImageStream是OpenShift中的一种对象,它并不是用来存储Image的,而是用来记录并管理Image信息的。它就像是所有Image的虚拟视图,可以通过它统一访问存放在不同Image Registry(OpenShift外部独立运行的Registry、或是OpenShift内置的Registry)上的Image。通过这个视图可以简化对那些来自不同Registry的Image的访问。

ImageStream使用访问标签(ImageStreamTag)和指向信息(ImageStreamImage)记录这种对应关系。
- ImageStreamTag:是由用户指定的、有意义的字符串,可用它来表示一个特定Image,我们可以把它想象成DNS的域名地址。
- ImageStreamImage:一串基于sha256的无意义的字符创,可用它来表示一个特定Image,我们可以把它想象成DNS的IP地址。
当我们使用ImageStreamTag访问一个Image的时候,其实OpenShift最终会识别出ImageStreamTag对应的ImageStreamImage(就像我们使用DNS域名访问一个地址时,系统需要将其翻译成IP地址访问目标)。ImageStreamTag和ImageStreamImage的这种对应关系可以通过2种方式被解析:
- 在ImageStream记录了ImageStreamTag和ImageStreamImage这种对应关系。当使用ImageStreamTag访问Image的时候,OpenShift实际是使用ImageStreamImage访问该Image。(这种情况类似DNS解析使用的本地hosts文件实现的)
- 在ImageStream不记录ImageStreamTag和ImageStreamImage这种对应关系,而只记录ImageStreamTag信息。因此每次通过ImageStreamTag访问Image的时候,OpenShift需要直接向Registry询问这个ImageStreamTag对应是哪个ImageStreamImage,然后才能访问该Image。(这种情况类似每次DNS解析使用的都是远程DNS服务实现的)

根据ImageStream所在项目,可将其分为集群级和项目级的ImageStream。无论当前在哪个项目中,任何用户都可访问到集群级的ImageStream;而项目级ImageStream只能该项目用户或被授权用户才可访问。
从Image生成ImageStream
如果我们跟随《OpenShift 4 Hands-on Lab (1) – 部署应用》成功创建应用后可以通过以下命令发现OpenShift会自动生成ImageStream对象,这就说明在运行应用前,OpenShift要创建ImageStream并建立App Image的指向关系。
$ oc get is
OpenShift除了可以自动创建ImageStream外,我们还可以从定义ImageStream的YAML文件创建它,但是我们通常用以下两种方法手工从Image生成ImageStream:
1.首选创建名为imagestream-lab1的OpenShift项目,以下所有操作都缺省在该项目中进行。
$ export USER_ID=YOUR-USER-ID $ oc new-project ${USER_ID}-imagestream-lab1
2.通过import-image导入镜像的信息并生成ImageStream。以下将docker.io/openshift/deployment-example:v1的镜像信息导入到名为is-example的ImageStream中,并用v1指向该远程镜像。
$ oc import-image --from=docker.io/openshift/deployment-example:v1 is-example:v1 --confirm -n ${USER_ID}-imagestream-lab1 Name: is-example Namespace: user1-imagestream-lab1 Created: Less than a second ago Labels: <none> Annotations: openshift.io/image.dockerRepositoryCheck=2020-02-02T04:27:15Z Image Repository: image-registry.openshift-image-registry.svc:5000/user1-imagestream-lab1/is-example Image Lookup: local=false Unique Images: 1 Tags: 1 v1 tagged from docker.io/openshift/deployment-example:v1 * docker.io/openshift/deployment-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b Less than a second ago Image Name: is-example:v1 Docker Image: docker.io/openshift/deployment-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b Name: sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b Created: Less than a second ago Annotations: image.openshift.io/dockerLayersOrder=ascending Image Size: 5.77MB in 6 layers Layers: 0B sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 5.77MB sha256:50438f3701c47319ff1c8189ff19f5a8c779f2479aa2066979b930c7dbb3bde8 0B sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 0B sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 0B sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 0B sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 Image Created: 4 years ago Author: Clayton Coleman <ccoleman@redhat.com> Arch: amd64 Entrypoint: /deployment v1 Working Dir: <none> User: <none> Exposes Ports: 8080/tcp Docker Labels: <none> Environment: COLOR=#006e9c
3.使用tag对镜像打标签。下面是将docker.io上的openshift/deployment-example:v2打标签为v2,并保存到名为is-example的ImageStream中。
$ oc tag --source=docker openshift/deployment-example:v2 is-example:v2 -n ${USER_ID}-imagestream-lab1 Tag is-example:v2 set to openshift/deployment-example:v2.
4.为了在后面证明tag命令的“–source=docker”选项会使用“docker.io”上的镜像,我们执行以下命令,其中“openshift/deployment-example-test:v2”的镜像实际在“docker.io”上并不存在。
$ oc tag --source=docker docker.io/openshift/deployment-example:v2 is-example:v3 -n ${USER_ID}-imagestream-lab1 $ oc tag --source=docker openshift/deployment-example-test:v2 is-example:v4 -n ${USER_ID}-imagestream-lab1
ImageStream的操作
1.查看ImageStream列表,注意TAGS部分的“v3,v2,v1,v4”。
$ oc get is -n ${USER_ID}-imagestream-lab1 NAME IMAGE REPOSITORY TAGS UPDATED is-example image-registry.openshift-image-registry.svc:5000/user1-imagestream-lab1/is-example v3,v2,v1,v4 42 minutes ago
2.查看名为is-example的ImageStream配置。注意:名为v2和v3的ImageStreamTag都指向ImageStreamImage为“sha256:1318f08b141aa6a4cdca8c09fe8754b6c9f7802f8fc24e4e39ebf93e9d58472b”的镜像;另外,在v4部分提示无法访问“docker.io/openshift/deployment-example-test:v2”,这说明“oc tag”命令的“–source=docker”选项是从“docker.io”获取镜像。
$ oc describe is is-example -n ${USER_ID}-imagestream-lab1 Name: is-example Namespace: user1-imagestream-lab1 Created: 2 hours ago Labels: <none> Annotations: openshift.io/image.dockerRepositoryCheck=2020-12-08T14:58:12Z Image Repository: image-registry.openshift-image-registry.svc:5000/user1-imagestream-lab1/is-example Image Lookup: local=false Unique Images: 2 Tags: 4 v1 tagged from docker.io/openshift/deployment-example:v1 * docker.io/openshift/deployment-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b 2 hours ago v2 tagged from openshift/deployment-example:v2 * openshift/deployment-example@sha256:1318f08b141aa6a4cdca8c09fe8754b6c9f7802f8fc24e4e39ebf93e9d58472b 2 hours ago v3 tagged from docker.io/openshift/deployment-example:v2 * docker.io/openshift/deployment-example@sha256:1318f08b141aa6a4cdca8c09fe8754b6c9f7802f8fc24e4e39ebf93e9d58472b 37 minutes ago v4 tagged from openshift/deployment-example-test:v2 ! error: Import failed (Unauthorized): you may not have access to the container image "docker.io/openshift/deployment-example-test:v2" 5 seconds ago
$ oc get is is-example -o yaml -n ${USER_ID}-imagestream-lab1 apiVersion: image.openshift.io/v1 kind: ImageStream metadata: annotations: openshift.io/image.dockerRepositoryCheck: "2020-12-08T13:03:59Z" creationTimestamp: "2020-12-08T12:59:18Z" generation: 3 name: is-example namespace: user1-imagestream-lab1 resourceVersion: "232297" selfLink: /apis/image.openshift.io/v1/namespaces/user1-imagestream-lab1/imagestreams/is-example uid: dd1f8458-3043-4791-b5da-2930ff3524c5 spec: lookupPolicy: local: false tags: - annotations: null from: kind: DockerImage name: docker.io/openshift/deployment-example:v1 generation: 1 importPolicy: {} name: v1 referencePolicy: type: Source - annotations: null from: kind: DockerImage name: openshift/deployment-example:v2 generation: 3 importPolicy: {} name: v2 referencePolicy: type: Source - annotations: null from: kind: DockerImage name: docker.io/openshift/deployment-example:v2 generation: 5 importPolicy: {} name: v3 referencePolicy: type: Source - annotations: null from: kind: DockerImage name: openshift/deployment-example-test:v2 generation: 9 importPolicy: {} name: v4 referencePolicy: type: Source status: dockerImageRepository: image-registry.openshift-image-registry.svc:5000/user1-imagestream-lab1/is-example tags: - items: - created: "2020-12-08T12:59:18Z" dockerImageReference: docker.io/openshift/deployment-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b generation: 1 image: sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b tag: v1 - items: - created: "2020-12-08T13:03:59Z" dockerImageReference: openshift/deployment-example@sha256:1318f08b141aa6a4cdca8c09fe8754b6c9f7802f8fc24e4e39ebf93e9d58472b generation: 3 image: sha256:1318f08b141aa6a4cdca8c09fe8754b6c9f7802f8fc24e4e39ebf93e9d58472b tag: v2 - items: - created: "2020-12-08T14:20:41Z" dockerImageReference: docker.io/openshift/deployment-example@sha256:1318f08b141aa6a4cdca8c09fe8754b6c9f7802f8fc24e4e39ebf93e9d58472b generation: 5 image: sha256:1318f08b141aa6a4cdca8c09fe8754b6c9f7802f8fc24e4e39ebf93e9d58472b tag: v3 - conditions: - generation: 9 lastTransitionTime: "2020-12-08T14:58:12Z" message: you may not have access to the container image "docker.io/openshift/deployment-example-test:v2" reason: Unauthorized status: "False" type: ImportSuccess items: null tag: v4
3.查看ImageStreamTag列表,确认没有“is-example:v4”的ImageStreamTag。这说明名为v4的ImageStreamTag没有创建成功。
$ oc get istag -n ${USER_ID}-imagestream-lab1 NAME IMAGE REFERENCE UPDATED is-example:v1 docker.io/openshift/deployment-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b 2 hours ago is-example:v2 openshift/deployment-example@sha256:1318f08b141aa6a4cdca8c09fe8754b6c9f7802f8fc24e4e39ebf93e9d58472b 2 hours ago is-example:v3 docker.io/openshift/deployment-example@sha256:1318f08b141aa6a4cdca8c09fe8754b6c9f7802f8fc24e4e39ebf93e9d58472b About an hour ago
4.查看ImageStreamTag配置
$ oc describe istag is-example:v1 -n ${USER_ID}-imagestream-lab1 Image Name: sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b Docker Image: docker.io/openshift/deployment-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b Name: sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b Created: 2 hours ago Annotations: image.openshift.io/dockerLayersOrder=ascending Image Size: 5.77MB in 6 layers Layers: 0B sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 5.77MB sha256:50438f3701c47319ff1c8189ff19f5a8c779f2479aa2066979b930c7dbb3bde8 0B sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 0B sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 0B sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 0B sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 Image Created: 4 years ago Author: Clayton Coleman <ccoleman@redhat.com> Arch: amd64 Entrypoint: /deployment v1 Working Dir: <none> User: <none> Exposes Ports: 8080/tcp Docker Labels: <none> Environment: COLOR=#006e9c
5.按大小排序查看USER-ID-imagestream-lab1项目中的imagestreams。注意,下面命令必须有“ -n USER-ID-imagestream-lab1”部分来指定查看的项目,否则看到的是“openshift”项目中的imagestreams。
$ oc adm top imagestreams -n ${USER_ID}-imagestream-lab1 NAME STORAGE IMAGES LAYERS USER-ID-imagestream-lab1/is-example 5.503MiB 2 12
6.执行命令,将“is-example:v1”指向docker.io网站的“openshift/deployment-example:v2”
$ oc tag --source=docker openshift/deployment-example:v2 is-example:v1 -n ${USER_ID}-imagestream-lab1
7.查看名为is-example的ImageStream,其中v1的指向的ImageStreamImage记录为2条,当前v1和v2指向的是同一个Image。而v1以前指向的是另一个Image。
$ oc describe is is-example -n ${USER_ID}-imagestream-lab1 Name: is-example Namespace: USER-ID-imagestream-lab1 Created: 4 minutes ago Labels: <none> Annotations: openshift.io/image.dockerRepositoryCheck=2020-02-02T14:07:48Z Image Repository: default-route-openshift-image-registry.apps.cluster-beijing-c70a.beijing-c70a.example.opentlc.com/USER-ID-imagestream-lab1/is-example Image Lookup: local=false Unique Images: 2 Tags: 2 v1 tagged from openshift/deployment-example:v2 * openshift/deployment-example@sha256:1318f08b141aa6a4cdca8c09fe8754b6c9f7802f8fc24e4e39ebf93e9d58472b 26 seconds ago docker.io/openshift/deployment-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b 3 hours ago v2 tagged from openshift/deployment-example:v2 * openshift/deployment-example@sha256:1318f08b141aa6a4cdca8c09fe8754b6c9f7802f8fc24e4e39ebf93e9d58472b 3 hours ago v3 tagged from docker.io/openshift/deployment-example:v2 * docker.io/openshift/deployment-example@sha256:1318f08b141aa6a4cdca8c09fe8754b6c9f7802f8fc24e4e39ebf93e9d58472b About an hour ago v4 tagged from openshift/deployment-example-test:v2 ! error: Import failed (Unauthorized): you may not have access to the container image "docker.io/openshift/deployment-example-test:v2" 37 minutes ago
8.删除名为“is-example:v2”的ImageStreamTag
$ oc delete istag/is-example:v2 -n ${USER_ID}-imagestream-lab1
生成ImageStream过程的选项
在使用“oc tag”和“oc import-image”命令生成ImageStream的时候,可以使用参数“–reference-policy=local”让OpenShift只在本地(其内部的Image Registry)找镜像;另外还可以用“–reference”参数让OpenShift只创建一个非导入的ImageStreamTag,即不导入目标Image的元数据。下面我们看看这两个选项对ImageStream有什么影响?
1.新建imagestream-lab2项目
$ oc new-project ${USER_ID}-imagestream-lab2
2.执行以下命令,使用不同选项生从“openshift/deployment-example:v1”成相关ImageStream资源。
$ oc tag --source=docker openshift/deployment-example:v1 is-example:v1 -n ${USER_ID}-imagestream-lab2 $ oc tag --source=docker openshift/deployment-example:v1 is-example:v2 --reference-policy=local -n ${USER_ID}-imagestream-lab2 $ oc tag --source=docker openshift/deployment-example:v1 is-example:v3 --reference=true -n ${USER_ID}-imagestream-lab2
3.查看ImageStream的信息,注意3个Tags它们之间的差异,其中v3没有相应的镜像ID(说明当使用–reference=true,OpenShift不会主动获取镜像元数据)。
$ oc describe is is-example -n ${USER_ID}-imagestream-lab2 Name: is-example Namespace: imagestream-lab2 Created: 2 minutes ago Labels: <none> Annotations: openshift.io/image.dockerRepositoryCheck=2020-02-02T11:14:02Z Image Repository: default-route-openshift-image-registry.apps.cluster-beijing-c70a.beijing-c70a.example.opentlc.com/USER-ID-imagestream-lab2/is-example Image Lookup: local=false Unique Images: 2 Tags: 3 v1 tagged from openshift/deployment-example:v1 * openshift/deployment-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b 2 minutes ago v2 tagged from openshift/deployment-example:v1 prefer registry pullthrough when referencing this tag * openshift/deployment-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b 2 minutes ago v3 reference to registry openshift/deployment-example:v1 * openshift/deployment-example:v1 2 minutes ago
4.查看ImageStreamTag列表。确认“is-example:v2”和“is-example:v2”指向的是同一个sha256的ImageStreamImage,但是镜像所在位置不同,前者指向是远程“docker.io”上的镜像,后者则是指向是已经在OpenShift内部Registry的镜像。另外还确认istag列表中没有“is-example:v3”,说明它是无效的。
$ oc get istag -n ${USER_ID}-imagestream-lab2 NAME IMAGE REF UPDATED is-example:v1 openshift/deployment-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b 2 minutes ago is-example:v2 image-registry.openshift-image-registry.svc:5000/USER-ID-imagestream-lab2/is-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b 2 minutes ago
5.在OpenShift控制台也可看到名为is-example的ImageStream的“is-example:v3”的Tag提示以下错误。

6.执行以下命令,根据已有的ImageSteamTag生成新的ImageSteamTag,这次使用了“–reference=true”参数。
$ oc tag --source=istag is-example:v1 is-example:v4 --reference=true -n ${USER_ID}-imagestream-lab2
7.再次查看ImageStreamTag,确认“is-example:v4”是正常的。虽然这次使用了“–reference=true”参数,即OpenShift不会主动获取镜像元数据,但是由于使用的是“–source=istag”,因此ImageStreamImage信息已经在本地有了(是在创建“is-example:v1”的步骤获取到的)。
$ oc get istag -n ${USER_ID}-imagestream-lab2 NAME IMAGE REF UPDATED is-example:v1 openshift/deployment-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b 22 minutes ago is-example:v2 image-registry.openshift-image-registry.svc:5000/USER-ID-imagestream-lab2/is-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b 22 minutes ago is-example:v4 openshift/deployment-example@sha256:c505b916f7e5143a356ff961f2c21aee40fbd2cd906c1e3feeb8d5e978da284b About a minute ago
常见问题
1.根据远程的Image创建ImageStream的时候,Image是否会下载到本地?
说明:不会。只有第一次基于这个Image运行应用的时候才去下载这个Image。
2.当使用“–reference-policy=local”参数和不使用它的时候,对使用Image有什么影响?
说明:当使用“–reference-policy=local”后,OpenShift就不会访问其外部的Registry获得Image了,只会使用其内置的Registry获取Image了。因此需要手动将Image提前push到其内置的Registry才可使用这些Image。
3.删除了ImageStreamTag后,对应的本地Image有影响么?
说明:没有。两者是若关联关系,删除任何一个不会自动删除相关的另一方。