k8s--volume卷

k8s–volume卷

1、volume

(1)将数据和镜像解耦,以及容器间相互共享数据。也减小了镜像包的大小
(2)k8s抽象出一个对象,用来保存数据
常用的卷有:
emptyDir:本地临时卷,容器删除数据就跟着删除了(卷是保存在容器上的)
hostPath:本地卷,容器的数据保存在本地磁盘上,容器删除数据不会删除(但是pod重启调度到另外节点就无法使用原先的数据了)
nfs:nfs共享卷,容器删除共享卷不会被删除
configmap:配置文件

1.1 emptyDir

当pod被创建时,会先创建emptyDir卷.只要该pod在该节点上运行,这个卷就会一直存在.被创建的时候这个卷是空的.pod中的容器可以读写该emptyDir卷中的文件.当pod被删除时,emptyDir将被永久删除.可以放一些缓存或日志等不重要的文件.

root@master1:~/yaml/volume# cat pod-emptydir.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ng-deploy
  template:
    metadata:
      labels:
        app: ng-deploy
    spec:
      containers:
      - name: ng-deploy
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /cache
          name: empty-volume  #卷的名称要和volumes声明的一致
      volumes:   
      - name: empty-volume
        emptyDir: {}

pod创建后写入文件到/cache/1.txt

在这里插入图片描述

刚创建的时候目录是空的,写入文件后可以在node节点上读取到该文件内容.

k8s--volume卷_第1张图片
删除pod后原先的目录就跟着删除了
k8s--volume卷_第2张图片

1.2 hostPath

和docker的-v效果比较类似,即使容器被删除,该路径下的数据任然会被保存下来.但发生节点切换就会造成数据丢失.

root@master1:~/yaml/volume# cat pod-hostpath.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-deploy
  template:
    metadata:
      labels:
        app: nginx-deploy
    spec:
      nodeName: 172.17.1.103
      containers:
      - name: deploy-nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /data
          name: cache-volume
      volumes:
      - name: cache-volume
        hostPath:
          path: /tmp/cache

k8s--volume卷_第3张图片

1.3 nfs

root@master1:~ apt update
root@master1:~ apt install nfs-server
root@master1:~ mkdir /data/k8s/ -p
root@master1:~/yaml/volume# cat /etc/exports 
/data/nfs  172.17.0.0/16(rw,no_root_squash,no_subtree_check)
/data/pv1  172.17.0.0/16(rw,no_root_squash,no_subtree_check)
/data/pv2  172.17.0.0/16(rw,no_root_squash,no_subtree_check)
root@master1:~ systemctl enable --now nfs-server
root@master1:~ systemctl restart nfs-server
# node节点验证nfs的共享目录
root@node2:~# showmount -e 172.17.1.101
Export list for 172.17.1.101:
/data/pv2 172.17.0.0/16
/data/pv1 172.17.0.0/16
/data/nfs 172.17.0.0/16

#单个nfs
root@master1:~/yaml/volume# cat pod-nfs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 1
  selector:
    matchLabels: #标签选择集
      app: nginx-deploy
  template:
    metadata:
      labels:
        app: nginx-deploy
    spec:
      containers:
      - name: nginx-deploy
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:    
        - mountPath: /usr/share/nginx/html/mysite
          name: nfs-volume
      volumes:
      - name: nfs-volume
        nfs:
          server: 172.17.1.101
          path: /data/nfs

---
apiVersion: v1
kind: Service
metadata:
  name: ng-deploy
spec:
  ports:
  - name: http
    port: 81
    targetPort: 80
    nodePort: 30016
    protocol: TCP
  type: NodePort
  selector:
    app: nginx-deploy
    
# 多个nfs
root@master1:~/yaml/volume# cat pod-nfss.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx-80
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-deploy
  template:
    metadata:
      labels:
        app: nginx-deploy
    spec:
      containers:
      - name: nginx-deploy
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /usr/share/nginx/html/html
          name: nginx-nfs-html
        - mountPath: /usr/share/nginx/html/photo
          name: nginx-nfs-photo
      volumes:
        - name: nginx-nfs-photo
          nfs:
            server: 172.17.1.102
            path: /data/photo

        - name: nginx-nfs-html
          nfs:
            server: 172.17.1.101
            path: /data/nfs
---
apiVersion: v1
kind: Service
metadata:
  name: ng-deploy-80
spec:
  ports:
  - name: http
    port: 82
    targetPort: 80
    nodePort: 30017
    protocol: TCP
  type: NodePort
  selector:
    app: nginx-deploy

1.4 configMap

1.4.1 configmap作为配置文件

存在的意义:使得镜像和配置解耦,将配置信息放入configmap,在pod的对象中导入configmap,实现配置导入

