k8s之存储(CSI插件)

存储的四种类型

 第一种就是本地卷:
      像hostPath类型与docker里面的bind mount类型,就是直接挂载到宿主机文件的类型 像 emptyDir是这样本地卷,也就是类似于volume类型 这两点都是绑定node节点的。

 第二种就是网络数据卷:

      比如Nfs、ClusterFs、Ceph,这些都是外部的存储都可以挂载到k8s上

 第三种就是云盘:

      比如AWS、微软(azuredisk)

 第四种就是k8s自身的资源:

      比如secret、configmap、downwardAPI

emptyDir存储

原理:创建一个空卷,挂载到Pod中的容器。Pod删除该卷也会被删除。

特点:

  • 容器删除数据卷也会跟着删除
  • 可以实现pod容器之间的数据共享
  • 容器崩溃不会从节点中移除pod,因此emptyDir卷中的数据在容器崩溃时是安全的。

配置yaml文档:

单容器挂载

#这个是我们的版本信息
apiVersion: v1 
#这个表示资源类型我们创建的是Pod
kind: Pod
metadata: #这个里面定义的是Pod中我们创建的对象信息
  #对象名称
  name: test-pod
spec: #这个是对Pod详细的定义
  containers:
  #基于下面的镜像去创建pod
  - image: hub.harbor.com/library/myapp:v1
    #容器名称是test-container
    name: test-container
    volumeMounts: #这里就是在容器中引用下面的定义的volumes挂载项
    #容器中挂载的位置是/cache
    - mountPath: /cache
      #引用名称为cache-volume的挂载卷,和下面名称保持一致
      name: cache-volume
  volumes: #表示我们定义了一个挂在卷
  #挂载卷的名称是cache-volume
  - name: cache-volume
    #挂载卷的类型是emptyDir
    emptyDir: {} 

多容器挂载:

#这个是我们的版本信息
apiVersion: v1 
#这个表示资源类型我们创建的是Pod
kind: Pod
metadata: #这个里面定义的是Pod中我们创建的对象信息
  #对象名称
  name: test-pod
spec: #这个是对Pod详细的定义
  containers:
  #基于下面的镜像去创建pod
  - image: hub.harbor.com/library/myapp:v1
    #容器名称是test-container
    name: test-container
    volumeMounts: #这里就是在容器中引用下面的定义的volumes挂载项
    #容器中挂载的位置是/cache
    - mountPath: /cache
      #引用名称为cache-volume的挂载卷,和下面名称保持一致
      name: cache-volume
  #基于下面的镜像去创建pod
  - image: hub.harbor.com/library/myapp:v1
    #容器名称是test-container2
    name: test-container2
    command: ["/bin/sh","-c","sleep 6000s"]
    imagePullPolicy: IfNotPresent
    volumeMounts: #这里就是在容器中引用下面的定义的volumes挂载项
    #容器中挂载的位置是/cache
    - mountPath: /cache
      #引用名称为cache-volume的挂载卷,和下面名称保持一致
      name: cache-volume    
  volumes: #表示我们定义了一个挂在卷
  #挂载卷的名称是cache-volume
  - name: cache-volume
    #挂载卷的类型是emptyDir
    emptyDir: {} 

hostpath存储:

yaml文件

[root@master1 volume]# cat hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-hostpath
spec:
  containers:
    - name: test-nginx
      image: nginx
      volumeMounts:
        - name: test-volume
          mountPath: /test-nginx
    - name: test-tomcat
      image: tomcat
      volumeMounts:
        - name: test-volume
          mountPath: /test-tomcat
  volumes:
    - name: test-volume
      hostPath:
        path: /data1
        type: DirectoryOrCreate 

type类型:

在这里插入图片描述

原理:挂载Node文件系统上文件或者目录到Pod中的容器。Pod中容器需要访问宿主机文件

配置yaml文档:

#这个是我们的版本信息
apiVersion: v1 
#这个表示资源类型我们创建的是Pod
kind: Pod
metadata: #这个里面定义的是Pod中我们创建的对象信息
  #对象名称
  name: test-pod
spec: #这个是对Pod详细的定义
  containers:
  #基于下面的镜像去创建pod
  - image: hub.harbor.com/library/myapp:v1
    #容器名称是test-container
    name: test-container
    volumeMounts: #这里就是在容器中引用下面的定义的volumes挂载项
    #容器中挂载的位置是/cache
    - mountPath: /cache
      #引用名称为cache-volume的挂载卷,和下面名称保持一致
      name: cache-volume
  volumes: #表示我们定义了一个挂在卷
  #挂载卷的名称是cache-volume
  - name: cache-volume
    #挂载卷的类型是hostPath,这个是将pod中容器的目录和宿主机进行同步
    hostPath:
      #这个是对应宿主机同步的位置,注意这个我们需要提前在Node节点建好目录
      path: /opt/pv/data
      #类型是文件夹 
      type: Directory

