k8s中为什么使用存储:
k8s中的副本控制器保证了pod的始终存储,却保证不了pod中的数据。只有启动一个新pod的,之前pod中的数据会随着容器的删掉而丢失!
pv和pvc的概念:
PersistentVolume(一些简称PV):由管理员添加的的一个存储的描述,是一个全局资源,包含存储的类型,存储的大小和访问模式等。它的生命周期独立于Pod,例如当使用它的Pod销毁时对PV没有影响。
PersistentVolumeClaim(一些简称PVC):是Namespace里的资源,描述对PV的一个请求。请求信息包含存储大小,访问模式等。
创建pv
后端存储用的是nfs,nfs共享存储配置可以看之前发布的博文
[root@k8s-master1 pv]# cat nginx-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nginx-pv
labels:
type: nginx-pv
spec:
capacity: #存储能力
storage: 2Gi #大小2G
accessModes:
- ReadWriteMany #多节点读写
persistentVolumeReclaimPolicy: Recycle #可回收
nfs: #指定nfs存储
path: "/data/k8s" #nfs主机存储路径,这个路径需要主机真实存在
server: 192.168.198.144 #nfs 服务端地址,是主机地址
readOnly: false
创建pv
[root@k8s-master1 pv]# kubectl apply -f nginx-pv.yaml
创建pvc
[root@k8s-master1 pv]# cat nginx-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginxpvc
spec:
accessModes:
- ReadWriteMany
resources: #需求资源
requests:
storage: 2Gi #需求资源大小2G
[root@k8s-master1 pv]# kubectl apply -f nginx-pvc.yaml
pvc会自动绑定和他需求资源大小最接近的pv资源(有个前提:pv资源必须答应pvc需求资源大小)
查询pv,pvc
pod使用pvc
[root@k8s-master1 pv]# cat nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment #deployment 控制器
metadata:
name: my-dep-pvc #deploymen 名称
spec: #deployment 元数据
replicas: 1 #副本数
selector: #选择器
matchLabels:
app: my-dep-pvc #label名称
template: #容器模板
metadata:
labels:
app: my-dep-pvc
spec: #容器元数据
containers:
- name: nginx #容器名称
image: centos-nginx:1.23.0 #容器镜像,本地build的一个镜像
imagePullPolicy: Never #容器镜像拉取方式,never表示只从本地拉取,不从远程仓库拉取
ports:
- containerPort: 80 #容器镜像
volumeMounts: #容器挂载的pvc卷
- name: nginx-data #自定义容器挂载卷的名称
mountPath: /apps/nginx/html #需要挂载出去的容器的路径,我的html文件放在了apps这个目录下
volumes: #挂载卷
- name: nginx-data #卷名称,需要和自定义容器挂载卷的名称一致
persistentVolumeClaim:
claimName: nginxpvc #本地创建的pvc名称
restartPolicy: Always
创建deployment
[root@k8s-master1 pv]# kubectl apply -f nginx-deployment.yaml
查询 pod卷信息
[root@k8s-master1 pv]# kubectl describe pod my-dep-pvc-6bc6fb7dd9-pnxs8
#截取一部分,mounts挂载情况,Volumes:信息
Ready: True
Restart Count: 0
Environment:
Mounts:
/apps/nginx/html from nginx-data (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-clqrl (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
nginx-data:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: nginxpvc
ReadOnly: false
default-token-clqrl:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-clqrl
主机上df -h可以查询到对应挂载信息
[root@k8s-node2 pods]# df -h | grep nginx-pv
192.168.198.144:/data/k8s 17G 3.7G 14G 22% /var/lib/kubelet/pods/74972e11-8dc1-4c39-a2ba-58050d8224d3/volumes/kubernetes.io~nfs/nginx-pv
测试pod容器数据持久性
nginx-pv对应主机真实路径:/data/k8s
在/data/k8s上传对应html文件,测试pod容器数据持久性
[root@k8s-master1 pv]# cd /data/k8s/
#这两个html文件从Nginx中拷贝过来
[root@k8s-master1 k8s]# ll
total 8
-rw-r--r-- 1 root root 497 Aug 29 09:21 50x.html
-rw-r--r-- 1 root root 5 Aug 29 09:22 index.html
#修改index文件
[root@k8s-master1 k8s]# echo xmxm > index.html
发布服务service
[root@k8s-master1 pv]# cat svc.yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
name: my-svc-pvc
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: my-dep-pvc
type: NodePort
status:
loadBalancer: {}
[root@k8s-master1 pv]# kubectl apply -f svc.yaml
查询svc,端口为32432
[root@k8s-master1 pv]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 16d
my-svc-pvc NodePort 10.102.155.197 80:32432/TCP 81m
readiness-svc NodePort 10.108.113.163 80:30663/TCP 5d19h
使用浏览器测试
删除pod后,重新测试
[root@k8s-master1 pv]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpget 1/1 Running 6 5d23h
my-dep-68dbd87f47-pmcdq 1/1 Running 7 10d
my-dep-pvc-6bc6fb7dd9-pnxs8 1/1 Running 0 82m
my-dep3-6f4f5bbc-48pml 1/1 Running 7 9d
my-dep3-6f4f5bbc-d8zmt 1/1 Running 7 9d
readiness-57cbcdfc6d-52ffg 1/1 Running 6 5d19h
[root@k8s-master1 pv]# kubectl delete pod my-dep-pvc-6bc6fb7dd9-pnxs8
pod "my-dep-pvc-6bc6fb7dd9-pnxs8" deleted
[root@k8s-master1 pv]#
[root@k8s-master1 pv]#
[root@k8s-master1 pv]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpget 1/1 Running 6 5d23h
my-dep-68dbd87f47-pmcdq 1/1 Running 7 10d
my-dep-pvc-6bc6fb7dd9-f828l 1/1 Running 0 5s
my-dep3-6f4f5bbc-48pml 1/1 Running 7 9d
my-dep3-6f4f5bbc-d8zmt 1/1 Running 7 9d
readiness-57cbcdfc6d-52ffg 1/1 Running 6 5d19h
再次使用浏览器访问,页面还是xmxm,数据没有丢失
pv,pvc释放
1. 删除pvc kubectl delete pvc -n namespace_name pvc_name
我们在修改PV的容量的时候,可能会想删除掉PVC,再进行重新创建,不就可以重新绑定之前的PV了, 可事实并不会,这时候的PV会变成Released状态,而PVC只能和Available 状态的 PV 进行绑定。
这时候需要管理员对PV进行修改,删除 claimRef 对 PVC 的引用, 使PV变成Available状态
[root@k8s-master1 xmgc1]# kubectl edit -n my-ns-xmgc pv nginx-pv2
persistentvolume/nginx-pv2 edited
[root@k8s-master1 xmgc1]# kubectl get pv -n my-ns-xmgc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nginx-pv1 2Gi RWX Retain Bound my-ns-xmgc/nginxpvc1 46m
nginx-pv2 5Gi RWX Retain Available 45m
nginx-pv3 8Gi RWX Retain Released default/nginxpvc3 45m
pv,pvc通过标签来选择绑定,比如ssd,sata等不同类型的磁盘需求
创建一个标签为sata的pv,和一个标签选择器为ssd的pvc,会发现pvc一直处于pending中,不会去绑定sata的pv
[root@k8s-master1 pv]# cat nginx-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nginx-pv3
labels:
type: sata
namespace: my-ns-xmgc
spec:
capacity:
storage: 8Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: "/data/k8s/xmgc3"
server: 192.168.198.144
readOnly: false
[root@k8s-master1 pv]# cat nginx-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginxpvc3
namespace: my-ns-xmgc
labels:
type: ssd
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
selector:
matchLabels:
type: ssd