在生产环境使用 Kubernetes ,绕不过去的一个问题就是持久化卷。
如果是使用阿里 ACK 托管平台的话,可以用 OSS 来持久化卷,如果是自搭的 kubernetes,那么存储就需要仔细考虑了。
ceph比较复杂,容易出故障。nfs 也不可用,毛病多多。minio倒是可以。
这种情况下使用双副本的 GlusterFS 就是不错的选择。
生产环境就不能随意了,最好不要使用 Heketi,因为凡是要持久化的东西,都是比较重要的东西,最好都有 yaml 记录。
GlusterFS 的搭建就不说了。说说实际使用过程:
一、装GFS,生产新卷
安装就不说了,我们的GFS有两个节点,172.19.20.18 和 172.19.20.36,我们强制建立一个两副本的卷: kuaijian-vol
1gluster volume create kuaijian-vol replica 2 transport tcp 172.19.20.18:/glusterfs/kuaijian-vol 172.19.20.36:/glusterfs/kuaijian-vol force
二、为k8s产生GFS的endingpoint和service
1cat << EOF >> ep-svc.yaml
2---
3apiVersion: v1
4kind: Service
5metadata:
6 name: gfs-cluster_svc
7spec:
8 ports:
9 - port: 1
10---
11apiVersion: v1
12kind: Endpoints
13metadata:
14 name: gfs-cluster_svc
15subsets:
16 - addresses:
17 - ip: 172.19.20.18
18 ports:
19 - port: 1
20 - addresses:
21 - ip: 172.19.20.36
22 ports:
23 - port: 1
24EOF
25
26kubectl apply -f ep-svc.yaml
这里要提一个概念,通常情况下 service 是通过 selector 标签来选择对应的 pod 来增加 endingpoint 的。如下:
1apiVersion: v1
2kind: Service
3metadata:
4 name: go-api_svc
5spec:
6 ports:
7 - port: 8080
8 protocol: TCP
9 targetPort: 8080
10 selector:
11 app: go-api
12 type: ClusterIP
而上面,我们没有通过标签,而是让 endingpoint 和 svc 同名而手动增加 endingpoint 到 svc 的。
三、为k8s生产创建 PV和PVC
静态环境不使用 Storageclass 持久化卷的图解如下,pod做pvc声明,pvc连接到pv,pv从GFS中拿到卷。
首先声明一个 pv:
1cat << EOF >> kuaijian-pv.yaml
2apiVersion: v1
3kind: PersistentVolume
4metadata:
5 name: gfs-kuaijian-50G_pv
6 labels:
7 name: gfs-kuaijian-50G_pv
8spec:
9 capacity:
10 storage: 50Gi
11 accessModes:
12 - ReadWriteMany
13 glusterfs:
14 endpoints: gfs-cluster_svc
15 path: kuaijian-vol
16 readOnly: false
17 persistentVolumeReclaimPolicy: Retain
18EOF
19
20kubectl apply -f kuaijian-pv.yaml
然后声明一个 pvc 通过 matchLabels 来跟之前的 pv 绑定。
1cat << EOF >> kuaijian-pvc.yaml
2kind: PersistentVolumeClaim
3apiVersion: v1
4metadata:
5 name: gfs-kuaijian-50G_pvc
6spec:
7 accessModes:
8 - ReadWriteMany
9 resources:
10 requests:
11 storage: 50Gi
12 selector:
13 matchLabels:
14 name: gfs-kuaijian-50G_pv
15EOF
16
17kubectl apply -f kuaijian-pvc.yaml
注意上面的 pvc,我们一下子申请了50G,把整个 pv 空间全用光了;当然我们也可以只申请个 10Gi,下个 pvc 再 10Gi,这样也是行的通的。
四、POD使用PVC
声明一个 Nginx 的 Deployment 来使用这个 pvc
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: nginx-deployment
5 labels:
6 app: nginx
7spec:
8 replicas: 2
9 selector:
10 matchLabels:
11 app: nginx
12 template:
13 metadata:
14 labels:
15 app: nginx
16 spec:
17 containers:
18 - name: nginx
19 image: nginx
20 ports:
21 - containerPort: 80
22 volumeMounts:
23 - name: data-www
24 mountPath: /data/www
25 volumes:
26 - name: data-www
27 persistentVolumeClaim:
28 claimName: gfs-kuaijian-50G_pvc
这样 kubernetes 的存储部分就搞定了。GFS 用于生产非常稳定,基本跑了 7 年了没有大毛病。