为了充分利用容器在开发和运行企业级应用程序方面的能力,请确保您的环境受支持工具的支持,这些工具允许容器:
创建为可与其他容器化和非容器化服务连接的独立微服务。例如,您可能希望将您的应用程序与数据库连接或附加监控应用程序。
具有弹性,因此如果服务器崩溃或需要停机进行维护或退役,容器可以在另一台机器上启动。
自动化以自动获取代码更改,然后启动和部署新版本。
随着需求的增加,可以扩展或复制以拥有更多实例来服务客户端,然后随着需求的减少而缩减到更少的实例。
根据应用程序的类型以不同的方式运行。例如,一个应用程序可能每月运行一次以生成报告,然后退出。另一个应用程序可能需要持续运行并对客户端高度可用。
进行管理,以便您可以监控应用程序的状态并在出现问题时做出反应。
容器的广泛接受以及对使它们成为企业级应用所需工具和方法的需求,导致了多种选择。
本节的其余部分解释了在 AWS 上构建和部署 Red Hat OpenShift Service 中的容器化 Kubernetes 应用程序时可以创建的资源选项。它还描述了您可以针对不同类型的应用程序和开发需求使用哪些方法。
您可以通过多种方式使用容器来进行应用程序开发,并且不同的方法可能更适合不同的情况。为了说明这种多样性,所呈现的一系列方法从开发单个容器开始,最终将该容器部署为大型企业的关键任务应用程序。这些方法展示了您可以用于容器化应用程序开发的不同工具、格式和方法。本主题介绍
构建简单的容器并将其存储在镜像仓库中
创建 Kubernetes 清单并将其保存到 Git 仓库
制作 Operator 以与他人共享您的应用程序
您有一个应用程序的想法,并且想要将其容器化。
首先,您需要一个用于构建容器的工具,例如 buildah 或 docker,以及一个描述容器中内容的文件,这通常是Dockerfile。
接下来,您需要一个位置来推送生成的容器镜像,以便您可以将其拉取到任何您想要运行它的位置。此位置是一个容器镜像仓库。
除 Dockerfile(您自己提供)外,大多数 Linux 操作系统默认安装了这些组件的一些示例。
下图显示了构建和推送镜像的过程
如果您使用运行 Red Hat Enterprise Linux (RHEL) 作为操作系统的计算机,则创建容器化应用程序的过程需要以下步骤:
安装容器构建工具:RHEL 包含一组工具,包括 podman、buildah 和 skopeo,您可以使用这些工具来构建和管理容器。
创建 Dockerfile 以组合基础镜像和软件:有关构建容器的信息将写入名为Dockerfile
的文件中。在该文件中,您将标识您从中构建的基础镜像、安装的软件包以及复制到容器中的软件。您还可以标识参数值,例如您在容器外部公开的网络端口和在容器内部挂载的卷。将您的 Dockerfile 和您想要容器化的软件放在 RHEL 系统上的目录中。
运行 buildah 或 docker build:运行buildah build-using-dockerfile
或docker build
命令将您选择的基础镜像拉取到本地系统,并创建一个本地存储的容器镜像。您也可以使用 buildah 在没有 Dockerfile 的情况下构建容器镜像。
标记并推送到镜像仓库:向您的新容器镜像添加一个标记,以标识您想要存储和共享容器的镜像仓库的位置。然后通过运行podman push
或docker push
命令将该镜像推送到镜像仓库。
拉取并运行镜像:从任何具有容器客户端工具(例如 podman 或 docker)的系统中,运行一个命令来标识您的新镜像。例如,运行podman run <image_name>
或docker run <image_name>
命令。这里<image_name>
是新容器镜像的名称,类似于quay.io/myrepo/myapp:latest
。镜像仓库可能需要凭据才能推送和拉取镜像。
使用 buildah、podman 和 skopeo 构建和管理容器会生成行业标准的容器镜像,其中包含专门针对在 AWS 上的 Red Hat OpenShift Service 或其他 Kubernetes 环境中部署容器而调整的功能。这些工具是无守护进程的,可以在没有 root 权限的情况下运行,运行它们的开销更少。
在 Kubernetes 1.20 中已弃用对 Docker Container Engine 作为容器运行时的支持,并将在未来版本中删除。但是,Docker 生成的镜像将继续在您的集群中与所有运行时(包括 CRI-O)一起工作。有关更多信息,请参阅Kubernetes 博客公告。 |
当您最终在 AWS 上的 Red Hat OpenShift Service 中运行容器时,您将使用CRI-O容器引擎。CRI-O 在 AWS 上的 Red Hat OpenShift Service 集群中的每个工作节点和控制平面机器上运行,但 CRI-O 尚未支持作为 AWS 上 Red Hat OpenShift Service 之外的独立运行时。
您选择构建应用程序的基础镜像包含一组类似于 Linux 系统的软件。当您构建自己的镜像时,您的软件将被放置到该文件系统中,并且会将该文件系统视为其操作系统。选择此基础镜像会对容器未来的安全性和可升级性产生重大影响。
Red Hat 提供了一组新的基础镜像,称为Red Hat 通用基础镜像(UBI)。这些镜像基于 Red Hat Enterprise Linux,与 Red Hat 过去提供的基础镜像类似,但有一个主要区别:它们可以免费重新分发,无需 Red Hat 订阅。因此,您可以使用 UBI 镜像构建您的应用程序,而无需担心它们是如何共享的或需要为不同的环境创建不同的镜像。
这些UBI镜像具有标准版、初始化版和精简版。您还可以使用Red Hat软件集合镜像作为依赖于特定运行时环境(例如Node.js、Perl或Python)的应用程序的基础。某些这些运行时基础镜像的特殊版本被称为Source-to-Image (S2I)镜像。使用S2I镜像,您可以将代码插入到一个已准备好运行该代码的基础镜像环境中。
您可以直接从AWS上的Red Hat OpenShift Service Web UI使用S2I镜像。在开发者视角中,导航到+添加视图,并在开发者目录磁贴中查看开发者目录中所有可用的服务。
容器注册表是您存储容器镜像的地方,以便您可以与他人共享这些镜像,并使其可用于最终运行它们的平台。您可以选择大型的公共容器注册表,这些注册表提供免费帐户或提供更多存储空间和特殊功能的高级版本。您还可以安装自己的注册表,该注册表可以专供您的组织使用,或有选择地与他人共享。
要获取Red Hat镜像和认证合作伙伴镜像,您可以从Red Hat注册表中获取。Red Hat注册表由两个位置表示:registry.access.redhat.com
(未经身份验证且已弃用)和registry.redhat.io
(需要身份验证)。您可以从Red Hat生态系统目录的容器镜像部分了解Red Hat和合作伙伴镜像。除了列出Red Hat容器镜像外,它还显示有关这些镜像的内容和质量的详细信息,包括基于应用安全更新的健康评分。
大型公共注册表包括Docker Hub和Quay.io。Quay.io注册表由Red Hat拥有和管理。AWS上的Red Hat OpenShift Service中使用的许多组件都存储在Quay.io中,包括容器镜像和用于部署AWS上的Red Hat OpenShift Service本身的Operators。Quay.io还提供存储其他类型内容的方法,包括Helm图表。
如果您想要自己的私有容器注册表,AWS上的Red Hat OpenShift Service本身包含一个私有容器注册表,该注册表与AWS上的Red Hat OpenShift Service一起安装并在其集群上运行。Red Hat还提供名为Red Hat Quay的Quay.io注册表的私有版本。Red Hat Quay包括地理复制、Git构建触发器、Clair镜像扫描以及许多其他功能。
此处提到的所有注册表都可能需要凭据才能从这些注册表下载镜像。其中一些凭据由AWS上的Red Hat OpenShift Service在集群范围内提供,而其他凭据可以分配给个人。
虽然容器镜像是容器化应用程序的基本构建块,但还需要更多信息才能在Kubernetes环境(例如AWS上的Red Hat OpenShift Service)中管理和部署该应用程序。创建镜像后的典型后续步骤是:
了解在Kubernetes清单中使用的不同资源
对您正在运行的应用程序类型做出一些决定
收集支持组件
创建一个清单并将该清单存储在Git存储库中,以便您可以将其存储在源版本控制系统中、对其进行审计、跟踪它、将其提升并部署到下一个环境、必要时将其回滚到早期版本以及与他人共享它。
虽然容器镜像是Docker的基本单元,但Kubernetes使用的基本单元称为Pod。Pod代表构建应用程序的下一步。一个Pod可以包含一个或多个容器。关键是Pod是您部署、缩放和管理的单个单元。
可扩展性和命名空间可能是确定Pod中包含内容时需要考虑的主要项目。为方便部署,您可能希望在Pod中部署一个容器,并在Pod中包含其自身的日志记录和监控容器。稍后,当您运行Pod并需要扩展其他实例时,这些其他容器也会随之扩展。对于命名空间,Pod中的容器共享相同的网络接口、共享存储卷和资源限制(例如内存和CPU),这使得更容易将Pod的内容作为一个单元进行管理。Pod中的容器还可以使用标准进程间通信(例如System V信号量或POSIX共享内存)相互通信。
虽然单个Pod代表Kubernetes中的可扩展单元,但服务提供了一种将一组Pod组合在一起以创建完整的、稳定的应用程序的方法,该应用程序可以完成负载平衡等任务。服务也比Pod更持久,因为服务会保持在相同的IP地址可用,直到您将其删除。当服务正在使用时,它会按名称请求,AWS上的Red Hat OpenShift Service集群会将该名称解析为您可以访问构成该服务的Pod的IP地址和端口。
容器化应用程序本质上与其运行的操作系统以及扩展的用户分离。Kubernetes清单的一部分描述了如何通过定义网络策略来将应用程序公开到内部和外部网络,这些策略允许对与容器化应用程序的通信进行细粒度控制。要将来自集群外部的HTTP、HTTPS和其他服务的传入请求连接到集群内部的服务,您可以使用Ingress
资源。
如果您的容器需要磁盘存储而不是数据库存储(这可能是通过服务提供的),您可以向清单中添加卷以使该存储可用于您的Pod。您可以配置清单以创建持久卷 (PV) 或动态创建添加到您的Pod
定义中的卷。
定义构成应用程序的一组Pod后,您可以在Deployment
和DeploymentConfig
对象中定义这些Pod。
接下来,考虑您的应用程序类型如何影响其运行方式。
Kubernetes定义了不同类型的适合不同类型应用程序的工作负载。要确定适合您应用程序的工作负载,请考虑该应用程序是否:
旨在运行到完成并结束。例如,一个应用程序启动以生成报告,并在报告完成后退出。然后该应用程序可能一个月都不会再次运行。适合这些类型应用程序的Red Hat OpenShift Service on AWS对象包括Job
和CronJob
对象。
预期持续运行。对于长期运行的应用程序,您可以编写部署。
需要高可用性。如果您的应用程序需要高可用性,则需要调整部署规模以拥有多个实例。一个Deployment
或DeploymentConfig
对象可以包含一个副本集来满足此类应用程序的需求。使用副本集,Pod 可以在多个节点上运行,以确保应用程序始终可用,即使某个工作节点宕机。
需要在每个节点上运行。某些类型的 Kubernetes 应用程序旨在在集群本身的每个主节点或工作节点上运行。DNS 和监控应用程序就是需要在每个节点上持续运行的应用程序示例。您可以将此类应用程序作为守护进程集运行。您还可以根据节点标签在节点子集上运行守护进程集。
需要生命周期管理。当您希望移交应用程序以便其他人可以使用时,请考虑创建一个Operator。Operator 允许您构建智能功能,以便它可以自动处理备份和升级等操作。结合 Operator 生命周期管理器 (OLM),集群管理器可以将 Operator 公开给选定的命名空间,以便集群中的用户可以运行它们。
具有身份或编号要求。应用程序可能具有身份要求或编号要求。例如,您可能需要运行应用程序的三个实例,并将实例命名为0
、1
和2
。有状态集适用于此类应用程序。有状态集最适用于需要独立存储的应用程序,例如数据库和 ZooKeeper 集群。
您编写的应用程序可能需要支持组件,例如数据库或日志记录组件。为了满足这一需求,您可以从 Red Hat OpenShift Service on AWS Web 控制台中提供的以下目录中获取所需的组件。
OperatorHub,可在每个 Red Hat OpenShift Service on AWS 集群中使用。OperatorHub 向集群管理员提供来自 Red Hat、经过认证的 Red Hat 合作伙伴和社区成员的 Operator。集群管理员可以将这些 Operator 提供给集群中的所有或选定命名空间,以便开发人员启动它们并将其与他们的应用程序配置。
模板,对于一次性类型的应用程序非常有用,其中组件的生命周期在其安装后并不重要。模板提供了一种简单的方法,可以以最小的开销开始开发 Kubernetes 应用程序。模板可以是资源定义列表,例如Deployment
、Service
、Route
或其他对象。如果要更改名称或资源,可以在模板中将这些值设置为参数。
您可以根据开发团队的具体需求配置支持的 Operator 和模板,然后将它们提供给开发人员工作的命名空间。许多人将共享模板添加到openshift
命名空间,因为它可以从所有其他命名空间访问。
如果您要使应用程序可供其他人运行,则可能更倾向于将应用程序打包并部署为 Operator。如前所述,Operator 为您的应用程序添加了一个生命周期组件,该组件承认运行应用程序的任务并非在安装后立即完成。
当您将应用程序创建为 Operator 时,您可以构建您自己关于如何运行和维护应用程序的知识。您可以构建用于升级应用程序、备份应用程序、扩展应用程序或跟踪其状态的功能。如果正确配置应用程序,则维护任务(例如更新 Operator)可以自动且对 Operator 用户不可见地发生。
一个有用的 Operator 示例是设置为在特定时间自动备份数据的 Operator。让 Operator 在设定的时间管理应用程序的备份可以避免系统管理员记住执行此操作。
任何传统上以手动方式完成的应用程序维护,例如备份数据或轮换证书,都可以通过 Operator 自动完成。