如何使环境变量在 kubernetes 中同一部署的两个 pods 之间不同?
How to make an environment variable different across two pods of the same deployment in kubernetes?
基于 this,可以创建在您定义的所有 pods 部署中都相同的环境变量。
有没有办法指示 Kubernetes 部署创建具有不同环境变量的 pods?
用例:
假设我有一个监控容器,我想为它创建 4 个副本。如果环境变量定义了此容器,则该容器有一个正在发送邮件的服务。例如,如果环境变量 IS_MASTER 为真,则服务会继续发送这些电子邮件。
apiVersion: v1
kind: Deployment
metadata:
...
spec:
...
replicas: 4
...
template:
...
spec:
containers:
-env:
-name: IS_MASTER
value: <------------- True only in one of the replicas
(在我的例子中,我使用的是 helm,但同样的事情也可以没有 helm)
根据定义,部署中的每个 pod 都与其其他副本相同。这在 yaml 定义中是不可能的。
一个可选的解决方案是覆盖 pod command
并让它处理和计算变量的值,设置变量 (export IS_MASTER=${resolved_value}
) 并触发容器的默认入口点。
这意味着你必须想出一个逻辑来实现它(即 pod 如何知道它应该是 IS_MASTER=true?)。这是一个实现细节,可以使用数据库或其他用作标志或信号量的共享公共资源来完成。
部署中的所有 Pod 副本都将具有相同的环境变量,并且没有用于标识特定 Pod 的唯一值。创建多个 Deployment 是更好的解决方案。
不知道为什么,OP 只针对一个 Deployment。一种解决方案是使用 StatefulSets。节点名称类似于 web-0、web1、web-2 等。在代码中检查主机名,如果是 web-0,则发送电子邮件或执行其他操作。
这是一个肮脏的解决方案,但我想不出比创建多个部署更好的解决方案。
据我所知,您正在寻找的更像是一种反模式而不是不可能的。
据我了解,您似乎希望部署一个 scalable/HA 监控平台,该平台不会在警报上发送 X 次邮件,因此您可以制作一个 sidecar 容器,与它的兄弟姐妹交谈, "elect" master-mailer(StatefulSet 在这种情况下会更容易),或者只是将邮件程序与监控分开,并让它们通过服务相互通信。这将允许您分别对监控和邮件进行负载平衡。
monitoring-1 \ / mailer-1
monitoring-2 --- > mailer.svc -- mailer-2
monitoring-3 / \ mailer-3
任何邮件请求都将由池中的一个且只有一个邮件程序处理,但这是假设您的监控 Pods 并非全部在警报时一起触发...如果不是这种情况,那么无论如何在您 "master" 选择邮寄者的过程中,您必须首先解决这个问题。
首先要解决这个问题,我的意思是向您的监控平台添加主选举逻辑,以协调事件的主故障转移,有几种方法可以做到这一点,但这实际上取决于您的监控平台是并且可以做...
虽然,如果你的副本只是为了以某种方式扩展计算能力,而你的主服务器应该是静态的,那么只需使用一个 StatefulSet,并在运行时添加一个 one liner 做 if hostname == $statefulset-name-0 then MASTER
,但我觉得好像这不是最好的主意。
另一种解决方案是对两种情况使用相同的 Helm Chart,并 运行 对每种情况使用一个 helm 部署。您可以用 helm 覆盖环境变量(使用 --set .Values.foo.deployment.isFirst=
"0"
或 "1"
)
请注意 Helm/K8s 不允许您 POST 完全相同的配置 twice。
因此,您必须仅在第一次部署时有条件地应用一些 Kubernetes 特定配置(Secrets、ConfigMaps、Secrets 等)。
{{- if eq .Values.foo.deployment.isFirst "1" }}
...
...
{{- end }}
基于 this,可以创建在您定义的所有 pods 部署中都相同的环境变量。
有没有办法指示 Kubernetes 部署创建具有不同环境变量的 pods?
用例:
假设我有一个监控容器,我想为它创建 4 个副本。如果环境变量定义了此容器,则该容器有一个正在发送邮件的服务。例如,如果环境变量 IS_MASTER 为真,则服务会继续发送这些电子邮件。
apiVersion: v1
kind: Deployment
metadata:
...
spec:
...
replicas: 4
...
template:
...
spec:
containers:
-env:
-name: IS_MASTER
value: <------------- True only in one of the replicas
(在我的例子中,我使用的是 helm,但同样的事情也可以没有 helm)
根据定义,部署中的每个 pod 都与其其他副本相同。这在 yaml 定义中是不可能的。
一个可选的解决方案是覆盖 pod command
并让它处理和计算变量的值,设置变量 (export IS_MASTER=${resolved_value}
) 并触发容器的默认入口点。
这意味着你必须想出一个逻辑来实现它(即 pod 如何知道它应该是 IS_MASTER=true?)。这是一个实现细节,可以使用数据库或其他用作标志或信号量的共享公共资源来完成。
部署中的所有 Pod 副本都将具有相同的环境变量,并且没有用于标识特定 Pod 的唯一值。创建多个 Deployment 是更好的解决方案。
不知道为什么,OP 只针对一个 Deployment。一种解决方案是使用 StatefulSets。节点名称类似于 web-0、web1、web-2 等。在代码中检查主机名,如果是 web-0,则发送电子邮件或执行其他操作。
这是一个肮脏的解决方案,但我想不出比创建多个部署更好的解决方案。
据我所知,您正在寻找的更像是一种反模式而不是不可能的。
据我了解,您似乎希望部署一个 scalable/HA 监控平台,该平台不会在警报上发送 X 次邮件,因此您可以制作一个 sidecar 容器,与它的兄弟姐妹交谈, "elect" master-mailer(StatefulSet 在这种情况下会更容易),或者只是将邮件程序与监控分开,并让它们通过服务相互通信。这将允许您分别对监控和邮件进行负载平衡。
monitoring-1 \ / mailer-1
monitoring-2 --- > mailer.svc -- mailer-2
monitoring-3 / \ mailer-3
任何邮件请求都将由池中的一个且只有一个邮件程序处理,但这是假设您的监控 Pods 并非全部在警报时一起触发...如果不是这种情况,那么无论如何在您 "master" 选择邮寄者的过程中,您必须首先解决这个问题。
首先要解决这个问题,我的意思是向您的监控平台添加主选举逻辑,以协调事件的主故障转移,有几种方法可以做到这一点,但这实际上取决于您的监控平台是并且可以做...
虽然,如果你的副本只是为了以某种方式扩展计算能力,而你的主服务器应该是静态的,那么只需使用一个 StatefulSet,并在运行时添加一个 one liner 做 if hostname == $statefulset-name-0 then MASTER
,但我觉得好像这不是最好的主意。
另一种解决方案是对两种情况使用相同的 Helm Chart,并 运行 对每种情况使用一个 helm 部署。您可以用 helm 覆盖环境变量(使用 --set .Values.foo.deployment.isFirst=
"0"
或 "1"
)
请注意 Helm/K8s 不允许您 POST 完全相同的配置 twice。
因此,您必须仅在第一次部署时有条件地应用一些 Kubernetes 特定配置(Secrets、ConfigMaps、Secrets 等)。
{{- if eq .Values.foo.deployment.isFirst "1" }}
...
...
{{- end }}