root@master1:~/yaml/volume# cat pod-cm.yaml
# 声明一个configmap的卷
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config      #卷的名称
data:
  mysite.cnf: |   #创建mysite.cnf文件
    server {       #mysite.cnf文件的内容
      listen   80;
      server_name www.mysite.com;
      index   index.html;
      location  / {
        root  /data/nginx/html;
        if (!-e $request_filename) {
           rewrite ^/(.*) /index.html last;
        }
      }
    }
  

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-configmap
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-configmap
  template:
    metadata:
      labels:
        app: nginx-configmap
    spec:
      containers:
      - name: ng-configmap
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /data/nginx/html
          name: my-nfs-volume
        - mountPath: /etc/nginx/conf.d
          name: nginx-config
      volumes:
      - name: nginx-config
        configMap: 
          name: nginx-config
      - name: my-nfs-volume
        nfs:
          server: 172.17.1.101
          path: /data/nfs

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  ports:
  - name: http
    port: 81   #service的端口
    targetPort: 80 #容器的端口
    nodePort: 30019  #映射node节点的port端口
    protocol: TCP
  type: NodePort
  selector:
    app: nginx-configmap

k8s--volume卷_第4张图片

1.4.2 configmap作为变量传递参数

configMap的data中创建key:username,val:user1通过env将来源就是来源名为nginx-config的configMap,key为username的值至传递给容器的MY_USERNAME变量。

root@master1:~/yaml/volume# cat pod-cm-env.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  username: user1

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-deploy
  template:
    metadata:
      labels:
        app: nginx-deploy
    spec:
      containers:
      - name: nginx-deploy
        image: nginx
        env:
        - name: "mykey"
          value: "myvalue"
        - name: MY_USERNAME
          valueFrom:
            configMapKeyRef:
              name: nginx-config
              key: username
        ports:
        - containerPort: 80

k8s--volume卷_第5张图片

1.5 pv/pvc

pv:集群资源

pvc:命名空间资源

持久卷(PersistentVolume,PV) 是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样, 也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。

持久卷申领(PersistentVolumeClaim,PVC) 表达的是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存);同样 PVC 申领也可以请求特定的大小和访问模式 (例如,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载,参见访问模式)。

pv是对底层网络存储的抽象,将存储定义为一种资源,将一个整体的存储资源拆分成多份后给不同的业务使用.
pvc是对pv资源的申请调用.就像POD消费NODE节点一样,POD通过PVC将数据保存至PV,PV在保存数据至存储.

k8s--volume卷_第6张图片

1.5.1 PV持久卷类型

PV 持久卷是用插件的形式来实现的。Kubernetes 目前支持以下插件 :

k8s--volume卷_第7张图片

1.5.2访问模式

PersistentVolume 卷可以用资源提供者所支持的任何方式挂载到宿主系统上。 如下表所示,提供者(驱动)的能力不同,每个 PV 卷的访问模式都会设置为对应卷所支持的模式值。 例如,NFS 可以支持多个读写客户,但是某个特定的 NFS PV 卷可能在服务器上以只读的方式导出。 每个 PV 卷都会获得自身的访问模式集合,描述的是特定 PV 卷的能力。
访问模式:

  • ReadWriteOnce:卷可以被一个节点以读的方式挂载。ReadWriteOnce访问模式也允许运行在同一个节点上的多个pod访问卷
  • ReadOnlyMany:卷可以被多个节点以只读方式挂载
  • ReadWriteMany:卷可以被多个节点以读写的方式挂载
  • ReadWriteOncePod:卷可以被单个pod以读写方式挂载。如果你想确保整个集群中只有一个Pod可以读取或写入该pvc,请使用 ReadWriteOncePod 访问模式。这只支持CSI卷以及需要 Kubernetes 1.22 以上版本。

在命令行接口(CLI)中,访问模式也使用一下缩写形式:

  • RWO - ReadWriteOnce 卷可以被一个节点以读写方式挂载
  • ROX - ReadOnlyMany 卷可以被多个节点以只读方式挂载
  • RWX - ReadWriteMany 卷可以被多个节点以读写方式挂载
  • RWOP - ReadWriteOncePod 卷可以被单个 Pod 以读写方式挂载
    k8s--volume卷_第8张图片
    k8s--volume卷_第9张图片
1.5.3 PV的创建模试
(1)自动创建
1.1 管理员创建存储类(StorageClass)
1.2 用户创建持久化存储卷声明
1.3 调用存储类,通知系统使用存储类创建PV
1.4 获取存储类信息
1.5 基于存储类创建PV
1.6 用户创建使用PVC的POD
1.7 指定POD使用哪个PVC
1.8 PVC使用PV存储数据

