×

为了充分利用容器在开发和运行企业级应用程序时的能力,请确保您的环境受支持的工具支持,这些工具允许容器:

  • 创建为可以连接到其他容器化和非容器化服务的独立微服务。例如,您可能希望将您的应用程序与数据库连接起来,或将监控应用程序附加到它。

  • 具有弹性,因此如果服务器崩溃或需要停机进行维护或退役,容器可以在另一台机器上启动。

  • 自动获取代码更改,然后启动和部署新版本。

  • 随着需求增加而扩展或复制,以便有更多实例为客户端服务,然后随着需求减少而缩减到更少的实例。

  • 根据应用程序的类型以不同的方式运行。例如,一个应用程序可能每月运行一次以生成报告,然后退出。另一个应用程序可能需要持续运行并对客户端高度可用。

  • 进行管理,以便您可以监视应用程序的状态并在出现问题时做出反应。

容器的广泛接受以及由此产生的使其成为企业就绪的工具和方法的要求,导致了它们的许多选项。

本节的其余部分解释了在 OpenShift Dedicated 中构建和部署容器化 Kubernetes 应用程序时可以创建的资产选项。它还描述了您可以针对不同类型的应用程序和开发需求使用哪些方法。

关于开发容器化应用程序

您可以通过多种方式进行容器化应用程序开发,不同的方法可能更适合不同的情况。为了说明其中的一些多样性,所提出的方法系列从开发单个容器开始,最终将该容器部署为大型企业的关键任务应用程序。这些方法展示了您可以使用容器化应用程序开发所采用的不同工具、格式和方法。本主题描述了

  • 构建简单的容器并将其存储在注册表中

  • 创建 Kubernetes 清单并将其保存到 Git 存储库

  • 制作 Operator 以与他人共享您的应用程序

构建简单的容器

您有一个应用程序的想法,并且想要将其容器化。

首先,您需要一个构建容器的工具,例如 buildah 或 docker,以及一个描述容器内容的文件,通常是 Dockerfile

接下来,您需要一个位置来推送生成的容器镜像,以便您可以将其拉取到任何想要运行它的位置。这个位置就是一个容器注册表。

大多数 Linux 操作系统默认安装了这些组件的一些示例,Dockerfile 除外,您需要自己提供 Dockerfile。

下图显示了构建和推送镜像的过程

Creating and pushing a containerized application
图 1. 创建一个简单的容器化应用程序并将其推送到注册表

如果您使用运行 Red Hat Enterprise Linux (RHEL) 的计算机作为操作系统,则创建容器化应用程序的过程需要以下步骤

  1. 安装容器构建工具:RHEL 包含一组工具,包括 podman、buildah 和 skopeo,您可以使用这些工具来构建和管理容器。

  2. 创建一个 Dockerfile 来组合基础镜像和软件:有关构建容器的信息将写入名为 Dockerfile 的文件中。在此文件中,您将标识要从中构建的基础镜像、要安装的软件包以及要复制到容器中的软件。您还可以标识参数值,例如在容器外部公开的网络端口和在容器内部挂载的卷。将您的 Dockerfile 和您想要容器化的软件放在 RHEL 系统上的一个目录中。

  3. 运行 buildah 或 docker build:运行 buildah build-using-dockerfiledocker build 命令将您选择的基础镜像拉取到本地系统,并创建一个存储在本地的容器镜像。您也可以使用 buildah 构建不使用 Dockerfile 的容器镜像。

  4. 标记并推送到注册表:向您的新容器镜像添加一个标记,以标识您想要存储和共享容器的注册表位置。然后通过运行 podman pushdocker push 命令将该镜像推送到注册表。

  5. 拉取并运行镜像:从任何具有容器客户端工具(例如 podman 或 docker)的系统中,运行一个标识您的新镜像的命令。例如,运行 podman run <image_name>docker run <image_name> 命令。这里 <image_name> 是您新容器镜像的名称,类似于 quay.io/myrepo/myapp:latest。注册表可能需要凭据才能推送和拉取镜像。