相当于容器的目录和宿主机的目录做了映射

NFS网络存储

NFS是一种很早的技术,单机的存储在服务器方面还是非常主流的,但nfs唯一的就是缺点比较大就 是没有集群版,做集群化还是比较费劲的,文件系统做不了,这是一个很大的弊端,大规模的还是需要 选择一些分布式的存储,nfs就是一个网络文件存储服务器,装完nfs之后,共享一个目录,其他的服务 器就可以通过这个目录挂载到本地了,在本地写到这个目录的文件,就会同步到远程服务器上,实现一 个共享存储的功能,一般都是做数据的共享存储,比如多台web服务器,肯定需要保证这些web服务器 的数据一致性,那就会用到这个共享存储了,要是将nfs挂载到多台的web服务器上,网站根目录下, 网站程序就放在nfs服务器上,这样的话。每个网站,每个web程序都能读取到这个目录,一致性的数 据,这样的话就能保证多个节点,提供一致性的程序了

新添加一块盘

查看磁盘设备

fdisk -l     查看系统磁盘设备
磁盘 /dev/sdb:10.7 GB, 10737418240 字节,20971520 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节

创建磁盘分区

fdisk /dev/sdb
n
p
1
w

[root@node1 ~]# fdisk -l

磁盘 /dev/sdb:10.7 GB, 10737418240 字节,20971520 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0x8630e752

   设备 Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    20971519    10484736   83  Linux
b 编辑 bsd disklabel;
c 切换 dos 兼容性标志;
d 删除一个分区;
g 创建一个新的空 GPT 分区表;
G 创建一个 IRIX(SGI)分区表;
l 列出已知的分区类型;
m 打印帮助菜单;
n 添加一个新分区;
o 创建一个新空 DOS 分区表;
p 打印分区表信息;
q 退出而不保存更改;
s 创建一个新的空的 Sun 磁盘标签;
t 更改分区的系统 ID;
u 更改显示/输入单位;
v 验证分区表;
w 将分区表写入磁盘并退出;
x 额外功能。

格式化

mkfs.ext4 /dev/sdb1 格式化磁盘分区
mke2fs 1.42.9 (28-Dec-2013)
文件系统标签=
OS type: Linux
块大小=4096 (log=2)
分块大小=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
655360 inodes, 2621184 blocks
131059 blocks (5.00%) reserved for the super user
第一个数据块=0
Maximum filesystem blocks=2151677952
80 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: 完成
正在写入inode表: 完成
Creating journal (32768 blocks): 完成
Writing superblocks and filesystem accounting information: 完成

mount挂载

 mount /dev/sdb1 /root/mulu

实验步骤:

1.单独创建一台服务器做nfs服务器。

yum install nfs-utils -y

2.暴露目录,让是让其他服务器能挂载这个目录

命令:
首先创建一个目录: mkdir /opt/k8s
为这个机器加上权限让其他机器可以读写:vim /etc/exports,内容如下:
/opt/k8s 192.168.56.14/24(rw,no_root_squash)

3.启动nfs

systemctl start nfs
ps -ef | grep nfs

4.其他节点也需要安nfs,并且将目录挂载到nfs服务器上面。

yum install nfs-utils -y

将本地的/mnt目录挂载到centos005的/opt/k8s目录下:

mount -t nfs 192.168.195.101:/opt/k8s /mnt 

df -h

我们测试一下在k8s节点的/mnt目录下创建一个文件,看看是否同步到nfs服务器的/opt/k8s目录下,查看nfs的目录下是否有这个文件

5.下面我们开始编写my-nfs.yaml文件

apiVersion: apps/v1
kind: Deployment
metadata: 
  name: nfs
  labels:
     app: nginx
spec: 
  replicas: 3
  selector:
     matchLabels:
          app: nginx
  template: 
    metadata: 
      labels:
        app: nginx
    spec: 
      containers: 
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        volumeMounts: 
        - name: wwwroot
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:
      - name: wwwroot        
        nfs: 
          server: 192.168.195.101
          path: /opt/k8s/wwwroot
          
-------------------


