发布企业容器镜像

比较企业注册表和公共注册表

许多开发人员从公共容器镜像注册表创建容器,例如 docker.io 的 Docker Hub 和 registry.access.redhat.com 的红帽注册表。 这些公共注册表很方便,但许多企业不允许开发人员从他们从互联网下载的镜像提取和运行容器。这些企业限制开发人员只能使用一组符合安全性、质量和一致性标准的容器镜像。

限制从互联网访问容器镜像的一种方法是在企业内部署企业注册表,也称为私有注册表。然后,将企业内的容器主机配置为仅从企业注册表中提取镜像。

企业注册表也可用于许多其他方案,例如:

  • 企业批准不同的容器镜像以供不同环境使用:例如开发、QA 和生产。每个环境都有不同的私有注册表。

  • 供应商提供预构建的容器镜像,但企业不希望为运行容器的每个主机从互联网手动提取这些镜像。

  • 企业提供内部为外部用户和客户创建的容器镜像。

  • 无需访问互联网即可安装和运行 OpenShift 以下载 OpenShift 容器镜像,例如路由器和 S2I 构建器镜像。


部署企业注册表

Docker 社区提供了两个开源容器镜像注册表服务器,由红帽作为 RHEL 7 附加通道的一部分进行打包并提供支持:

  1. docker-registry 软件包实施了较旧的 v1 注册表 API,并且已知存在磁盘和网络 I/O 方面的性能问题。

  2. docker-distribution 软件包实施了较新的 v2 注册表 API。除了性能和可扩展性改进之外,此镜像注册表服务器设计成可以嵌入到其他软件包中。

红帽建议使用较新的 docker-distribution 软件包代替较旧的 docker-registry 软件包。不幸的是,docker-distribution 软件包没有实施搜索功能。每个提供搜索功能的供应商(包括 Docker Hub)都以专有方式完成。

多个供应商(如 JFrog、Sonatype、Docker Inc 和红帽)提供商业支持的容器镜像注册表服务器。 其中许多都基于 docker-distribution 软件包源代码。

红帽提供了两种用于部署注册表服务器的产品:

  • 红帽卫星:此注册表服务器是外部注册表的代理。它不提供推送功能。 如果您的企业已使用红帽卫星系统管理功能在内部分发 RPM 软件包,您可以考虑使用红帽卫星在内部分发容器镜像。

  • 红帽 OpenShift 容器注册表:这是专门用于运行安全的企业注册表的红帽 OpenShift 容器平台集群安装。与 docker-distribution 软件包相比,红帽 OpenShift 容器注册表在高可用性、安全性和管理方面提供了增强功能。


将企业注册表与 OpenShift 一起使用

OpenShift 可以直接从存储在企业注册表中的镜像部署应用。OpenShift 将这些企业注册表命名为外部注册表,以区别于 OpenShift 内部注册表。

有两种方法可以使用带 OpenShift 的外部注册表中的容器镜像:

  1. 将存储在外部注册表中的容器镜像的完整 URL 提供给 oc new-app 等命令。

  2. 创建指向外部注册表中的镜像的镜像流资源。

推荐的方法是使用镜像流资源。除了其他优势之外,镜像流还允许集群管理员使用 oc import-image 命令更新镜像流中的元数据,并触发 OpenShift 集群内的构建和部署。


安装并配置 docker-distribution 注册表

RHEL 7 的 docker-distribution 软件包配置了 docker-distribution 服务并安装了随时可运行的配置,但需要注意几点:

  • 注册表不需要身份验证来推送或提取容器镜像。

  • 注册表拒绝删除容器镜像的请求。

本书未介绍如何为模拟生产环境配置 docker-distribution 软件包。有关配置身份验证、存储、缓存和其他设置的信息,请查看本节末尾的参考资料。

无法删除容器镜像可能会产生磁盘空间问题。要允许从注册表存储中删除镜像,请将 delete.enabled 属性添加到位于 /etc/docker-distribution/registry/config.yml 的 docker-distribution 配置文件的 storage 部分:
应用的自动构建:Openshift开发系列第二篇_java


