GKE部署PostgreSQL遭遇CrashLoopBackOff错误求助
问题现象
在GKE中部署PostgreSQL StatefulSet后,Pod持续处于CrashLoopBackOff状态,查看Pod日志得到关键报错:
initdb: error: directory "/var/lib/postgresql/data" exists but is not empty
initdb: detail: It contains a lost+found directory, perhaps due to it being a mount point.
initdb: hint: Using a mount point directly as the data directory is not recommended.
Create a subdirectory under the mount point.
问题原因
GKE通过pd.csi.storage.gke.io提供的PersistentVolume挂载后,根目录会自动生成lost+found系统目录,而PostgreSQL的initdb初始化工具要求数据目录必须为空,因此触发初始化失败,导致容器反复重启。
解决方案
方法1:通过环境变量指定子目录(推荐)
修改StatefulSet的容器配置,保留PVC挂载路径不变,新增PGDATA环境变量指定PostgreSQL实际使用的子目录,避开根目录的lost+found:
apiVersion: apps/v1 kind: StatefulSet metadata: name: imgress-db namespace: db spec: serviceName: imgress-db replicas: 1 selector: matchLabels: app: imgress-db template: metadata: labels: app: imgress-db spec: containers: - name: imgress-db image: postgres env: # 新增PGDATA,指定子目录作为PostgreSQL数据存储路径 - name: PGDATA value: /var/lib/postgresql/data/pgdata - name: POSTGRES_HOST valueFrom: configMapKeyRef: name: db-configmap key: DATABASE_HOST - name: POSTGRES_DB valueFrom: configMapKeyRef: name: db-configmap key: POSTGRES_DB - name: POSTGRES_USER valueFrom: configMapKeyRef: name: db-configmap key: POSTGRES_USER - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: db-secret key: POSTGRES_PASSWORD ports: - containerPort: 5432 volumeMounts: - name: postgres-data mountPath: /var/lib/postgresql/data volumes: - name: postgres-data persistentVolumeClaim: claimName: postgres-pvc restartPolicy: Always
方法2:清理PVC数据(仅适用于全新部署)
如果PVC中无需要保留的数据,可删除现有PVC和关联PV后重新创建:
# 删除StatefulSet kubectl delete statefulset imgress-db -n db # 删除PVC kubectl delete pvc postgres-pvc -n db # 重新部署资源 kubectl apply -f postgres-pvc.yaml kubectl apply -f postgres-deployment.yaml
注意:此操作会清除所有存储数据,请勿在生产环境使用。
验证修复
修改配置后重新部署,检查Pod状态:
kubectl get pods -n db
当Pod状态变为Running且READY列显示1/1时,说明问题已解决。
内容的提问来源于stack exchange,提问作者Eziz Durdyyev

