为什么需要存储卷?
1.启动时需要初始化数据,例如配置文件
2.启动过程中产生临时数据,该临时数据需要多个容器间共享
3.启动过程中产生持久数据,例如mysql的data数据
kubernetes中的volume提供了在容器中挂在外度存储的能力
pod需要设置卷来源(soec.volume)和挂载点(spec.containers.volumeMount两个信息后才能使用相应的volume常用的数据卷)
1.本地(hostPath, emptyDir)
2.网络(NFS,Ceph, GlusterFS)
3.公有云(AWS EBS)
4.k8s资源(configmap, secret)
1.0认识临时存储卷 emptyDir
emptyDir是一个临时存储卷与pod生命周期绑定在一起,如果pod删除了卷也会删除
应用场景:pod中容器之间数据共享
实验一
1.1创建一个pod,一个pod写数据,一个pod读数据
[root@k8s-master ~]# cat zf-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: zf-pod
image: centos
command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;done"]
volumeMounts:
- name: data
mountPath: /data
- name: zf-pod-log
image: centos
command: ["bash","-c","tail -f /data/hello"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
emptyDir: {}
1.2查看数据
kubectl exec my-pod -c zf-pod -- tail /data/hello
kubectl logs -f my-pod -c zf-pod-log
查看宿主机真实数据目录
去 k8s-node2目录上查找该容器
2.1确认容器信息
1.2查找真实目录
ls /var/lib/kubelet/pods/7e53914b-b419-4497-a841-536665d97f7c/volumes/kubernetes.io~empty-dir/data
确认该目录为容器真实目录
2.0 节点存储卷 hostPath
hostPath卷: 挂载Node文件系统 (Pod所在节点)上文件或者目录到Pod中的容器。
应用场景:pod中容器需要访问宿主机文件
2.1 创建pod
apiVersion: v1
kind: Pod
metadata:
name: host-pod
spec:
containers:
- name: busybox
image: busybox
args:
- /bin/sh
- -c
- sleep 36000
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
hostPath:
path: /tmp
type: Directory
2.2验证
kubectl get pods -o wide
2.33去k8s-node1上查看发现宿主机目录tmp下和容器保持一致
在该节点下创建目录,容器中也会映射该目录
3.0网络存储卷 NFS
NFS卷:提供对NFS挂载支持,可以自动将NFS共享路径挂载到pod中
NFS:是一个主流的文件共享服务器
3.1安装 nfs
yum -y install nfs-utils
vim /etc/exports
/ifs/kubernetes *(rw,no_root_squash)
mkdir -p /ifs/kubernetes
systemctl start nfs
systemctl status nfs
systemctl enable nfs
#每个node上都要按照nfs-utils
3.2 安装客户端并测试nfs
yum -y install nfs-utils
mount -t nfs 192.168.106.200:/ifs/kubernetes /mnt/
cd /mnt/;touch nfs;echo 123 >> nfs
服务端查看
验证nfs共享存储成功,df -h | grep ifs也能验证
#创建Pod使用nfs共享
[root@cka-node ~]# cat nfs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: deploy-nfs
name: deploy-nfs
spec:
replicas: 1
selector:
matchLabels:
app: deploy-nfs
strategy: {}
template:
metadata:
labels:
app: deploy-nfs
spec:
containers:
- image: nginx
name: nginx
resources: {}
volumeMounts: #指定共享目录
- name: data
mountPath: /usr/share/nginx/html
volumes:
- name: data
nfs: #创建共享类型为nfs
server: 192.168.106.200 #指定共享服务器
path: /ifs/kubernetes #指定共享路径
kubectl apply -f nfs.yaml
去nfs服务器上查看信息,创建一个页面
访问pod就能显示刚才的页面
删除pod并暴露端口检擦信息是否丢失
kubectl delete pod deploy-nfs-65b77b9fc5-jgp2b
kubectl expose deployment deploy-nfs --port=80 --target-port=80 --type=NodePort
该资源数据还是正常访问,并没有丢失
####分享一个错误案例
k8s-node2节点没有安装nfs-nuils,创建的pod分配到这个节点启动会报错
发现node节点的pod启动失败,检查发现未安装nfs客户端yum -y install nfs-utils后重新创建pod正常
4.0pv与pvc使用流程:
1.pod将数据持久化到远程存储
2.pod多副本共享数据
持久卷概念
- PersistentVolume(PV):
对存储资源创建和使用的抽象,使得存储作为集群中的资源管理
- PersistentVolumeClaim(PVC):
让用户不需要关心具体的volume实现细节
4.1 创建pod
[root@k8s-master ~]# cat deploy-pvc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: deploy-pvc
name: deploy-pvc
spec:
replicas: 3
selector:
matchLabels:
app: deploy-pvc
strategy: {}
template:
metadata:
labels:
app: deploy-pvc
spec:
containers:
- image: nginx
name: nginx
resources: {}
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumes:
- name: data
persistentVolumeClaim:
claimName: my-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
kubectl apply -f deploy-pod.yaml
调度状态出现Pending原因
`1.cpu不足
2.内存不足
3.有污点
4.没有标签
5.pvc没有绑定pv`
4.2 创建pvc
[root@k8s-master ~]# cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
nfs:
path: /ifs/kubernetes
server: 172.16.226.5
kubectl apply -f pv.yaml
#绑定后pvc正常
#pv 自动绑定与存储大小最接近的pvc
pv生命周期
AccessModes(访问模式):
AccessModes 是用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式: • ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
• ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
• ReadWriteMany(RWX):读写权限,可以被多个节点挂载
RECLAIM POLICY(回收策略):
目前 PV 支持的策略有三种:
• Retain(保留): 保留数据,需要管理员手工清理数据
• Recycle(回收):清除 PV 中的数据,效果相当于执行 rm -rf /ifs/kuberneres/*
• Delete(删除):与 PV 相连的后端存储同时删除
STATUS(状态):
一个 PV 的生命周期中,可能会处于4中不同的阶段:
• Available(可用):表示可用状态,还未被任何 PVC 绑定
• Bound(已绑定):表示 PV 已经被 PVC 绑定
• Released(已释放):PVC 被删除,但是资源还未被集群重新声明
• Failed(失败): 表示该 PV 的自动回收失败
默认都是RWX,读写权限,可以被多个节点挂载
默认保留策略,保留数据,需要管理员手动清理数据挂载上pvc之后默认是bound绑定状态
pv与pvc之间的关系
1.pv与pvc是一对一的关系
2.匹配关系-----存储空间和访问模式
3容器匹配最近的pv容量,如果满足不了处于pending状态
4.存储空间的字段是限制主要做匹配,实际使用限制取决于后段存储
现在使用pv的方式称为静态供给,需要工程师提前创建一堆pv,给开发者使用
创建nfs动态供给pv
下载github动态供给nfs插件
class. 创建存储类,实现pv动态供给的能力(接口)
deployment. 联系k8s创建pv和pvc的请求
rbac 授权
#配置文件详解
[root@k8s-master nfs-external-provisioner]# cat class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage #存储类名称
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'。#指定提供者的名称
parameters:
archiveOnDelete: "false" #false当pv删除时,pvc不删除!true时,pvc删除
cat deployment.yaml
#镜像需要*,指定国内镜像
kubectl apply -f .
在静态pvc 文件中添加如下配置,并改名称
需要修改的内容如下
name: deploy-storageclass
claimName: my-sc
name: my-sc
storageClassName: "managed-nfs-storage"
Pod 创建成功,检查pv和pvc
检查nfs服务器
#在容器中/usr/share/nginx/html/目录下创建的文件会同步持久到/ifs/kubernetes/default-my-sc-pvc-0e0d61a1-09ae-4138-b4c2-62a6e7c23da4/目录下