skopeo 命令

docker 命令提供动词以将容器镜像从注册表提取并推送到本地容器存储,但不是用于管理存储在注册表中的容器镜像的完整解决方案。

红帽支持使用 skopeo 命令管理容器镜像注册表中的镜像。与 docker 命令相比,skopeo 命令提供了一些好处:

  • 以普通用户身份运行,没有等同于 root 的特权。

  • 支持从注册表删除镜像。

  • 支持镜像签名。

  • 直接在两个注册表之间或注册表与本地文件系统之间传输容器镜像,无需通过容器运行时守护进程发送。

  • 支持标准开放容器项目 (OCI) 文件格式。

开放容器项目 (OCI) 定义了容器运行时和容器镜像格式的开放标准。OCI 容器镜像格式是文件系统文件夹,包含存储容器镜像清单、元数据和图层的离散文件。

skopeo verb [options] location...

  • copy 将镜像从一个位置复制到另一个位置

  • delete 从注册表删除镜像

  • inspect 查看有关镜像的元数据。

主要选项是:

  • --creds username:password 向注册表提供登录凭据。

  • --[src-|dest-]tls-verify=false 不需要 HTTPS,也不需要 TLS 证书。

要将容器镜像从 myimage OCI 格式的文件夹复制到位于 registry.example.com 的不安全的注册表:
skopeo copy --dest-tls-verify=false oci:myimage docker://registry.example.com/myimage

要从位于 registry.example.com 的不安全的注册表删除 myimage 容器镜像:skopeo delete --tls-verify=false docker://registry.example.com/myimage

创建独立注册表

应用的自动构建:Openshift开发系列第二篇_java_02

firewall-cmd --zone=trusted --add-port 5000/tcp --permanent
firewall-cmd --reload

vi /etc/docker-distribution/registry/config.yml
应用的自动构建:Openshift开发系列第二篇_java_03

应用的自动构建:Openshift开发系列第二篇_java_04

通过从磁盘上的开放容器项目 (OCI) 兼容文件向其推送镜像来测试独立注册表。

检查本地磁盘中的 rhel7-sleep 容器 OCI 镜像层。OCI 镜像存储为包含多个文件的文件系统文件夹:
应用的自动构建:Openshift开发系列第二篇_java_05
应用的自动构建:Openshift开发系列第二篇_java_06
应用的自动构建:Openshift开发系列第二篇_java_07

配置本地 Docker 守护进程以将独立注册表用作不安全的注册表。

将独立注册表主机和端口添加到 Docker 守护进程配置中的 INSECURE_REGISTRY 环境变量。

以 root 用户身份,使用文本编辑器打开 /etc/sysconfig/docker 文件并找到以下行:
INSECURE_REGISTRY='--insecure-registry registry.lab.example.com:5000 --insecure-registry workstation.lab.example.com:5000'
systemctl restart docker

从独立注册表中的镜像启动测试容器:
应用的自动构建:Openshift开发系列第二篇_java_08

从独立注册表中的容器镜像部署应用应用的自动构建:Openshift开发系列第二篇_java_09应用的自动构建:Openshift开发系列第二篇_java_10


构建流程

红帽 OpenShift 容器平台可通过构建流程,将输入参数转变为容器镜像。在大多数情况下,红帽 OpenShift 容器平台会下载源代码应用,并构建相应的容器镜像以用于在该平台上实施新的部署。

OpenShift 需要使用 BuildConfig 资源以构建容器镜像。对于这类资源,需要配置一个策略以及一个或多个输入源。
构建策略

以下是 OpenShift 中可供使用的构建策略:

Source

Pipeline

Docker

Custom

每种策略都需要使用相应的容器镜像。OpenShift 提供了用于实施 Source、Pipeline 和 Docker 的容器镜像。

Source

Source 策略会基于应用源代码创建新的容器镜像。OpenShift 会克隆兼容构建器镜像中的应用源代码,然后通过汇编方式构建一个可以即刻在该平台中进行部署的新容器镜像。