容器构建工具选项

使用 buildah、podman 和 skopeo 构建和管理容器会生成行业标准的容器镜像,其中包含专门针对在 OpenShift Dedicated 或其他 Kubernetes 环境中部署容器而调整的功能。这些工具是无守护进程的,可以在没有 root 权限的情况下运行,运行它们的开销更少。

在 Kubernetes 1.20 中,对 Docker Container Engine 作为容器运行时的支持已弃用,并在未来的版本中将被删除。但是,Docker 生成的镜像将继续在您的集群中与所有运行时一起工作,包括 CRI-O。有关更多信息,请参阅 Kubernetes 博客公告

当您最终在 OpenShift Dedicated 中运行容器时,您将使用 CRI-O 容器引擎。CRI-O 运行在 OpenShift Dedicated 集群中的每个工作节点和控制平面机器上,但 CRI-O 尚未支持作为 OpenShift Dedicated 之外的独立运行时。

基础镜像选项

您选择在其上构建应用程序的基础镜像包含一组软件,这些软件对您的应用程序来说类似于 Linux 系统。当您构建自己的镜像时,您的软件将被放入该文件系统中,并且会看到该文件系统,就好像它正在查看其操作系统一样。选择此基础镜像会对您将来容器的安全性和效率以及可升级性产生重大影响。

Red Hat 提供了一组新的基础镜像,称为 Red Hat 通用基础镜像 (UBI)。这些镜像基于 Red Hat Enterprise Linux,与 Red Hat 过去提供的基础镜像类似,但有一个主要区别:它们可以在没有 Red Hat 订阅的情况下免费再分发。因此,您可以使用 UBI 镜像构建应用程序,而无需担心它们是如何共享的,也无需为不同的环境创建不同的镜像。

这些 UBI 镜像具有标准版、init 版和精简版。您还可以使用 Red Hat 软件集合 镜像作为依赖于特定运行时环境(例如 Node.js、Perl 或 Python)的应用程序的基础。某些这些运行时基础镜像的特殊版本称为 Source-to-Image (S2I) 镜像。使用 S2I 镜像,您可以将代码插入到一个准备好运行该代码的基础镜像环境中。

您可以直接从 OpenShift Dedicated Web UI 使用 S2I 镜像。在“开发者”视角中,导航到“+添加”视图,在“开发者目录”磁贴中,查看开发者目录中所有可用的服务。

OpenShift Dedicated Developer Catalog
图 2. 为需要特定运行时的应用程序选择 S2I 基础镜像

注册表选项

容器注册表是您存储容器镜像的地方,这样您可以与他人共享它们,并使它们可用于最终运行它们的平台。您可以选择大型公共容器注册表,这些注册表提供免费帐户或提供更多存储空间和特殊功能的高级版本。您还可以安装自己的注册表,该注册表可以专供您的组织使用,也可以有选择地与他人共享。

要获取 Red Hat 镜像和认证合作伙伴镜像,您可以从 Red Hat Registry 中获取。Red Hat Registry 由两个位置表示:registry.access.redhat.com(未经身份验证且已弃用)和 registry.redhat.io(需要身份验证)。您可以从 Red Hat 生态系统目录的容器镜像部分 了解 Red Hat 和合作伙伴镜像在 Red Hat Registry 中的信息。除了列出 Red Hat 容器镜像外,它还显示有关这些镜像的内容和质量的广泛信息,包括基于应用的安全更新的健康评分。

大型公共注册表包括 Docker HubQuay.io。Quay.io 注册表由 Red Hat 拥有和管理。OpenShift Dedicated 中使用的许多组件都存储在 Quay.io 中,包括容器镜像和用于部署 OpenShift Dedicated 本身的 Operators。Quay.io 还提供了存储其他类型内容的方法,包括 Helm 图表。

如果您想要自己的私有容器注册表,OpenShift Dedicated 本身包含一个与 OpenShift Dedicated 一起安装并在其集群上运行的私有容器注册表。Red Hat 还提供 Quay.io 注册表的私有版本,称为 Red Hat Quay。Red Hat Quay 包括地理复制、Git 构建触发器、Clair 镜像扫描以及许多其他功能。

