存储卷类型

Kubernetes提供的存储卷(volume)属于Pod资源,共享于Pod内的所有容器,存储卷可在容器的文件系统之外存储相关的数据,也可以独立于Pod的生命周期实现数据持久化存储。

按照类型划分,大致分为三类:

k8s 数据卷挂载 nfs多个 k8s存储卷_Pod

如下是工作中使用到的存储,持久卷声明对应于持久化数据存储类型。

k8s 数据卷挂载 nfs多个 k8s存储卷_nginx_02

详细说明

1. EmptyDir

EmptyDir字面意思理解为空目录。在容器启动时被创建,在容器移除时一并删除,因此不具有持久化存储的能力,但是如果作为同一个Pod内的多个容器间共享文件,或者作为容器数据的临时存储目录是非常好用的选择。

关键词:生命周期同Pod生命周期;作用域为同一个Pod内。

emptyDir存储卷可用字段主要包含两个:

  • medium:存储介质的类型,可取值为"default"或"Memory","default"使用节点的默认存储介质,占用磁盘空间;"Memory"基于RAM的临时文件系统tmpfs,占用内存空间。
  • sizeLimit:当前存储卷的空间限额,默认值为nil,表示不限制;一般在medium字段值为"Memory"时需要限制。
2. HostPaht

hostPath将目录从工作节点的文件系统挂载到pod中,它独立于Pod的生命周期,因而具有持久性,类似于docker中的-v。但是如果发生pod故障转移等情况,将不能获取到数据,除非数据在所有节点中都有。

关键词:某一工作节点的存储。

hostPath存储卷的嵌套字段共有两个:“path”(必选)和"type",它支持的存储卷类型(type)有如下几种:

  • DirectoryOrCreate:宿主机上不存在则创建此目录
  • Directory:宿主机上必须存在此目录
  • FileOrCreate:宿主机上不存在此文件则创建
  • File:宿主机上必须存在此文件
  • Socket:宿主机上必须存在的Socket文件路径
  • CharDevice:宿主机上必须存在的字符设备文件路径
  • BlockDevice:宿主机上必须存在的块设备文件路径
3. ConfigMap&Secret

ConfigMap和Secret作为配置集,以key-value的形式保存于etcd中,通过存储卷或者配置引用的形式在Pod中使用,区别在于Secret是经过加密的字段显示。示例如下:

# 新建configMap
# my-config.yaml
apiVersion: v1
data:
  redis.conf: |
    appendonly yes
  nginx.conf: |
    welcome nginx
  project:
    edsp
kind: ConfigMap
metadata:
  name: my-conf
  namespace: default
[root@k8s-master test]# kubectl apply -f my-config.yaml 
configmap/my-conf created
[root@k8s-master test]# kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      11d
my-conf            3      10s
[root@k8s-master test]#

data是所有真正的数据,key:默认是文件名,value:配置文件的内容。

# 新建secret
[root@k8s-master secret]# echo -n "jiangxiaonan" > user
[root@k8s-master secret]# echo -n "xxcjxn12345" > password
[root@k8s-master secret]# ls
password  user
[root@k8s-master secret]#
kubectl create secret generic db-user-pass \
  --from-file=user \
  --from-file=password
# 获取内容查看
[root@k8s-master secret]# kubectl get secrets
NAME                  TYPE                                  DATA   AGE
db-user-pass          Opaque                                2      7s
default-token-dp677   kubernetes.io/service-account-token   3      11d
[root@k8s-master secret]# kubectl get secrets db-user-pass -o=yaml
apiVersion: v1
data:
  password: eHhjanhuMTIzNDU=
  user: amlhbmd4aWFvbmFu
kind: Secret
metadata:
  creationTimestamp: "2022-07-20T14:47:10Z"
  managedFields:
  name: db-user-pass
  namespace: default
  resourceVersion: "140362"
  uid: 92095b33-385e-48a9-8418-ee5d86817cc3
type: Opaque
[root@k8s-master secret]# echo eHhjanhuMTIzNDU= | base64 -d
xxcjxn12345
[root@k8s-master secret]#

data是所有真正的数据。

4. PV&PVC

PV&PVC是基于文件系统存在的,我们这里使用NFS文件系统,独立于Pod的生命周期实现数据的持久化存储。

NFS文件系统自行安装,这里只准备pv和pvc。

# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv01-10m
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/01
    server: 172.31.0.2
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 500Mi
  storageClassName: nfs
[root@k8s-master test]# kubectl get pv,pvc
NAME                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
persistentvolume/pv01-10m   1Gi        RWX            Retain           Bound    default/nginx-pvc   nfs                     11d

NAME                              STATUS   VOLUME     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/nginx-pvc   Bound    pv01-10m   1Gi        RWX            nfs            11d
[root@k8s-master test]#