该策略可以简化开发人员构建容器镜像的方式,因为该策略会使用与容器镜像类似的工具,而不是使用低级别的 OS 命令,如包含 Dockerfiles 的 yum。

Source 策略基于 source-to-image (S2I) 流程。


Pipeline

pipeline 策略会使用 Jenkins pipeline 插件来创建新的容器镜像。虽然这些容器镜像是 Jenkins 构建的,但构建可由 OpenShift 来启动、监控和管理。


BuildConfig 资源可在构建配置或 Git 存储库中直接引用包含管道工作流的 Jenkinsfile。

OpenShift 会启动新的 Jenkins 服务器,以便在第一次构建时采用管道策略来执行管道。项目中的后续管道构建配置则会共享这个 Jenkins 服务器。

Docker

docker 策略会运行 docker build 命令以构建新的容器镜像。该策略需要使用包含 Dockerfile 的 Git 存储库以及相应的构建构件。

Docker build 会作为 OpenShift 集群内部的一个 Pod 来运行。无需在开发人员的工作站上构建 Docker 环境。


Custom

custom 策略会指定负责实施构建流程的构建器镜像。它允许开发人员自定义构建流程。请参见本单元中的“参考资料”部分,以查找有关如何创建自定义构建器镜像的更多信息。

构建输入源

构建输入源可为构建提供源内容。OpenShift 支持六种类型来源:

  • Git:从 Git 存储库克隆输入源。可以将该存储库中的某个位置配置为默认位置,以便在构建时从中查找应用源代码。

  • Dockerfile:指定用于构建镜像的内联 Dockerfile。这个 Dockerfile 会覆盖来自 Git 存储库的 Dockerfile。

  • Binary:允许将本地文件系统中的二进制内容流化至构建器。

  • Image:可为构建流程提供来自镜像的其他文件。

  • Input secrets:允许为构建创建在最终应用镜像中不可用的凭据。

  • External artifacts:允许将二进制文件复制到构建流程中。

可将多个输入整合到单个构建中。Binary 和 Git 是两种互斥的输入类型。

虽然 OpenShift 提供了多种策略和输入源,但最常见的场景是使用 Source 或 Docker 策略并将 Git 存储库作为唯一的输入源。



管理应用构建

  • OpenJDK S2I 构建器镜像 (redhat-openjdk-18/openjdk18-openshift)。

  • 应用 Git 存储库 (java-serverhost)。

基于 Git 中的来源创建新应用。将应用命名为 jhost,并在 oc new-app 命令中使用 --build-env 选项来定义构建环境变量和 maven 存储库位置。

oc new-app --name jhost
--build-env MAVEN_MIRROR_URL=\http://services.lab.example.com:8081/nexus/content/groups/training-java
-i redhat-openjdk18-openshift
http://services.lab.example.com/java-serverhost
应用的自动构建:Openshift开发系列第二篇_java_11

应用的自动构建:Openshift开发系列第二篇_java_12

应用的自动构建:Openshift开发系列第二篇_java_13

应用的自动构建:Openshift开发系列第二篇_java_14

将应用更新至 2.0 版。

编辑 /home/student/java-serverhost/src/main/java/com/redhat/training/example/ 文件夹中的 ServerHostEndPoint.java 文件,并更新至 2.0 版:
应用的自动构建:Openshift开发系列第二篇_java_15
应用的自动构建:Openshift开发系列第二篇_java_16
应用的自动构建:Openshift开发系列第二篇_java_17
应用的自动构建:Openshift开发系列第二篇_java_18
应用的自动构建:Openshift开发系列第二篇_java_19



使用构建触发器

您可以定义 OpenShift 构建触发器,以允许新构建自动启动。这些触发器可基于新的容器镜像和各种配置变化,不断更新应用容器。OpenShift 可以定义两类构建触发器:

镜像更改触发器
镜像更改触发器会重新构建应用容器镜像,以体现其父镜像所做的更改。

配置更改触发器
配置更改触发器会在构建配置创建后构建应用容器镜像。


