在 minikube 中使用 nfs

注: 本文写于 12/12/2019,仅针对以下版本进行过测试,新的/旧的版本可能在命令参数/接口等方面存在一定差异,需根据官方文档进行调整

intro

环境
  • Ubuntu 18.04.3 LTS (bionic)
  • nfs

    nfsstat 查看的时候 v3, v4 都有

  • k8s(本文用的是面向单机环境的 minikube)

    minikube: v1.5.2

    kubectl Client Version: v1.16.3

    kubectl Server Version: v1.16.2

    kubeadm version: v1.16.3

背景知识
  • 什么是 nfs, 为什么 nfs

    NFS, or Network File System, 客户端可以访问服务端的文件,且访问过程和访问本地存储一样。 NFS 既是一种协议, 也可以指具体的软件 。个人感觉类似于 SMB (协议、软件)。

    NFS 可以把远程的文件 mount 到本地,可以用 df -h 查看。可以实现文件传输 (同步、共享) 等功能。

    本项目中, NFS 可用于数据库的共享

  • 什么是 kubernetes/k8s, 为什么 minikube

    Kubernetes (常简称为K8s) , 是用于自动部署、扩展和管理 “容器化(containerized)应用程序” 的开源系统。

    至于为啥用 minikube, emmm 因为我的 PC 装完整版的 Kubernetes 有问题, 而 minikube 也是 k8s 生态中的一部分 (见 https://kubernetes.io/docs/se... ), 基本功能是一样的, 适合单机部署, 因此选择了 minikube

  • 什么是 PV, PVC, 为什么用 PV, PVC

    PV, Persistent Volume. PVC, Persistent Volume Claim. 个人感觉, PV 相当于一个【可用的 存储资源 】的描述文件,PVC 是对于某一类 app 的【存储需求】的描述。

    通过 PV 和 PVC,可以把 app 对存储的需求进行抽象,存储端具体提供什么样的解决方案由运维负责, 而开发者不需要参与。同时,PV 和 PVC 可以解耦 app 和 存储, 有更高的灵活性。

    同时, 根据 https://www.cnblogs.com/wangx... , 在Docker的设计实现中,容器中的数据是临时的,即当容器被销毁时,其中的数据将会丢失。如果需要持久化数据,需要使用Docker数据卷挂载宿主机上的文件或者目录到容器中。在Kubernetes中,当Pod重建的时候,数据是会丢失的,Kubernetes也是通过数据卷挂载来提供Pod数据的持久化的。Kubernetes数据卷是对Docker数据卷的扩展,Kubernetes数据卷是Pod级别的,可以用来实现Pod中容器的文件共享。

  • k8s what is STORAGECLASS

    https://www.google.com/search...

  • 说完这些,是不是感觉有点抽象?下面的例子可以帮助我们理解上面这些概念

搭建过程

准备 NFS
  • 这篇文章 https://vitux.com/install-nfs... 是一个很好的 step-by-step 的例子
  • 假设进行单机安装测试, 假设本机局域网 IP 是 192.168.1.100/24

    (服务端和客户端在同一台机器上)

  • 目标:

    • 创建文件夹 /mnt/server_folder, /mnt/client_folder
    • 在 /mnt/server_folder 中 创建/删除/修改 文件时, 可以同步更新到 /mnt/client_folder,反之亦然
    • 有个问题:这里是 S/C 完全做同样的操作,得到两个备份吗?还是说只有 server 一个备份,而 client 只是一个 link?
  • Step 0(optional): 替换 /etc/apt/sources.list 为国内源

    cp /etc/apt/sources.list /etc/apt/sources.list.bak
    echo 'deb http://mirrors.aliyun.com/ubuntu bionic main restricted
    deb http://mirrors.aliyun.com/ubuntu bionic-updates main restricted
    deb http://mirrors.aliyun.com/ubuntu bionic universe
    deb http://mirrors.aliyun.com/ubuntu bionic-updates universe
    deb http://mirrors.aliyun.com/ubuntu bionic multiverse
    deb http://mirrors.aliyun.com/ubuntu bionic-updates multiverse
    deb http://mirrors.aliyun.com/ubuntu bionic-backports main restricted universe multiverse
    deb http://mirrors.aliyun.com/ubuntu bionic-security main restricted
    deb http://mirrors.aliyun.com/ubuntu bionic-security universe
    deb http://mirrors.aliyun.com/ubuntu bionic-security multiverse' > /etc/apt/sources.list
  • Step 1: 安装 NFS Kernel Server

    sudo apt-get update
    sudo apt-get install nfs-kernel-server -y
  • Step 2: 创建待共享文件夹 (Export Directory)

    sudo mkdir -p /mnt/server_folder

    sudo chown nobody:nogroup /mnt/server_folder

  • apt-add-repo
准备 k8s
  • 国内环境在 pull 官方镜像的时候可能会龟速甚至连接失败, 因此我们需要通过其他镜像进行加速。下面是一个解决方案

    chmod +x azk8spull.sh
    ./azk8spull.sh k8s.gcr.io/echoserver:1.10
使用 NFS 作为 k8s 的 PV
  • 在当前目录下创建文件 pv.yaml, pvc.yaml, depolyment.yaml
  • pv.yaml 内容如下 (由于 segmentfault 的解析器有一定的问题,会把yaml中开头的 - 解析成奇怪的东西,因此在前面加了个斜杠 \, 需要在复制到本地后将斜杠去掉 )

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: my-pv
    spec:
      storageClassName: standard
      capacity:
        storage: 512Mi
      accessModes:
        \- ReadWriteOnce
      hostPath:
        path: /home/ubuntu/data

    保存文件后执行命令 kubectl apply -f pv.yaml

  • pvc.yaml 内容如下 (由于 segmentfault 的解析器有一定的问题,会把yaml中开头的 - 解析成奇怪的东西,因此在前面加了个斜杠 \, 需要在复制到本地后将斜杠去掉 )

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: my-pvc
    spec:
      storageClassName: standard
      accessModes:
        \- ReadWriteOnce
      resources:
        requests:
          storage: 512Mi

    注意 pvc.yaml 中的 storageClassName 与 pv.yaml 中的 storageClassName 保持一致,否则 k8s 无法把 pvc 连接到 pv 的资源池, 而是会在 /tmp/hostpath-provisioner 目录下新建一个名字类似于 pvc-[uuid], 如 pvc-d47f4936-dd7c-49b4-a512-6241d3ff15ef, 的文件夹, 以此作为 PVC 的 Volume

    保存文件后执行命令 kubectl apply -f pvc.yaml

  • deployment.yaml 内容如下

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-deployment
    spec:
      selector:
        matchLabels:
          app: my-app
      replicas: 1
      template:
        metadata:
          labels:
            app: my-app
        spec:
          containers:
          \- name: my-container
            image: k8s.gcr.io/echoserver:1.10
            volumeMounts:
            \- mountPath: /home/pod/data
              name: my-pv
            ports:
            \- containerPort: 8080
          volumes:
          \- name: my-pv
            persistentVolumeClaim:
              claimName: my-pvc
    

    保存文件后执行 kubectl apply -f deployment.yaml

  • 查看效果, 首先在命令行输入如下指令,查看已经部署的 pod

    $ kubectl get pods
    # 输出如下
    NAME                             READY   STATUS    RESTARTS   AGE
    my-deployment-6fb68d7b69-b69vn   1/1     Running   0          1m45s

    然后输入如下命令进入 Pod

    $ kubectl exec -it my-deployment-6fb68d7b69-b69vn bash
    # 会像 ssh 一样进入一个新的 shell
    root@my-deployment-6fb68d7b69-b69vn:/# 

    进入 pod 内部的目录 /home/pod/data

    root@my-deployment-6fb68d7b69-b69vn:/# ls /home/pod/data

    这时就可以看到 masterpv 绑定的目录 /home/ubuntu/data 中的文件已经同步过来了。

常用命令
  • kubectl create/apply -f xxx.yaml
  • kubectl get pv/pvc/pods
  • kubectl delete pv/pvc/pod name
  • kubectl delete deployments --all

参考资料


FrozenMap
64 声望6 粉丝

今天,你快乐吗?


« 上一篇
GET POST 区别