【问题标题】:How to update a set of pods running in kubernetes?如何更新在 kubernetes 中运行的一组 pod?
【发布时间】:2015-07-22 23:19:33
【问题描述】:

更新由 kubernetes 集群中的复制控制器控制的一组 pod(例如,在进行代码更改并将底层 docker 映像推送到 docker hub 之后)的首选方式是什么?

我可以看到两种方式:

  1. 手动删除和重新创建复制控制器
  2. 使用kubectl rolling-update

使用rolling-update 我必须更改复制控制器名称。由于我将复制控制器定义存储在 YAML 文件中而不是手动生成它,因此必须更改文件以推出代码更新似乎会带来不良习惯,例如在复制控制器的两个名称(例如 controllerA 和 controllerB)之间交替避免名称冲突。

有什么更好的方法?

【问题讨论】:

    标签: kubernetes kubectl


    【解决方案1】:

    更新:kubectl rolling-update 已被弃用,替换命令为 kubectl rollout。另请注意,由于我编写了原始答案,因此添加了 Deployment 资源,并且是比 ReplicaSets 更好的选择,因为滚动更新是在服务器端而不是由客户端执行的。


    您应该使用kubectl rolling-update。我们最近添加了一个功能来执行“简单滚动更新”,它将更新复制控制器中的图像而不重命名它。这是kubectl help rolling-update 输出中显示的最后一个示例:

    // Update the pods of frontend by just changing the image, and keeping the old name
    $ kubectl rolling-update frontend --image=image:v2
    

    此命令还支持恢复 - 如果您取消更新并稍后重新启动,它将从上次中断的地方恢复。尽管它在后台创建了一个新的复制控制器,但在更新结束时,新的复制控制器会采用旧复制控制器的名称,因此它看起来像纯粹的更新,而不是切换到一个全新的复制控制器。

    【讨论】:

    • 它包含在 0.16.1 和更新版本的 kubectl 中。
    • 如果您有 rc 文件,您可以使用 kubectl rolling-update -f rc_spec.yaml 更改 pod 的任何部分。您仍然需要更改 rc 名称和选择器字段之一(通常是“版本”或“部署”字段)。话虽如此,复制控制器最初并不意味着是长期存在的对象。管理一组 pod 并随时间更新它们的更好的抽象是 deployments,它目前作为 API 扩展提供,并将在未来的版本中添加到 API 中。
    • 在 k8s v1.2+ 中,建议使用部署而不是 rc。部署对象控制滚动更新。使用只需运行 kubectl apply -f your-apps-deployment.yaml。该命令在一秒钟左右返回,滚动更新发生在后台。您可以通过各种方式观看它,例如运行 kubectl get po 以查看新 pod 的到来和旧 pod 的运行
    • 不确定部署是否解决了这个问题,但我有一个用例,我不想每次都更新图像的名称,我只想使用最新的图像(例如作为自动部署过程的一部分)。除非图像名称发生变化,否则我不能使用滚动更新(即使附加了:latest)。我可以删除并重新制作复制控制器以重新创建所有 pod,但这似乎不是最佳选择。有什么建议吗?
    • 如果它是自动部署过程的一部分,为什么不直接更新映像?你可以很容易地从:latest 到一个完整的图像散列进行客户端解析,并将其用作新的图像名称。由于无论如何它都是自动化的,您只需编写一次翻译代码,然后让机器继续运行。拥有完整的哈希值还可以让您更轻松地实际查看当前部署的特定版本。
    【解决方案2】:

    到目前为止,我发现的最佳选择是Skaffold,它会自动构建映像,将其推送到映像注册表并更新相应的 Pod/控制器。它甚至可以监视代码更改并在使用skaffold dev 命令保存更改后立即重建图像。这只需要添加一个简单的skaffold.yaml,指定注册表上的图像和 Kubernetes 清单的路径。这个工作流程在Getting Started guide中有详细描述。

    【讨论】:

      【解决方案3】:

      The following explanations are fromKubernetes In Action's book

      手动删除和重新创建复制控制器

      手动滚动更新是 laboriouserror-prone。根据副本的数量,您需要以正确的顺序运行十几个或更多命令来执行更新过程。幸运的是,Kubernetes 允许您使用单个命令执行滚动更新。

      使用 kubectl 滚动更新

      您可以让 kubectl 执行它们,而不是手动使用 ReplicationControllers 执行滚动更新。使用 kubectl 来执行更新使这个过程变得更加容易,但是,现在这是一种过时的更新应用程序的方式。

      为什么执行这样的更新不如预期的那样好,因为它势在必行。 Kubernetes 是如何让您告诉它系统的所需状态并让 Kubernetes 通过找出最佳方式来实现该状态的。

      使用 Deployments 以声明方式更新应用 -- 最佳选择 --

      Deployment 是一种更高级别的资源,用于部署应用程序并以声明方式更新它们,而不是通过 ReplicationController 或 ReplicaSet 来完成,这两者都被认为是较低级别的概念。

      使用 Deployment 而不是较低级别的构造可以更轻松地更新应用程序,因为您通过单个 Deployment 资源定义所需的状态,并让 Kubernetes 处理其余工作。

      还有一点,回滚部署是可能的,因为部署。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-20
        • 2019-04-26
        • 1970-01-01
        • 2018-11-01
        • 1970-01-01
        • 2018-12-20
        • 2022-12-17
        • 2018-10-04
        相关资源
        最近更新 更多