在以后的红帽 OpenShift 容器平台版本中,构建配置触发器也会在构建配置发生变化时启动新的应用构建。

镜像更改触发器使得开发人员无需密切留意应用父镜像中的各种变化。镜像更改触发器会由可向 OpenShift 主控机发送相关通知的注册表服务器(如 OpenShift 内部注册表)自动激活。如果注册表服务器不支持通知功能,则您需要定期运行 oc import-image 命令,以验证注册表服务器中的容器镜像是否有所变化。
oc new-app 命令会自动采用 Source 或 Docker 构建策略为应用创建镜像更改触发器。

  • 采用 Source 策略时,父镜像就是应用编程语言的 S2I 构建器镜像。

  • 采用 Docker 策略时,父镜像就是应用 Dockerfile 中 FROM 指令所引用的镜像。

要为构建配置添加镜像更改触发器,请使用 oc set triggers 命令:

oc set triggers bc/name --from-image=project/image:tag

一个构建配置可以包含多个镜像更改触发器,但是采用 Source 和 Docker 策略的构建配置应该只需要一个镜像更改触发器。



使用 webhook 触发器

OpenShift webhook 触发器是可启动新构建的 HTTP API 端点。如果使用 webhook 以更改源代码的方式将 OpenShift 与版本控制系统 (VCS)(如 Git)进行整合,则会在 OpenShift 中启动新的构建。

即使软件并非 VCS,也可以使用这些 API 端点,但是 OpenShift 构建只能从 Git 服务器获取源代码。
红帽 OpenShift 容器平台 3.6 提供了专用的 webhook 类型,用于支持与以下 VCS 软件兼容的 API 端点:

GitLab
GitHub
Bitbucket

红帽 OpenShift 容器平台 3.6 还提供了一种通用 webhook 类型,用于获取 OpenShift 定义的载荷。通用 webhook 可供任意软件用于启动 OpenShift 构建。请参见本节末尾的产品文档参考资料,以了解通用 webhook 载荷的语法以及可针对各类 webhook 提出的 HTTP API 请求。

oc new-app 命令可以创建通用 webhook 和 Git webhook。要向构建配置添加其他类型的 webhook,请使用 oc set triggers 命令。例如,要向构建配置添加 GitLab webhook,请使用以下命令:

oc set triggers bc/name --from-gitlab

如果构建配置已包含 GitLab webhook,则先前的命令会重置嵌在 URL 中的身份验证机密。您必须更新自己的 GitLab 项目,以使用新的 webhook URL。

触发构建

  • PHP S2I 构建器镜像 (rhscl/php-70-rhel7:latest)。

  • PHP S2I 构建器镜像的新版本 (php-70-rhel7-newer.tar.gz)

  • 应用 Git 存储库 (trigger-builds)。

基于 Git 中的来源创建新应用。将应用命名为 trigger。
应用的自动构建:Openshift开发系列第二篇_java_20
应用的自动构建:Openshift开发系列第二篇_java_21
应用的自动构建:Openshift开发系列第二篇_java_22

如果镜像流检测到其基础镜像有所变化,则最后一个触发器(即 ImageChange 触发器)会启动新构建。

更新镜像流以启动新构建。查看用于标记 rhscl/php-70-rhel7 的新版本并将其推送至课堂私有注册表的脚本。该脚本位于 /home/student/DO288/labs/trigger-builds 文件夹中:
应用的自动构建:Openshift开发系列第二篇_java_23
应用的自动构建:Openshift开发系列第二篇_java_24

要更新 openshift 命名空间中的镜像流,用户需要拥有集群管理员特权。以集群管理员身份登录 OpenShift。


更新 php 镜像流,以从新的容器镜像中获取元数据。外部注册表会使用 docker-distribution 软件包,而且不会向 OpenShift 发送镜像更改通知。
应用的自动构建:Openshift开发系列第二篇_java_25

镜像流更新操作触发了新的构建。列出所有构建,以验证第二个构建是否已启动:
应用的自动构建:Openshift开发系列第二篇_java_26