0%

k8s-数据管理

由于容器和Pod是短暂的,会被频繁销毁和创建,容器销毁时,内部的文件系统也会被清理。为了持久化保存容器的数据,可以使用Kubernates Volume

emptyDir Volume

emptyDir是Host上的一个空目录,对于容器是持久化的,对于Pod不是。emptyDir Volume的生命周期与Pod一致

适用场景:

  1. Pod中的容器需要通过文件传递数据

  2. Pod中的容器临时共享存储空间

hostPath Volume

hostPath Volume将Host文件系统中已有的目录mount给Pod的容器,这样会将Pod与节点耦合,限制了Pod的创建

适用场景:需要访问kubernetes或docker内部数据(配置文件或二进制文件)的应用

云存储

如Elastic Block Store

PV&PVC

Persistent Volume(PV)是外部存储系统中的一块空间,由管理员创建和维护。具有持久性,生命周期独立于Pod

Persistent Volume Claim(PVC)是对PV的申请,由普通账号创建和维护,需要为Pod分配存储资源时,用户创建一个PVC,指明存储资源的小大和访问权限等信息

k8s支持的PV类型有:EBS,Ceph,NFS等

Think:为什么不直接为Pod创建云存储空间,而是通过PV-PVC

NFS

NFS(network file system)通过网络,使不同的机器不同的系统实现文件共享。NFS客户端可以将NFS服务器共享的目录挂载到本地的文件系统中,访问目录如同访问本地目录一样

创建NFS服务器

在node1节点安装nfs服务

1
2
3
4
5
6
7
8
9
10
11
# 安装nfs服务组件
yum install nfs-utils -y
mkdir /home/work/nfs
cat > /etc/exports <<EOF
/home/work/nfs 192.168.174.0/24(rw,sync,no_root_squash)
EOF
systemctl start rpcbind
systemctl start nfs
cd /etc
exportfs -r
netstat -ntlp
客户端配置

搜索网络中可用的共享目录 showmount -e node1

创建本地目录并挂载共享目录

1
2
3
mkdir /home/work/mnt
mount -t nfs node1:/home/work/nfs /home/work/mnt
cd /home/work/mnt && ll

创建PV

编写配置文件 nfs-pv1.yml,手动创建PV的方式叫静态供给

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nginx-html
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nginx-html
nfs:
path: /home/work/nfs/nginx/html
server: node1
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nginx-log
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nginx-log
nfs:
path: /home/work/nfs/nginx/log
server: node1
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nginx-conf
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nginx-conf
nfs:
path: /home/work/nfs/nginx/conf
server: node1

说明:

  1. capacity指定PV容量
  2. accessModes 指定访问模式:
    1. ReadWriteOnce:可读可写,只支持被单个节点挂载
    2. ReadOnlyMany:只读,可被多个节点挂载
    3. ReadWriteMany:可读可写,被多个节点挂载
  3. persistentVolumeReclaimPolicy 指定PV的回收策略:
    1. Retain:管理员手动清理
    2. Recycle:删除数据(NFS和HostPath支持)
    3. Delete:删除存储资源(EBS等云存储支持)
  4. storageClassName 指定PV的类型为nfs
  5. nfs的path需要是nfs服务器是存在的路径

创建pv1:Kubectl apply -f nfs-pv1.yml

查看pv:kubectl get pv

创建pvc

编写配置文件 nfs-pvc1.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginx-html-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: nginx-html
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginx-conf-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: nginx-conf
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginx-log-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: nginx-log

创建pvc:kubectl apply -f nfs-pvc1.yml

查看pvc:kubectl get pvc

在Pod中使用存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
volumeMounts:
- name: nginx-log
mountPath: /var/log/nginx
- name: nginx-html
mountPath: /etc/nginx/html
- name: nginx-conf-d
mountPath: /etc/nginx/conf.d
tolerations:
- key: "key"
operator: "Equal"
value: "nginx"
effect: "NoSchedule"
volumes:
- name: nginx-log
persistentVolumeClaim:
claimName: nginx-log-pvc
- name: nginx-html
persistentVolumeClaim:
claimName: nginx-html-pvc
- name: nginx-conf-d
persistentVolumeClaim:
claimName: nginx-conf-pvc

这样,将容器内nginx的html、conf、log挂载到nfs服务器上,方便编写页面、修改配置、查看日志

Think:多个应用要挂载路径可能很多,需要创建很多的PV和PVC,管理很不方便,而且PV一般由管理员创建,PVC由开发人员创建,如果每个挂载路径都要要求管理员创建PV,效率低下,不便于管理,该如何解决

Think:在nfs中修改nginx配置文件后,需要重启Pod才可以让配置生效,如果让Pod按照顺序先后重启,而不是全部同时重启

回收PV

kubectl delete pvc {pvc_name}

PV 动态供给

静态供给的缺点有:

  1. 需要提前创建PV,还需要在nfs等共享存储上提前创建目录,管理员的工作增加,效率低;
  2. 维护成本高

为了解决上面的问题,使用动态共给

https://kubernetes.io/docs/concepts/storage/storage-classes/#nfs

安装动态pv

使用helm安装nfs-client-provisioner:helm install nfs-client-provisioner stable/nfs-client-provisioner --set nfs.server=node1 --set nfs.path=/home/work/nfs --set storageClass.defaultClass=true --set image.repository=rkevin/nfs-subdir-external-provisioner --set image.tag=fix-k8s-1.20

验证
1
2
3
4
5
6
7
8
9
10
11
12
13
cat > test-pvc.yaml << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-nfs-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client
resources:
requests:
storage: 1Gi
EOF
image-20220417035033623
image-20220417035117442
image-20220417035331218

无需手动创建pv

存在问题

  1. 为什么不直接为Pod创建云存储空间,而是通过PV-PVC(创建的云存储空间是一次性创建很大一块空间,应用是很多的,每个应用都挂载到一个独立的云存储空间不利于管理和维护,容易造成空间的浪费)
  2. 挂载路径太多,PV&PVC不便于管理,如何解决(答案:PV的动态供给)
  3. 重启nginx服务,如何不全部同时重启,防止服务不可用