此处提到的所有注册表都可能需要凭据才能从这些注册表下载镜像。一些凭据是从 OpenShift Dedicated 以集群范围的方式提供的,而其他凭据可以分配给个人。

为 OpenShift Dedicated 创建 Kubernetes 清单

虽然容器镜像是容器化应用程序的基本构建块,但在 Kubernetes 环境(例如 OpenShift Dedicated)中管理和部署该应用程序还需要更多信息。创建镜像后的典型后续步骤是

  • 了解您在 Kubernetes 清单中使用的不同资源

  • 对您正在运行的应用程序类型做出一些决定

  • 收集支持组件

  • 创建清单并将该清单存储在 Git 仓库中,以便您可以将其存储在源版本控制系统中,对其进行审计、跟踪,并将其提升和部署到下一个环境,如有必要,可以回滚到早期版本,并与他人共享。

关于 Kubernetes Pod 和服务

虽然容器镜像是 Docker 的基本单元,但 Kubernetes 使用的基本单元称为Pod。Pod 代表构建应用程序的下一步。一个 Pod 可以包含一个或多个容器。关键在于 Pod 是您部署、扩展和管理的单个单元。

可扩展性和命名空间可能是确定 Pod 中包含内容时需要考虑的主要因素。为方便部署,您可能希望在一个 Pod 中部署一个容器,并在 Pod 中包含其自己的日志记录和监控容器。之后,当您运行 Pod 并需要扩展另一个实例时,这些其他容器也会随之扩展。对于命名空间,Pod 中的容器共享相同的网络接口、共享存储卷和资源限制(例如内存和 CPU),这使得将 Pod 的内容作为一个单元进行管理更加容易。Pod 中的容器还可以使用标准进程间通信(例如 System V 信号量或 POSIX 共享内存)相互通信。

虽然单个 Pod 代表 Kubernetes 中的可扩展单元,但服务提供了一种将一组 Pod 组合在一起以创建完整的、稳定的应用程序的方法,该应用程序可以完成负载平衡等任务。服务也比 Pod 更持久,因为服务将保持相同的 IP 地址,直到您将其删除。当服务正在使用时,它会按名称被请求,OpenShift Dedicated 集群会将该名称解析为可以访问构成服务的 Pod 的 IP 地址和端口。

容器化应用程序的本质是与它们运行的操作系统以及扩展的用户分离。Kubernetes 清单的一部分描述了如何通过定义网络策略来将应用程序公开到内部和外部网络,这些策略允许对与容器化应用程序的通信进行细粒度控制。要将来自集群外部的 HTTP、HTTPS 和其他服务的传入请求连接到集群内部的服务,可以使用Ingress 资源。

如果您的容器需要磁盘存储而不是数据库存储(这可能通过服务提供),您可以向清单中添加以使该存储可用于您的 Pod。您可以配置清单以创建持久卷 (PV) 或动态创建添加到您的Pod 定义中的卷。

定义构成应用程序的一组 Pod 后,您可以在DeploymentDeploymentConfig 对象中定义这些 Pod。

应用程序类型

接下来,考虑您的应用程序类型如何影响其运行方式。

