将基于 VM 的应用程序移动到 Kubernetes
本教程可能会发生成本。 使用 成本估算器 根据您的预计使用量生成成本估算。
本教程将指导您完成使用 Kubernetes Service将基于 VM 的应用程序移动到 Kubernetes 集群的过程。Kubernetes Service 通过组合容器和 Kubernetes 技术,直观的用户体验以及内置安全性和隔离来提供强大的工具,以自动执行计算主机集群中容器化应用程序的部署,操作,缩放和监视。
本教程中的课程包括关于如何选取现有应用程序、将应用程序容器化以及将应用程序部署到 Kubernetes 集群的概念。 要将基于 VM 的应用程序容器化,可以在下列两个选项中进行选择。
- 识别整体应用程序中可以拆分为独立微服务的组件。 您可以将这些微服务打包,并将其部署到 Kubernetes中。
- 将整个应用程序容器化,然后将应用程序部署到 Kubernetes 集群。
根据您拥有的应用程序的类型不同,迁移应用程序的步骤也可能不同。 您可以使用此教程来了解在迁移应用程序之前必须执行的一般步骤和必须考虑的事项。
目标
- 了解如何识别基于虚拟机的应用程序中的微服务,并学习如何在虚拟机和 Kubernetes 之间映射组件。
- 了解如何将基于 VM 的应用程序容器化。
- 了解如何在 Kubernetes Service 中将容器部署到 Kubernetes 集群中。
- 将学到的所有做法付诸实践,在集群中运行 JPetStore 应用程序。
体系结构
使用 VM 的传统应用程序体系结构
下图显示了基于虚拟机的传统应用程序体系结构的示例。
{: caption="" caption-side="bottom"}架构图
- 用户将请求发送到应用程序的公共端点。 公共端点由负载均衡器服务表示,该负载均衡器对各个可用应用程序服务器实例之间的入局网络流量进行负载均衡。
- 负载均衡器选择一个在 VM 上运行的运行状况良好的应用程序服务器实例,并转发请求。 应用程序文件(如应用程序代码、配置文件和依赖项)存储在应用程序服务器虚拟机上。
- 应用程序服务器将应用程序数据存储在数据库虚拟机上运行的 MySQL。
容器化的体系结构
下图显示了在 Kubernetes 集群中运行的现代容器体系结构的示例。

