系列文章
第一章:✨ k8s入门:裸机部署 k8s 集群
第二章:✨ k8s入门:部署应用到 k8s 集群
第三章:✨ k8s入门:service 简单使用
第四章:✨ k8s入门:StatefulSet 简单使用
第五章:✨ k8s入门:存储(storage)
第六章:✨ K8S 配置 storageclass 使用 nfs 动态申领本地磁盘空间
第七章:✨ k8s入门:配置 ConfigMap & Secret
第八章:✨ k8s入门:k8s入门:Helm 构建 MySQL
第九章:✨ k8s入门:kubernetes-dashboard 安装
第十章:✨ k8s入门:kube-prometheus-stack 全家桶搭建(Grafana + Prometheus)
文章目录
参考文章:
- k8s官网:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes
- k8s中文社区:http://docs.kubernetes.org.cn/429.html
- 易文档: https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/Q2gBbjyW
一、简介
接上篇 StatefulSet 管理有状态的应用,例如数据库时,当 pod 重启,重新创建会导致数据丢失,这篇博客介绍存储,主要介绍 Volumes、Persistent Volumes、Storage Classes
二、Volumes
1、volume 的作用
Container 中的文件在磁盘上是临时存放的,这给 Container 中运行的较重要的应用程序带来一些问题。
- 问题一:当容器崩溃时文件丢失。 kubelet 会重新启动容器,但容器会以干净的状态重启。
- 问题二:同一 Pod 中运行的多个容器需要共享文件。
Kubernetes 卷(Volume) 能够解决上面这两个问题。
2、volume 的特点
- 支持很多类型的卷, Pod 可以同时使用任意数目的卷类型。
- 临时卷类型的生命周期与 Pod 相同,但持久卷可以比 Pod 的存活期长。当 Pod 不再存在时,Kubernetes 也会销毁临时卷,不会销毁持久卷。 对于给定 Pod 中任何类型的卷,在容器重启期间数据都不会丢失。
- 卷的核心是一个目录,其中可能存有数据,Pod 中的容器可以访问该目录中的数据。 所采用的特定的卷类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放的内容
- Pod 配置中的每个容器必须独立指定各个卷的挂载位置
3、volume 支持的类型
-
可用:cephfs, configMap, downwardAPI, emptyDir, fc (光纤通道), gcePersistentDisk, glusterfs, hostPath, iscsi, local, nfs, persistentVolumeClaim, portworxVolume, projected (投射), rbd, secret
-
已弃用:awsElasticBlockStore (已弃用), azureDisk (已弃用), azureFile (已弃用), cinder (已弃用), flocker (已弃用), gitRepo (已弃用), quobyte (已弃用), storageOS (已弃用), vsphereVolume(弃用)
三、PersistentVolume 和 PersistentVolumeClaim
1、PersistentVolume 说明
- 持久卷(PersistentVolume,PV)是集群中的一块存储,可以由管理员事先供应,或者使用存储类(Storage Class)来动态供应。
- 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样,也是使用 卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。
- PV不属于任何Node,但是可以在每个Node上访问
2、PersistentVolumeClaim 说明
- 持久卷申领(PersistentVolumeClaim,PVC)表达的是用户对存储的请求。概念上与 Pod 类似。
- Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。
- Pod 可以请求特定数量的资源(CPU 和内存);同样 PVC 申领也可以请求特定的大小和访问模式 (例如,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载,参见访问模式)。
3、PersistentVolume 和 PersistentVolumeClaim 的关系和图解
pvc 是一种 pv 的请求方案,PVC 定义我当前需要什么样类型的 PV,然后会自动在当前存在的 pv 中选取一个匹配度最高的 pv
一个 PVC 只能绑定一个 PV!!
4、Persistent Volume(持久卷)类型
PV 持久卷是用插件的形式来实现的。Kubernetes 目前支持以下插件:
- awsElasticBlockStore - AWS 弹性块存储(EBS)
- azureDisk - Azure Disk
- azureFile - Azure File
- cephfs - CephFS volume
- csi - 容器存储接口 (CSI)
- fc - Fibre Channel (FC) 存储
- gcePersistentDisk - GCE 持久化盘
- glusterfs - Glusterfs 卷
- hostPath - HostPath 卷 (仅供单节点测试使用;不适用于多节点集群; 请尝试使用 local 卷作为替代)
- iscsi - iSCSI (SCSI over IP) 存储
- local - 节点上挂载的本地存储设备
- nfs - 网络文件系统 (NFS) 存储
- portworxVolume - Portworx 卷
- rbd - Rados 块设备 (RBD) 卷
- vsphereVolume - vSphere VMDK 卷
以下的持久卷已被弃用。这意味着当前仍是支持的,但是 Kubernetes 将来的发行版会将其移除。
- cinder - Cinder(OpenStack 块存储)(于 v1.18 弃用)
- flexVolume - FlexVolume (于 v1.23 弃用)
- flocker - Flocker 存储(于 v1.22 弃用)
- quobyte - Quobyte 卷 (于 v1.22 弃用)
- storageos - StorageOS 卷(于 v1.22 弃用)
旧版本的 Kubernetes 仍支持这些“树内(In-Tree)”持久卷类型:
- photonPersistentDisk - Photon 控制器持久化盘。(v1.15 之后 不可用)
- scaleIO - ScaleIO 卷(v1.21 之后 不可用)
四、Storage Classes
StorageClass 为管理员提供了描述存储 “类” 的方法。 不同的类型可能会映射到不同的服务质量等级或备份策略,或是由集群管理员制定的任意策略。 Kubernetes 本身并不清楚各种类代表的什么。这个类的概念在其他存储系统中有时被称为 “配置文件”。
每个 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段, 这些字段会在 StorageClass 需要动态分配 PersistentVolume 时会使用到。
StorageClass 对象的命名很重要,用户使用这个命名来请求生成一个特定的类。 当创建 StorageClass 对象时,管理员设置 StorageClass 对象的命名和其他参数,一旦创建了对象就不能再对其更新。
详细信息参考:https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes
每个 StorageClass 都有一个制备器(Provisioner),用来决定使用哪个卷插件制备 PV。 该字段必须指定。
-
回收策略(reclaimPolicy)可以是 Delete 或者 Retain,如果 StorageClass 对象创建时没有指定 reclaimPolicy,它将默认为 Delete。
-
PersistentVolume 可以配置为可扩展。将此功能设置为 true 时,允许用户通过编辑相应的 PVC 对象来调整卷大小。
-
参数(parameters)最多可以定义 512 个参数,这些参数对象的总长度不能 超过 256 KiB, 包括参数的键和值。
Storage Classes 可以通过 PVC 动态申领 PV,一般需要借助云服务商,使用 nfs 服务本地磁盘实现可参考 https://blog.csdn.net/qq_41538097/article/details/125380287
五、volume 简单示例
1、emptyDir
- 使用 emptyDir,当 Pod 分配到 Node 上时,将会创建 emptyDir,并且只要 Node 上的 Pod 一直运行,Volume就会一直存。
- 当 Pod(不管任何原因)从 Node上被删除时,emptyDir 也同时会删除,存储的数据也将永久删除。注:删除容器不影响emptyDir。
emptyDir 简单使用,新建 k8s-emptydir-volume.yaml 配置文件,添加如下内容
apiVersion: v1
kind: Pod
metadata:
name: k8s-emptydir-volume
spec:
# 定义容器,可以多个
containers:
- name: nginx
image: nginx:latest
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /data # 容器内部目录
name: emptydir-volume
- name: redis
image: redis:latest
ports:
- containerPort: 6379
hostPort: 6379
volumeMounts:
- mountPath: /data
name: emptydir-volume
volumes:
- name: emptydir-volume
emptyDir: {}
根据 yaml 文件创建 pod,并测试 volume
# 根据文件创建 pod
[root@master volume]# kubectl apply -f k8s-emptydir-volume.yaml
pod/k8s-emptydir-volume created
# 查看 pod
[root@master volume]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
k8s-emptydir-volume 2/2 Running 0 4s 10.244.1.22 node1 <none> <none>
# 进入 pod/k8s-emptydir-volume 中的 nginx 容器,-c 指定 pod 中的容器
[root@master volume]# kubectl exec -it pod/k8s-emptydir-volume -c nginx /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# 进入 volume 指定目录,添加测试文件
root@k8s-emptydir-volume:/# echo "test k8s-emptydir-volume" > /data/test.log
root@k8s-emptydir-volume:/# cat /data/test.log
test k8s-emptydir-volume
root@k8s-emptydir-volume:/# exit
exit
# 进入 pod/k8s-emptydir-volume 中的 redis 容器
[root@master volume]# kubectl exec -it pod/k8s-emptydir-volume -c redis /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# 进入 volume 指定目录,查看 nginx 容器添加的测试文件
root@k8s-emptydir-volume:/data# ls
test.log
root@k8s-emptydir-volume:/data# cat test.log
test k8s-emptydir-volume
emptydir 常用于 pod 中容器间分享文件,或者用于创建临时目录。
2、hostPath
警告:
HostPath 卷存在许多安全风险,最佳做法是尽可能避免使用 HostPath。 当必须使用 HostPath 卷时,它的范围应仅限于所需的文件或目录,并以只读方式挂载。
如果通过 AdmissionPolicy 限制 HostPath 对特定目录的访问,则必须要求volumeMounts
使用 readOnly
挂载以使策略生效。
注意:hostPath 仅供单节点测试使用;不适用于多节点集群; 请尝试使用 local 卷作为替代。
hostPath 允许挂载 Node 上的文件系统到 Pod 里面去,也支持 pod 里文件系统挂载到 Node 节点上,属于双向挂载。
除了必需的 path 属性之外,用户可以选择性地为 hostPath 卷指定 type。
取值 | 行为 |
---|---|
空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。 | |
DirectoryOrCreate | 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。 |
Directory | 在给定路径上必须存在的目录。 |
FileOrCreate | 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。 |
File | 在给定路径上必须存在的文件。 |
Socket | 在给定路径上必须存在的 UNIX 套接字。 |
CharDevice | 在给定路径上必须存在的字符设备。 |
BlockDevice | 在给定路径上必须存在的块设备。 |
①、修改配置文件
如下 pod/springboot-pod 是 springboot 项目,默认端口号 8080
下面使用 hostPath 挂载 Node 上的文件到 Pod 里面,修改 springboot 项目端口号 8080-> 8090
springboot 的配置文件 /root/config/application.yaml 在 node1 节点上
server:
port: 8090
修改配置文件 aliyun-private-springboot-pod.yaml
,添加如下内容,因为我要把 node1 节点的文件挂载到 pod 节点里,所以需要保证节点有该文件,需要将 pod 部署到指定节点,如果你要将 pod 节点文件目录挂载到宿主机,可以不指定节点,Pod调度到哪个节点,则直接挂载到当前节点上
apiVersion: v1
kind: Pod
metadata:
name: springboot-pod
spec:
nodeName: node1 # 指定部署到 node1 节点
imagePullSecrets:
- name: mysecret # 名字保持和创建的验证保持一致
# 定义容器,可以多个
containers:
- name: springboot # 容器名字
image: registry.cn-zhangjiakou.aliyuncs.com/k8s-private/springboot:1.4 # 阿里云私人镜像
volumeMounts:
- mountPath: /root/config/ # 容器内部目录
name: hostpath-volume
volumes:
- name: hostpath-volume
hostPath:
path: /root/volume/ # node节点目录
type: Directory
②、部署测试
部署 pod 并测试
在 node1 节点新建文件 /root/volume/test.log
进入 pod/springboot-pod 查看是否挂载成功
反之在 pod 里面 /root/config/ 目录下创建文件也可以同步到 node1 节点 /root/volume 目录下
3、local 本地存储设备
local 卷所代表的是某个被挂载的本地存储设备,例如磁盘、分区或者目录。
local 卷只能用作静态创建的持久卷。尚不支持动态配置。
与 hostPath 卷相比,local 卷能够以持久和可移植的方式使用,而无需手动将 Pod 调度到节点
。系统通过查看 PersistentVolume 的节点亲和性配置,就能了解卷的节点约束。
然而,local 卷仍然取决于底层节点的可用性,并不适合所有应用程序。 如果节点变得不健康,那么 local 卷也将变得不可被 Pod 访问。使用它的 Pod 将不能运行。 使用 local 卷的应用程序必须能够容忍这种可用性的降低,以及因底层磁盘的耐用性特征而带来的潜在的数据丢失风险。
local 示例:PersistentVolume 示例下的 local 示例
4、nfs 共享文件系统
nfs 卷能将 NFS (网络文件系统) 挂载到你的 Pod 中。 不像 emptyDir 那样会在删除 Pod 的同时也会被删除,nfs 卷的内容在删除 Pod 时会被保存,卷只是被卸载。 这意味着 nfs 卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享。
注意: 在使用 NFS 卷之前,你必须运行自己的 NFS 服务器并将目标 share 导出备用。
需要先安装 NFS 文件共享系统,安装 NFS 文件系统,我安装的 NFS 服务器是 master 节点,IP:192.168.25.100
创建 /root/volume/nginx-pod.yaml
配置文件
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
volumes:
- name: nginx-volume
nfs:
path: /home/data/nginx-pod
# NFS 服务器节点
server: 192.168.25.100
containers:
- name: nginx-container
image: nginx:latest
ports:
- containerPort: 80
name: "http-server"
hostPort: 100
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-volume
创建 nginx-pod
[root@master volume]# kubectl apply -f nginx-pod.yaml
pod/nginx-pod created
[root@master volume]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
k8s-emptydir-volume 2/2 Running 4 (11h ago) 2d3h 10.244.1.30 node1 <none> <none>
nginx-pod 1/1 Running 0 9s 10.244.2.36 node2 <none> <none>
进入 /home/data/nginx-pod 目录添加文件测试
[root@master volume]# cd /home/data/nginx-pod
[root@master nginx-pod]# echo "volume type: nfs,config file:nginx-pod.yaml" > index.html
[root@master nginx-pod]# cat index.html
volume type: nfs,config file:nginx-pod.yaml
[root@master nginx-pod]#
访问 http://192.168.25.102:100/ 测试成功
六、PersistentVolume 示例
1、hostPath / local
pv-volume.yaml,使用 hostPath / local 卷时,需要设置 PersistentVolume 对象的 nodeAffinity 字段,指定存储卷到正确的节点
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: manual # ⽤于绑定PVC和PV,PV 和 PVC 的 storageClassName 保持一致
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce # 单个节点以读/写模式挂载
local:
path: "/opt/data/nginx" # node2 节点目录
# 如果要使用 hostPath 类型,只需要将 local 类型替换如下内容即可
#hostPath:
# path: "/opt/data/nginx" # node2 节点目录
nodeAffinity:
required:
# 通过 hostname 限定在某个节点创建存储卷
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node2 # 存储卷创建到 node2 节点
访问模式 accessModes 一共有三种:
- ReadWriteOnce:该卷可以被单个节点以读/写模式挂载,简写 RWO
- ReadOnlyMany::该卷可以被多个节点以只读模式挂载,简写 ROX
- ReadWriteMany::该卷可以被多个节点以读/写模式挂载,简写 RWX
pv-claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
pv-pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pv-pod
spec:
volumes:
- name: nginx-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: nginx-pv-container
image: nginx:latest
ports:
- containerPort: 80
name: "http-server"
hostPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-pv-storage
创建 PV,输出结果显示该 PV 的状态(STATUS) 为 Available,这意味着它还没有被绑定给 PVC
创建 PVC 之后,Kubernetes 查找满足申领要求的 PV,找到具有相同 StorageClass=manual 的 PV, 则将 PVC 绑定到了 task-pv-volume上。
创建 Pod
在 node2 节点的目录 /opt/data/nginx 添加测试文件 index.html
[root@node2 ~]# mkdir -p /opt/data/nginx
[root@node2 ~]# echo 'Hello from Kubernetes storage' > /opt/data/nginx/index.html
[root@node2 ~]# cat /opt/data/nginx/index.html
Hello from Kubernetes storage
2、nfs 共享文件系统
① 添加配置文件
nginx-pv-volume-nfs.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nginx-pv-volume-nfs
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /home/data/nginx-pv-nfs-pod
server: 192.168.25.100
nginx-pv-claim-nfs.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pv-claim-nfs
spec:
storageClassName: nfs
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
nginx-pv-pod-nfs.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pv-nfs-pod
spec:
volumes:
- name: nginx-pv-nfs-storage
persistentVolumeClaim:
claimName: nginx-pv-claim-nfs
containers:
- name: nginx-pv-nfs-container
image: nginx:latest
ports:
- containerPort: 80
name: "http-server"
hostPort: 90
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-pv-nfs-storage
②、创建 pod、PV、PVC
创建 pod、PV、PVC 并查看信息
[root@master volume]# kubectl apply -f nginx-pv-volume-nfs.yaml
persistentvolume/nginx-pv-volume-nfs created
[root@master volume]# kubectl apply -f nginx-pv-claim-nfs.yaml
persistentvolumeclaim/nginx-pv-claim-nfs created
[root@master volume]# kubectl apply -f nginx-pv-pod-nfs.yaml
pod/nginx-pv-nfs-pod created
[root@master volume]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 21m 10.244.2.36 node2 <none> <none>
nginx-pv-nfs-pod 1/1 Running 0 4m11s 10.244.2.37 node2 <none> <none>
[root@master volume]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nginx-pv-volume-nfs 10Gi RWO Retain Bound default/nginx-pv-claim-nfs nfs 5m44s
task-pv-volume 10Gi RWO Retain Bound default/task-pv-claim manual 3h59m
[root@master volume]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nginx-pv-claim-nfs Bound nginx-pv-volume-nfs 10Gi RWO nfs 5m34s
task-pv-claim Bound task-pv-volume 10Gi RWO manual 3h59m
③、测试
进入 /home/data/nginx-pv-nfs-pod 目录添加文件测试
[root@master volume]# cd /home/data/nginx-pv-nfs-pod/
[root@master nginx-pv-nfs-pod]# echo "volume type: nfs,config file: nginx-pv-volume-nfs.yaml,nginx-pv-claim-nfs.yaml,nginx-pv-pod-nfs.yaml" > index.html
[root@master nginx-pv-nfs-pod]# cat index.html
volume type: nfs,config file: nginx-pv-volume-nfs.yaml,nginx-pv-claim-nfs.yaml,nginx-pv-pod-nfs.yaml
[root@master nginx-pv-nfs-pod]#
访问 http://192.168.25.102:90/ 测试成功
七、安装 NFS 文件系统
NFS(Network File System,网络文件系统)是一个共享文件系统。
安装 nfs 文件系统参考:https://blog.csdn.net/make_progress/article/details/124295978
1、环境配置
rpcbind 是一个 RPC(Remote Procedure Call,远程过程调用)服务,在nfs共享时向客户端通知服务器的 nfs 端口号。
主机名 | IP地址 | 安装的软件 | 挂载目录 |
---|---|---|---|
master | 192.168.25.100 | nfs-utils rpcbind | /home/data |
node1 | 192.168.25.101 | nfs-utils rpcbind | ~/volume/node1 |
node2 | 192.168.25.102 | nfs-utils rpcbind | ~/volume/node2 |
2、安装软件
# 在 K8S 所有节点安装开启服务
yum -y install nfs-utils rpcbind
# 开启服务并设置服务自启动
systemctl enable rpcbind && systemctl start nfs
systemctl enable nfs-server && systemctl start rpcbind
3、共享文件
将 master 节点的目录共享到任意 IP,master 节点添加如下配置
# ro: 默认选项,以只读的方式共享。
# rw: 以读写的方式共享。
# root_squash: 将客户端使用的是root用户时,则映射到NFS服务器的用户为NFS的匿名用户(nfsnobody)。
# no_root_squash: 将客户端使用的是root用户时,则映射到NFS服务器的用户依然为root用户。
# all_squash: 默认选项,将所有访问NFS服务器的客户端的用户都映射为匿名用户,不管客户端使用的是什么用户。
# anonuid: 设置映射到本地的匿名用户的UID
# anongid: 设置映射到本地的匿名用户的GID
# sync: 默认选项,保持数据同步,数据同步写入到内存和硬盘。
# async: 异步,先将数据写入到内存,在将数据写入到硬盘。
# secure: 限制客户端只能从小于1024的tcp/ip端口连接nfs服务器(默认设置);
# insecure: 允许客户端从大于1024的tcp/ip端口连接服务器
# subtree_check: 如果共享/usr/bin之类的子目录时,强制NFS检查父目录的权限(默认)
# no_subtree_check: 和上面相对,不检查父目录权限
# wdelay: 如果多个用户要写入NFS目录,则归组写入(默认)
# no_wdelay: 如果多个用户要写入NFS目录,则立即写入,当使用async时,无需此设置。
# Hide: 在NFS共享目录中不共享其子目录
# no_hide: 共享NFS目录的子目录
# (1)编辑exports文件
[root@master data]# sudo vim /etc/exports
# (2)添加以下内容
# 将"/home/data"目录共享任意地址(*),也可以指定某个网段(192.168.108.*)
/home/data *(insecure,rw,sync,no_subtree_check)
# (3)重启服务
[root@master data]# sudo systemctl restart nfs rpcbind
# (4)查看共享目录
[root@master data]# showmount -e
Export list for master:
/home/data *
# 查看挂载日志
[root@master data]# tail -f /var/log/messages | grep mount
在 node1 节点上挂载
# 在node1上创建目录
[root@node1 volume]# sudo mkdir -p ~/volume/node1
# 将本地目录 ~/volume/node1 挂载到“192.168.25.100:/home/data”上
[root@node1 volume]# sudo mount -t nfs 192.168.25.100:/home/data ~/volume/node1
# 查看挂载目录 (部分信息)
[root@node1 volume]# df -h
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 1.9G 14M 1.9G 1% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 2.7G 15G 16% /
overlay 17G 2.7G 15G 16% /var/lib/docker/overlay2/39b4c8dc27e029eb4166b30579fed4bc91adafaf2a73f864649504e164d02cdd/merged
192.168.25.100:/home/data 17G 3.1G 14G 19% /root/volume/node1
4、测试
在 master 节点添加文件 /home/data/test.log,到 node1 节点 /root/volume/node1/test.log 查看
# master 节点
[root@master data]# echo "mount" > test.log
[root@master data]# ls
test.log
[root@master data]# cat test.log
mount
# node1 节点
[root@node1 node1]# pwd
/root/volume/node1
[root@node1 node1]# ls
test.log
[root@node1 node1]# cat test.log
mount
# 卸载挂载的目录
[root@node1 node1]# umount -l /root/volume/node1