千家信息网

kubernetes如何通过​pv和pvc来实现存储管理?

发表于:2024-10-10 作者:千家信息网编辑
千家信息网最后更新 2024年10月10日,kubernetes版本:1.16.0概念pv全称为PersistentVolume(持久化卷),是对底层的共享存储的一种抽象,它和具体的底层的共享存储技术的实现方式有关,比如 Ceph、Gluste
千家信息网最后更新 2024年10月10日kubernetes如何通过​pv和pvc来实现存储管理?

kubernetes版本:1.16.0

概念

pv全称为PersistentVolume(持久化卷),是对底层的共享存储的一种抽象,它和具体的底层的共享存储技术的实现方式有关,比如 Ceph、GlusterFS、NFS 等。

pvc全称PersistentVolumeClaim(持久化卷声明),PVC 是用户存储的一种声明,PVC 消耗的是 PV 资源,对于真正使用存储的用户不需要关心底层的存储实现细节,只需要直接使用 PVC 即可。

NFS

k8s支持的 PV 类型有很多,常见的有 Ceph、GlusterFs、nfs以及 hostPath,不过 hostPath 仅仅可用于单机测试。方便起见,我们以NFS存储资源进行演示。

接下来我们在节点192.168.248.139上面安装nfs服务,共享的数据目录为/data/nfs/

1、安装配置nfs

yum install nfs-utils rpcbind -ymkdir -p /data/nfs && chmod 755 /data/nfs/cat /etc/exports/data/nfs  *(rw,sync,no_root_squash)systemctl start rpcbind nfs && systemctl enable rpcbind nfs

在k8s上配置使用pv与pvc之前,我们需要在所有的node节点上安装nfs客户端,我所使用的环境节点如下:

[root@k8s-master-01 ~]# kubectl get nodes -o wideNAME          STATUS   ROLES    AGE   VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION          CONTAINER-RUNTIMEk8s-node-01   Ready       90d   v1.16.0   192.168.248.134           CentOS Linux 7 (Core)   3.10.0-957.el7.x86_64   docker://18.9.6k8s-node-02   Ready       90d   v1.16.0   192.168.248.135           CentOS Linux 7 (Core)   3.10.0-957.el7.x86_64   docker://18.9.6

必须在所有节点都安装 nfs 客户端,否则可能会导致 PV 挂载不上的问题。

创建pv

部署完nfs存储,接下来我们就可以通过编辑yaml文件,来创建pv和pvc资源了。下面我们来创建一个 PV 资源对象,使用 nfs 类型的后端存储,2G 的存储空间,访问模式为 ReadWriteOnce,回收策略为 Recyle。

vim pv1.yaml
apiVersion: v1kind: PersistentVolumemetadata:  name: pv-01  labels:    name: pv-01spec:  nfs:    path: /data/nfs    server: 192.168.248.139  accessModes: ["ReadWriteOnce"]  persistentVolumeReclaimPolicy: Retain  capacity:    storage: 2Gi

对以上yaml文件中一些参数做以下解释

nfs:表示使用的后端存储为nfs

path:表示后端存储共享的数据目录

accessMode:是用来对pv进行访问权限的设置,包括以下几种方式:

  • ReadWriteOnce(RWO):读写权限,只能被单个节点挂载

  • ReadOnlyMany(ROX):只读权限,可以被多个节点挂载

  • ReadWriteMany(RWX):读写权限,可以被多个节点挂载

persistentVolumeReclaimPolicy:表示pv的回收策略,默认为Retain,目前支持的有三种:

  • Retain(保留)

  • Recycle(回收)

  • Delete(删除)

然后使用kubectl命令创建即可

[root@k8s-master-01 pv]# kubectl apply -f pv1.yaml persistentvolume/pv-01 created[root@k8s-master-01 pv]# kubectl get pvNAME              CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                    STORAGECLASS   REASON   AGEmysql-pv-volume   20Gi       RWO            Retain           Bound       default/mysql-pv-claim   manual                  2d2hpv-01             2Gi        RWO            Recycle          Available                                                    6s

如上,pv-01已经创建成功,状态为Available,表示pv-01已经准备就绪,可以被pvc申请使用。

pv的生命周期中可能会处于4种不同的阶段:

  • Available(可用)

  • Bound(已绑定)

  • Released(已释放)

  • Failed(失败)

创建pvc

对应的yaml文件内容如下:

vim pvc-nfs.yaml
apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: pvc-nfsspec:  accessModes: ["ReadWriteOnce"]  resources:    requests:      storage: 2Gi

然后使用kubectl命令创建即可

[root@k8s-master-01 pv]# kubectl apply -f pvc-nfs.yaml persistentvolumeclaim/pvc-nfs created[root@k8s-master-01 pv]# kubectl get pv,pvcNAME                               CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS   REASON   AGEpersistentvolume/mysql-pv-volume   20Gi       RWO            Retain           Bound    default/mysql-pv-claim   manual                  2d3hpersistentvolume/pv-01             2Gi        RWO            Retain           Bound    default/pvc-nfs                                  19sNAME                                   STATUS   VOLUME            CAPACITY   ACCESS MODES   STORAGECLASS   AGEpersistentvolumeclaim/mysql-pv-claim   Bound    mysql-pv-volume   20Gi       RWO            manual         2d3hpersistentvolumeclaim/pvc-nfs          Bound    pv-01             2Gi        RWO                           7s

