k8s之存储
k8s存储
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 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
更多推荐
所有评论(0)