使用存储卷的步骤:

1 定义pod的volume,这个volume要指明关联到那个存储。

2 容器中要使用的volume mounts 挂载存储。

临时存储

使用临时存储,在pod生命周期结束后,数据就会消失。

kubectl explain pod.spec.volumes

emptyDir

可以通过查看官方样例。

样例:

apiVersion: v1
kind: Pod
metadata:
  name: test-tmpdir
spec:
  containers:
  - name: test-tmpdir
    image: nginx
    volumeMounts:
    # 挂载存储
    - mountPath: /tmpdir
      name: test-vol
  # 指定需要关联的存储
  volumes:
  - name: test-vol
    emptyDir: {}

查看pod的uid

kubectl get pod test-tmpdir -o yaml| grep uid

根据uid查看pod所在node节点的文件目录

 持久化存储

hostpath

是指Pod挂载在宿主机的目录或文件。

 样例:

apiVersion: v1
kind: Pod
metadata:
  name: test-host
spec:
  containers:
  - name: test-host
    image: nginx
    volumeMounts:
    - mountPath: /tmpdir
      name: test-vol1
  volumes:
  - name: test-vol1
    hostPath:
      path: /tmpdir
      # 不存在创建文件夹
      type: DirectoryOrCreate

pod删除后node节点文件内容不会被删除

nfs:

NFS(Network File System),它最大的功能就是可以通过网络,让不同的机器、不同的操作系统可以共享彼此的文件.

# 安装NFS服务(在所有K8S的节点都需要安装)
yum install -y nfs-utils
# 创建共享目录
mkdir -p /opt/nfs
# 编写NFS的共享配置
vi /etc/exports
# 内容如下:
/opt/nfs/jenkins  *(rw,no_root_squash)    *代表对所有IP都开放此目录,rw是读写
# 启动服务
ystemctl enable nfs  开机启动
systemctl start nfs   启动

# 更新nfs配置
exportfs -arv

# 查看NFS共享目录
showmount -e nfsServerIP

样例:

apiVersion: v1
kind: Pod
metadata:
  name: test-nfs
spec:
  containers:
  - name: test-nfs
    image: nginx
    volumeMounts:
    - mountPath: /tmpdir
      name: test-vol2
  volumes:
  - name: test-vol2
    nfs:
      # 填写nfs信息
      path: /opt/nfs
      server: 192.168.241.191

pv和pvc

简介

pv(PersistentVolume) 是集群中的一块存储,由管理员配置或使用动态存储类配置的。他是集群中的资源类似于一个pod资源。Pod消耗节点资源,PVC消耗PV资源。 Pod可以请求特定级别的资源(CPU和内存)。 pvc在申请pv的时候也可以请求特定的大小和访问模式(例如,可以一次读写或多次只读)。

工作原理:

pv是资源,pvc是请求,pvc跟pv根据请求的资源一一绑定

静态pv:

手动创建多个pv,指定pv容量权限。

动态 pv:

集群基于StorageClasses动态创建pv.

用户创建pvc并指定需要的资源和访问模式。在找到可用pv之前,pvc会保持未绑定状态

使用:
a)需要找一个存储服务器,把它划分成多个存储空间;
b)k8s管理员可以把这些存储空间定义成多个pv;
c)在pod中使用pvc类型的存储卷之前需要先创建pvc,通过定义需要使用的pv的大小和对应的访问模式,找到合适的pv;
d)pvc被创建之后,就可以当成存储卷来使用了,我们在定义pod时就可以使用这个pvc的存储卷
e)pvc和pv它们是一一对应的关系,pv如果被pvc绑定了,就不能被其他pvc使用了;
f)我们在创建pvc的时候,应该确保和底下的pv能绑定,如果没有合适的pv,那么pvc就会处于pending状态。

回收策略:

当我们创建pod时如果使用pvc做为存储卷,那么它会和pv绑定,当删除pod,pvc和pv绑定就会解除,解除之后和pvc绑定的pv卷里的数据需要怎么处理,目前,卷可以保留,回收或删除。

Retain

