0

我正在玩弄 Kubernetes,并设法将一个有状态的应用程序(jenkins 实例)部署到单个节点。它使用 PVC 来确保我可以保存我的 jenkins 数据(作业、插件等)。

现在我想尝试故障转移。

我的集群有 2 个数字海滴。

目前,我的 jenkins pod 仅在一个节点上运行。当它下降时,詹金斯变得不可用。

我现在正在研究如何完成故障转移,当 jenkins pod 在我的节点上关闭时,它将在另一个节点上启动。(在此过程中的停机时间很短是可以的)。

当然,它必须使用相同的 PVC,以便我的数据保持完整。

我相信,在阅读时,StatefulSet 可以用于此目的吗?

任何指针都非常感谢!

此致

4

4 回答 4

4

Digital Ocean 的 Kubernetes 服务仅支持ReadWriteOncePVC 的访问模式(参见此处)。这意味着卷一次只能附加到一个节点。

我遇到了这篇博文,虽然它专注于 Azure 上的 Jenkins,但同样的情况是只支持ReadWriteOnce. 作者指出:

对我来说,缺点在于 Azure Disk 持久卷的访问模式是 ReadWriteOnce。这意味着一次只能将一个 Azure 磁盘附加到一个群集节点。如果发生节点故障或更新,Azure 磁盘可能需要 1-5 分钟才能分离并附加到下一个可用节点。

请注意,Pod故障和节点故障是不同的东西。由于 DO 仅支持,因此在对节点故障ReadWriteOnce的容忍度方面,尝试比您现在拥有的更复杂的方法没有任何好处。由于它是卷,因此需要从故障节点卸载并重新安装到新节点,然后将在新节点上安排一个新的。Kubernetes 会为你做这件事,你可以做的事情不多来优化它。ReadWriteOncePod

对于Pod失败,您可以使用 aDeployment因为您想要读取和写入相同的数据,您不希望将不同的 PV 附加到不同的副本。这样做的好处可能非常有限,您将Pod在同一个节点上运行所有副本的多个副本,因此这取决于 Jenkins 进程如何扩展,以及它是否可以支持这种类型的横向扩展模型,同时全部写入同一个节点卷(而不是简单地垂直扩展内存或 CPU 请求)。

如果您真的想在面对节点和/或Pod故障时实现更高的可用性,并且您正在部署的 Jenkins 工作负载对持久状态的本地卷有硬性要求,您将需要考虑像 NFS 这样的替代卷插件,或者迁移到 GKE 等其他云提供商。

于 2019-09-24T21:05:54.350 回答
0

您所描述的是 Kubernetes for Pod 的默认行为,由控制器(例如 Deployment)管理。

您应该将任何应用程序部署为 Deployment(或另一个控制器),即使它仅包含单个 Pod。您永远不会真正将 Pod 直接部署到 Kubernetes。所以,在这种情况下,你不需要做任何特别的事情来获得这种行为。

当您的一个节点死亡时,Pod 也会死亡。Deployment 控制器会检测到这一点,并会创建一个新的 Pod。这反过来又被调度程序检测到,调度程序将新 Pod 分配给一个节点。由于其中一个节点已关闭,它会将 Pod 分配给仍在运行的另一个节点。一旦将 Pod 分配给该节点,该节点的 kubelet 将在该节点上运行该 Pod 的容器。

于 2019-09-24T21:02:30.417 回答
0

好的,让我尝试在这里回答我自己的问题。我认为Amit Kumar Gupta最接近我所相信的这里发生的事情。

由于我使用的是 Deployment 和我的 PVC ReadWriteOnce,我基本上只能在一个节点上使用一个运行 jenkins 的 pod。

weibelds答案让我意识到我是在对 Kubernetes 默认执行的一个概念提出问题。如果我的 pod 出现故障(在我的情况下,我通过硬断电来模拟故障来故意关闭节点),集群(控制器?)将检测到这一点并在另一个节点上生成一个新的 pod。

到目前为止一切都很好,但后来我注意到我的新 pod 卡在了ContainerCreating状态。

describe在我的新 pod(ContainerCreating状态中的)上运行 a显示了这一点

Warning  FailedAttachVolume  16m                attachdetach-controller  Multi-Attach error for volume "pvc-cb772fdb-492b-4ef5-a63e-4e483b8798fd" Volume is already used by pod(s) jenkins-deployment-6ddd796846-dgpnm
Warning  FailedMount         70s (x7 over 14m)  kubelet, cc-pool-bg6u    Unable to mount volumes for pod "jenkins-deployment-6ddd796846-wjbkl_default(93747d74-b208-421c-afa4-8d467e717649)": timeout expired waiting for volumes to attach or mount for pod "default"/"jenkins-deployment-6ddd796846-wjbkl". list of unmounted volumes=[jenkins-home]. list of unattached volumes=[jenkins-home default-token-wd6p7]

然后它开始打击我,这是有道理的。这是一个遗憾,但它是有道理的。

由于我对节点进行了硬断电,因此 PV 随之下降。因此,现在控制器尝试在新节点上启动一个新 pod,但它无法传输 PV,因为前一个 pod 上的那个变得无法访问。

当我阅读更多关于此的内容时,我读到 DigitalOcean 仅支持ReadWriteOnce,这让我现在想知道,我到底如何才能在 Digital Ocean 上的 Kubernetes 集群上为仅由几个简单的液滴组成的有状态应用程序实现简单的故障转移?

于 2019-09-25T05:32:40.693 回答
0

是的,您将根据用例使用 Deployment 或 StatefulSet。对于 Jenkins,StatefulSet 是合适的。如果正在运行的 pod 变得不可用,StatefulSet 控制器将看到并生成一个新的。

于 2019-09-24T20:48:11.303 回答