繁体   English   中英

K8s:使用 dbs 的 node.js 应用程序的部署模式

[英]K8s: deployment patterns for node.js apps with dbs

你好!

我的问题与通过 k8s、架构模式部署 node.js 应用程序有关,并将它们与 DB 连接。

 alpha | beta | gamma1 | gamma2

我有以下 node.js 应用程序服务,其中一些可通过应用程序实例(如 gamma)进行扩展,另一些是独立的,所有这些都构建在带有.Dockefile的单个 docker 映像中并从中运行。

而且我还有一个非云数据库,比如弹性和 mongo 从他们的容器中运行.envmongo | elastic mongo | elastic

就目前而言,我的docker-compose.yml就像一个典型的 node.js 示例应用程序,但具有通用卷和桥接网络(除了我有多个 node.js 应用程序):

version: '3'
services:
  node:
    restart: always
    build: .
    ports:
      - 80:3000
    volumes:
      - ./:/code
  mongo:
    image: mongo
    ports:
      - 27017:27017
    volumes:
      - mongodb:/data/db
volumes:
 mongodb:

networks:
  test-network:
    driver: bridge

当前部署:

所有这些东西都在单个docker-compose.yml文件的单个重型 VPS(X CPU 内核、Y RAM、Z SSD,所有内容加载 70%)上运行。

我想问和实现的目标:

由于一个 VPS 已经不够用了,我想开始使用k8s和 Rancher。 所以问题是关于正确的部署:

例如,我有N个 VPS 连接在一个私有网络中,每个 VPS 是一个连接在一个集群中的工作程序,(使用 Rancher,当然其中一个是主节点)这给了我 X 核、Y RAM 和其他共享资源。

  1. 我是否需要另一个单独的集群(或专用网络中的 VPS 机器,但不是集群的一部分),并在其上运行 DB? 或者我可以在同一个集群中部署数据库? 如果集群中的每个 VPS(worker)只有 40GB 卷,而 DB 的增长会超过这个卷呢? 工作人员的共享资源是否包括共享卷空间?

  2. 拥有一个可以启动所有应用程序的图像是否正确,或者在 k8s 的情况下,我应该为每个服务拥有一个单独的 docker 图像吗? 因此,如果我在一个单一存储库中有 5 个 node.js 应用程序,我应该有 5 个单独的 docker-image,而不是一个常见的?

我会理解我的问题可能有一个复杂的答案,所以我会很高兴看到,不仅仅是答案,还有链接或与问题相关的任何内容。 如果您知道以及如何询问,则更容易找到或搜索某些内容。

一个纯粹的答案:

您的五项服务中的每一项都应该有自己的映像和自己的数据库。 只要您有办法备份它们、运行迁移和执行其他与数据库相关的事情,数据库就可以位于同一个集群中。 如果您的云提供商提供这些数据库的托管版本,那么将数据存储在集群之外也很好,并且可以帮助解决您提到的一些磁盘空间问题。

我倾向于将Helm用于实际部署机制,作为在部署时注入主机名和其他设置等内容的一种方式。 每个服务都有自己的 Dockerfile、自己的 Helm 图表、自己的package.json等等。 您的 CI 系统将分别构建和部署每个服务。

一个实用的答案:

在同一个镜像上运行多个容器做不同的工作在技术上没有任何问题。 如果您现在有一个存储库和一个构建系统,并且您不介意更改一项服务会导致所有服务重新部署,那么这种方法将可以正常工作。

无论您的存储库现在有什么构建系统,如果您使用这种方法 go,我会在存储库根目录中放置一个 Dockerfile 并且可能有一个 Helm 图表来部署它。 在 Helm 图表部署规范中,您可以覆盖命令以运行类似

# This fragment appears under containers: in a Deployment's Pod spec
# (this is Helm chart, Go text/template templated, YAML syntax)
image: {{ .Values.repository }}/{{ .Values.image }}:{{ .Values.tag }}
command: node service3/index.js

此处 Kubernetes 的术语与 Docker 的术语略有不同,特别是如果您使用入口点包装脚本。 Kubernetes command: args: CMD ENTRYPOINT

在任一情况下:

Kubernetes 中的许多东西动态分配基础设施。 例如,您可以设置一个水平 pod 自动扩缩器来根据负载设置部署的副本数,或者设置一个集群自动扩缩器来设置更多(云)实例来运行 Pod(如果需要)。 如果您有一个持久卷配置器,那么 Kubernetes PersistentVolumeClaim object 可以由动态分配的存储支持(例如,在 AWS 上,它会创建一个 EBS 卷),并且您不会受到单个节点的存储空间的限制。 您通常可以为数据库找到预构建的 Helm 图表; 如果没有,请使用 StatefulSet 让 Kubernetes 为您创建 PVC。

确保您的 CI 系统生成具有唯一标签的图像,可能基于时间戳或源代码控制提交 ID。 不要使用...:latest或其他固定字符串:Kubernetes 不会在更新时重新部署,除非image:字符串更改。

多个集群在很多方面都很棘手。 在我的日常工作中,每个环境(开发、预生产、生产)都有单独的集群,但应用程序本身在单个集群中运行,并且集群之间没有通信。 如果您可以管理存储,那么在同一个集群中运行数据库就可以了。

几个 Compose 选项不能很好地转换为 Kubernetes。 我特别建议删除volumes:在您执行任何特定于 Kubernetes 的操作之前,将您的代码绑定到容器中并验证您的映像是否正确运行。 如果您要替换映像中的整个源代码树,那么您实际上并没有真正运行映像,并且在本地调试会容易得多。 在 Kubernetes 中,您也几乎无法控制networks:但 Compose 中也不需要它们。

我无法回答您关于 VPS 机器设置的部分问题,但我可以就图像设置提出一些建议。

实际上,虽然您已经问过这个关于节点应用程序的问题,但它实际上不仅仅适用于节点。

关于docker镜像,有共同镜像或单独镜像; 通常,您和/或您的公司是否拥有共同的或单独的形象取决于您和/或您的公司。

两种方法各有利弊:

您可以将代码“烘焙”到映像中,并为每个应用程序提供不同的映像,但如果遇到任何安全漏洞,您必须修补、重建和重新部署所有映像。 如果您有 5 个应用程序都使用同一个库,但该库不在基础映像中,那么您必须对其进行 5 次修补,每个映像一次,重建映像并重新部署。

或者,您可以只使用包含所需库的单个基础映像,并将代码库安装在其中(例如作为配置映射),除非您必须在底层操作系统中修补某些内容,否则该基础映像永远不需要更改。 上面段落中提到的相同漏洞只需要在基础映像中进行修补,并且可以重新启动受影响的 Pod(无需重新部署)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM