0%

我们可以通过hostPath或者emptyDir的方式来持久化数据。但这两种存储方式都是很大局限性的。我们希望容器在重建以后,依然能正确使用之前保存的数据。Kubernetes引入了PV和PVC两个重要的资源来实现对存储的管理。

PV

PersistentVolume,持久化卷,是对底层共享存储的一种抽象。底层共享的实现,可以是Ceph, GlusterFS, NFS等。

我们在CentOS上搭建NFS服务讲了如何搭建NFS服务。PV作为存储资源,主要包括存储能力、访问模式、存储类型、回收策略等关键信息。

现在新建一个PV资源对象,使用NFS类型的存储,1G空间,访问模式为ReadWriteOnce,回收策略为Recycle,yaml文件pv1-demo.yaml内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /data/nfs
server: 172.16.64.233

应用一下

1
2
# kubectl apply -f pv1-demo.yaml
persistentvolume/pv1 created

查看刚才创建的结果

1
2
3
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv1 1Gi RWO Recycle Available 82s

Status状态为Available,表示pv1已经就绪,可以被PVC申请了。

这里讲一下PV的几个属性

STATUS

一个 PV 的生命周期中,可能会处于4中不同的阶段:

  • Available(可用):表示可用状态,还未被任何 PVC 绑定
  • Bound(已绑定):表示 PVC 已经被 PVC 绑定
  • Released(已释放):PVC 被删除,但是资源还未被集群重新声明
  • Failed(失败): 表示该 PV 的自动回收失败

CAPACITY

目前只有空间大小,pv1的空间为1G,以后可能会加入IOPS,吞吐量等指标。

ACCESS MODES

AccessModes是用来对PV进行访问模式的设置。

  • ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
  • ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
  • ReadWriteMany(RWX):读写权限,可以被多个节点挂载

RECLAIM POLICY

回收策略

  • Retain(保留)- 保留数据,需要管理员手工清理数据
  • Recycle(回收)- 清除PV中的数据,效果相当于执行 rm -rf /thevoluem/*
  • Delete(删除)- 与PV相连的后端存储完成volume的删除操作

生产上一般使用Retain策略。

PVC

PersistentVolumeClaim,持久化卷声明。如果说Pod消耗的是Node资源的话,PVC则是消耗的PV资源,Pod可以请求CPU和内存,而PVC可以请求特定的存储空间和访问模式。

我们新建一个PVC,请求1G的空间,pvc-nfs.yaml内容如下:

1
2
3
4
5
6
7
8
9
10
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-nfs
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

这里需要注册的是,PV是没有namespace的,而PVC是有namespace的。

1
2
3
4
5
# kubectl apply -f pvc-nfs.yaml
persistentvolumeclaim/pvc-nfs created
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-nfs Bound pv1 1Gi RWO 3m22s

PVC已经是Bound状态了。我们再查看一个PV的状态,发现也是Bound状态了。对应的声明是default/pvc-nfs,就是default命名空间下面的pvc-nfs

1
2
3
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv1 1Gi RWO Recycle Bound default/pvc-nfs 48m

这里可能觉得奇怪,我们并没有在 yaml 文件里面指定 PVC 和 PV 的关系,他们怎么可能绑定到一起呢?其实这是系统自动帮我们去匹配的,他会根据我们的声明要求去查找处于 Available 状态的 PV,如果没有找到的话那么我们的 PVC 就会一直处于 Pending 状态,找到了的话当然就会把当前的 PVC 和目标 PV 进行绑定,这个时候状态就会变成 Bound 状态了。

如果使用PVC,可以参考Grafana安装及持久化

为了配合设置k8s的存储,这篇文章讲解一下如何搭建NFS服务。

为了测试,我们暂时在k8s-master节点(172.16.64.233/24)来安装NFS服务,数据共享目录设置为/data/nfs

关闭防火墙

k8s集群其实都已经关了的,如果在其他机器上,先关掉。

1
2
# systemctl stop firewalld
# systemctl disable firewalld

安装NFS

通过yum安装nfs-utils,这个组件会依赖rpcbind,也会自动被安装上。

1
# yum install nfs-utils

设置共享目录权限

1
# chmod 755 /data/nfs/

配置NFS

NFS的默认配置文件在/etc/exports文件里,在该文件中添加如下内容:

1
2
# vi /etc/exports
/data/nfs *(rw,sync,no_root_squash)
  • /data/nfs:是共享的数据目录

  • *:表示任何人都有权限连接,当然也可以是一个网段,一个IP,也可以是域名
    rw:读写的权限
    sync:表示文件同时写入硬盘和内存
    no_root_squash:当登录NFS主机使用共享目录的使用者是root时,其权限将被转换成为匿名使用者,通常它的UID与GID,都会变成nobody身份

启动NFS

注意启动顺序,先启动rpcbind

启动服务 nfs 需要向 rpc 注册,rpc 一旦重启了,注册的文件都会丢失,向他注册的服务都需要重启。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# systemctl enable rpcbind
# systemctl start rpcbind
# systemctl status rpcbind
● rpcbind.service - RPC bind service
Loaded: loaded (/usr/lib/systemd/system/rpcbind.service; enabled; vendor preset: enabled)
Active: active (running) since 日 2020-03-08 13:24:03 CST; 5s ago
Process: 114504 ExecStart=/sbin/rpcbind -w $RPCBIND_ARGS (code=exited, status=0/SUCCESS)
Main PID: 114505 (rpcbind)
Tasks: 1
Memory: 748.0K
CGroup: /system.slice/rpcbind.service
└─114505 /sbin/rpcbind -w

3月 08 13:24:03 k8s-master systemd[1]: Starting RPC bind service...
3月 08 13:24:03 k8s-master systemd[1]: Started RPC bind service.

RPC bind服务Started说明RPC启动成功。

然后启动NFS服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# systemctl enable nfs
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.
# systemctl start nfs
# systemctl status nfs
● nfs-server.service - NFS server and services
Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; enabled; vendor preset: disabled)
Drop-In: /run/systemd/generator/nfs-server.service.d
└─order-with-mounts.conf
Active: active (exited) since 日 2020-03-08 13:25:57 CST; 6s ago
Process: 116906 ExecStartPost=/bin/sh -c if systemctl -q is-active gssproxy; then systemctl reload gssproxy ; fi (code=exited, status=0/SUCCESS)
Process: 116889 ExecStart=/usr/sbin/rpc.nfsd $RPCNFSDARGS (code=exited, status=0/SUCCESS)
Process: 116887 ExecStartPre=/usr/sbin/exportfs -r (code=exited, status=0/SUCCESS)
Main PID: 116889 (code=exited, status=0/SUCCESS)
Tasks: 0
Memory: 0B
CGroup: /system.slice/nfs-server.service

3月 08 13:25:57 k8s-master systemd[1]: Starting NFS server and services...
3月 08 13:25:57 k8s-master systemd[1]: Started NFS server and services.

NFS server成功启动。

我们还可以通过下面的命令确认NFS服务启动成功。

1
2
3
4
5
6
7
# rpcinfo -p | grep nfs
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100227 3 tcp 2049 nfs_acl
100003 3 udp 2049 nfs
100003 4 udp 2049 nfs
100227 3 udp 2049 nfs_acl

查看具体的挂载权限:

1
2
# cat /var/lib/nfs/etab
/data/nfs *(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,secure,no_root_squash,no_all_squash)

查看共享目录

在其他机器上,可以检查NFS是否有共享目录

1
2
3
showmount -e 172.16.64.233
Exports list on 172.16.64.233:
/data/nfs *

我们常常会遇到如下情况,把日期转换成timestamp,或者把timestamp转换成日期格式。

初级选手一般都会打开网页,有些站点提供了日期转换的功能。

高级选手可以直接通过shell命令,就能成功的完成日期和timestamp的转换。

我们先来看看Linux的date命令。

  • 显示日期时间
1
2
# date
Wed Mar 4 11:44:05 CST 2020
  • 显示带时区的日期时间
1
2
# date -R
Wed, 04 Mar 2020 11:44:41 +0800
  • 按指定格式显示日期时间
1
2
# date '+%Y-%m-%d %H:%M:%S %Z'
2020-03-04 11:46:14 CST
  • 查看当前时间的timestamp
1
2
# date +%s
1583293699
  • 显示描述类型的日期时间
1
2
# date -d "1970-01-01 UTC"
Thu Jan 1 08:00:00 CST 1970

-d的参数是指:-d, --date=STRING display time described by STRING, not 'now'

  • 日期时间转timestamp
1
2
# date -d '1970-01-01 UTC' +%s
0
  • timestamp转日期时间
1
2
# date -d @1583395499.709
Thu Mar 5 16:04:59 CST 2020