我正在尝试在 Azure Kubernetes 上部署 Postgresql 并实现数据持久性。所以我用的是PVC。 我在这里搜索了很多帖子,其中大多数都提供了如下所示的 yaml 文件,但它给出了以下错误;
chmod: changing permissions of '/var/lib/postgresql/data/pgdata': Operation not permitted
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.utf8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".
Data page checksums are disabled.
initdb: error: could not change permissions of directory "/var/lib/postgresql/data/pgdata": Operation not permitted
fixing permissions on existing directory /var/lib/postgresql/data/pgdata ...
部署yaml文件如下;
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgresql
spec:
replicas: 1
selector:
matchLabels:
app: postgresql
template:
metadata:
labels:
app: postgresql
spec:
containers:
- name: postgresql
image: postgres:13.2
securityContext:
runAsUser: 999
imagePullPolicy: "IfNotPresent"
ports:
- containerPort: 5432
envFrom:
- secretRef:
name: postgresql-secret
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgredb-kap
volumes:
- name: postgredb-kap
persistentVolumeClaim:
claimName: postgresql-pvc
秘密yaml如下;
apiVersion: v1
kind: Secret
metadata:
name: postgresql-secret
type: Opaque
data:
POSTGRES_DB: a2V5sd4=
POSTGRES_USER: cG9zdGdyZXNhZG1pbg==
POSTGRES_PASSWORD: c234Rw==
PGDATA: L3Za234dGF0YQ==
pvc 和 sc yaml 文件如下:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: postgresql-pvc
labels:
app: postgresql
spec:
storageClassName: postgresql-sc
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
---
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: postgresql-sc
mountOptions:
- dir_mode=0777
- file_mode=0777
- uid=1000
- gid=1000
parameters:
skuName: Standard_LRS
provisioner: kubernetes.io/azure-file
reclaimPolicy: Retain
因此,当我使用“- mountPath:/var/lib/postgresql/”之类的安装路径时,它正在工作。我可以到达数据库,这很好。但是当我删除 pod 并重新创建时,没有数据库!所以没有数据持久性。
你能帮忙吗,我在这里缺少什么?
谢谢!
您可以尝试的一件事是将挂载选项中的
uid=1000,gid=1000
更改为999,因为这是postgres容器中postgres用户的uid(我没有测试这一点)。
另一个可以肯定解决此问题的解决方案涉及 init 容器。
Postgres 容器需要以 root 身份启动才能访问
chown
pgdata 目录,因为它是作为 root 目录安装的。执行此操作后,它会删除 root 权限并以 postgres 用户身份运行。
但是您可以使用 init 容器(以 root 身份运行)来 chmod 卷目录,以便您可以以非 root 身份运行主容器。
这是一个例子:
initContainers:
- name: init
image: alpine
command: ["sh", "-c", "chown 999:999 /var/lib/postgresql/data"]
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgredb-kap
基于马特的有用回答。对于 bitnami postgresql,initContainer 也可以工作,但配置略有不同:
initContainers:
- name: init
image: alpine
command: ["sh", "-c", "chown 1001:1001 /bitnami/postgresql"]
volumeMounts:
- mountPath: /bitnami/postgresql
name: postgres-volume
正如 @zingi 在评论中指出的那样,您可以创建一个使用 nfs 的存储类,提供完整的 POSIX 文件系统支持,如 Microsoft 文档 中所述。 这就是存储类定义:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azurefile-csi-nfs
provisioner: file.csi.azure.com
allowVolumeExpansion: true
parameters:
protocol: nfs
mountOptions:
- nconnect=4
- noresvport
- actimeo=30
只需将 PVC 上的
spec.storageClassName
指向它即可。
我还将容器的环境变量PGDATA
设置为/var/lib/postgresql/data/pgdata
,以避免 postgres 容器上的初始化例程尝试更改挂载点的权限,这在图像文档中进行了解释。