部署重新加载/重启时 Kubernetes ReadWriteOnce 多附加死锁

Joh*_*oge 7 digital-ocean kubernetes persistent-volume-claims

考虑下面的 PersistentVolumeClaim 以及使用它的部署。

由于是ReadWriteOnce,PVC一次只能被一个节点挂载。由于我的部署只有一个副本,因此我认为这应该没问题。但是,在重新启动/重新加载时,两个 Pod 将在切换期间共存。

如果 Kubernetes 决定在与原始 pod 相同的节点上启动后继 pod,它们都将能够访问该卷,并且切换会顺利进行。但是 - 如果它决定在一个新节点上启动它(它似乎更喜欢),我的部署最终会陷入僵局:

卷“pvc-c474dfa2-9531-4168-8195-6d0a08f5df34”的多重附加错误卷已被 pod test-cache-5bb9b5d568-d9pmd 使用

后继 Pod 无法启动,因为该卷挂载在另一个节点上,而原始 Pod/节点当然不会释放该卷,直到 Pod 停止服务。在继任者上任之前,情况不会如此。

我在这里缺少什么?


apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: vol-test
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: do-block-storage
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-cache
spec:
  selector:
    matchLabels:
      app: test-cache-deployment
  replicas: 1
  template:
    metadata:
      labels:
        app: test-cache-deployment
    spec:
      containers:
      - name: test-cache
        image: myrepo/test-cache:1.0-SNAPSHOT
        volumeMounts:
          - mountPath: "/test"
            name: vol-mount
        ports:
        - containerPort: 8080
        imagePullPolicy: Always
      volumes:
        - name: vol-mount
          persistentVolumeClaim:
            claimName: vol-name
      imagePullSecrets:
      - name: regcred
Run Code Online (Sandbox Code Playgroud)

Joh*_*oge 9

我想出了一个解决方法:

虽然远非理想,但对于我的具体情况来说,这是一个可以接受的折衷方案。

ReadWriteOnce 卷显然不能很好地适应 Kubernetes 默认升级策略:“滚动”(即使在单个副本部署的情况下)。如果我使用“重新创建”升级策略,Kubernetes 将在启动后继容器之前销毁原始 pod,从而在再次安装卷之前分离该卷。

...
spec:
  selector:
    matchLabels:
      app: test-cache-deployment
  replicas: 1
  strategy:
    type: Recreate
...
Run Code Online (Sandbox Code Playgroud)

该解决方案显然有一个主要缺点:部署将在关闭和成功启动之间离线 - 这可能需要几秒钟到永远。


aci*_*uji 3

如果您使用 ,这是预期的行为ReadWriteOnce。如果您查看手册,您会遇到以下信息:

\n\n
\n
    \n
  • ReadWriteOnce \xe2\x80\x93 该卷可以由单个节点以读写方式挂载
  • \n
\n
\n\n

Kubernetes 文档有表格 显示哪些 PV 支持 ReadWriteMany(即同时在多个节点上进行写访问,例如 NFS)

\n\n

如果您仍然坚持使用,ReadWriteOnce您可以使用NodeAffinity并确保将 2 个副本安排到同一个节点,但这被认为是不好的做法,因为它错过了 Kubernetes 的全部要点。请注意,如果特定节点出现故障,您的所有副本都将出现故障。

\n\n

您在评论中提到的所需状态可以通过以下方式实现pod affinity

\n\n
\n

Pod 亲和性和 Pod 反亲和性允许您指定有关 Pod 相对于其他 Pod 的放置方式的规则。这些规则是使用节点上的自定义标签和 Pod 中指定的标签选择器来定义的。Pod 亲和性/反亲和性允许 pod 指定与其放置的一组 pod 的亲和性(或反亲和性)。该节点无法控制放置。\n

\n
\n\n

从 Kubernetes 文档中查看有关 pod 关联性的示例。

\n