StatefulSet & 数据持久化

本文目录结构

设置有状态服务(StatefulSet)

创建有状态的Pod,执行”kubectl apply -f mongo.yaml“。

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
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
serviceName: mongodb
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
selector:
app: mongodb
type: ClusterIP
# HeadLess
clusterIP: None
ports:
- port: 27017
targetPort: 27017

以上mongo.yaml包涵了创建StatefulSet特性的pod和Service,关于StatefulSet特性:

  • Service 的 CLUSTER-IP 是空的,Pod 名字也是固定的。
  • Pod 创建和销毁是有序的,创建是顺序的,销毁是逆序的。
  • Pod 重建不会改变名字,除了IP,所以不要用IP直连

查看创建的pods。

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
kubectl get endpoints mongodb -o yaml
apiVersion: v1
kind: Endpoints
metadata:
annotations:
endpoints.kubernetes.io/last-change-trigger-time: "2023-10-18T09:13:07Z"
creationTimestamp: "2023-10-18T09:13:07Z"
labels:
service.kubernetes.io/headless: ""
name: mongodb
namespace: default
resourceVersion: "218593"
selfLink: /api/v1/namespaces/default/endpoints/mongodb
uid: 448feace-dbd8-4c94-b878-688566266bcb
subsets:
- addresses:
- hostname: mongodb-0
ip: 172.17.0.14
nodeName: vm-1-127-centos
targetRef:
kind: Pod
name: mongodb-0
namespace: default
resourceVersion: "212661"
uid: a265b68e-1aaf-409a-b84e-2f2851061314
- hostname: mongodb-1
ip: 172.17.0.15
nodeName: vm-1-127-centos
targetRef:
kind: Pod
name: mongodb-1
namespace: default
resourceVersion: "212671"
uid: 578c3937-6c06-4ef3-bcda-8bd5f594607d
- hostname: mongodb-2
ip: 172.17.0.16
nodeName: vm-1-127-centos
targetRef:
kind: Pod
name: mongodb-2
namespace: default
resourceVersion: "212685"

这时可以连接到mongodb上进行写入数据测试。

1
kubectl run mongodb-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mongodb:4.4.10-debian-10-r20 --command -- bash

pod内部使用hostnmae进行链接,可以使用mongodb-0.mongodb,这格式为hostname.servicesName。连接上执行以下MongoDB测试语句。

1
2
3
4
5
6
7
8
9
10
show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
> use test
switched to db test
> db.users.save({'_id':'1','name':'djangowang'})
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "1" })
> db.users.find()
> { "_id" : "1", "name" : "djangowang" }

不过这里带来的问题是,当Pod重启时内部数据会丢失,需要做数据持久化。

数据持久化

数据持久化,将容器中的Mongodb挂载到母机上,编写storage.yaml。

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
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
serviceName: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /data/db # 容器里面的挂载路径
name: mongo-data # 卷名字,必须跟下面定义的名字一致
volumes:
- name: mongo-data # 卷名字
hostPath:
path: /data/mongo-data # 节点上的路径
type: DirectoryOrCreate # 指向一个目录,不存在时自动创建

以上会把容器里路径/data/db ,挂载到节点的/data/mongo-data目录下,我们可以进入容器,在/data/db目录下创建一个文件来验证挂载后的效果。

1
2
kubectl exec -it mongodb-0 -- bash
touch /data/db/test