kubernetes利用NFS创建PV PVC的过程(测试通过)

Persistent Volume(持久化卷)简称PV, 是一个K8S资源对象,我们可以单独创建一个PV, 它不和Pod直接发生关系, 而是通过Persistent Volume Claim, 简称PVC来实现动态绑定, 我们会在Pod定义里指定创建好的PVC, 然后PVC会根据Pod的要求去自动绑定合适的PV给Pod使用。

持久化卷下PV和PVC概念:
Persistent Volume(PV)是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV 也是集群中的资源。 PV 是 Volume 之类的卷插件,但具有独立于使用 PV 的 Pod 的生命周期。此 API 对象包含存储实现的细节,即 NFS、iSCSI 或特定于云供应商的存储系统。
PersistentVolumeClaim(PVC)是用户存储的请求。它与 Pod 相似,Pod 消耗节点资源,PVC 消耗 PV 资源。Pod 可以请求特定级别的资源(CPU 和内存)。PVC声明可以请求特定的大小和访问模式(例如,可以以读/写一次或只读多次模式挂载)。有了PersistentVolumeClaim,用户只需要告诉Kubernetes需要什么样的存储资源,而不必关心真正的空间从哪里分配,如何访问等底层细节信息;这些Storage Provider的底层信息交给管理员来处理,只有管理员才应该关心创建PersistentVolume的细节信息

它和普通Volume的区别是什么呢?
普通Volume和使用它的Pod之间是一种静态绑定关系,在定义Pod的文里,同时定义了它使用的Volume。Volume是Pod的附属品,我们无法单独创建一个Volume,因为它不是一个独立的K8S资源对象。

1、 准备一台机器,搭建NFS服务

https://blog.csdn.net/BigData_Mining/article/details/8863887

2、 在node节点上测试

sudo apt install nfs-kernel-server
showmount -e  192.168.10.100(主节点)

3、 pv模块:创建pv

vim mypv.yaml //内容如下

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    pv: nfs-pv
spec:
  capacity:
    storage: 10Gi #指定pv的容量为10Gi
     #指定访问模式
  accessModes:
    - ReadWriteMany   #pv能以readwriteMany模式mount到单个节点
  #指定pv在nfs服务器上对应的目录
  storageClassName: nfs
  nfs:
    path: /home/work (服务器端的挂在目录)
    server: 192.168.10.100(服务器IP)

固定写法,最下方定义了nfs的server和path,这就需要k8s本机安装nfs-utils,才能识别nfs;其次,还要在nfs服务器上指定path,并确保挂载nfs后,可以正常创建文件,写入内容。这里创建的pv存储总大小为1GB。定义pv的名称为pv001,label为nfs-pv。

细节解析:

PV 的访问模式(accessModes)有三种:

· ReadWriteOnce(RWO):是最基本的方式,可读可写,但只支持被单个 Pod 挂载。
· ReadOnlyMany(ROX):可以以只读的方式被多个 Pod 挂载。
· ReadWriteMany(RWX):这种存储可以以读写的方式被多个 Pod 共享。

不是每一种PV都支持这三种方式,例如ReadWriteMany,目前支持的还比较少。在 PVC 绑定 PV 时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。

PV 的回收策略(persistentVolumeReclaimPolicy,即 PVC 释放卷的时候 PV 该如何操作)也有三种:

Retain,不清理, 保留 Volume(需要手动清理)
Recycle,删除数据,即 rm -rf /thevolume/*(只有 NFS 和 HostPath 支持)
Delete,删除存储资源,比如删除 AWS EBS 卷(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)

PVC释放卷是指用户删除一个PVC对象时,那么与该PVC对象绑定的PV就会被释放。

kubectl create -f mypv.yaml
kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv001 10Gi RWX Retain Available 10m

状态为Available,这是因为它还没有绑定到任何的pvc上面,当定义完pvc后,就可以自动绑定了。

4 、pvc模块:创建pvc

vim mypvc.yaml //内容如下
 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 200Mi
  storageClassName: nfs
  selector:
    matchLabels:
      pv: nfs-pv

首先关注这个配置:storageClassName: nfs(如果不配置的话,可以自动的去匹配)。此配置用于绑定PVC和PV。这表明这个PVC希望使用storageClassName=nfs的PV。返回到上文中PV的定义,我们可以看到PV定义中也包含storageClassName=nfs的配置。
pvc向pv声明使用的存储空间大小为200MB,并且通过selector指定与label名为nfs-pv的pv相匹配(如果不配置的话,可以自动的去匹配),由于之前创建了label名为nfs-pv的pv,所以这里可以匹配成功,即pvc成功的向pv申请了200MB的空间。

kubectl create -f mypvc.yaml
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
myclaim Bound pv001 10Gi RWX 2m

可以看到,pvc状态为Bound,它绑定了pv001

5 定义pod

vim pvpod.yaml //内容如下
 
apiVersion: v1
kind: Pod
metadata:
  name: httpd-pvpod
spec:
  containers:
  - image: httpd
    name: httpd-withpvc-pod
    imagePullPolicy: Always
    volumeMounts:
    - mountPath: "/usr/local/apache2/htdocs/"   #容器中指定路径(可自己指定),挂载到容器的某个路径下
      name: httpd-volume    #挂载设备的名字,与volumes[*].name 需要对应   
  volumes:
    - name: httpd-volume   #与上面volumeMounts的name对应
      persistentVolumeClaim:
        claimName: myclaim

最主要的,需要挂载pvc,实现持久化存储,并最终将该存储映射到容器内的/usr/local/apache2/htdocs/路径下,实现数据的持久化。

kubectl create -f pvpod.yaml
kubectl describe pod httpd-pvpod //查看Volumes那部分里的ClaimName

6 验证

1)到NFS的共享目录下创建一个文件

cd  /home/work/
echo "Test file" > 1.html

2)进入到httpd-pod里

kubectl exec -it httpd-pvpod bash
cat /usr/local/apache2/htdocs/1.html

3)删除httpd-pvpod

kubectl delete pod httpd-pvpod
cat /data/k8s/1.html

4)重建httpd-pod

kubectl create -f pvpod.yaml

5)curl访问

kubectl get pod httpd-pvpod -o wide //查看其对应的IP
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
httpd-pod 1/1 Running 0 2m 172.20.3.5 172.7.15.114 <none>

curl 172.20.3.5/1.html

遇到的问题

[root@devhadoop225 k8s]#kubectl get svc
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGEdeployment-wp   NodePort   10.68.224.222           80:36661/TCP   5dkubernetes      ClusterIP   10.68.0.1               443/TCP        9dmysql-service   ClusterIP  None                    3306/TCP       16h

查看service也是正常的。但查看pod时,出现了如下错误:

[root@devhadoop225 k8s]# kubectl logs wordpress-mysql-6976864748-m2nph
Error from server: Gethttp://192.168.1.240:10250/containerLogs/default/wordpress-mysql-6976864748-m2nph/mysql:net/http: HTTP/1.x transport connection broken: malformed HTTP response"\x15\x03\x01\x00\x02\x02"
[root@devhadoop225 k8s]# kubectl describepods wordpress-mysql-6976864748-js75f
Warning BackOff                12s (x4over 41s)  kubelet, 192.168.1.229  Back-off restartingfailed container

在k8s node端,查看container的运行日志,也没有任何内容,查不着任何有用的信息,于是就一直卡在这个问题上。但此时,在node上查看磁盘挂载情况,是可以看到的:
在这里插入图片描述
尝试去掉如下部分,再启动k8s mysq了,则一切正常:
在这里插入图片描述
这说明,问题就出现在了这部分上。但就是找不到问题的突破口。按上面的报错信息查找原因,根本找不出来原因。
后来,经过摸索,尝试在kubelet上直接运行docker命令创建mysql,但是volumes需要绑定nfs配置目录到容器的/var/lib/mysql,即执行:

docker run -p 3316:3306 --name mysql -v/data/mysql/conf:/etc/mysql/conf.d -v/var/lib/kubelet/pods/777d6238-d75c-11e8-b75b-ea2abbd44791/volumes/kubernetes.io~nfs/nfs-pv:/var/lib/mysql-e MYSQL_ROOT_PASSWORD=123456 -d 192.168.1.229/project/mysql:5.7.18

同样是创建失败,查看logs发现报错如下:changing ownership of ‘/var/lib/mysql/’: Operation notpermitted正是因为这个错误的暴露,才让我解决了整个k8s+mysql+pv+pvc+nfs的整套问题!!!
提示说确实是与NFS的配置有关,NFS默认是squash_all模式,但是要想使用NFS目录,将目录映射到docker容器中,必须要配置成no_root_squash模式才行,否则root用户无权限使用nfs的volume来映射docker容器中的目录!!!no_root_squash模式:是登入 NFS 主机使用分享目录的使用者,如果是 root 的话,那么对于这个分享的目录来说,他就具有 root 的权限!这个项目『极不安全』,不建议使用! 这正是我遇到的问题,之前一直在排查k8s master节点的问题,查找资料有说是kube-controller-manager的问题,但是排查一圈,没有发现问题。原来是NFS的问题啊,于是果断在NFS配置文件中增加了no_root_squash:

[root@dev252 etc]# more exports
#/home/centos7/ 192.168.1.0/24(insecure,rw,sync,fsid=0)
/home/centos7/nfs192.168.1.0/24(insecure,rw,sync,no_root_squash,fsid=0)

这样,再重启nfs后,再次通过k8s启动mysql service,就一切都正常了,可以正常创建pod,也可在240上正常创建容器了!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/BigData_Mining/article/details/88637182