8. Kubernetes核心资源之数据存储持久化
假如存在很多PV, K8S 要用PV的时候直接调用某个PV的话,那如果需要的是存储能力比较大存储资源,所以这个时候需要一个一个去对比pv,这样很耗费资源(因为要满足需求)删除 Delete – 当PV对象被删除之后,与之相关的位于外部的基础设施中的数据也被一并删除(如nfs),需要根据实际情况手动回收,更多是云厂商设备。是集群中由管理员配置的一段网络存储,它是集群的一部分资源和底层存储密切相关,对
- **Volumes常见类型: **
- 常规存储:EmptyDir、HostPath
- 高级存储:PV、PVC
- 配置存储:ConfigMap、Secret
- 其他:网络存储系统 NFS、CIFS,包括云服务商提供的、本地、分布式
- **EmptyDir : **
-
当 Pod 指定到某个节点上时,首先创建的是一个 emptyDir 卷,只要 Pod 在该节点上运行卷就一直存在
-
当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会永久删除
-
容器崩溃并不会导致 Pod 被从节点上移除,所以容器崩溃时 emptyDir 卷中的数据是安全的。
-
用途 : 临时缓存空间
-
案例
volume-emptydir.yaml
-
pod里面定义两个容器,一个产生日志,一个是读日志输出到控制台
apiVersion: v1
kind: Pod
metadata:
name: xdclass-volume-emptydir
namespace: dev
spec:
containers:
- name: xdclass-nginx
image: nginx:1.20
ports:
- containerPort: 80
volumeMounts: # 将nginx-log-volume挂在到nginx容器中,对应的目录为 /var/log/nginx
- name: nginx-log-volume
mountPath: /var/log/nginx
- name: xdclass-busybox
image: busybox:1.35.0
command: ["/bin/sh","-c","tail -f /usr/local/test/access.log"] # 容器启动后初始命令,读取指定文件中内容
volumeMounts: # 将nginx-log-volume挂在到busybox容器中,对应的目录为 /logs
- name: nginx-log-volume
mountPath: /usr/local/test
volumes: # 这里声明volume存储劵, name为nginx-log-volume,类型是emptyDir
- name: nginx-log-volume
emptyDir: {}
- **操作 : **
#创建
kubectl apply -f volume-emptydir.yaml
#查看
kubectl get pods -n dev -o wide
#访问nignx 产生访问日志
curl ip
#查看容器输出 -f 后是 pod的名称
kubectl logs -f xdclass-volume-emptydir -n dev -c xdclass-busybox
# 删除
kubectl delete -f volume-emptydir.yaml
- **HostPath : **
- Directory 给定的目录路径必须存在
- DirectoryOrCreate 如果给定路径不存在,将根据需要在那里创建一个空目录
- File 给定路径上必须存在对应文件
- FileOrCreate 如果给定路径不存在,将根据需要在那里创建一个空文件
- 案例
volume-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: xdclass-volume-hostpath
namespace: dev
spec:
containers:
- name: xdclass-nginx
image: nginx:1.20
ports:
- containerPort: 80
volumeMounts: # 将nginx-log-volume挂在到nginx容器中,对应的目录为 /var/log/nginx
- name: nginx-log-volume
mountPath: /var/log/nginx
- name: xdclass-busybox
image: busybox:1.35.0
command: ["/bin/sh","-c","tail -f /usr/local/test/access.log"] # 容器启动后初始命令,读取指定文件中内容
volumeMounts: # 将nginx-log-volume挂在到busybox容器中,对应的目录为 /logs
- name: nginx-log-volume
mountPath: /usr/local/test
volumes: # 这里声明volume存储劵, name为nginx-log-volume,类型是hostPath
- name: nginx-log-volume
hostPath:
path: /usr/local/test
type: DirectoryOrCreate #如果给定路径不存在,将根据需要在那里创建一个空目录
- **操作 : **
#创建
kubectl apply -f volume-hostpath.yaml
#查看
kubectl get pods -n dev -o wide
#访问nignx 产生访问日志
curl ip
#查看容器输出 -f 后是 pod的名称
kubectl logs -f xdclass-volume-hostpath -n dev -c xdclass-busybox
#去节点对应的目录查看文件是否有,即pod运行的节点,主节点上是没的!!!!
ls /usr/local/test
# 删除
kubectl delete -f volume-hostpath.yaml
- **emptyDir和hostPath对比 : **
- 都是本地存储卷方式
- emptyDir是临时存储空间,完全不提供持久化支持;
- hostPath的卷数据是持久化在node节点的文件系统中的,即便pod已经被删除了,volume卷中的数据还留存在node节点上
- **ConfigMap : **
- 是K8S的一种API对象,用来把【非加密数据】保存到键值对中,比如etcd
- 可以用作环境变量、命令行参数等,将环境变量、配置信息和容器镜像解耦,便于应用配置的修改
# 命令格式
kubectl create configmap NAME --from-literal=key1=value1 --from-literal=key2=value2
- **操作 : **
kubectl create configmap xdclass-config --from-literal=account=xdclass --from-literal=password=123456
#查看
kubectl get cm xdclass-config -o yaml
apiVersion: v1
data:
account: xdclass
password: password
kind: ConfigMap
metadata:
creationTimestamp: "2022-07-04T06:36:18Z"
name: xdclass-config
namespace: default
resourceVersion: "1716676"
selfLink: /api/v1/namespaces/default/configmaps/xdclass-config
uid: 6ae2890e-fad3-452c-9179-78dd63ddbbba
apiVersion: v1
kind: ConfigMap
metadata:
name: xdclass-configmap
namespace: dev
data:
info:
username:xdclass
password:123456
# 操作
#创建
kubectl create -f configmap.yaml
# 查看configmap详情
kubectl describe cm xdclass-configmap -n dev
- 创建pod的yaml,pod-configmap.yaml,然后吧将创建的configmap挂载进去
apiVersion: v1
kind: Pod
metadata:
name: pod-configmap
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.20
volumeMounts: # configmap挂载的目录
- name: config
mountPath: /config
volumes: # 声明configmap
- name: config
configMap:
name: xdclass-configmap
- **操作 : **
#创建pod
kubectl create -f pod-configmap.yaml
#查看
kubectl get pod pod-configmap -n dev
#进入容器
kubectl exec -it pod-configmap -n dev -- /bin/sh
# cd /config
# cat info
username:xdclass
password:123456
-
**Secret : **
-
用来保存敏感信息,例如密码、秘钥、证书、OAuth 令牌和 ssh key等
-
就不需要把这些敏感数据暴露到镜像或者Pod中
-
Secret有多种类型 :
- dockerconfigson : 用来存储私有 docker registry的认证信息
-
ServiceAccount :
- 只要与Kubernetes API有交互的Pod,都会自动拥有此种类型的Secret
- K8S自动创建,并且会自动挂载到Pod的 /run/secrets/kubernetes.io/serviceaccount 目录中
-
操作 :
#查看
kubectl get pod -A | grep 'kube-proxy'
#进到容器,加了 -- /bin/bash,不会有警告
kubectl exec -it -n kube-system kube-proxy-9wb4g -- /bin/sh
#查看
ls -l /run/secrets/kubernetes.io/serviceaccount
cd /run/secrets/kubernetes.io/serviceaccount
cat ca.crt
- **Opaque : **加密类型为base64,其特点就是将明文改为了密文
echo -n 'admin' | base64 #账号
echo -n '123456' | base64 #密码
#创建secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MTIzNDU2
#创建
kubectl apply -f secret.yaml
# 查看secret的信息
kubectl get secret
# 查看mysecret详细信息
kubectl get secret mysecret -o yaml
#将secret挂载到Pod的Volume中,创建pod-secret-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-secret
spec:
containers:
- name: nginx
image: nginx:1.20
volumeMounts: # secret挂载
- name: xdclass-config
mountPath: /etc/secret
volumes:
- name: xdclass-config
secret:
secretName: mysecret
#创建pod
kubectl apply -f pod-secret-volume.yaml
#查看
kubectl get pod -o wide
#查看secret, 在pod中的secret信息实际已经被解密
kubectl exec -it pod-secret -- /bin/sh
#ls /etc/secret
#cat /etc/secret/username
#cat /etc/secret/password
#删除secret
kubectl delete secret mysecret
-
**NFS(Network File System) : **
-
一种基于TCP/IP 传输的网络文件系统协议, 通过使用NFS协议,可以像访问本地目录一样访问远程服务器中的共享资源
-
NFS服务的实现依赖于RPC (Remote Process Call,远端过程调用)机制,以完成远程到本地的映射过程
-
需要安装nfs-utils、 rpcbind 软件包来提供NFS共享服务,前者用于NFS共享发布和访问,后者用于RPC支持
-
采用TCP/IP传输网络文件,适合局域网环境,简单操作
- NFS端口:2049
- RPC端口:111
- **部署NFS服务器 : **
- 下载nfs-util (主从均执行, 对应要用到的节点都需要安装,但是不需要启动)
yum install nfs-utils -y
- 创建目录(nfs服务器)
#目录可以自定义
mkdir /opt/nfsdata
#给路径授权
chmod 777 /opt/nfsdata
- 编辑/etc/exports 配置文件(nfs服务器)
vim /etc/exports
# 目录的读写权限暴露给这个网段的全部主机
/opt/nfsdata 172.31.101.0/24(rw,insecure,sync)
**解释 : **
172.31.101.0/24表示的IP范围, 换成32位二进制,四组,每组8位
/24 表示前24位不变,后8位由全0变化到全1的过程,也就是由“00000000”变化到“11111111”
又因为全0是子网网络地址,全1是子网广播地址,这两个地址是不分配给主机使用的。
所以有效的可分配的范围是前24位不变,后8位由“00000001”变化为“11111110”的范围
再转换回十进制就是172.31.101.1~172.31.101.254
**参数 : **
-
rw 共享目录可读可写
-
secure 限制客户端只能从小于1024的tcp/ip端口连接服务器;
-
insecure允许客户端从大于1024的tcp/ip端口连接服务器;
-
sync 将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性;
-
async 将数据先保存在内存缓冲区中,必要时才写入磁盘;
-
**启动rpcbind(安装nfs依赖包会自动下载)和nfs服务 : **
systemctl start rpcbind
systemctl start nfs
- **验证 : **
showmount -e localhost
- **NFS持久卷挂载 : **
apiVersion: v1
kind: Pod
metadata:
name: xdclass-nfs
namespace: dev
labels:
apps: nginx-nfs
spec:
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
volumeMounts:
- name: logs-volume
mountPath: /var/log/nginx
volumes:
- name: logs-volume
nfs:
server: 192.168.100.150 #nfs服务器地址
path: /opt/nfsdata #共享文件路径
- **操作 : **
# 创建pod
kubectl apply -f pod-log-volume.yaml
# 暴露服务
kubectl expose pod xdclass-nfs -n dev --port=80 --target-port=80 --type=NodePort
# 查看nfs服务器的/opt/nfsdata
kubectl exec -it xdclass-nfs -- /bin/sh
cd /opt/nfsdata
ls
# 查看日志
tail -f access.log
-
**PV 持久卷(Persistent Volume): **
-
是集群中由管理员配置的一段网络存储,它是集群的一部分资源和底层存储密切相关,对象包含存储实现的细节,即 对接NFS、CIFS等存储系统
-
不同的PV会对应到不用的存储资源,这样在部署pod的时候直接调用集群内部的pv即可
-
PV没有命名空间隔离概念
-
**PVC 持久卷声明 (Persistent Volume Claim): **
-
假如存在很多PV, K8S 要用PV的时候直接调用某个PV的话,那如果需要的是存储能力比较大存储资源,所以这个时候需要一个一个去对比pv,这样很耗费资源(因为要满足需求)
-
PVC是用户存储的一种声明, PVC 可以请求特定的存储空间和访问模式,PVC 消耗的是 PV 资源
-
PVC必须与对应的PV建立关系,PVC会根据定义的PV去申请
-
创建pod的时候会附带一个PVC的请求,PVC的请求相当于就是去寻找一个合适的pv
-
使用逻辑 :
- 在 pod 中定义一个存储卷(该存储卷类型为 PVC),定义的时候按指定大小,PVC 必须与对应的 PV 建立关系,PVC 会根据定义的需求【去 PV 申请】,而 PV 是由存储空间创建出来的
-
**PV和PVC逻辑 : **
-
PV 是集群中的【资源】,PVC 是对这些【资源的请求】
-
PV 和 PVC 之间的相互作用遵循这个生命周期
-
Provisioning(配置) —> Binding(绑定) —> Using(使用) —> Releasing(释放) —> Recycling(回收)
-
**PV的yaml模板 : **
apiVersion: v1
kind: PersistentVolume
metadata:
name: xdclass-pv
spec:
capacity:
storage: 5Gi #存储大小
accessModes: #访问模式
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle #回收策略
storageClassName: slow #存储类别
nfs: #卷插件
path: /tmp
server: 192.168.100.150
-
**存储大小:**存储大小是可以设置和请求的唯一资源。 未来可能会包含 IOPS、吞吐量等属性
-
访问模式:用户对资源的访问权限
- ReadWriteOnce(RWO):读写权限,只能被单个节点挂载
- ReadOnlyMany(ROX): 只读权限,可以被多个节点挂载
- ReadWriteMany(RWX):读写权限,可以被多个节点挂载
-
存储类别:
-
每个 PV 可以属于某个类,通过将其 storageClassName属性设置为某个 StorageClass 的名称来指定。
-
特定类的 PV 卷只能绑定到请求该类存储卷的 PVC 申领。
-
未设置 storageClassName 的 PV 卷没有类设定,只能给到那些没有指定特定 存储类的 PVC 申领。
-
回收策略(当PV不再被使用了之后的处理策略)
-
保留 Retain – 当PV对象被删除之后,与之相关的位于外部的基础设施中的数据仍然存在(如nfs),需要根据实际情况手动回收
-
回收 Recycle – 相当于在卷上执行rm -rf /volume/* 操作,之后该卷可以用于新的pvc申领
-
删除 Delete – 当PV对象被删除之后,与之相关的位于外部的基础设施中的数据也被一并删除(如nfs),需要根据实际情况手动回收,更多是云厂商设备
-
状态( PV 的生命周期有4种不同状态)
-
Available(可用)——一块空闲资源还没有被任何声明绑定
-
Bound(已绑定)——卷已经被声明绑定
-
Released(已释放)——声明被删除,但是资源还未被集群重新声明
-
Failed(失败)——该卷的自动回收失败
-
**PVC的yaml模板 : **
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: xdclass-pvc
namespace: dev
spec:
accessModes: # 访问模式
- ReadWriteMany
selector: # 采用label标签对PV选择过滤
storageClassName: # 存储类别,设置对应的class的PV才能被系统选出
resources: # 需要存储资源的请求
requests:
storage: 3Gi
-
**需求 : **
-
基于NFS存储,创建2个PV
-
创建PVC绑定PV
-
创建Pod挂载PVC
-
创建目录
mkdir /opt/nfsdata/pv1
mkdir /opt/nfsdata/pv2
chmod 777 /opt/nfsdata/pv1
chmod 777 /opt/nfsdata/pv2
- 修改配置文件
vim /etc/exports
#暴露nfs服务
/opt/nfsdata/pv1 172.31.101.0/24(rw,insecure,sync)
/opt/nfsdata/pv2 172.31.101.0/24(rw,insecure,sync)
- 重启NFS
systemctl restart nfs
- **创建两个PV : **
**kubectl apply -f pv.yaml **
apiVersion: v1
kind: PersistentVolume
metadata:
name: xdclass-pv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
server: 192.168.100.150
path: /opt/nfsdata/pv1
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: xdclass-pv2
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
server: 192.168.100.150
path: /opt/nfsdata/pv2
-
**查看PV : **
**kubectl get pv -o wide**
-
**创建PVC,使用pvc.yaml : **
**kubectl apply -f pvc.yaml **
-
(与PV不同,PVC不属于集群资源,拥有自己的名称空间)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: xdclass-pvc1
namespace: dev
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: xdclass-pvc2
namespace: dev
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
-
**查看pvc : **
**kubectl get pvc -n dev**
-
**创建pod 挂载pvc : **
apiVersion: v1
kind: Pod
metadata:
name: xdclass-pod1
namespace: dev
spec:
containers:
- name: xdclass-busybox
image: busybox
command: ["/bin/sh","-c","while true;do echo hello xdclass pod1 >> /opt/print.txt; sleep 5; done;"]
volumeMounts:
- name: volume
mountPath: /opt/
volumes:
- name: volume
persistentVolumeClaim:
claimName: xdclass-pvc1
readOnly: false
---
apiVersion: v1
kind: Pod
metadata:
name: xdclass-pod2
namespace: dev
spec:
containers:
- name: xdclass-busybox
image: busybox
command: ["/bin/sh","-c","while true;do echo hello xdclass pod2 >> /opt/print.txt; sleep 5; done;"]
volumeMounts:
- name: volume
mountPath: /opt/
volumes:
- name: volume
persistentVolumeClaim:
claimName: xdclass-pvc2
readOnly: false
- 创建pod完成后,到nfs服务器查看 /opt/nfsdata/pv1/print.txt
tail -f pv1/print.txt
更多推荐
所有评论(0)