完整配置演示

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy
  name: nginx-deploy
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-deploy
  template:
    metadata:
      labels:
        app: nginx-deploy
    spec:
      restartPolicy: Always
      containers:
        - name: mynginx
          image: nginx
          imagePullPolicy: IfNotPresent
          envFrom:
          - configMapRef:
              name: my-conf
          - secretRef:
              name: db-user-pass
          volumeMounts:
          - mountPath: /sams/redis.conf
            name: redisconf
            subPath: redis.conf
          - mountPath: /sams/nginx.conf
            name: nginxconf
            subPath: nginx.conf
          - mountPath: /sams/emptydir/test
            name: emptydir-test
          - mountPath: /sams/hostpaht/test
            name: hostpaht-test
          - mountPath: /sams/nginx
            name: my-pvc
      volumes:
      - emptyDir:
          sizeLimit: 300Mi
        name: emptydir-test
      - hostPath:
          path: /sams/hostPaht/test
          type: DirectoryOrCreate
        name: hostpaht-test
      - configMap:
          name: my-conf
        name: redisconf
      - configMap:
          name: my-conf
        name: nginxconf
      - name: my-pvc
        persistentVolumeClaim:
          claimName: nginx-pvc

通过yaml可以看出,ConfigMap和Secret使用了配置引用的方式在Pod中使用,其余使用挂载。

[root@k8s-master test]# kubectl apply -f deployment.yaml 
deployment.apps/nginx-deploy created
[root@k8s-master test]# kubectl get pod
NAME                           READY   STATUS    RESTARTS   AGE
nginx-deploy-744dfb6ff-f4px5   1/1     Running   0          56s
nginx-deploy-744dfb6ff-zk5zf   1/1     Running   0          58s
[root@k8s-master test]#

检查验证

进入到容器内部进行验证。

[root@k8s-master test]# kubectl exec -it nginx-deploy-744dfb6ff-f4px5 -c mynginx -- /bin/bash
root@nginx-deploy-744dfb6ff-f4px5:/# cd /sams/
root@nginx-deploy-744dfb6ff-f4px5:/sams# ls
emptydir  hostpaht  nginx  nginx.conf  redis.conf
root@nginx-deploy-744dfb6ff-f4px5:/sams#
  1. EmptyDir
root@nginx-deploy-744dfb6ff-f4px5:/sams# cd /sams/emptydir/test/
root@nginx-deploy-744dfb6ff-f4px5:/sams/emptydir/test# pwd
/sams/emptydir/test
root@nginx-deploy-744dfb6ff-f4px5:/sams/emptydir/test#

EmptyDir挂载成功。

  1. HostPaht
root@nginx-deploy-744dfb6ff-f4px5:/sams/emptydir/test# cd /sams/hostpaht/test/
root@nginx-deploy-744dfb6ff-f4px5:/sams/hostpaht/test# pwd
/sams/hostpaht/test 
root@nginx-deploy-744dfb6ff-f4px5:/sams/hostpaht/test# touch hostpaht.txt
root@nginx-deploy-744dfb6ff-f4px5:/sams/hostpaht/test# ls
hostpaht.txt
root@nginx-deploy-744dfb6ff-f4px5:/sams/hostpaht/test#
# 查看nginx-deploy-744dfb6ff-f4px5所在的节点为k8s-worker1
[root@k8s-master /]# kubectl describe pod nginx-deploy-744dfb6ff-f4px5
...
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  15m   default-scheduler  Successfully assigned default/nginx-deploy-744dfb6ff-f4px5 to k8s-worker1
  Normal  Pulled     15m   kubelet            Container image "nginx" already present on machine
  Normal  Created    15m   kubelet            Created container mynginx
  Normal  Started    15m   kubelet            Started container mynginx
[root@k8s-master /]#
# 到 k8s-worker1 验证
[root@k8s-worker1 test]# pwd
/sams/hostPaht/test
[root@k8s-worker1 test]# ll
total 0
-rw-r--r-- 1 root root 0 Jul 21 00:39 hostpaht.txt
[root@k8s-worker1 test]#

存在/sams/hostPaht/test文件夹,并且hostpaht.txt同样存在,HostPaht挂载成功。

  1. ConfigMap&Secret
root@nginx-deploy-744dfb6ff-f4px5:/sams# cat redis.conf 
appendonly yes
root@nginx-deploy-744dfb6ff-f4px5:/sams# cat nginx.conf 
welcome nginx
root@nginx-deploy-744dfb6ff-f4px5:/sams# echo $project
edsp
root@nginx-deploy-744dfb6ff-f4px5:/sams# echo $user
jiangxiaonan
root@nginx-deploy-744dfb6ff-f4px5:/sams#

ConfigMap挂载成功,Secret配置引用成功。

  1. PV&PVC
root@nginx-deploy-744dfb6ff-f4px5:/sams# cd nginx
root@nginx-deploy-744dfb6ff-f4px5:/sams/nginx# touch aaa.txt
root@nginx-deploy-744dfb6ff-f4px5:/sams/nginx#
# 到NFS文件系统查看
[root@k8s-master test]# cd /nfs/data/01
[root@k8s-master 01]# ls
aaa.txt
[root@k8s-master 01]#

pvc挂载成功。