车里雅宾斯克的南桥和 Kubernetes 的 Bitrix

Sysadminka 系统管理员聚会正在车里雅宾斯克举行,在最后一次聚会上,我报告了我们在 Kubernetes 中的 1C-Bitrix 上运行应用程序的解决方案。

Bitrix、Kubernetes、Ceph——一个伟大的组合?

我将告诉您我们如何从这一切中整合出一个可行的解决方案。

走吧!

车里雅宾斯克的南桥和 Kubernetes 的 Bitrix

聚会于 18 月 XNUMX 日在车里雅宾斯克举行。 您可以在以下位置阅读有关我们聚会的信息: 时间垫 看看 YouTube.

如果您想向我们报告或作为听众 - 欢迎,请写信至 [电子邮件保护] 以及 Telegram t.me/vadimisakanov。

我的报告

车里雅宾斯克的南桥和 Kubernetes 的 Bitrix

幻灯片

解决方案“Kubernetes 中的 Bitrix,南桥 1.0 版”

我将以“Kubernetes 傻瓜”的形式讨论我们的解决方案,就像聚会上所做的那样。 但我假设您至少在 Wikipedia 上的文章级别上了解 Bitrix、Docker、Kubernetes、Ceph 这些词。

Kubernetes 中的 Bitrix 有哪些现成的?

整个互联网上关于Bitrix应用程序在Kubernetes中运行的信息非常少。
我只找到这些材料:

来自 Qsoft 的 Alexander Serbul、1C-Bitrix 和 Anton Tuzlukov 的报告:

我建议听一下。

从用户那里开发您自己的解决方案 塞基隆 关于哈布雷.
发现更多 这样的决定.

啊……实际上,仅此而已。

我警告您,我们尚未检查上面链接中解决方案的质量:)
顺便说一句,在准备我们的解决方案时,我与 Alexander Serbul 进行了交谈,当时他的报告还没有出现,所以在我的幻灯片中有一个项目“Bitrix 不使用 Kubernetes”。

但是已经有很多现成的 Docker 镜像可以在 Docker 中运行 Bitrix: https://hub.docker.com/search?q=bitrix&type=image

这足以在 Kubernetes 中为 Bitrix 创建完整的解决方案吗?
不。 有大量的问题需要解决。

Kubernetes 中 Bitrix 存在哪些问题?

首先,Dockerhub 提供的现成镜像不适合 Kubernetes

如果我们想构建一个微服务架构(在 Kubernetes 中我们通常这样做),我们需要将 Kubernetes 应用程序分离到容器中,并让每个容器执行一项小功能(并且做得很好)。 为什么只有一个? 简而言之,越简单越可靠。
更具体地说,请观看这​​篇文章和视频: https://habr.com/ru/company/southbridge/blog/426637/

Dockerhub 中的 Docker 镜像主要是基于一体化原则构建的,因此我们仍然必须制作自己的自行车,甚至从头开始创建镜像。

其次 - 站点代码是从管理面板编辑的

我们在网站上创建了一个新部分 - 代码已更新(添加了具有新部分名称的目录)。

如果您从管理面板更改了组件的属性,代码就会更改。

Kubernetes “默认情况下”无法处理此问题;容器必须是无状态的。

原因:集群中的每个容器(pod)仅处理一部分流量。 如果只更改一个容器(Pod)中的代码,那么不同 Pod 中的代码将会不同,站点的工作方式也会不同,并且站点的不同版本将显示给不同的用户。 你不能那样生活。

第三 - 您需要解决部署问题

如果我们有一个整体和一个“经典”服务器,一切都非常简单:我们部署一个新的代码库,迁移数据库,将流量切换到新版本的代码。 切换立即发生。
如果我们在 Kubernetes 中有一个站点,切入微服务,有很多带有代码的容器 - 哦。 您需要收集具有新版本代码的容器,推出它们而不是旧版本,正确迁移数据库,并且最好在访问者不注意的情况下完成此操作。 幸运的是,Kubernetes 帮助我们实现了这一点,支持大量不同类型的部署。

第四 - 你需要解决存储静态的问题

如果您的站点“只有”10 GB 并且您将其完全部署在容器中,那么您最终将得到 10 GB 的容器,并且需要很长时间才能部署。
您需要将站点“最重”的部分存储在容器之外,问题是如何正确执行此操作

