K8S中的存储

一、Volume

  • Kubernetes 支持很多类型的卷。Pod可以同时使用任意数目的卷类型。临时卷类型的生命周期与 Pod 相同, 但持久卷可以比 Pod 的存活期长。 当 Pod 不再存在时,Kubernetes 也会销毁临时卷;不过 Kubernetes 不会销毁持久卷。 对于给定 Pod 中任何类型的卷,在容器重启期间数据都不会丢失。
  • 我们上面讲的都是持久卷相关的。

emptyDir

  • 对于定义了emptyDir卷的 Pod,在 Pod 被指派到某节点时此卷会被创建。
  • 就像其名称所表示的那样,emptyDir卷最初是空的。
  • 当 Pod 因为某些原因被从节点上删除时,emptyDir卷中的数据也会被永久删除。
  • 容器崩溃并不会导致 Pod 被从节点上移除,因此容器崩溃期间emptyDir卷中的数据是安全的。

emptyDir的一些用途:

  • 缓存空间,例如基于磁盘的归并排序。
  • 为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。
  • 在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      sizeLimit: 500Mi

hostpath

  • 其实不推荐使用,因为宿主机不安全。
  • hostPath宿主机路径,就是把pod所在的宿主机之上的脱离pod中的容器名称空间的之外的宿主机的文件系统的某一目录和pod建立关联关系,在pod删除时,存储数据不会丢失。
  • hostpath的type相当重要,常用的如下:

因为FileOrCreate模式不会创建文件的父目录。如果挂载文件的父目录不存在,Pod 将启动失败。所以可以分别创建父目录和文件。如下:

apiVersion: v1
kind: Pod
metadata:
  name: test-webserver
spec:
  os: { name: linux }
  nodeSelector:
    kubernetes.io/os: linux
  containers:
  - name: test-webserver
    image: registry.k8s.io/test-webserver:latest
    volumeMounts:
    - mountPath: /var/local/aaa
      name: mydir
    - mountPath: /var/local/aaa/1.txt
      name: myfile
  volumes:
  - name: mydir
    hostPath:
      path: /var/local/aaa
      type: DirectoryOrCreate
    hostPath:
      path: /var/local/aaa/1.txt
      type: FileOrCreate

NFS

  • nfs卷能将 NFS (网络文件系统) 挂载到你的 Pod 中。
  • 不像emptyDir那样会在删除 Pod 的同时也会被删除,nfs卷的内容在删除 Pod 时会被保存,卷只是被卸载。
  • 这意味着nfs卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享。
  • 我们需要提前在节点上安装NFS,并配置NFS服务。
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /my-nfs-data
      name: test-volume
  volumes:
  - name: test-volume
    nfs:
      server: my-nfs-server.example.com
      path: /my-nfs-volume
      readOnly: true

PV

非常重要,见下面。

CSI

也很重要,主要是看不懂。。。

https://jimmysong.io/kubernetes-handbook/concepts/cri.html

二、持久卷相关

PV、PVC和SC

  • PVC
    • PersistentVolumeClaim (持久卷创建申请),当我们创建一个pod时,需要申请一块空间,这个申请就是PVC。
  • PV
    • PersistentVolume(持久卷)是集群中的一块存储资源,由管理员预先配置或通过动态 provisioner 自动创建,是物理资源。
  • SC
    • StorageClass(存储类型)为不同的存储后端提供了不同的类别。SC定义了存储的类型、性能参数、provisioner等信息,用于动态创建PV。
    • 一般会定义PV的属性。比如,存储类型,Volume的大小等。
    • 一般会定义创建这种PV需要用到的存储插件,即存储制备器。

PV、PVC、SC的协作流程

在这里插入图片描述

  1. 用户提交 PVC:
    • 用户在 Kubernetes 集群中提交一个 PVC,声明所需的存储特性,如存储大小、访问模式等。
  2. 匹配 StorageClass:
    • Kubernetes 查找与 PVC 匹配的StorageClass。
    • 如果 PVC 指定了特定的StorageClass,则使用该StorageClass。
    • 如果 PVC 没有指定StorageClass而集群有默认的StorageClass,则使用默认的StorageClass。
  3. 动态创建 PV:
    • Kubernetes 调用StorageClass声明的存储插件(如nfs.csi.k8s.io)来动态创建一个新的 PV。
    • 存储插件就是一个一个的pod,每个node上都有,各种类型的,nfs,s3等等
    • 存储插件根据StorageClass的参数(如server和share)和挂载选项(如rw、hard)来配置存储资源。
  4. PV 和 PVC 绑定:
    • Kubernetes 将新创建的 PV 绑定到 PVC。
    • 绑定后,PV 将专门为该 PVC 服务,直到 PVC 被删除。
  5. Pod 使用存储:
    • 用户的 Pod 通过 PVC 访问到绑定的 PV,从而使用存储资源。
  6. 存储回收:
    • 当 PVC 被删除时,根据StorageClass的回收策略(如Retain),PV 可以被自动删除(数据丢失)或者保留(数据保留)。

当我创建数据源和代码源的时候,其实就是创建了sc。

当我创建任务的时候,就是创建了pvc,pvc找sc,sc找插件,插件创建pv,再绑定。

三、配置容器:CM和Secret

  • 在k8s中,用户通过configmap和secret从集群外部向Pod内部的容器应用注入配置信息。

