K8s 学习笔记—— 数据存储(持久化)
文章目录数据存储基本存储EmptyDirHostPathNFSPV 和PVCConfigMapSecret数据存储容器的生命周期可能会很短,会被频繁的创建和销毁。那么容器在销毁的时候,保存在容器中的数据也会被清除。这种结果对于用户来说,在某些情况下是不愿意看到的。为了持久化保存容器中的数据,K8s 引入了Volume 的概念。Volume 是Pod 中能够被多个容器访问的共享目录,它被定义在Pod
数据存储
容器的生命周期可能会很短,会被频繁的创建和销毁。那么容器在销毁的时候,保存在容器中的数据也会被清除。这种结果对于用户来说,在某些情况下是不愿意看到的。为了持久化保存容器中的数据,K8s 引入了Volume 的概念。
Volume 是Pod 中能够被多个容器访问的共享目录,它被定义在Pod 上,然后被一个pod 里面的多个容器挂载在具体的文件目录下,K8s 通过Volume 实现同一个Pod 中不同容器之间的数据共享以及数据的持久化存储。
Volume 的生命容器不与pod 中单个容器的生命周期相关,当容器终止或重启时,Volume 中的数据也不会丢失。
k8s 的Volume 支持多种类型,常见的有下面几种:
- 简单存储: EmptyDir, HostPath,NFS
- 高级存储: PV, PVS
- 配置存储 : ConfigMap, Secret
基本存储
EmptyDir
EmptyDir 是最基础的Volume 类型,一个EmptyDir 就是Host 上的一个空目录。
EmptyDir 是在Pod 被分配到Node 的时候被创建的。它的初始内容为空,并且无需指定宿主机上的对应的目录文件。因为K8s 会自动分配一个目录,当pod 被销毁时,EmptyDir 中的数据也会被永久删除。
EmptyDir 用途如下。
- 临时空间,例如用于某些应用程序运行时所需的临时目录(存放临时文件),且无需永久保存
- 一个容器需要从另一个容器中获取数据的目录(多容器共享目录)
举例:容器之间文件共享案例
在一个pod 中准备两个容器nginx 和busybox, 然后声明一个Volume 分别挂载到两个容器的目录中,然后nginx 容器负责向Volume 中写日志,busybox 中通过命令将日志内容读到控制台。
创建volume-emptydir.yaml
apiVersion: v1 #固定的,可以查看
kind: Pod
metadata:
name: volume-emptydir
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
volumeMounts: # 将logs-volume 挂载在nginx 容器中,对应的目录为 /var/log/nginx
- name: logs-volume
mountPath: /var/log/nginx
- name: busybox
image: busybox:1.30
command: ["bin/sh","-c","tail -f /logs/access.log"] #初始化命令,动态读取指定文件中的内容
volumeMounts:
- name: logs-volume
mountPath: /logs # 挂载到 /logs 文件下
volumes: # 声明volume,name 为logs-volume, 类型为emptyDir
- name: logs-volume
emptyDir: {}
访问nginx 容器
使用 kubectl logs 命令查看指定容器的标准输出
kubectl logs -f volume-emptydir -n dev -c busybox
HostPath
主机路径
EmptyDir 中的数据不会被持久化,它会随着pod 的结束而销毁。如果想简单的数据持久化到主机上,就可以选择HostPath。
HostPath 就是将 Node 主机中一个实际目录挂载到pod 中,以供容器使用,这样的设计就可以保证pod 被销毁了,但数据依旧存在与Node 主机上。
创建一个 volume-hostpath.yaml
apiVersion: v1 #固定的,可以查看
kind: Pod
metadata:
name: volume-hostpath
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
volumeMounts: # 将logs-volume 挂载在nginx 容器中,对应的目录为 /var/log/nginx
- name: logs-volume
mountPath: /var/log/nginx
- name: busybox
image: busybox:1.30
command: ["bin/sh","-c","tail -f /logs/access.log"] #初始化命令,动态读取指定文件中的内容
volumeMounts:
- name: logs-volume
mountPath: /logs # 挂载到 /logs 文件下
volumes: # 声明volume,name 为logs-volume, 类型为emptyDir
- name: logs-volume
hostPath:
path: /root/logs #主机path 路径
type: DirectoryOrCreate
type 类型说明:
查看详细信息
在minikube 节点查看路径 /root/logs 可以看到生成了两个nginx 相关的文件。
访问nginx,可以看到产生了一条记录。
使用 下列命令删除该pod
kubectl delete -f volume-hostpath.yaml
删除了该pod ,其对应的文件还在。
NFS
HostPath 也存在一些缺陷,一旦Node 节点故障了,Pod 如果转移到别的节点,就无法读取到故障节点上存储的文件。 这个时候需要准备单独的网络存储系统,常见的有NFS,CIFS
NFS 是一个网络文件存储系统,可以搭建一台NFS 服务器,然后将pod 中的存储直接连接到NFS 系统上。这样的话,无论pod 在节点上怎么转移。只要Node 跟NFS 的对接没有问题,数据就可以成功访问。
1 准备nfs 服务器
1 安装nfs 服务
apt install nfs-common
2 准备一个共享目录
mkdir /root/data/nfs -pv
3 将共享目录以读写权限暴露给网段中的所有主机
vim /etc/exports
更改为
/root/data/nfs 172.18.0.0/16(rw,no_root_squash)
4 重启nfs 服务
systemctl start nfs
2 创建volume-nfs.yaml 文件
apiVersion: v1 #固定的,可以查看
kind: Pod
metadata:
name: volume-nfs
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
volumeMounts: # 将logs-volume 挂载在nginx 容器中,对应的目录为 /var/log/nginx
- name: logs-volume
mountPath: /var/log/nginx
- name: busybox
image: busybox:1.30
command: ["bin/sh","-c","tail -f /logs/access.log"] #初始化命令,动态读取指定文件中的内容
volumeMounts:
- name: logs-volume
mountPath: /logs # 挂载到 /logs 文件下
volumes: # 声明volume,name 为logs-volume, 类型为emptyDir
- name: logs-volume
nfs:
server: 172.0.18.100 #nfs 服务器地址
path: /root/data/nfs #共享文件路径
PV 和PVC
由于K8s支持的存储系统有很多,要求客户全部掌握显然不是很显示,为了屏蔽底层存储的实现细节,方便用户使用,K8s 引入了PV 和 PVC 两种资源对象。
PV(Persistent Volume) 是持久化卷的意思,是对底层共享存储的一种抽象
,一般情况下,PV由K8s 管理员进行创建和配置。它与底层具体的共享存储技术有关。并通过插件完成与共享存储的对接 。
PVC(Persistent Volume Claim)持久卷声明的意思,是用户对存储需求的一种说明。
PVC 其实就是用户向K8s 系统发出的一种 组员需求申请。
存储 :存储工程师维护
PV:K8s 管理员维护
PVC: K8s 用户进行维护
PV
PV 资源清单文件
apiVersion: v1 #固定的,可以查看
kind: PersistentVolume
metadata:
name: pv2
spec:
nfs: #存储类型,与底层真正存储对应
capacity: # 存储能力,目前只支持存储空间设置
storage: 2Gi
accessModes: # 访问模式
storageClassName: #存储类别
persistentVolumeReclaimPolicy: # 回收策略
PV 关键配置说明:
使用NFS 作为存储,演示PV 的使用,创建3个PV,对应NFS 中3个暴露的路径
创建pv.yaml
apiVersion: v1 #固定的,可以查看
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity: # 存储能力,目前只支持存储空间设置
storage: 1Gi
accessModes: # 访问模式
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain # 回收策略
nfs: #存储类型,与底层真正存储对应
path: /root/data/pv1
server: 192.168.109.100
---
apiVersion: v1 #固定的,可以查看
kind: PersistentVolume
metadata:
name: pv2
spec:
capacity: # 存储能力,目前只支持存储空间设置
storage: 2Gi
accessModes: # 访问模式
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain # 回收策略
nfs: #存储类型,与底层真正存储对应
path: /root/data/pv2
server: 192.168.109.100
---
apiVersion: v1 #固定的,可以查看
kind: PersistentVolume
metadata:
name: pv3
spec:
capacity: # 存储能力,目前只支持存储空间设置
storage: 2Gi
accessModes: # 访问模式
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain # 回收策略
nfs: #存储类型,与底层真正存储对应
path: /root/data/pv3
server: 192.168.109.100
PVC
PVC 是资源的申请,用来声明对存储空间,访问模式,存储类别需求信息,下面是资源清单。
通过PVC 申请PV,然后在Pod 中使用PVC
PVC 资源清单文件
apiVersion: v1 #固定的,可以查看
kind: PersistentVolumeClaim
metadata:
name: pvc
namespace: dev # 注意PV 是跨namespace 的,但是pvc不跨namespace
spec:
accessModes: # 访问模式
selector: # 采用标签对PV选择
storageClassName: #存储类别
resource: #请求空间
requests:
storage: 5Gi
创建pvc.yaml,申请pv
apiVersion: v1 #固定的,可以查看
kind: PersistentVolumeClaim
metadata:
name: pvc1
namespace: dev
spec:
accessModes: # 访问模式
- ReadWriteMany
resource: #请求空间
requests:
storage: 1Gi
ConfigMap
ConfigMap 是一种比较特殊的存储卷,它的主要作用是来存储配置信息的。
创建configmap.yaml
apiVersion: v1 #固定的,可以查看
kind: ConfigMap
metadata:
name: configmap
namespace: dev
data:
info: |
username:admin
password:123456
创建configmap:
kubectl create -f configmap.yaml
查看configmap 详情:
kubectl describe cm configmap -n dev
创建一个pod-configmap.yaml, 将上面创建的 configmap 挂载上去。
apiVersion: v1 # API版本号,注意:具有多个,不同的对象可能会使用不同API
kind: Pod # 对象类型,pod
metadata: # 元数据
name: pod-configmap # POD名称
namespace: dev # 所属的命名空间
spec: # specification of the resource content(资源内容的规范)
containers: # 容器列表
- name: nginx # 容器名称
image: nginx:1.17.1 # 容器镜像
volumeMounts: #将configmap 挂载到目录
- name: config
mountPath: /configmap/config
volumes: #引用configmap
- name: config
configMap:
name: configmap
1 创建pod
2 查看pod
3 进入容器查看是否挂载成功
kubectl exec -it pod-configmap -n dev /bin/sh
可以看到映射已经生效,每个configmap 都可以映射成一个目录
key 对应文件名, value 对应文件中的内容
如果此时更新 configmap 的内容,容器中的值也会动态更新
password 后面添加一个7,使用kubectl apply 进行更新
挂载的文件也进行了更新
Secret
在K8s 中,还存在一种和ConfigMap 非常类似的对象,称为Secret 对象,ConfigMap 是用明文进行存储,而Secret 对象主要用来存储敏感信息,例如密码,密钥,证书等。
1 首先使用base64 对数据进行编码
echo -n "admin" | base64
echo -n "123456" | base64
2 编写secret.yaml, 并创建secret
apiVersion: v1 #固定的,可以查看
kind: ConfigMap
metadata:
name: configmap
namespace: dev
data:
info: |
username:YWRtaW4=
password:MTIzNDU2
更多推荐
所有评论(0)