我们的解决方案缺少什么?

整个Bitrix代码没有划分为微功能/微服务(以便注册是分开的,在线商店模块是分开的等)。 我们将整个代码库存储在每个容器中。

我们也不将数据库存储在 Kubernetes 中(我仍然在 Kubernetes 中实现了用于开发环境的数据库解决方案,但不用于生产环境)。

站点管理员仍然会注意到该站点在 Kubernetes 上运行。 “系统检查”功能无法正常工作;要从管理面板编辑站点代码,您必须首先单击“我要编辑代码”按钮。

问题已经确定,实现微服务的需求已经确定,目标也很明确——在 Kubernetes 中获得一个在 Bitrix 上运行应用程序的工作系统,同时保留 Bitrix 的功能和 Kubernetes 的优势。 让我们开始实施吧。

建筑

有许多带有 Web 服务器(工作人员)的“工作”pod。
下一项是 cron 任务(只需要一项)。
一项用于从管理面板编辑站点代码的升级(也只需要一项)。

车里雅宾斯克的南桥和 Kubernetes 的 Bitrix

我们解决问题:

  • 在哪里存储会话?
  • 缓存存放在哪里?
  • 在哪里存储静态数据,而不是在一堆容器中放置千兆字节的静态数据?
  • 数据库将如何工作?

Docker镜像

我们首先构建一个 Docker 镜像。

理想的选择是我们拥有一个通用映像,在其基础上我们获得工作 Pod、带有 Crontasks 的 Pod 以及升级 Pod。

我们做了这样的图像.

它包括nginx、apache/php-fpm(构建时可以选择)、用于发送邮件的msmtp和cron。

组装图像时,站点的整个代码库都会复制到 /app 目录(除了我们将移动到单独的共享存储的那些部分)。

微服务、服务

工人 Pod:

  • 带有 nginx 的容器 + apache/php-fpm 容器 + msmtp
  • 将msmtp移到单独的微服务中并没有成功,Bitrix开始对它无法直接发送邮件感到愤慨
  • 每个容器都有一个完整的代码库。
  • 禁止更改容器中的代码。

克罗恩下:

  • 带有 apache、php、cron 的容器
  • 包含完整的代码库
  • 禁止更改容器中的代码

升级如下:

  • nginx 容器 + apache/php-fpm 容器 + msmtp
  • 不禁止更改容器中的代码

会话存储

Bitrix缓存存储

另一件重要的事情是:我们将连接到所有内容(从数据库到邮件)的密码存储在 kubernetes 机密中。 我们得到了一个好处:密码仅对那些我们授予其秘密访问权限的人可见,而不是对所有有权访问该项目代码库的人可见。

静态存储

您可以使用任何东西:ceph、nfs(但我们不建议将 nfs 用于生产)、来自云提供商的网络存储等。

存储需要在容器中连接到站点的 /upload/ 目录和其他包含静态内容的目录。

数据库

为简单起见,我们建议将数据库移至 Kubernetes 之外。 Kubernetes 中的基础是一个单独的复杂任务;它将使该方案复杂一个数量级。

会话存储

我们使用内存缓存:)

它可以很好地处理会话存储,是集群式的,并且在 php 中作为 session.save_path “本地”支持。 当我们构建具有大量 Web 服务器的集群时,这样的系统已经在经典的整体架构中进行了多次测试。 对于部署,我们使用 helm。

$ helm install stable/memcached --name session

php.ini - 这里的图像包含用于在 memcached 中存储会话的设置

我们使用环境变量通过 memcached 传递有关主机的数据 https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/.
这允许您在 dev、stage、test、prod 环境中使用相同的代码(其中的 memcached 主机名会不同,因此我们需要将会话的唯一主机名传递到每个环境)。
Bitrix缓存存储

我们需要所有 Pod 都可以写入和读取的容错存储。

我们还使用memcached。
该方案是Bitrix自己推荐的。

$ helm install stable/memcached --name cache

bitrix/.settings_extra.php - 在 Bitrix 中指定缓存的存储位置

我们还使用环境变量。

克龙塔斯基