apiVersion: v1 
kind: Service
metadata: 
  name: nginx-service
  labels:
    app: nginx
spec: 
  ports: 
  - port: 80
    targetPort: 80
  selector:
    app: nginx
  type: NodePort  
          

#这个是我们的版本信息
apiVersion: apps/v1beta1
#这个表示资源类型我们创建的是Deployment
kind: Deployment
metadata: #这个里面定义的是Deployment中我们创建的对象信息
  #对象名称
  name: nfs
spec: #这个是对Deployment详细的定义
  # 告知副本控制器ReplicaSet维护3个副本
  replicas: 3
  template: #template下面是用来描述pod的
    #定义pod元数据信息
    metadata: 
      labels:
        app: nginx
    spec: #对pod进行详细的定义
      containers: #在这里定义容器信息
      #容器的名称
      - name: nginx
        #定义我们要用到的镜像名称 
        image: nginx
        #定义镜像的拉取策略
        imagePullPolicy: IfNotPresent
        volumeMounts: #这里就是在容器中引用下面的定义的nfs挂载项
        - name: wwwroot
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:
      - name: wwwroot        
        nfs: 
          server: 192.168.195.101
          #这个目录我们需要提前在nfs服务器上建好
          path: /opt/k8s/wwwroot
---
#这个是我们的版本信息
apiVersion: v1 
#这个表示资源类型我们创建的是service
kind: Service
metadata: #这个里面定义的是deployment中我们创建的对象信息
  #对象名称
  name: nginx-service
  labels:
    app: nginx
spec: #这个是对详细对象的定义
  ports: #指定容器需要用到的端口列表
  - port: 80
    targetPort: 80
  selector:
    app: nginx
  type: NodePort     

6.执行文件

kubectl create -f my-nfs.yaml

7.测试我们在nfs服务器的/opt/k8s/wwwroot目录下创建一个index.html

echo “hello” > index.html

通过创建的svc的hostport模式访问web,如果是hello则成功

pv&pvc

  • PersistentVolume(持久卷,简称PV)是集群内,由管理员提供的网络存储的一部分。就像 集群中的节点一样,PV也是集群中的一种资源。它也像Volume一样,是一种volume插件, 但是它的生命周期却是和使用它的Pod相互独立的。PV这个API对象,捕获了诸如NFS、 ISCSI、或其他云存储系统的实现细节。
  • PersistentVolumeClaim(持久卷声明,简称PVC)是用户的一种存储请求。它和Pod类似, Pod消耗Node资源,而PVC消耗PV资源。Pod能够请求特定的资源(如CPU和内存)。PVC能 够请求指定的大小和访问的模式(可以被映射为一次读写或者多次只读)。

pv是真是的内存,pvc是使用pv的。

删除pvc回收pv的操作。

当pv不再需要时,可通过删除pvc回收。

如何进行删除PVC回收PV

当 PVC mypvc1 被删除后,我们发现 Kubernetes 启动了一个新 Pod recycler-for-mypv1,这个 Pod 的作用就是清除 PV mypv1 的数据。此时 mypv1 的状态为 Released,表示已经解除了与 mypvc1 的 Bound,正在清除数据,不过此时还不可用。

persistentVolumeReclaimPolicy:retain (pvc被删除保留pv数据,需手动删除)

根据上面nfs的一个实验:

1.首先创建一个my-pvc的yaml文件

apiVersion: v1
#这个表示资源类型我们创建的是PVC
kind: PersistentVolumeClaim
metadata: #这个里面定义的是pvc中我们创建的对象信息
  #对象名称
  name:  my-pvc
spec: #这个是对PVC详细的定义
  accessModes: #对权限的定义
    #该Volume能被挂载在多个节点上,读写权限。
    - ReadWriteMany
  resources: #对资源的描述
    requests: #下面表示申请一个5G大小的空间
      storage: 5Gi  
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name:  my-pvc
spec:
  accessModes: 
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi  

创建pvc

kubectl create -f my-pvc.yaml
查看状态
kubectl get pvc
此时pvc还为绑定pv,因此此时的状态为pending

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r1X9XmCQ-1688030718139)(C:\Users\86186\AppData\Roaming\Typora\typora-user-images\image-20221013135631564.png)]

2.创建一个my-pv1.yaml和my-pv2.yaml文件

#这个是我们的版本信息
apiVersion: v1
#这个表示资源类型我们创建的是PV
kind: PersistentVolume
metadata: #这个里面定义的是pvc中我们创建的对象信息
  #对象名称
  name:  my-pv1
