修复使用 K8S 部署 PostgreSQL 时每次重启后数据丢失的问题
本来挂载的卷是配置到 data 目录的:
yaml
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: data
1
2
3
2
3
但是启动时报了如下错误:
initdb: error: directory "/var/lib/postgresql/data" exists but is not empty
It contains a lost+found directory, perhaps due to it being a mount point.
Using a mount point directly as the data directory is not recommended.
Create a subdirectory under the mount point.
使用 PVC 创建的卷默认会有一个 lost+found 目录,所以导致了这个错误,于是将挂载目录改成 data 目录的上一级目录。
yaml
volumeMounts:
- mountPath: /var/lib/postgresql
name: data
1
2
3
2
3
之后就可以正常启动了,但后来发现容器重启后所有的表和数据都没了。
在这篇博客上说是必须将卷挂载到 data 目录。
这里要注意的是一定要映射到容器中的
/var/lib/postgresql/data
文件夹,而不是/var/lib/postgresql
为了解决 data 目录不为空的启动异常,在部署的清单文件上添加了 initContainers 配置:
yaml
initContainers:
- command:
- rm
- -fr
- /var/lib/postgresql/data/lost+found
image: busybox:1.32
imagePullPolicy: IfNotPresent
name: remove-lost-found
resources:
requests:
cpu: 10m
memory: 10Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: data
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
这里使用了 busybox 工具,在 container 创建时删除这个 lost+found 目录,这样初始化数据库时就不会报错了。
记录下完整的清单文件,以供今后参考:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: jiajia-postgres-deploy
namespace: jiajia-test
spec:
replicas: 1
revisionHistoryLimit: 3
selector:
matchLabels:
app: jiajia-postgres
template:
metadata:
labels:
app: jiajia-postgres
spec:
containers:
- env:
- name: POSTGRES_DB
value: jiajia
- name: POSTGRES_USER
value: jiajia
- name: POSTGRES_PASSWORD
value: aPassword
- name: TZ
value: Asia/Shanghai
image: postgres:13.4
imagePullPolicy: Always
name: jiajia-postgres
ports:
- containerPort: 5432
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: data
initContainers:
- command:
- rm
- -fr
- /var/lib/postgresql/data/lost+found
image: busybox:14.3
imagePullPolicy: IfNotPresent
name: remove-lost-found
resources:
requests:
cpu: 10m
memory: 10Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: data
imagePullSecrets:
- name: jiajia-artifacts
volumes:
- name: data
persistentVolumeClaim:
claimName: pvc-jiajia-postgres
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
45
46
47
48
49
50
51
52
53
54
55
56
57
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
45
46
47
48
49
50
51
52
53
54
55
56
57