在 Kubernetes 中运行 Crontasks 有不同的方法。

  • 使用用于运行 Crontasks 的 pod 进行单独部署
  • 用于执行 crontasks 的 cronjob(如果这是一个 Web 应用程序 - 使用 wget https://$host$cronjobname,或某个工作单元内的 kubectl exec 等)
  • 等等

您可以争论最正确的一个,但在本例中,我们选择了“与 Crontasks 的 pod 单独部署”选项

它是如何完成的:

  • 通过 ConfigMap 或通过 config/addcron 文件添加 cron 任务
  • 在一个实例中,我们启动一个与工作容器相同的容器+允许在其中执行皇冠任务
  • 使用相同的代码库,由于统一,容器组装很简单

我们得到什么好处:

  • 我们在与开发人员环境(docker)相同的环境中运行 Crontasks
  • Crontasks 不需要为 Kubernetes 进行“重写”,它们以与以前相同的形式和相同的代码库工作
  • cron 任务可以由对生产分支具有提交权限的所有团队成员添加,而不仅仅是管理员

南桥 K8SDeploy 模块和从管理面板编辑代码

我们正在谈论升级?
如何疏导那里的交通?
万岁,我们用 PHP 编写了一个模块:)这是 Bitrix 的一个小型经典模块。 目前尚未公开,但我们计划开放。
该模块的安装方式与 Bitrix 中的常规模块类似:

车里雅宾斯克的南桥和 Kubernetes 的 Bitrix

它看起来像这样:

车里雅宾斯克的南桥和 Kubernetes 的 Bitrix

它允许您设置一个 cookie 来识别站点管理员并允许 Kubernetes 将流量发送到升级 Pod。

当更改完成后,您需要点击 git Push,代码更改将发送到 git,然后系统将使用新版本的代码构建镜像并在整个集群中“推出”,替换旧的 pod 。

是的,这有点像拐杖,但同时我们维护微服务架构,并且不会剥夺 Bitrix 用户最喜欢的从管理面板更正代码的机会。 最后,这是一个选项;您可以通过不同的方式解决编辑代码的问题。

舵图

为了在 Kubernetes 上构建应用程序,我们通常使用 Helm 包管理器。
对于 Kubernetes 中的 Bitrix 解决方案,我们的首席系统管理员 Sergey Bondarev 编写了一个特殊的 Helm 图表。

它构建worker、ugrade、cron pod,配置入口、服务,并将变量从 Kubernetes 秘密传输到 pod。

我们将代码存储在 Gitlab 中,并且还从 Gitlab 运行 Helm 构建。

简而言之,它看起来像这样

$ helm upgrade --install project .helm --set image=registrygitlab.local/k8s/bitrix -f .helm/values.yaml --wait --timeout 300 --debug --tiller-namespace=production

如果部署期间突然出现问题,Helm 还允许您进行“无缝”回滚。 当您没有惊慌失措时(因为产品崩溃而通过 ftp 修复代码),这很好,但 Kubernetes 会自动执行此操作,并且无需停机。

部署

是的,我们是 Gitlab 和 Gitlab CI 的粉丝,我们使用它:)
当在 Gitlab 中提交到项目存储库时,Gitlab 会启动一个部署新版本环境的管道。

步骤:

  • build(构建新的 Docker 镜像)
  • 测试(测试)
  • 清理(​​删除测试环境)
  • 推送(我们将其发送到 Docker 注册表)
  • 部署(我们通过 Helm 将应用程序部署到 Kubernetes)。

车里雅宾斯克的南桥和 Kubernetes 的 Bitrix

万岁,已经准备好了,让我们实施吧!
嗯,或者有问题就问吧。

那么我们做了什么

从技术角度来说:

  • dockerized Bitrix;
  • Bitrix“切”成容器,每个容器执行最少的功能;
  • 实现容器的无状态状态;
  • 解决了 Kubernetes 中更新 Bitrix 的问题;
  • 所有 Bitrix 功能都继续工作(几乎全部);
  • 我们致力于部署到 Kubernetes 以及版本之间的回滚。

从商业角度来看:

  • 容错;
  • Kubernetes 工具(与 Gitlab CI 轻松集成、无缝部署等);
  • 秘密密码(仅对那些直接有权访问密码的人可见);
  • 在单个基础设施中创建额外的环境(用于开发、测试等)很方便。

来源: habr.com

添加评论