七. k8s--volumes之pv pvc学习笔记

k8s存储卷-volumes

为什么要用volumes?

容器中的磁盘的生命周期是短暂的, 这就带来了一些列的问题:

  1. 当一个容器损坏之后, kubelet会重启这个容器, 但是文件会丢失, 这个容器将是一个全新的状态
  2. 当很多容器运行在同一个pod中时, 很多时候需要数据文件的共享
  3. k8s中,由于pod分布在各个不同的节点之上,并不能实现不同节点之间持久性数据的共享,并且,在节点故障时,可能会导致数据的永久性丢失。

volumes就是用来解决以上问题的

Volume 的生命周期独立于容器,Pod 中的容器可能被销毁和重建,但 Volume 会被保留。

volumes类型

emptyDir

一个emptyDir第一次被创建是在一个pod被指定到具体node的时候, 并且会一直存在在pod的生命周期中, 它初始化是一个空的目录,pod中的容器都可以读写这个目录,这个目录可以被挂在到各个容器相同或者不相同的的路径下。当一个pod因为任何原因被移除的时候,这些数据会被永久删除。注意:一个容器崩溃了不会导致数据的丢失,因为容器的崩溃并不移除pod.
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo   #name必须小写
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    create-by: tianpei.wang
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /data/web/html/

  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: html
      mountPath: /data/
    command: ["/bin/sh", "-c", "sleep 7200"]
  volumes:
  - name: html
    emptyDir: {}

gitrepo

本质上还是一个emptyDir,创建的那一刻从git上clone下来文件,不会在更新,所以会借助sidecar容器来更新或者推送目录中的文件代码

hostPath

一个hostPath类型的磁盘就是挂在了主机的一个文件或者目录,这个功能可能不是那么常用,但是这个功能提供了一个很强大的突破口对于某些应用来说 例如,如下情况我们旧可能需要用到hostPath 某些应用需要用到docker的内部文件,这个时候只需要挂在本机的/var/lib/docker作为hostPath 在容器中运行cAdvisor,这个时候挂在 /dev/cgroups
apiVersion: v1
kind: Pod
metadata:
    name: pod-volume-hostpath
    namespace: default
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
      volumeMounts:
      - name: html
        mountPath: /usr/share/nginx/html
    volumes:
    - name: html
      hostPath:
        path: /data/pod/volume1
        type: DirectoryOrCreate

nfs

安装部署nfs

yum install -y nfs-utils rpcbind
systemctl start rpcbind
systemctl start nfs
[root@test share]# cat /etc/exports
/data/share 10.0.0.0/24(rw,no_root_squash)
apiVersion: v1
kind: Pod
metadata:
    name: pod-volume-hostpath
    namespace: default
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
      volumeMounts:
      - name: html
        mountPath: /usr/share/nginx/html
    volumes:
    - name: html
      nfs:
        path: /data/share
        server: 10.0.0.53

k8s--PV, PVC

PV PVC带来了哪些好处

Volume 提供了非常好的数据持久化方案,不过在可管理性上还有不足。

如前面nfs-volume举例, 当我们创建一个挂载到nfs服务器上的pod时, 我们需要知道:

  1. nfs服务的ip
  2. nfs服务的共享目录

Pod 通常是由应用的开发人员维护,而 Volume 则通常是由存储系统的管理员维护。开发人员要获得上面的信息:

  1. 要么询问管理员。
  2. 要么自己就是管理员。

这样就带来一个管理上的问题:应用开发人员和系统管理员的职责耦合在一起了。如果系统规模较小或者对于开发环境这样的情况还可以接受。但当集群规模变大,特别是对于生成环境,考虑到效率和安全性,这就成了必须要解决的问题。

Kubernetes 给出的解决方案是 PersistentVolume 和 PersistentVolumeClaim。

PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员创建和维护。与 Volume 一样,PV 具有持久性,生命周期独立于 Pod。

扫描二维码关注公众号,回复: 7249564 查看本文章

PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。PVC 通常由普通用户创建和维护。需要为 Pod 分配存储资源时,用户可以创建一个 PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 会查找并提供满足条件的 PV。

有了 PersistentVolumeClaim,用户只需要告诉 Kubernetes 需要什么样的存储资源,而不必关心真正的空间从哪里分配,如何访问等底层细节信息。这些 Storage Provider 的底层信息交给管理员来处理,只有管理员才应该关心创建 PersistentVolume 的细节信息。

  • 一个pv只能对应一个pvc,但是一个pvc可以对应多个pod
  • pv属于集群级别的资源,整个集群都可以用;pvc属于namespace级别的资源,只属于所属namespace
  • pvc资源存储在etcd中,只要etcd服务正常就不会丢失,和节点没有关系

基于nfs配置pv和pvc

nfs的配置参考前文

定义pv

apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv001
    labels:
        name: pv001
spec:
    nfs:
        path: /data/volumes/test1
        server: 10.0.0.53
    accessModes: ["ReadWriteMany","ReadWriteOnce"]
    capacity:
        storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv002
    labels:
        name: pv002
spec:
    nfs:
        path: /data/volumes/test2
        server: 10.0.0.53
    accessModes: ["ReadWriteMany","ReadWriteOnce"]
    capacity:
        storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv003
    labels:
        name: pv003
