Kubernetes 使用 NFS 部署应用

在分布式系统中,经常需要跨机器存取数据,用 NFS(Network File System)做数据持久化,可以很方便地在节点间共享存储资源,本文介绍如何在 Kubernetes 中使用 NFS 作存储后端。

安装 NFS

NFS 安装很简单,以我使用的 Alpine Linux 为例,安装 nfs 工具包:

1
apk add nfs-utils

创建一个 nfs 服务端目录,然后配置服务

1
2
3
4
5
6
7
8
9
10
mkdir /nfs
# 增加读写权限
chmod a+rw -R /nfs
# 配置 NFS 服务
echo '/nfs *(rw,sync,no_root_squash)' >> /etc/exports

# 启动NFS
service nfs start
# 开机自动启动
rc-update add nfs boot

测试 NFS

创建一个测试目录,并尝试挂载

1
2
3
4
# 测试目录
mkdir test
# 挂载NFS目录
mount 192.168.199.24:/nfs test

查看挂载信息

1
2
3
4
5
6
7
8
$ df -h
Filesystem Size Used Available Use% Mounted on
devtmpfs 10.0M 0 10.0M 0% /dev
shm 1.9G 0 1.9G 0% /dev/shm
/dev/sda3 5.8G 120.5M 5.4G 2% /
tmpfs 394.8M 132.0K 394.6M 0% /run
/dev/sda1 92.8M 13.3M 72.5M 15% /boot
192.168.199.24:/nfs 5.8G 120.5M 5.4G 2% /root/test

可以看到已经把 NFS 服务挂载到 test 目录下

在 Kubernetes 中使用 NFS 服务

在 Kubernetes 中,存储资源的生产者和消费者被抽象为 PersistentVolume 和 PersistentVolumeClaim 两个对象,通过这两个 API 实现应用数据持久化。

创建一个 PersistentVolume,挂载 NFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-pv
labels:
type: NFS
spec:
capacity:
storage: 1Gi
storageClassName: standard
persistentVolumeReclaimPolicy: Recycle
accessModes:
- ReadWriteMany
nfs:
# nfs服务端地址
server: 192.168.199.24
# 服务端目录
path: /nfs/postgre

部署 PostgreSQL

使用刚才创建的 NFS 服务,在 Kubernetes 集群中部署 PostgreSQL。

创建 statefulset 和 service,完整代码见:https://github.com/yunTerry/K8s-Postgre

1
2
3
4
5
6
7
8
9

# 创建PersistentVolume
kubectl apply -f pg-volume.yml

# 部署PostgreSQL
kubectl apply -f pg-statefulset.yml

# 创建service
kubectl apply -f pg-service.yml

在 DashBoard 中查看应用部署情况

可以看到已经启动了两个 PostgreSQL 实例,它们共用 NFS 服务。

服务发现

Service 是对一组 pod 实例的抽象,方便做服务发现和负载均衡。默认情况下,服务是以 ClusterIP 形式运行在集群内部的,如果想要从外部访问,可以通过 Ingress、LoadBalancer 或 NodePort 将服务暴露出来。

但通常并不需要把服务暴露出去,比如数据库这种让它待在 K8s 集群内就好了,借助 kube-dns 强大的服务发现能力,集群内应用可以通过服务名直接连接,这就类似于我们在 Spring Cloud 中用 Eureka 做服务注册发现,不过用 kube-dns 的方式更方便。

此外,在 Docker compose 中也提供了类似的服务发现能力,具体可以参考之前的代码:
https://github.com/yunTerry/Spring-Cloud-Docker

Kubernetes 就像一个王国,通过强大的服务发现能力,各种应用可以在这个王国里自由交流,但又与世隔绝,不受外界干扰,必要时也可以开个小门(Ingress),而且这个王国还可以随意拓展疆土(kubeadm join)。

本文源码

https://github.com/yunTerry/K8s-Postgre