可以看到 pvc-nfs已经创建成功,并且处于绑定状态,pv也处于绑定状态。

使用pvc

上面我们已经完成了pv和pvc的创建及绑定,接下来我们创建一个deployment,来使用上面的pvc

vim deployment-pvc.yaml
apiVersion: v1kind: Servicemetadata:  name: svc-nginx-demospec:  ports:  - port: 80    protocol: TCP    targetPort: 80    nodePort: 31080  selector:    app: liheng  type: NodePort---apiVersion: apps/v1kind: Deploymentmetadata:  name: deployment-pvc-demo  labels:     app: deployment-pvc-demo  annotations:    liheng86876/created-by: "LIHENG"spec:  replicas: 3  selector:    matchLabels:      app: liheng  template:    metadata:      labels:        app: liheng    spec:      containers:      - name: web-test        image: nginx        imagePullPolicy: IfNotPresent         ports:        - name: http          containerPort: 80        volumeMounts:        - name: html          mountPath: /usr/share/nginx/html/      volumes:      - name: html        persistentVolumeClaim:          claimName: pvc-nfs

然后使用kubectl命令创建即可

[root@k8s-master-01 pv]# kubectl get deploy,pod,svcNAME                                  READY   UP-TO-DATE   AVAILABLE   AGEdeployment.apps/deployment-pvc-demo   3/3     3            3           2m6sNAME                                       READY   STATUS    RESTARTS   AGEpod/deployment-pvc-demo-77859488fc-bmlhd   1/1     Running   0          2m5spod/deployment-pvc-demo-77859488fc-c8xkn   1/1     Running   0          2m5spod/deployment-pvc-demo-77859488fc-pz6g9   1/1     Running   0          2m5sNAME                     TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGEservice/kubernetes       ClusterIP   10.0.0.1             443/TCP        90dservice/svc-nginx-demo   NodePort    10.0.0.194           80:31080/TCP   2m6s

可以看到pod已经处于running状态,我们可以通过如下命令查看deployment和svc的详细信息

[root@k8s-master-01 pv]# kubectl describe deploy deployment-pvc-demoName:                   deployment-pvc-demoNamespace:              defaultCreationTimestamp:      Mon, 17 Feb 2020 18:04:26 +0800Labels:                 app=deployment-pvc-demoAnnotations:            deployment.kubernetes.io/revision: 1                        kubectl.kubernetes.io/last-applied-configuration:                          {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"liheng86876/created-by":"LIHENG"},"labels":{"app":"deployment-pvc-...                        liheng86876/created-by: LIHENGSelector:               app=lihengReplicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailableStrategyType:           RollingUpdateMinReadySeconds:        0RollingUpdateStrategy:  25% max unavailable, 25% max surgePod Template:  Labels:  app=liheng  Containers:   web-test:    Image:        nginx    Port:         80/TCP    Host Port:    0/TCP    Environment:      Mounts:      /usr/share/nginx/html/ from html (rw)  Volumes:   html:    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)    ClaimName:  pvc-nfs    ReadOnly:   falseConditions:  Type           Status  Reason  ----           ------  ------  Available      True    MinimumReplicasAvailable  Progressing    True    NewReplicaSetAvailableOldReplicaSets:  NewReplicaSet:   deployment-pvc-demo-77859488fc (3/3 replicas created)Events:  Type    Reason             Age    From                   Message  ----    ------             ----   ----                   -------  Normal  ScalingReplicaSet  4m48s  deployment-controller  Scaled up replica set deployment-pvc-demo-77859488fc to 3
[root@k8s-master-01 pv]# kubectl describe svc svc-nginx-demoName:                     svc-nginx-demoNamespace:                defaultLabels:                   Annotations:              kubectl.kubernetes.io/last-applied-configuration:                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"svc-nginx-demo","namespace":"default"},"spec":{"ports":[{"nodePor...Selector:                 app=lihengType:                     NodePortIP:                       10.0.0.194Port:                       80/TCPTargetPort:               80/TCPNodePort:                   31080/TCPEndpoints:                10.244.0.134:80,10.244.0.135:80,10.244.1.129:80Session Affinity:         NoneExternal Traffic Policy:  ClusterEvents:                   

访问测试

我们就可以通过任意节点的 IP:31080 端口来访问我们这里的Nginx服务

为什么会出现403呢???那是应为我们的nfs共享目录没有文件导致

[root@localhost nfs]# pwd/data/nfs[root@localhost nfs]# ls[root@localhost nfs]# 我们创建一个index.html,然后访问测试[root@localhost nfs]# echo "

Welcome k8s

" > index.html

然后在刷新页面:

我们可以看到已经可以正常访问到页面。

数据持久化测试


测试方法:

1、我们将创建的nginx应用删除掉,然后重新创建nginx应用,然后访问测试

结果:后端nfs存储里面的数据不会丢失,页面访问正常

2、我们将创建的nginx应用和pv及pvc全部删除,然后重新创建,然后访问测试

结果:后端nfs存储里面的数据不会丢失,页面访问正常


0