Sysadminka 系统管理员聚会正在车里雅宾斯克举行,在最后一次聚会上,我报告了我们在 Kubernetes 中的 1C-Bitrix 上运行应用程序的解决方案。
Bitrix、Kubernetes、Ceph——一个伟大的组合?
我将告诉您我们如何从这一切中整合出一个可行的解决方案。
走吧!
聚会于 18 月 XNUMX 日在车里雅宾斯克举行。 您可以在以下位置阅读有关我们聚会的信息:
如果您想向我们报告或作为听众 - 欢迎,请写信至 [电子邮件保护] 以及 Telegram t.me/vadimisakanov。
我的报告
解决方案“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:
这足以在 Kubernetes 中为 Bitrix 创建完整的解决方案吗?
不。 有大量的问题需要解决。
Kubernetes 中 Bitrix 存在哪些问题?
首先,Dockerhub 提供的现成镜像不适合 Kubernetes
如果我们想构建一个微服务架构(在 Kubernetes 中我们通常这样做),我们需要将 Kubernetes 应用程序分离到容器中,并让每个容器执行一项小功能(并且做得很好)。 为什么只有一个? 简而言之,越简单越可靠。
更具体地说,请观看这篇文章和视频:
Dockerhub 中的 Docker 镜像主要是基于一体化原则构建的,因此我们仍然必须制作自己的自行车,甚至从头开始创建镜像。
其次 - 站点代码是从管理面板编辑的
我们在网站上创建了一个新部分 - 代码已更新(添加了具有新部分名称的目录)。
如果您从管理面板更改了组件的属性,代码就会更改。
Kubernetes “默认情况下”无法处理此问题;容器必须是无状态的。
原因:集群中的每个容器(pod)仅处理一部分流量。 如果只更改一个容器(Pod)中的代码,那么不同 Pod 中的代码将会不同,站点的工作方式也会不同,并且站点的不同版本将显示给不同的用户。 你不能那样生活。
第三 - 您需要解决部署问题
如果我们有一个整体和一个“经典”服务器,一切都非常简单:我们部署一个新的代码库,迁移数据库,将流量切换到新版本的代码。 切换立即发生。
如果我们在 Kubernetes 中有一个站点,切入微服务,有很多带有代码的容器 - 哦。 您需要收集具有新版本代码的容器,推出它们而不是旧版本,正确迁移数据库,并且最好在访问者不注意的情况下完成此操作。 幸运的是,Kubernetes 帮助我们实现了这一点,支持大量不同类型的部署。
第四 - 你需要解决存储静态的问题
如果您的站点“只有”10 GB 并且您将其完全部署在容器中,那么您最终将得到 10 GB 的容器,并且需要很长时间才能部署。
您需要将站点“最重”的部分存储在容器之外,问题是如何正确执行此操作
我们的解决方案缺少什么?
整个Bitrix代码没有划分为微功能/微服务(以便注册是分开的,在线商店模块是分开的等)。 我们将整个代码库存储在每个容器中。
我们也不将数据库存储在 Kubernetes 中(我仍然在 Kubernetes 中实现了用于开发环境的数据库解决方案,但不用于生产环境)。
站点管理员仍然会注意到该站点在 Kubernetes 上运行。 “系统检查”功能无法正常工作;要从管理面板编辑站点代码,您必须首先单击“我要编辑代码”按钮。
问题已经确定,实现微服务的需求已经确定,目标也很明确——在 Kubernetes 中获得一个在 Bitrix 上运行应用程序的工作系统,同时保留 Bitrix 的功能和 Kubernetes 的优势。 让我们开始实施吧。
建筑
有许多带有 Web 服务器(工作人员)的“工作”pod。
下一项是 cron 任务(只需要一项)。
一项用于从管理面板编辑站点代码的升级(也只需要一项)。
我们解决问题:
- 在哪里存储会话?
- 缓存存放在哪里?
- 在哪里存储静态数据,而不是在一堆容器中放置千兆字节的静态数据?
- 数据库将如何工作?
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 传递有关主机的数据
这允许您在 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 中的常规模块类似:
它看起来像这样:
它允许您设置一个 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)。
万岁,已经准备好了,让我们实施吧!
嗯,或者有问题就问吧。
那么我们做了什么
从技术角度来说:
- dockerized Bitrix;
- Bitrix“切”成容器,每个容器执行最少的功能;
- 实现容器的无状态状态;
- 解决了 Kubernetes 中更新 Bitrix 的问题;
- 所有 Bitrix 功能都继续工作(几乎全部);
- 我们致力于部署到 Kubernetes 以及版本之间的回滚。
从商业角度来看:
- 容错;
- Kubernetes 工具(与 Gitlab CI 轻松集成、无缝部署等);
- 秘密密码(仅对那些直接有权访问密码的人可见);
- 在单个基础设施中创建额外的环境(用于开发、测试等)很方便。
来源: habr.com