spec:
    nfs:
        path: /data/volumes/test3
        server: 10.0.0.53
    accessModes: ["ReadWriteMany","ReadWriteOnce"]
    capacity:
        storage: 7Gi
[root@master volumes]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON   AGE
pv001   2Gi        RWO,RWX        Retain           Available                                           14m
pv002   2Gi        RWO,RWX        Retain           Available                                           14m
pv003   7Gi        RWO,RWX        Retain           Available                                           14m

accessModes:

  • ReadWriteOnce (RWO) – the volume can be mounted as read-write by a single node
  • ReadOnlyMany (ROX) – the volume can be mounted read-only by many nodes
  • ReadWriteMany (RWX) – the volume can be mounted as read-write by many nodes

定义pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: mypvc
    namespace: default
spec:
    accessModes: ["ReadWriteMany"]
    resources:
        requests:
            storage: 6Gi
---
apiVersion: v1
kind: Pod
metadata:
    name: myapp-pvc
    namespace: default
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
      volumeMounts:
      - name: html
        mountPath: /usr/share/nginx/html
    volumes:
    - name: html
      persistentVolumeClaim:
        claimName: mypvc

此时发现有符合要求的pv被绑定到了pod上

[root@master volumes]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON   AGE
pv001   2Gi        RWO,RWX        Retain           Available                                           15m
pv002   2Gi        RWO,RWX        Retain           Available                                           15m
pv003   7Gi        RWO,RWX        Retain           Bound       default/mypvc                           15m

以mysql:5.6镜像为例

  1. 直接使用上例创建的pv

  2. 创建mysql的pvc和deployment

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
        name: mypvc
        namespace: default
    spec:
        accessModes: ["ReadWriteMany"]
        resources:
            requests:
                storage: 6Gi
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
        name: mysql-deployment
        namespace: default
    spec:
        replicas: 1
        selector:
            matchLabels:
                app: mysql
        template:
            metadata:
              labels:
                app: mysql
            spec:
                containers:
                - name: mysql
                  image: mysql:5.6
                  imagePullPolicy: IfNotPresent
                  args:
                  - "--ignore-db-dir=lost+found"
                  ports:
                  - containerPort: 3306
                  env:
                  - name: MYSQL_ROOT_PASSWORD
                    value: "mysql"
                  volumeMounts:
                  - name: mysql
                    mountPath: /var/lib/mysql
                volumes:
                - name: mysql
                  persistentVolumeClaim:
                      claimName: mypvc
  3. 然后在创建的pod中创建数据

    kubectl exec -it pod mysql-deployment-5b9cf7df5c-mh94v -- /bin/sh
    
    #在pod中可以看到挂载好的nfs磁盘
    # df -h
    Filesystem                     Size  Used Avail Use% Mounted on
    overlay                         20G  3.7G   16G  19% /
    tmpfs                           64M     0   64M   0% /dev
    tmpfs                          912M     0  912M   0% /sys/fs/cgroup
    /dev/sda2                       20G  3.7G   16G  19% /etc/hosts
    shm                             64M     0   64M   0% /dev/shm
    10.0.0.53:/data/volumes/test3   20G  4.3G   16G  22% /var/lib/mysql
    
    #进入mysql
    # mysql -uroot -pmysql
    
    #创建新的数据库
    mysql> create database wtp;
    
    #进入新库
    mysql> use wtp;
    
    #创建新的表
    mysql> CREATE TABLE `tbl_dept`(
        -> `id` INT(11) NOT NULL AUTO_INCREMENT,
        -> `deptName` VARCHAR(30) DEFAULT NULL,
        -> `locAdd`  VARCHAR(40) DEFAULT NULL,
        -> PRIMARY KEY (`id`)
        -> )ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
    Query OK, 0 rows affected (0.12 sec)
    
    #删除mysql的deployment
    kubectl delete deployments mysql-deployment
    
    #重新创建mysql的deployment
    kubectl apply -f pvc.yaml
    
    #进入新的mysql pod
    kubectl exec -it mysql-deployment-5b9cf7df5c-ztfwx -- /bin/sh
    
    #可以看到依旧挂载的之前的目录
    # df -h
    Filesystem                     Size  Used Avail Use% Mounted on
    overlay                         20G  3.7G   16G  19% /
    tmpfs                           64M     0   64M   0% /dev
    tmpfs                          912M     0  912M   0% /sys/fs/cgroup
    /dev/sda2                       20G  3.7G   16G  19% /etc/hosts
    shm                             64M     0   64M   0% /dev/shm
    10.0.0.53:/data/volumes/test3   20G  4.3G   16G  22% /var/lib/mysql
    
    #进入mysql查看之前的数据都还在
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | wtp                |
    +--------------------+
    4 rows in set (0.08 sec)
    
    mysql> use wtp
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    mysql> show tables
        -> ;
    +---------------+
    | Tables_in_wtp |
    +---------------+
    | tbl_dept      |
    +---------------+
    1 row in set (0.00 sec)

猜你喜欢

转载自www.cnblogs.com/peitianwang/p/11498279.html