(2)手动创建
1.5.4pv参数
Capacity: 当前pv空间大小
accessModes: 访问模式
  ReadWriteOnce	PV可以被一个节点以读写方式挂载
  ReadOnlyMany      PV可以被多个节点以只读方式挂载
  ReadWriteMany   PV可以被多个节点以读写方式挂载
persistentVolumeReclaimPolicy 删除机制删除数据存储的时候,已经创建好的卷由以下删除操作.
   Retain -- 手动回收
   Recycle -- 基本擦除 (`rm -rf /thevolume/*`) 仅支持NFS和HostPath
   Delete -- 诸如 AWS EBS、GCE PD、Azure Disk 或 OpenStack Cinder 卷这类关联存储资产也被删除
volumeMode	#卷类型
  定义存储卷使用的文件系统是块设备还是文件系统,默认文件系统
mountOptions  附加的挂载选项列表,实现更精细的权限控制ro 等
1.5.5 回收策略

当用户不再使用其存储卷时,他们可以从 API 中将 PVC 对象删除, 从而允许该资源被回收再利用。PersistentVolume 对象的回收策略告诉集群, 当其被从申领中释放时如何处理该数据卷。 目前,数据卷可以被 Retained(保留)、Recycled(回收)或 Deleted(删除)。

目前的回收策略有:

Retain – 手动回收
Recycle – 基本擦除 (rm -rf /thevolume/*) 仅支持NFS和HostPath
Delete – 诸如 AWS EBS、GCE PD、Azure Disk 或 OpenStack Cinder 卷这类关联存储资产也被删除

每个卷会处于以下阶段(Phase)之一:

Available(可用)-- 卷是一个空闲资源,尚未绑定到任何申领;
Bound(已绑定)-- 该卷已经绑定到某申领;
Released(已释放)-- 所绑定的申领已被删除,但是资源尚未被集群回收;
Failed(失败)-- 卷的自动回收操作失败。

1.5.6PersistentVolumeClaims(pvc)

pvc的访问模式:

  • RWO - ReadWriteOnce PVC可以被一个节点以读写方式挂载
  • ROX - ReadOnlyMany PVC可以被多个节点以只读方式挂载
  • RWX - ReadWriteMany PVC可以被多个节点以读写方式挂载

pvc创建参数

accessModes:
  ReadWriteOnce	PVC可以被一个节点以读写方式挂载
  ReadOnlyMany      PVC可以被多个节点以只读方式挂载
  ReadWriteMany   PVC可以被多个节点以读写方式挂载

resources:  定义pvc创建存储卷的空间大小

selector: 标签选择器,选择要绑定的pv
  matchLables  匹配标签名称
  matchExpressions  基于正则匹配
volumeName  要绑定的pv名称
volumeMode  卷类型
	定义pvc使用文件系统是块设备还是文件系统,默认是文件系统
1.5.7 实例

k8s--volume卷_第10张图片
申请pv卷

root@master1:~/yaml/volume# cat pod-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1
spec:
  capacity: #存储能力,目前只支持存储空间的设置
    storage: 2Gi
  accessModes: #访问模式
  - ReadWriteMany
  persistentVolumeReclaimPolicy:  Retain  #回收策略
  nfs:
    server: 172.17.1.101
    path: /data/pv1

绑定pv卷

root@master1:~/yaml/volume# cat pod-pvc1.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc1
spec:
  accessModes: #访问模式
  - ReadWriteMany
  resources:  #请求资源
    requests:
      storage: 1Gi

pod挂载卷

root@master1:~/yaml/volume# cat pod-nginx-pvc.yaml
# 声明一个configmap的卷
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config      #卷的名称
data:
  mysite.conf: |
    server {
      listen   80;
      server_name www.mysite.com;
      index   index.html;
      location  / {
        root  /data/nginx/html;
        if (!-e $request_filename) {
           rewrite ^/(.*) /index.html last;
        }
      }
    }

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx-pv
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-pvc
  template:
    metadata:
      labels:
        app: nginx-pvc
    spec:
      containers:
      - name: nginx-deploy-pvc
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
# 挂载configMap卷
        - name: nginx-config
          mountPath: /etc/nginx/conf.d
# 挂载pvc卷
        - name: nginx-pvc1   
          mountPath: /data/nginx/html
      volumes:
# configMap卷
        - name: nginx-config
          configMap:
            name: nginx-config
# pvc卷
        - name: nginx-pvc1
          persistentVolumeClaim:
            claimName: pvc1
            readOnly: false
        
---
apiVersion: v1
kind: Service
metadata:
  name: service-nginx
spec:
  selector:
    app: nginx-pvc
  ports:
  - name: http
    port: 81   #service的端口
    targetPort: 80 #容器的端口
    nodePort: 30019  #映射node节点的port端口
    protocol: TCP
  type: NodePort

你可能感兴趣的:(kubernetes,容器,云原生)