Secret

  • Secret对象存储数据的方式是以键值方式存储数据。
  • Secret对象的数据存储和打印格式为Base64编码的字符串,因此用户在创建Secret对象时,也需要提供该类型的编码格式的数据。在容器中以环境变量或存储卷的方式访问时,会自动解码为明文格式。
  • 需要注意的是,如果是在Master节点上,Secret对象以非加密的格式存储在etcd中,所以需要对etcd的管理和权限进行严格控制。
  • 四种类型:
    • Service Account :用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中;
    • Opaque :base64编码格式的Secret,用来存储密码、密钥、信息、证书等,类型标识符为generic;
    • kubernetes.io/dockerconfigjson :用来存储私有docker registry的认证信息,类型标识为docker-registry。
    • kubernetes.io/tls:用于为SSL通信模式存储证书和私钥文件,命令式创建类型标识为tls。

创建Sercret

[root@k8s-master ~]# kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456
secret/mysecret created
[root@k8s-master ~]# kubectl get secret
NAME                    TYPE                                  DATA      AGE
mysecret                Opaque                                2         6s
[root@k8s-master ~]# echo -n admin > ./username
[root@k8s-master ~]# echo -n 123456 > ./password
[root@k8s-master ~]# kubectl create secret generic mysecret --from-file=./username --from-file=./password 
secret/mysecret created
[root@k8s-master ~]# kubectl get secret
NAME                    TYPE                                  DATA      AGE
mysecret                Opaque                                2         6s
#事先完成敏感数据的Base64编码
[root@k8s-master ~]# echo -n admin |base64
YWRtaW4=
[root@k8s-master ~]# echo -n 123456 |base64
MTIzNDU2

[root@k8s-master ~]# vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
data:
  username: YWRtaW4=
  password: MTIzNDU2
[root@k8s-master ~]# kubectl apply -f secret.yaml 
secret/mysecret created
[root@k8s-master ~]# kubectl get secret  #查看存在的 secret,显示有2条数据
NAME                    TYPE                                  DATA      AGE
mysecret                Opaque                                2         8s
[root@k8s-master ~]# kubectl describe secret mysecret  #查看数据的 Key
Name:         mysecret
Namespace:    default
Labels:       <none>
Annotations:  
Type:         Opaque

Data
====
username:  5 bytes
password:  6 bytes
[root@k8s-master ~]# kubectl edit secret mysecret  #查看具体的value,可以使用该命令
apiVersion: v1
data:
  password: MTIzNDU2
  username: YWRtaW4=
kind: Secret
metadata:
......
[root@k8s-master ~]# echo -n MTIzNDU2 |base64 --decode  #通过 base64 将 Value 反编码:
123456
[root@k8s-master ~]# echo -n YWRtaW4= |base64 --decode
admin

使用Sercret

以 Volume 方式使用的 Secret 支持动态更新:Secret 更新后,容器中的数据也会更新。


[root@k8s-master volumes]# vim pod-secret-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret
spec:
  containers:
  - name: pod-secret
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10;touch /tmp/healthy;sleep 30000
    volumeMounts:   #将 foo mount 到容器路径 /etc/foo,可指定读写权限为 readOnly。
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:    #定义 volume foo,来源为 secret mysecret。
  - name: foo
    secret:
      secretName: mysecret
[root@k8s-master volumes]# kubectl apply -f pod-secret-demo.yaml 
pod/pod-secret created
[root@k8s-master volumes]# kubectl get pods
pod-secret                           1/1       Running   0          1m
[root@k8s-master volumes]# kubectl exec -it pod-secret sh
/ # ls /etc/foo/
password  username
/ # cat /etc/foo/username 
admin/ # 
/ # cat /etc/foo/password 
123456/ # 

可以看到,Kubernetes 会在指定的路径 /etc/foo 下为每条敏感数据创建一个文件,文件名就是数据条目的 Key,这里是 /etc/foo/username 和 /etc/foo/password,Value 则以明文存放在文件中。

可以自定义存放数据的文件名:

[root@k8s-master volumes]# cat pod-secret-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret
spec:
  containers:
  - name: pod-secret
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10;touch /tmp/healthy;sleep 30000
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      items:    #自定义存放数据的文件名
      - key: username
        path: my-secret/my-username
      - key: password
        path: my-secret/my-password
[root@k8s-master volumes]# kubectl delete pods pod-secret
pod "pod-secret" deleted
[root@k8s-master volumes]# kubectl apply -f pod-secret-demo.yaml 
pod/pod-secret created
[root@k8s-master volumes]# kubectl exec -it pod-secret sh
/ # cat /etc/foo/my-secret/my-username 
admin
/ # cat /etc/foo/my-secret/my-password 
123456

以 环境变量 方式使用的 Secret 不支持动态更新。

[root@k8s-master volumes]# cp pod-secret-demo.yaml pod-secret-env-demo.yaml
[root@k8s-master volumes]# vim pod-secret-env-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-env
spec:
  containers:
  - name: pod-secret-env
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 10;touch /tmp/healthy;sleep 30000
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password
[root@k8s-master volumes]# kubectl apply -f pod-secret-env-demo.yaml 
pod/pod-secret-env created

[root@k8s-master volumes]# kubectl exec -it pod-secret-env sh
/ # echo $SECRET_USERNAME
admin
/ # echo $SECRET_PASSWORD
abcdef

ConfigMap

  • Configmap是让配置文件从镜像中解耦,让镜像的可移植性和可复制性。ConfigMap API给我们提供了向容器中注入配置信息的机制,ConfigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。
  • Configmap和Secret很类似,创建和使用几乎一致,不再展开。

四、引用文档

https://www.cnblogs.com/linuxk/p/9760363.html#tid-mDhj4d

官方文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值