在Kubernetes中更新configmap时重新启动pod?

时间:2016-05-19 07:47:25

标签: kubernetes

我知道当配置映射发生变化时,我们已经谈到了自动重启pod的能力,但据我所知,Kubernetes 1.2尚未提供。

那么(我认为)我想做的是"滚动重启"与使用配置映射的pod相关联的deployment资源。是否有可能,如果是这样,如何在Kubernetes中强制重新启动部署而不更改实际模板中的任何内容?这是目前最好的方式还是有更好的选择?

8 个答案:

答案 0 :(得分:88)

此问题的当前最佳解决方案(在兄弟答案中链接的https://github.com/kubernetes/kubernetes/issues/22368中深入引用)是使用部署,并认为您的ConfigMaps是不可变的。

如果要更改配置,请使用要进行的更改创建新的ConfigMap,并将部署指向新的ConfigMap。如果新配置中断,部署将拒绝缩小您正在工作的ReplicaSet。如果新配置有效,则旧的ReplicaSet将缩放为0个副本并删除,新的pod将使用新配置启动。

不如仅仅编辑ConfigMap快,但更安全。

答案 1 :(得分:34)

在配置地图更新中发信号通知pod是工作中的一项功能(https://github.com/kubernetes/kubernetes/issues/22368)。

您可以随时编写自定义pid1,通知配置已更改并重新启动您的应用。

您还可以例如:在2个容器中安装相同的配置映射,如果配置映射内容的散列发生更改,则在第二个容器中公开http运行状况检查,并将其作为第一个容器的活动探测器推送(因为pod中的容器共享相同的网络命名空间)。当探针失败时,kubelet将为您重新启动第一个容器。

当然,如果你不关心pod所在的节点,你可以简单地删除它们,复制控制器将重新启动"他们适合你。

答案 2 :(得分:13)

https://github.com/kubernetes/helm/blob/master/docs/charts_tips_and_tricks.md#user-content-automatically-roll-deployments-when-configmaps-or-secrets-change

配置文件或机密通常作为配置文件注入容器中。如果应用程序使用后续helm upgrade进行更新,则可能需要重新启动,但如果部署规范本身没有更改,则应用程序将继续使用旧配置运行,从而导致部署不一致。

sha256sum函数可以与include函数一起使用,以确保在另一个规范发生更改时更新部署模板部分:

kind: Deployment
spec:
  template:
    metadata:
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
[...]

就我而言,由于某些原因,$.Template.BasePath无法正常工作,$.Chart.Name会这样做:

spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: admin-app
      annotations:
        checksum/config: {{ include (print $.Chart.Name "/templates/" $.Chart.Name "-configmap.yaml") . | sha256sum }}

答案 3 :(得分:9)

我发现最好的方法是运行Reloader

https://github.com/stakater/Reloader

它允许您定义要查看的配置映射或秘密,当它们被更新时,将对部署进行滚动更新。这是一个示例:

您有一个部署foo和一个名为foo-configmap的ConfigMap。您想在每次更改configmap时滚动部署的Pod。您需要使用以下命令运行Reloader:

kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml

然后在您的部署中指定此注释:

kind: Deployment
metadata:
  annotations:
    configmap.reloader.stakater.com/reload: "foo-configmap"
  name: foo
...

答案 4 :(得分:5)

您可以更新与您的部署无关的元数据标签。它将触发滚动更新

例如:

metadata:
  labels:
    configmap-version: 1

答案 5 :(得分:1)

我也曾为此纠结过一段时间,希望以一种优雅而快速的方式解决这个问题。

这是我的 20 美分

  • 如果您要更新标签,则使用上述 here 标签的答案将不起作用。但是如果你总是添加标签会起作用。更多详情here

  • 在我看来,here 中提到的答案是快速执行此操作的最优雅方法,但存在处理删除的问题。我要补充这个答案:

解决方案

我在其中一个 Kubernetes Operator 中执行此操作,其中在一个协调循环中仅执行一项任务。

  • 计算配置映射数据的哈希值。假设它是 v2
  • 创建具有标签的 ConfigMap cm-v2version: v2product: prime(如果它不存在并返回)。如果存在,请往下看。
  • 找到所有带有 product: prime 标签但没有 version: v2 的部署,如果找到这样的部署,删除它们并返回。否则请往下看。
  • 删除所有标签为 product: prime 但没有 version: v2 ELSE GO BELOW 的 ConfigMap。
  • 使用标签 deployment-v2product: prime 创建部署 version: v2,并将配置映射附加为 cm-v2 和 RETURN,否则什么都不做。

就是这样!看起来很长,但这可能是最快的实现,并且原则上处理 infrastructure as Cattle(不变性)。

此外,当您的 Kubernetes 部署具有 Recreate 更新策略时,上述解决方案也有效。对于其他场景,逻辑可能需要稍作调整。

答案 6 :(得分:0)

在展开图位于子图表中且控制它的值在父图表的值文件中的情况下,出现了此问题。这是我们用来触发重启的东西:

spec:
  template:
    metadata:
      annotations:
        checksum/config: {{ tpl (toYaml .Values) . | sha256sum }}

很明显,这会触发任何值更改重新启动,但适用于我们的情况。子图表中的原始内容只有在子图表中的config.yaml更改时才能起作用:

    checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}

答案 7 :(得分:-1)

另一种方法是将其粘贴到部署的命令部分:

<?php
$output = array('data' => array());
$sql = "SELECT * FROM items";
$query = $connect->query($sql);

while ($row = $query->fetch_assoc()) {
    $output['data'][] = array(
        $row['name'],
    );
}
echo json_encode($output);
?>

<form action=" " method="POST">
    <div>
        <label>Name</label>
        <input type="text"><br>
        <label>Formulation</label>
        <select >
            <!--What should be the codes here? -->
        </select>
    </div>
    <button type = "submit">Save changes</button>
</form>

或者,为了使其更像ConfigMap,请使用另一个部署,该部署仅在... command: [ "echo", " option = value\n other_option = value\n " ] ... 部分中托管该配置,并在其上执行command,同时在其名称中添加唯一的“版本” (比如计算内容的哈希)并修改使用该配置的所有部署:

kubectl create

如果它最终有效,我可能会发布... command: [ "/usr/sbin/kubectl-apply-config.sh", " option = value\n other_option = value\n " ] ...

(不要这样做;看起来太糟糕了)