spec: #这个是对PVC详细的定义
  capacity: #下面定义的空间大小是5G
    storage: 5Gi
  accessModes: #对权限的定义
    #该Volume能被挂载在多个节点上,读写权限。
    - ReadWriteMany
  nfs: #对资源的描述,将pv的地址挂载在nfs上,下面的地址需要提前创建好
    path: /opt/k8s/demo1
    server: 192.168.56.14
apiVersion: v1
kind: PersistentVolume
metadata:
  name:  my-pv1
spec: 
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs: 
    path: /opt/k8s/demo1
    server: 192.168.195.101
#这个是我们的版本信息
apiVersion: v1
#这个表示资源类型我们创建的是PV
kind: PersistentVolume
metadata: #这个里面定义的是pvc中我们创建的对象信息
  #对象名称
  name:  my-pv2
spec: #这个是对PVC详细的定义
  capacity: #下面定义的空间大小是5G
    storage: 5Gi
  accessModes: #对权限的定义
    #该Volume能被挂载在多个节点上,读写权限。
    - ReadWriteMany
  nfs: #对资源的描述,将pv的地址挂载在nfs上,下面的地址需要提前创建好
    path: /opt/k8s/demo2
    server: 192.168.56.14

创建两个pv

kubectl create -f my-pv1.yaml
kubectl create -f my-pv2.yaml

此时查看pvc的状态,是bound的状态,他匹配到了pv。

3.下面我们再创建一个my-pod.yaml文件

#这个是我们的版本信息
apiVersion: v1
#这个表示资源类型我们创建的是Pod
kind: Pod
metadata: #这个里面定义的是Pod中我们创建的对象信息
  #对象名称
  name: my-pod
spec: #这个是对Deployment详细的定义
  containers: #在这里定义容器信息
  #容器的名称
  - name: nginx
    #定义我们要用到的镜像名称 
    image: hub.harbor.com/library/myapp:v1
    #定义镜像的拉取策略
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80  
    volumeMounts: #这里就是在容器中引用下面的定义的pvc挂载项
      - name: www
        mountPath: /usr/share/nginx/html
  volumes:
    - name: www        
      persistentVolumeClaim: 
        #引用的pvc名称
        claimName: my-pvc
apiVersion: v1
kind: Pod
metadata: 
  name: my-pod
spec: 
  containers: 
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80  
    volumeMounts: 
      - name: www
        mountPath: /usr/share/nginx/html
  volumes:
    - name: www        
      persistentVolumeClaim: 
        claimName: my-pvc

创建pod

kubectl create -f my-pod.yaml
kubectl get pod

3.测试

pod中操作
kubectl exec -it my-pod /bin/bash
cd /usr/share/nginx/html
ls
echo date > index.html

nfs服务器上
cd /opt/k8s/demo1
cat index.html

测试是否一致

pv的访问模式:

Access Modes(访问权限)

◎ ReadWriteOnce(RWO):读写权限,并且只能被单个Node挂载。

◎ ReadOnlyMany(ROX):只读权限,允许被多个Node挂载。

◎ ReadWriteMany(RWX):读写权限,允许被多个Node挂载。

pv的回收策略

persistentVolumeReclaimPolicy:pv回收策略。

◎ Retain 保留:保留数据,需要手工处理。

◎ Recycle 回收空间:简单清除文件的操作(例如执行rm -rf /thevolume/* 命令)。

◎ Delete 删除:与PV相连的后端存储完成Volume的删除操作

EBS、GCE PD、Azure Disk、OpenStack Cinder等设备的内部Volume清理)。

对接ceph

查看ceph集群状态

ceph health

创建存储池

root ~ >>> ceph osd pool create mypool 128 128 #设置PG和PGP为128
pool 'mypool' created

root ~ >>> ceph osd pool ls
mypool

创建secret对象

在ceph中创建kube用户并授予相应的权限
root ~ >>> ceph auth get-or-create client.kube mon 'allow r' osd 'allow class-read object_prefix rbd_children,allow rwx pool=mypool'
创建secret对象
root ~/k8s/ceph >>> cat ceph-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: ceph-kube-secret
  namespace: default
data: 
  key: "ceph auth get-key client.kube | base64" 
type: kubernetes.io/rbd
---
apiVersion: v1
kind: Secret
metadata:
  name: ceph-admin-secret
  namespace: default
data:
  key: "ceph auth get-key client.admin | base64"
type: kubernetes.io/rb
Logo

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

更多推荐