Recycle (不推荐使用,1.15可能被废弃了)

Delete

Retain:

当删除pvc的时候,pv仍然存在,处于released状态,但是它不能被其他pvc绑定使用,里面的数据还是存在的,当我们下次再使用的时候,数据还是存在的,这个是默认的回收策略

Delete:

删除pvc时即会从Kubernetes中移除PV,也会从相关的外部设施中删除存储资产

静态pv

样例:

创建pv

kubectl explain pv

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv1
spec:
  # pv 大小
  capacity:
    storage: 5Gi
  # pv权限,
    # ReadWriteOnce 卷可以被一个节点以读写方式挂载 
    # ReadOnlyMany 卷可以被多个节点以只读方式挂载。
    # ReadWriteMany 卷可以被多个节点以读写方式挂载
    # ReadWriteOncePod 卷可以被单个 Pod 以读写方式挂载
  accessModes:
    - ReadWriteOnce
  nfs:
    path: /opt/v4
    server: 192.168.241.191

 创建pvc绑定pv

kubectl explain pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  # 权限
  accessModes:
  - ReadWriteOnce
  # 使用内存大小, 如果不存在完全匹配的,则寻找最相近的
  resources:
    requests:
      storage: 5Gi

 pod 挂载pvc

apiVersion: v1
kind: Pod
metadata:
  name: test-pv
spec:
  containers:
  - name: test-pv
    image: nginx
    volumeMounts:
    - mountPath: /tmpdir
      name: test-vol
  volumes:
    # pvc名称
  - persistentVolumeClaim:
      claimName: test-pvc
    name: test-vol

 删除旧的pod,pv中的文件不会删除,挂载新pod后还存在。

删除pvc,pv状态是Released

此时再次绑定pv,pvc会处于Pending,因为默认策略是Retain

 

 删除pv后nfs目录中的文件还存在。

修改pv中的回收策略 :

目前,仅 NFS 和 HostPath 支持回收(Recycle)。 AWS EBS、GCE PD、Azure Disk 和 Cinder 卷都支持删除(Delete)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv1
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
    # 设置回收策略
  persistentVolumeReclaimPolicy: Delete
  nfs:
    path: /opt/v4
    server: 192.168.241.191

动态pv

pv和pvc是一一绑定的,但我们需要大量的pv,创建起来就太繁琐了。k8s提供一种自动创建pv的机制。StorageClass他的作用就是生成一个模板,通过StorageClass动态生成pv供pvc使用

定义:

1、pv的属性,比如存储类的大小,类型等。

2、创建这种PV需要使用到的存储插件,比如Ceph、NFS等

通过下面命令可以查看sc的yaml编写帮助,重点是存储插件

 kubectl explain sc

也可查看官方文档实例

存储类 | Kubernetes

 这里演示使用nfs,需要借用第三方驱动完成StorageClass的创建

1 创建服务账户

sa的全称是serviceaccount

serviceaccount是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。

指定了serviceaccount之后,我们把pod创建出来了,我们在使用这个pod时,这个pod就有了我们指定的账户的权限了

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-provisioner

2 服务账户授权

kubectl create clusterrolebinding nfs-provisioner-clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:nfs-provisioner

3 安装nfs-provisioner程序

kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-provisioner
spec:
  selector:
    matchLabels:
       app: nfs-provisioner
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-provisioner
    spec:
      serviceAccount: nfs-provisioner
      containers:
        - name: nfs-provisioner
          image: registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
              # 存储类的驱动类型
            - name: PROVISIONER_NAME
              value: example.com/nfs
            - name: NFS_SERVER
              value: 192.168.241.191
            - name: NFS_PATH
              value: /opt/v2
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.241.191
            path: /opt/v2

4 创建storageclass,动态供给pv

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs
provisioner: example.com/nfs

5 创建pvc, 通过storageclass动态生成pv

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  # 指定名称
  storageClassName: nfs

6 绑定pod

nfs共享卷中会创建一个pv

如果删除pvc nfs中文件会修改文件名(软删除),如果要彻底删除需要手动执行rm -rf

 

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