使用 Container OS (COS) 在 Google Container Engine 中挂载 NFS 卷

Posted

技术标签:

【中文标题】使用 Container OS (COS) 在 Google Container Engine 中挂载 NFS 卷【英文标题】:Mounting NFS volume in Google Container Engine with Container OS (COS) 【发布时间】:2017-05-24 15:44:38 【问题描述】:

为 GKE 集群的节点将镜像类型从 container-vm 迁移到 cos 后,似乎不再可能为 pod 挂载 NFS 卷。

问题似乎是缺少 NFS 客户端库,因为在我尝试过的所有 COS 版本(cos-stable-58-9334-62-0、cos-beta-59-9460-20- 0, cos-dev-60-9540-0-0)。

sudo mount -t nfs mynfsserver:/myshare /mnt

失败

mount: wrong fs type, bad option, bad superblock on mynfsserver:/myshare,
       missing codepage or helper program, or other error
       (for several filesystems (e.g. nfs, cifs) you might
       need a /sbin/mount.<type> helper program)

但这与此处列出的支持的卷类型相矛盾: https://cloud.google.com/container-engine/docs/node-image-migration#storage_driver_support

在 pod 中挂载 NFS 卷适用于映像类型为 container-vm 但不适用于 cos 的池。

因为我收到了kubectl describe pod 的以下消息:

MountVolume.SetUp failed for volume "kubernetes.io/nfs/b6e6cf44-41e7-11e7-8b00-42010a840079-nfs-mandant1" (spec.Name: "nfs-mandant1") pod "b6e6cf44-41e7-11e7-8b00-42010a840079" (UID: "b6e6cf44-41e7-11e7-8b00-42010a840079") with: mount failed: exit status 1
Mounting command: /home/kubernetes/containerized_mounter/mounter
Mounting arguments: singlefs-1-vm:/data/mandant1 /var/lib/kubelet/pods/b6e6cf44-41e7-11e7-8b00-42010a840079/volumes/kubernetes.io~nfs/nfs-mandant1 nfs []
Output: Mount failed: Mount failed: exit status 32
Mounting command: chroot
Mounting arguments: [/home/kubernetes/containerized_mounter/rootfs mount -t nfs singlefs-1-vm:/data/mandant1 /var/lib/kubelet/pods/b6e6cf44-41e7-11e7-8b00-42010a840079/volumes/kubernetes.io~nfs/nfs-mandant1]
Output: mount.nfs: Failed to resolve server singlefs-1-vm: Temporary failure in name resolution

【问题讨论】:

“cos”上似乎存在 DNS 问题。如果我在定义持久卷时使用 NFS 服务器的 IP 地址,它也适用于 cos 我有同样的问题,使用直接 ip 定义卷但使用 DNS 名称不起作用(尝试主机名、内部 dns 名称以及公共 dns)。 【参考方案1】:

Martin,您是手动设置挂载(自己执行挂载),还是让 kubernetes 通过引用 NFS 卷的 pod 代表您完成?

前者行不通。以后会的。正如您发现的那样,COS 不附带 NFS 客户端库,因此 GKE 通过使用所需的二进制文件设置 chroot(位于 /home/kubernetes/containerized_mounter/rootfs)并在其中调用 mount 来解决这个问题。

【讨论】:

Saad,感谢您解释挂载 pod 的 NFS 卷的机制。【参考方案2】:

我已经从 kubernetes 项目中截取了上面提到的解决方案 @saad-ali,以实现这项工作。

具体来说,我已将以下内容添加到我的云配置中:

# This script creates a chroot environment containing the tools needed to mount an nfs drive
- path: /tmp/mount_config.sh
  permissions: 0755
  owner: root
  content: |
    #!/bin/sh
    set +x # For debugging

    export USER=root
    export HOME=/home/dockerrunner
    mkdir -p /tmp/mount_chroot
    chmod a+x /tmp/mount_chroot
    cd /tmp/
    echo "Sleeping for 30 seconds because toolbox pull fails otherwise"
    sleep 30
    toolbox --bind /tmp /google-cloud-sdk/bin/gsutil cp gs://<uploaded-file-bucket>/mounter.tar /tmp/mounter.tar
    tar xf /tmp/mounter.tar -C /tmp/mount_chroot/
    mount --bind /tmp/mount_chroot /tmp/mount_chroot
    mount -o remount, exec /tmp/mount_chroot
    mount --rbind /proc /tmp/mount_chroot/proc
    mount --rbind /dev /tmp/mount_chroot/dev
    mount --rbind /tmp /tmp/mount_chroot/tmp
    mount --rbind /mnt /tmp/mount_chroot/mnt

kube 团队创建的 chroom 镜像的上传文件桶容器,下载自:https://storage.googleapis.com/kubernetes-release/gci-mounter/mounter.tar

然后,云配置的 runcmd 看起来像:

runcmd:
- /tmp/mount_config.sh
- mkdir -p /mnt/disks/nfs_mount
- chroot /tmp/mount_chroot /bin/mount -t nfs -o rw nfsserver:/sftp /mnt/disks/nfs_mount

这行得通。丑得要命,但现在必须这样做。

【讨论】:

以上是关于使用 Container OS (COS) 在 Google Container Engine 中挂载 NFS 卷的主要内容,如果未能解决你的问题,请参考以下文章

嵌入式实时操作系统μCOS原理与实践+事件部分代码

docker container里面为什么不用装OS

在 Cocoa App Swift [Mac OS] 中显示在 containerView 内的 NSViewController 不会与 Container 的边界对齐

g++ 在 -Os 处启用错误标志

openresty中的set_by_lua&os.getenv:alpine docker container

腾讯云COS群晖NAS?