k8s 中 pv和pvc

kubenetes 存储

一. hostPath类型的Volume

这种类型的Volume是使用node节点本地的存储资源。

  • 优点是相对于其他网络存储没有网络开销
  • 缺点是无法和其他node节点上的pod共享数据。Pod必须要与Volume在同一台宿主机

配置hostPath存储卷的嵌套字段共有两个:一个是用于指定工作节点上的目录路径的必须按字段path 一个是指定存储卷类型的type,它支持使用的卷类型包含如下几种:

  • DirectoryOrCreate:指定的路径不存在时自动将其创建为权限是0755的空目录,属主属组均为kubelet。

  • Directory:必须存在的目录路径

  • FileOrCreate:指定的路径不存在时自动将其创建为权限0644的空文件,属主和属组同是kubelet。

  • File:必须存在的文件路径

  • Socket:必须存在的Socket文件路径

  • CharDevice:必须存在的字符设备文件路径

  • BlockDevice:必须存在的块设备文件路径

使用方法

apiVersion: v1
kind: Pod
metadata:
  name: vo-hostpath-pod
spec:
  containers:
  - name: filebeat
    image: ikubernetes/filebeat:5.6.7-alpine
    env:                            #定义变量
    - name: REDIS_HOST              #变量名
      value: redis.ilinux.io:6379   #变量值
    - name: LOG_LEVEL               #变量明
      value: info                   #变量值
    volumeMounts:                   #卷挂载配置
    - name: varlog                  #挂载名称为varlog的卷
      mountPath: /var/log           #挂载到容器中的/var/log目录中
    - name: socket                  #挂载名称为socket的卷
      mountPath: /var/run/docker.sock#挂载到容器中的/var/run/docker.sock
    - name: varlibdockercontainers  #挂载名称为varlibdockercontainers的卷
      mountPath: /var/lib/docker/containers#挂载到容器中的/var/lib/docker/containers目录中
      readOnly: true                #为只读挂载
  volumes:                          #卷配置
  - name: varlog                    #自定义的卷名称
    hostPath:                       #节点路径配置
      path: /var/log                #在节点上的路径
      type: DirectoryOrCreate       #节点上不存在/var/log目录时,则自动创建权限为0755的目录,属性信息为kubelet用户
  - name: varlibdockercontainers
    hostPath:
      path: /var/lib/docker/containers
      type: Directory
  - name: socket
    hostPath:
      path: /var/run/docker.sock
      type: Socket         #节点上必须存在/var/run/docker.sock,否则创建Pod失败

二. emptyDir存储卷

emptyDir存储卷是Pod对象生命周期中的一个临时目录,类似于Docker上的docker挂载卷,在Pod对象启动时即被创建,而在Pod对象被移除时会被一并删除。不具有持久能力的emptyDir存储卷只能用于某些特殊场景中,例如,用一Pod内的多个容器间文件的共享,或者作为容器数据的临时存储目录用于数据缓存系统等。

emptyDir存储卷则定义于.spec.volumes.emptyDir嵌套字段中,可用字段主要包含两个,具体如下:

  • medium:此目录所在存储介质的类型,可取值为defaultMemory,默认为default,表示使用节点的默认存储介质:Memory 表示基于RAM的临时文件系统tmpfs,空间受于内存,但性能非常好,通常用于为容器中的应用提供缓存空间。

  • sizeLimit:当前存储卷的空间限额,默认值为 nil,表示不限制;不过在 medium 字段为 Memory时,建议定义此限额。

使用方法

apiVersion: v1
kind: Pod
metadata:
  name: vol-emptydir-pod
spec:
  volumes:
  - name: html
    emptyDir: { }
  containers:
  - name: nginx
    image: nginx:latest
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  - name: pagegen
    image: alpine
    volumeMounts:
    - name: html
      mountPath: /html
    command: [ "/bin/sh", "-c" ]
    args:   #定义循环,每10秒向/html/文件中追加写入当前主机名和时间
    - while true; do
        echo $(hostname) $(date) >> /html/index.html;
        sleep 10;
      done
