我正在尝试了解如何在 Kubernetes 上部署应用程序,这要求同一部署的每个 Pod 具有与启动命令一起使用的不同参数。
我有这个应用程序,它在 Kubernetes 上运行 Spark,需要在启动时生成执行器 Pod。问题是应用程序的每个 Pod 都需要使用自己的端口和 Spark 应用程序名称生成自己的执行器。
我已经阅读了有状态集并搜索了文档,但我没有找到解决问题的方法。由于每个 Pod 都需要使用不同的端口,如果我理解正确,我需要在服务中声明该端口,并且还直接作为参数传递给 args 中的 pod 命令。
有没有办法在不使用多个部署的情况下获得它,我需要创建的每个 pod 一个部署?因为这是我能想到的唯一解决方案,但在部署后无法扩展。 我正在使用 Helm 来部署应用程序,因此我可以根据需要轻松创建任意数量的部署和/或服务,但我希望找到一种可以在运行时扩展的解决方案(如果可能的话(。
我认为你不能有一个从不同规范创建 POD 的部署。你不能在 Kubernetes 中拥有它,Helm 在这里也无济于事(因为 Helm 只是 Kubernetes 配置上的模板管理器(。
你可以做的是将每个 Pod 指定为一个单独的配置(如果是单个 Pod,你不一定需要部署(,然后让 Helm 管理它。
发布我使用的解决方案,因为它可能对其他人搜索有用。
最后,我找到了一个很好的配置来解决我的问题。我使用 StatefulSet 来声明 Spark 应用程序的部署。与 StatefulSet 相关联,这是一种无外设服务,可在特定端口上公开每个 Pod。
StatefulSet 可以声明一个属性spec.serviceName
该属性可以具有与无头服务相同的名称,以便为每个 Pod 创建唯一的网络名称。类似<pod_name>.<service_name>
此外,每个 Pod 都有一个唯一且不变的名称,该名称是使用应用程序名称和每个副本 Pod 从 0 开始的序号创建的。
在 docker 映像中使用启动脚本并在每个 Pod 的环境中插入元数据中的 pod 名称,我能够为每个 pod 使用不同的配置,因为即使使用相同的部署,每个 pod 也有自己唯一的元数据名称,我可以使用 StatefulSet 服务来获取我需要的东西。
这样,StatefulSet 在运行时是可伸缩的,并按预期工作。
嘿,我不确定这是否与您的场景完全匹配,但我认为这是您可以尝试的。使用挎斗容器运行副本实例,挎斗是与主容器一起运行的容器,也共享相同的命名空间,并且可以在每个容器之间共享卷。
现在,要将不同的参数传递给每个容器或挎斗,您必须调整 dockerfile 或者更确切地说,调整容器的启动方式。
创建一个接受参数并使用这些参数启动容器的 start.sh 脚本文件,这里的诀窍是接受来自环境变量的参数,从而允许您稍后从配置映射或 pod env 配置这些参数。
所以这里有一个php/laravel应用程序运行相同代码并以不同参数开头的示例。文件start.sh
如下所示。
#!/bin/sh
if [ "${CONTAINER_ROLE}" = "queue" ];
then
echo "Running the queue..."
php artisan queue:work --queue=${QUEUENAME}
echo "Queue Started"
else
echo "Running Iceberg."
exec apache2-foreground
fi
所以一个示例 dockerfile 看起来像这样
FROM php:7.1.24-apache
COPY . /srv/myapp
...
...
RUN chown -R www-data:www-data /srv/app
&& a2enmod remoteip && a2enmod rewrite
WORKDIR /srv/app
RUN chmod +x .docker/start.sh
CMD [ "sh",".docker/start.sh"]
让我知道它是怎么回事。