- 用户将请求发送到应用程序的公共端点。 公共端点由 Ingress 应用程序负载均衡器 (ALB) 表示,该负载均衡器对集群中各个应用程序 pod 之间的入局网络流量进行负载均衡。 ALB 是一组规则,用于允许进入以公共方式公开的应用程序的入站网络流量。
- ALB 将请求转发到集群中某个可用的应用程序 pod。 应用程序 pod 在工作程序节点上运行,这些节点可以是虚拟机,也可以是物理机器。
- 应用程序 pod 将数据存储在持久卷中。 持久卷可用于在应用程序实例或工作程序节点之间共享数据。
- 应用程序 pod 将数据存储在 IBM Cloud 数据库服务中。 您可以在 Kubernetes 集群中运行自己的数据库,但使用受管的数据库即服务 (DBaaS) 通常更容易进行配置,并且提供了内置的备份和缩放。 您可以在 IBM Cloud 目录 中找到许多类型的数据库。
VM、容器和 Kubernetes
Kubernetes Service 提供了在 Kubernetes 集群中运行容器化应用程序的功能,并交付了以下工具和功能:
- 直观的用户体验和强大的工具。
- 内置的安全性和隔离功能,能够快速交付安全的应用程序。
- 云服务,包括 Watson™认知功能。
- 能够管理无状态应用程序和有状态工作负载的专用集群资源。
虚拟机与容器
VM,传统应用程序在本机硬件上运行。 单个应用程序通常不使用单个计算主机的完整资源。 大多数组织都尝试在单个计算主机上运行多个应用程序以避免浪费资源。 您可以运行同一应用程序的多个副本,但要提供隔离,可以使用 VM 在相同的硬件上运行多个应用程序实例 (VM)。 这些虚拟机拥有完整的操作系统堆栈,但由于运行时和磁盘上的重复,导致效率相对较低。
容器是打包应用程序及其所有依赖项的标准方法,以便您可以无缝地在环境之间移动应用程序。 与虚拟机不同,容器不会捆绑操作系统。 容器仅会打包应用程序代码、运行时、系统工具、库和设置。 容器比虚拟机更轻巧、可移植性更强、更高效。
此外,使用容器可以共享主机操作系统。 这样就能在减少重复的情况下仍提供隔离。 使用容器还可以丢弃不需要的文件(如系统库和二进制文件)以节省空间并减少攻击面。 请在 什么是容器?中阅读有关虚拟机和容器的更多信息。
Kubernetes 编排
Kubernetes 是一个容器编排器,用于管理工作节点集群中容器化应用程序的生命周期。 您的应用程序可能需要其他许多资源才能运行,如卷、网络、可帮助您连接其他云服务的私钥,以及安全密钥。 Kubernetes 帮助您将这些资源添加到应用程序。 Kubernetes 的密钥范例是其声明式模型。 用户提供所需的状态,Kubernetes 尝试满足描述的状态,然后保持该状态。
这个自定进度的 Kubernetes 研讨会可以帮助您获得 Kubernetes初步实践经验。 此外,请查看 Kubernetes 概念文档页面,了解更多关于 Kubernetes 的概念。
IBM 正在为您执行的操作
通过将 Kubernetes 集群与 IBM Cloud Kubernetes Service 一起使用,您可获得以下优点:
- 可在其中部署集群的多个数据中心。
- 对 Ingress 和负载均衡器联网选项的支持。
- 动态持久卷支持。
- IBM 管理的高可用性 Kubernetes 主节点。
调整集群大小
在设计集群体系结构时,您希望针对可用性、可靠性、复杂性和恢复来平衡成本。 IBM Cloud Kubernetes Service 中的 Kubernetes 集群根据应用程序的需求来提供体系结构选项。 只需进行少量规划,即可最充分地利用云资源,而不会过度设计或过度花费。 即使您高估或低估了集群,也可以通过改变工作节点的数量或类型轻松地扩大或缩小集群。
要使用 Kubernetes 在云中运行生产应用程序,请考虑下列各项:
- 您预期会有来自特定地理位置的流量吗? 如果有,请选择实际离您最近的位置,以获得最佳性能。
- 为了实现更高的可用性,需要有多少集群副本? 比较合适的起点是三个集群,一个用于开发,一个用于测试,一个用于生产。 查看 用于组织资源和分配访问权的最佳实践 解决方案指南,以创建多个环境。
- 工作程序节点需要什么硬件? 虚拟机还是裸机?
- 需要多少个工作程序节点? 这主要取决于应用程序规模,您拥有的节点数量越多,应用程序的弹性越高。
- 为了实现更高可用性,应该具备多少个副本? 在多个位置部署副本集群以提高应用程序可用性,并防止应用程序因某个位置故障而停止运行。
- 您的应用程序启动时需要哪些最少的资源? 您可能要测试应用程序运行所需的内存量和 CPU。 然后,您的工作程序节点应该有足够的资源来部署并启动应用程序。 接着,作为 pod 规范的一部分,确保设置资源配额。 Kubernetes 正是使用此设置来选择(或安排)有足够容量来支持请求的工作程序节点。 估算有多少个 pod 会在工作程序节点上运行,以及这些 pod 的资源需求。
- 何时增加工作节点的数量? 您可以监视集群使用情况,并根据需要增加节点数。 请参阅 监控群集健康状况。
- 是否需要冗余的可靠存储? 如果是,请为 NFS 存储创建一个持久卷声明,或将IBM Cloud绑定到您的容器。
- 是否需要在 Virtual Private Cloud 基础架构 或 经典基础架构 中部署集群? VPC 提供了私有云环境的安全性以及公共云的动态可伸缩性。
为了更具体地说明前面的步骤,假设您想在云端运行一个生产网络应用程序,并预计会有中等到高负载的流量。 让我们看一下您将需要哪些资源:
- 设置三个集群,一个用于开发,一个用于测试,一个用于生产。
- 开发和测试集群可以以最低的内存和CPU选项启动(例如,2个CPU 4GB和每个集群一个工作节点)。
- 对于生产集群,可能需要有更多资源才能保证性能、高可用性和弹性。 我们可以选择专用或裸机选项,至少配备4个CPU 16GB和两个工作节点。
确定要使用的数据库选项
利用 Kubernetes,您可以使用两个选项来处理数据库:
- 您可以在 Kubernetes 集群中运行数据库,以执行创建微服务来运行数据库所需的操作。 例如,如果使用的是 MySQL 数据库,那么需要完成以下步骤:
- 第二个选项是使用受管的数据库即服务 (DBaaS) 选项。 此选项通常更容易配置,并提供内置备份和缩放功能。 您可以在 IBM Cloud 目录 中找到许多类型的数据库。 要使用此选项,需要执行下列操作:
- 从 IBM Cloud 目录创建受管数据库即服务 (DBasS)。
- 将数据库凭证存储在私钥中。 您 Kubernetes的商店凭证 中了解更多关于密钥的秘密。
- 在应用程序中使用数据库即服务 (DBaaS)。
确定存储应用程序文件的位置
Kubernetes Service 提供了用于在不同 pod 中存储和共享数据的几个选项。 在灾难情况下,并非所有存储选项提供的持久性和可用性级别都是相同的。
非持久性数据存储
根据设计,容器和 pod 的生存时间短,并且可能会意外发生故障。 您可以在容器的本地文件系统中存储数据。 容器内的数据不能与其他容器或 pod 共享,并且在容器崩溃或被除去时会丢失。
了解如何为应用程序创建持久数据存储
通过使用原生 Kubernetes 持久卷,您可以将应用程序数据和容器数据持久化到 NFS 文件存储或 块存储中。
要供应 NFS 文件存储器或块存储器,必须通过创建持久卷声明 (PVC) 来为 pod 请求存储器。 在您的PVC中,您可以从预定义的存储类别中进行选择,这些类别定义了存储类型、以千兆字节为单位的存储容量、IOPS、数据保留策略以及存储的读写权限。 PVC 动态供应持久卷 (PV),用于表示 IBM Cloud 中的实际存储设备。 您可以将 PVC 安装到 pod 中以在 PV 中进行读写。 存储在 PV 中的数据即使在容器崩溃或者 pod 重新安排的情况下也是可用的。 IBM支持PV NFS 文件存储和块存储进行集群,为您的数据提供高可用性。
要了解如何创建 PVC,请按照 Kubernetes Service 存储文档中涵盖的步骤执行操作。
了解如何将现有数据移动到持久存储
要将数据从本地计算机复制到持久存储中,必须将 PVC 安装到 pod。 然后可以将数据从本地计算机复制到 pod 中的持久卷。
-
要复制数据,首先需要创建一个类似如下的配置:
kind: Pod apiVersion: v1 metadata: name: task-pv-pod spec: volumes: - name: task-pv-storage persistentVolumeClaim: claimName: mypvc containers: - name: task-pv-container image: nginx ports: - containerPort: 80 name: "http-server" volumeMounts: - mountPath: "/mnt/data" name: task-pv-storage
-
然后,要将数据从本地计算机复制到 pod,需要使用如下命令:
kubectl cp <local_filepath>/<filename> <namespace>/<pod>:<pod_filepath>
-
将数据从集群中的 pod 复制到本地计算机:
kubectl cp <namespace>/<pod>:<pod_filepath>/<filename> <local_filepath>/<filename>
为持久存储设置备份
文件共享和块存储器会供应到集群所在的位置。 存储器本身由 IBM 在集群服务器上托管以提供高可用性。 但是,文件共享和块存储器不会自动进行备份,因此它们在整个位置发生故障时可能无法进行访问。 为了防止数据丢失或损坏,可以设置定期备份,以便在需要时可用于复原数据。
更多信息,请参阅 NFS 文件存储和块存储 的存储选项规划。
准备代码
应用 12 因子原则
十二因子应用是一种构建云原生应用的方法。 当您要将应用程序容器化,将此应用程序移动到云,以及使用 Kubernetes 编排应用程序时,请务必理解并应用其中一些原则。 IBM Cloud 中要求使用其中一些原则。
需要以下关键原则:
- 代码库 - 在版本控制系统(如 Git 存储库)中跟踪所有源代码和配置文件,这在使用 DevOps 管道进行部署时是必需的。
- 构建、发布、运行 - 12 因子应用程序在构建、发布和运行阶段之间使用严格分离。 这可以使用集成的 DevOps Delivery Pipeline 自动执行,以在将应用程序部署到集群之前先构建和测试应用程序。 请查看 在 Kubernetes 教程,以了解如何设置持续集成和交付管道。 它涵盖了源代码控制、构建、测试和部署阶段的设置,并演示了如何添加集成,例如安全扫描程序、通知和分析。
- 配置 - 所有配置信息都存储在环境变量中。 任何服务凭证都不会在应用程序代码中进行硬编码。 要存储凭证,可以使用 Kubernetes 私钥。 稍后提供有关凭证的更多信息。
将凭证存储在 Kubernetes 私钥中
将凭证存储在应用程序代码中绝不是一个好的做法。 相反,Kubernetes 提供了所谓的 “秘密”,用于保存敏感信息,例如密码、OAuth令牌或SSH密钥。 Kubernetes
默认情况下对密钥进行加密,这使得密钥成为存储敏感数据的一种更安全、更灵活的选择,而不是将这些数据原封不动地存储在 pod
定义或容器镜像中。
Kubernetes 中使用秘密的一种方法是这样做:
-
创建名为
cloud-secrets.txt
的文件,并在其中存储任何云服务的服务凭证。{ "url": "<SERVICE_URL>", "api_key": <API_Key> }
-
然后,通过运行以下命令创建一个 Kubernetes 密钥,并通过运行以下命令后使用
kubectl get secrets
验证密钥是否已创建:kubectl create secret generic cloud-service-secret --from-file=cloud-secrets.txt=./cloud-secrets.txt
将应用程序容器化
要打包您的应用程序,您必须创建一个容器镜像。
镜像是 由Dockerfile 创建的,该文件包含构建镜像的说明和命令。 Dockerfile 可能会在其单独存储的指令中引用构建工件,例如应用程序、应用程序配置及其依赖项。
要为现有应用程序构建自己的 Dockerfile,可使用以下命令:
- FROM - 选择用于定义容器运行时的父映像。
- ADD/COPY - 将目录内容复制到容器中。
- WORKDIR - 在容器中设置工作目录。
- RUN - 安装应用程序在运行时期间需要的软件包。
- EXPOSE - 使一个端口在容器外部可用。
- ENV NAME - 定义环境变量。
- CMD - 定义在容器启动时运行的命令。
图像通常存储在注册表中,注册表可以设置为公众可访问(公共注册表),也可以设置为仅对特定用户组开放(私有注册表)。 开始使用 Docker 和 Kubernetes 在集群中创建第一个容器化应用程序时,可以使用公共注册表(如 Docker Hub)。 但是对于企业应用程序,请使用专用注册表(如在 IBM Cloud Container Registry 中提供的注册表),以保护映像不被未经授权的用户使用和更改。
要将应用程序容器化并将其存储在 IBM Cloud Container Registry 中,请执行以下操作:
- 您需要创建一个Dockerfile,以下代码是一个Dockerfile的示例。
# Build JPetStore war FROM openjdk:8 as builder COPY . /src WORKDIR /src RUN ./build.sh all # Use WebSphere Liberty base image from the Docker Store FROM websphere-liberty:latest # Copy war from build stage and server.xml into image COPY --from=builder /src/dist/jpetstore.war /opt/ibm/wlp/usr/servers/defaultServer/apps/ COPY --from=builder /src/server.xml /opt/ibm/wlp/usr/servers/defaultServer/ RUN mkdir -p /config/lib/global COPY lib/mysql-connector-java-3.0.17-ga-bin.jar /config/lib/global
- 创建 Dockerfile 之后,接着需要构建容器映像并将其推送到 IBM Cloud Container Registry。 您可以使用以下命令构建容器:
docker build . -t <image_name> docker push <image_name>
将应用程序部署到 Kubernetes 集群
在构建容器映像并将其推送到云之后,接下来需要将其部署到 Kubernetes 集群。 要执行该操作,需要创建 deployment.yaml 文件。
了解如何创建 Kubernetes deployment.yaml 文件
要创建 Kubernetes deployment.yaml 文件,需要执行以下操作:
-
创建一个 deployment.yaml 文件,以下是 部署 YAML 文件的示例。
-
在deployment.yaml,您可以为容器定义 资源配额,以指定每个容器正常启动所需的CPU和内存。 如果容器已指定资源配额,那么 Kubernetes 调度程序在决定将 pod 放置在哪个工作程序节点上时,可以做出更好的选择。
-
接下来,您可以使用以下命令创建和查看部署和创建的服务:
kubectl create -f <filepath/deployment.yaml> kubectl get deployments kubectl get services kubectl get pods
摘要
在本教程中,您学到了以下内容:
- VM、容器和 Kubernetes 之间的差别。
- 如何针对不同的环境类型(开发、测试、生产)定义集群。
- 如何处理数据存储以及持久数据存储的重要性。
- 对应用程序应用 12 因子原则并使用私钥作为 Kubernetes 中的凭证。
- 创建容器镜像并将其推送到 IBM Cloud Container Registry。
- 创建 Kubernetes 部署文件,并将容器镜像部署到 Kubernetes。
将学到的所有做法付诸实践,在集群中运行 JPetStore 应用程序。
为了将所学知识付诸实践,请按照 演示在您的集群上运行 JPetStore,并应用所学概念。 JPetStore具有一些扩展功能,允许您通过将图像分类作为单独的微服务来扩展 Kubernetes应用。