pod 挂载 ceph pvc 更新,pod不释放,新pod无法挂载

解决pvc无法mount的问题

  Normal   Scheduled           <unknown>  default-scheduler        Successfully assigned senyint/fms-server-5ccc948568-fgzbx to node4
  Warning  FailedAttachVolume  3m32s      attachdetach-controller  Multi-Attach error for volume "pvc-65a5f731-42bd-47d3-9e4b-3f3c7c0a4e43" Volume is already used by pod(s) fms-server-55bb4f6ff7-l5xk7
  Warning  FailedMount         89s        kubelet, node4           Unable to attach or mount volumes: unmounted volumes=[senyintdatafile], unattached volumes=[logs senyintdatafile default-token-227x7]: timed out waiting for the condition

 

查看pvc

[root@master1 ~]# kubectl get pvc -n senyint
NAME                                  STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS           AGE
remote-fmsserver-hdd-pvc              Bound    pvc-65a5f731-42bd-47d3-9e4b-3f3c7c0a4e43   200Gi      RWO            ceph-rbd-provisioner   78m

 

查看pv信息

[root@master1 ~]# kubectl describe pv pvc-65a5f731-42bd-47d3-9e4b-3f3c7c0a4e43 -n senyint
Name:            pvc-65a5f731-42bd-47d3-9e4b-3f3c7c0a4e43
Labels:          <none>
Annotations:     kubernetes.io/createdby: rbd-dynamic-provisioner
                 pv.kubernetes.io/bound-by-controller: yes
                 pv.kubernetes.io/provisioned-by: kubernetes.io/rbd
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    ceph-rbd-provisioner
Status:          Bound
Claim:           senyint/remote-fmsserver-hdd-pvc
Reclaim Policy:  Delete
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        200Gi
Node Affinity:   <none>
Message:         
Source:
    Type:          RBD (a Rados Block Device mount on the host that shares a pod's lifetime)
    CephMonitors:  [192.168.200.11:6789 192.168.200.12:6789 192.168.200.13:6789]
    RBDImage:      kubernetes-dynamic-pvc-f6d69818-7265-4038-8f7b-f2eb6d5b9b9e
    FSType:        
    RBDPool:       databasedata
    RadosUser:     admin
    Keyring:       /etc/ceph/keyring
    SecretRef:     &SecretReference{Name:ceph-secret-admin,Namespace:,}
    ReadOnly:      false
Events:            <none>

 

用ceph的相关命令查一下该rbd镜像现在被哪个node节点使用了:

[root@master1 ~]# rbd info databasedata/kubernetes-dynamic-pvc-f6d69818-7265-4038-8f7b-f2eb6d5b9b9e
rbd image 'kubernetes-dynamic-pvc-f6d69818-7265-4038-8f7b-f2eb6d5b9b9e':
    size 200 GB in 51200 objects
    order 22 (4096 kB objects)
    block_name_prefix: rbd_data.100986b8b4567
    format: 2
    features: layering
    flags: 

 

这里将上面的block_name_prefix属性值拿出来,将rbd_data修改为rbd_header即可

根源分析

首先回顾一下k8s里volume的挂载过程:

  • provision,卷分配成功,这个操作由PVController完成
  • attach,卷挂载在对应worker node,这个操作为AttachDetachController完成
  • mount,卷挂载为文件系统并且映射给对应Pod,这个操作为VolumeManager完成

k8s里volume的卸载过程跟上述场景完全相反:

  • umount,卷已经和对应worker node解除映射,且已经从文件系统umount
  • detach,卷已经从worker node卸载
  • recycle,卷被回收

pod的迁移会导致原来的pod从其node节点删除,这时AttachDetachController没有成为将rbd从原来的node节点detach。后面多次尝试却无法重现问题,猜测是当时由于某些原因AttachDetachController执行detach操作失败了,可能是强制删除pod导致的,所以删除pod时还是要慎用—force —grace-period=0选项。

 

问题二

问题描述

还是上述那个场景,这次对deployment作了一次滚动更新,这时k8s会新创建一个pod,尝试挂载volume,但这次原来那个node节点上pod仍处于Running状态,因而其使用volume是正常的。

问题解决

这次很容易解决,直接删除旧的pod就可以了:

$ kubectl delete pod xxxx

 

根源分析

很明显,滚动更新时产生多了一个pod,为什么会这样了,我们看一下deployment里的滚动更新策略:

$ kubectl get deployment xxxx -o yaml
...
deploySpec:
  replicas: 1
  ...
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    volumes:
        - name: data
          persistentVolumeClaim:
            claimName: data-vol
...

$ kubectl get pvc data-vol -o yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: data-vol
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
  storageClassName: rbd

 

可以看到这里默认配置的滚动更新参数为maxSurge=1,也即允许比desired的pod数目多1个。而pvc又是ReadWriteOnce的访问模式,因此滚动更新时会产生多一个pod,而ReadWriteOnce的访问模式又不允许两个pod挂载同一个volume。

因此这里有几个的解决方案:

使用ReadWriteMany访问模式的pvc
将maxSurge设置为0,避免在更新过程中产生多余的pod
将deployment改为statefulset,statefulset对应的pod与pvc是一一绑定的,在更新过程中不会产生多余的pod

 

方法二:重启

使用cephfs的方式:

出现这个问题的一个重要原因是ceph-rbd只能支持单读写(RWO).而cephfs支持多读写(RWX),就不会有这个问题了.

 

参考: https://cloud.tencent.com/developer/article/1469533

posted @ 2020-08-04 14:27  fengjian1585  阅读(4020)  评论(0编辑  收藏  举报