#  vol-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: vol-emptydir-pod
spec:
  volumes:
  - name: html
    emptyDir:
      medium: Memory                #指定临时存储到内存
      sizeLimit: 256Mi              #给予的内存空间大小
  containers:
  - name: nginx
    image: nginx:latest
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  - name: pagegen
    image: alpine
    volumeMounts:
    - name: html
      mountPath: /html
    command: [ "/bin/sh", "-c" ]
    args:
    - while true; do
        echo $(hostname) $(date) >> /html/index.html;
        sleep 10;
      done

emptyDir卷简单易用,但仅能用于临时存储

三.Persistent Volume(PV)

由于使用本地的Volume会有一些限制,比如Pod必须要与Volume在同一台宿主机,宿主机挂了数据就会丢失。所以K8S还提供了真正的持久化存储的技术,将数据挂载到其他专门用于存储数据的服务器上,这样即使宿主机挂了,数据还在。

PersistentVolume是为用户和管理员提供了一个API抽象的细节如何提供如何使用存储。 K8S引入了两个新的API资源:PersistentVolume(PV)、PersistentVolumeClaim(PVC)。

PersistentVolume:PV在K8S中也是一种资源,但生命周期独立于Pod。封装了底层存储卷实现的细节。它是用来定义或配置存储的资源,市面上有很多可以作为文件服务器的工具,比如NFS、RBD、Cinder等,PV就是帮我们打通了与这些服务器的对接。

PersistentVolumeClaim:PVC是给用户申请存储空间的。 当开发者需要通过PVC去申请存储空间,可以请求特定的空间大小和访问模式,比如他们可以申请是一次读/写或多次只读等。

简单来说,PV定义了一块存储空间,Pod想要申请存储空间,就要通过PVC去申请,PVC通过访问模式与申请的空间大小去匹配PV。

使用方法

以简单的NFS共享服务器说明

  • 准备一台NFS共享服务器,配置共享的目录
  • 保证node节点可以访问到共享服务器
1.创建PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-1
  labels:
    name: nfs-pv1
spec:
  capacity:
    storage: 3Gi                          # 存储空间大小
  volumeMode: Filesystem                  # 存储模式
  accessModes: ["ReadWriteMany","ReadWriteOnce","ReadOnlyMany"]   # 访问模式
    #- ReadWriteMany                       # 表示允许多个Pod多次读写
    # ReadWriteOnece 表示只允许一个Pod进行独占式读写操作
  nfs:
    path: /home/data/nfs/k8s               # 远端服务器的目录
    server: 192.168.123.3                    # 远端的服务器ip
2.创建pvc
[root@node-1 pv]# cat create_pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-1
  labels:
    name: pvc-1
spec:
  accessModes:
    - ReadWriteMany                    # 访问模式
  resources:
    requests:
      storage: 1Gi                      # 申请的存储空间大小
  selector:
    matchLabels:
      name: nfs-pv1						# 通过标签选择器选择上面创建的pv

3. 创建pod测试
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-test-pvc
  namespace: default
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx-test-pvc
    spec:
      containers:
      - name: nginx-test-pvc
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - name: html
          containerPort: 80
        volumeMounts:
        - name: nfs
          mountPath: "/usr/share/nginx/html"    
      - name: test-pod
        image: busybox:1.24
        command:
          - "/bin/sh"
        args:
         - "-c"
         - "echo 'Hello world'>>/mnt/pvc/index.html"
        volumeMounts:
        - name: nfs
          mountPath: "/mnt/pvc"    
      volumes:
      - name: nfs
        persistentVolumeClaim:
          claimName: pvc-1				# 选择上面创建的pvc名字

现在访问pod 应该可以看到上面输入的hello world

这样就可以实现pod通过网络访问共享资源

posted @ 2020-09-04 17:53  郭默涵  阅读(543)  评论(0)    收藏  举报