Kubernetes 定义了不同类型的 workload,适用于不同类型的应用程序。要确定适合您应用程序的 workload,请考虑以下几点:

  • 旨在运行到完成并结束。例如,一个应用程序启动以生成报告,并在报告完成时退出。然后该应用程序可能一个月都不会再次运行。适用于此类应用程序的 OpenShift Dedicated 对象包括JobCronJob 对象。

  • 预期持续运行。对于长期运行的应用程序,您可以编写一个部署。

  • 需要高可用性。如果您的应用程序需要高可用性,则需要调整部署的大小以拥有多个实例。DeploymentDeploymentConfig 对象可以包含一个副本集 用于此类应用程序。使用副本集,Pod 可以在多个节点上运行,以确保应用程序始终可用,即使某个工作节点发生故障。

  • 需要在每个节点上运行。某些类型的 Kubernetes 应用程序旨在在集群本身的每个主节点或工作节点上运行。DNS 和监控应用程序是需要在每个节点上持续运行的应用程序的示例。您可以将此类型的应用程序作为守护程序集运行。您还可以根据节点标签在节点子集上运行守护程序集。

  • 需要生命周期管理。当您想要移交应用程序以便其他人可以使用它时,请考虑创建一个Operator。Operator 允许您构建智能,以便它可以自动处理备份和升级等任务。结合 Operator Lifecycle Manager (OLM),集群管理器可以将 Operator 公开给选定的命名空间,以便集群中的用户可以运行它们。

  • 具有身份或编号要求。应用程序可能具有身份要求或编号要求。例如,您可能需要运行应用程序的三个实例,并将这些实例命名为012。一个有状态集适用于此应用程序。有状态集最适用于需要独立存储的应用程序,例如数据库和 ZooKeeper 集群。

可用的支持组件

您编写的应用程序可能需要支持组件,例如数据库或日志记录组件。为了满足这一需求,您可以从 OpenShift Dedicated Web 控制台中提供的以下目录中获取所需的组件:

  • OperatorHub,它在每个 OpenShift Dedicated 集群中都可用。OperatorHub 为集群运营商提供了来自 Red Hat、经过认证的 Red Hat 合作伙伴和社区成员的 Operator。集群运营商可以使这些 Operator 在集群中的所有或选定命名空间中可用,以便开发人员可以启动它们并使用其应用程序配置它们。

  • 模板,这对于一次性类型的应用程序很有用,在安装后组件的生命周期并不重要。模板提供了一种简单的方法,可以以最小的开销开始开发 Kubernetes 应用程序。模板可以是资源定义列表,例如DeploymentServiceRoute或其他对象。如果要更改名称或资源,可以在模板中将这些值设置为参数。

您可以根据开发团队的特定需求配置支持的 Operator 和模板,然后将它们提供给开发人员工作的命名空间。许多人将共享模板添加到openshift 命名空间,因为它可以从所有其他命名空间访问。

应用清单

Kubernetes 清单允许您创建更完整的 Kubernetes 应用程序组成组件的图片。您可以将这些清单编写为 YAML 文件,并通过将它们应用到集群来部署它们,例如,通过运行oc apply 命令。

后续步骤

此时,请考虑如何自动化您的容器开发流程。理想情况下,您应该拥有某种 CI 管道来构建镜像并将其推送到注册表。特别是,GitOps 管道将您的容器开发与用于存储构建应用程序所需软件的 Git 存储库集成在一起。

到目前为止的工作流程可能如下所示:

  • 第一天:您编写一些 YAML 文件。然后,您运行 oc apply 命令将该 YAML 应用到集群并测试其是否有效。

  • 第二天:您将 YAML 容器配置文件放入您自己的 Git 存储库中。从那里,想要安装该应用程序或帮助您改进该应用程序的人员可以提取 YAML 并将其应用到他们的集群以运行该应用程序。

  • 第三天:考虑为您的应用程序编写一个 Operator。

为 Operator 开发

如果您要使您的应用程序可供其他人运行,则可能更倾向于将您的应用程序打包并部署为 Operator。如前所述,Operator 为您的应用程序添加了一个生命周期组件,它承认运行应用程序的工作并非在安装后立即完成。

当您将应用程序创建为 Operator 时,您可以构建您自己关于如何运行和维护应用程序的知识。您可以构建用于升级应用程序、备份应用程序、扩展应用程序或跟踪其状态的功能。如果您正确配置了应用程序,则维护任务(例如更新 Operator)可以自动进行,并且对 Operator 的用户来说是不可见的。

一个有用的 Operator 示例是设置为在特定时间自动备份数据的 Operator。让 Operator 在设定的时间管理应用程序的备份可以避免系统管理员记住要执行此操作。

任何传统上手动完成的应用程序维护(例如备份数据或轮换证书)都可以通过 Operator 自动完成。