PostgreSQL作为一款高性能、开源的关系型数据库,在云原生场景中,常需与轻量级Kubernetes发行版K3s结合部署,以实现资源高效利用与灵活运维。本文将详细拆解基于K3s部署PostgreSQL的完整流程,涵盖存储配置、配置管理、服务暴露及部署编排等核心环节,助力开发者快速完成部署落地。
一、环境准备 部署前需确保K3s集群已正常运行,且kubectl工具已完成集群连接配置(可通过kubectl get nodes命令验证集群状态)。本文所有资源配置均部署在独立的postgres命名空间下,避免与其他应用资源冲突,需先执行以下命令创建该命名空间:
1 kubectl create namespace postgres
二、存储配置:PersistentVolume与PersistentVolumeClaim PostgreSQL作为有状态应用,数据持久化是核心需求。本文提供两种存储配置方案,可根据集群规模(单节点/多节点)及实际存储需求灵活选择。
方案1:基于local-path存储类(单节点场景) local-path是K3s默认集成的存储类,适用于单节点K3s集群,无需手动创建PersistentVolume(PV),仅需定义PersistentVolumeClaim(PVC),系统会自动创建PV并完成绑定。创建postgres-pvc-local-path.yaml配置文件,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres-pvc namespace: postgres labels: app: postgres spec: accessModes: - ReadWriteOnce storageClassName: local-path resources: requests: storage: 10Gi
该配置声明了10Gi的存储资源请求,访问模式为ReadWriteOnce(仅允许单个节点读写),完全适配单节点K3s的部署场景,配置简洁且无需额外运维。
方案2:基于hostPath的自定义存储类(多节点/自定义路径场景) 若需自定义存储路径,或集群为多节点架构,可手动创建PV并绑定PVC,实现更灵活的存储管理。创建postgres-pvc-host-path.yaml文件,包含PV与PVC的完整定义(修正原文中storge的拼写错误为storage):
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 apiVersion: v1 kind: PersistentVolume metadata: name: postgres-pv namespace: postgres labels: app: postgres spec: storageClassName: postgres-persistent-storage capacity: storage: 5Gi accessModes: - ReadWriteMany hostPath: path: /mnt/postgres/data --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres-pvc labels: app: postgres spec: storageClassName: postgres-persistent-storage accessModes: - ReadWriteMany resources: requests: storage: 5Gi
需提前在集群节点上创建/mnt/postgres/data目录,并确保目录权限正确(建议设置为777或匹配Pod运行用户权限);访问模式ReadWriteMany支持多节点读写,可满足多节点K3s集群的部署需求。
执行以下命令创建对应存储资源:
1 2 3 4 kubectl apply -f postgres-pvc-local-path.yaml kubectl apply -f postgres-pvc-host-path.yaml
三、配置管理:ConfigMap定义环境变量 PostgreSQL的核心初始化配置(如默认数据库名、管理员用户名、密码)可通过ConfigMap统一管理,便于后续配置修改与维护,无需重新构建镜像或重启Pod。创建postgres-config.yaml配置文件:
1 2 3 4 5 6 7 8 9 10 11 apiVersion: v1 kind: ConfigMap metadata: name: postgres-config namespace: postgres labels: app: postgres data: POSTGRES_DB: postgres POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres
本文为简化部署流程,使用ConfigMap存储密码;实际生产环境中,建议使用Secret存储敏感信息(如数据库密码),提升配置安全性。
执行以下命令创建ConfigMap资源:
1 kubectl apply -f postgres-config.yaml
四、服务暴露:Service与IngressRouteTCP 为实现PostgreSQL的可访问性,需根据访问场景(集群内/集群外)配置对应的服务暴露方式。K3s默认集成Traefik作为Ingress控制器,可通过Service实现集群内访问,通过IngressRouteTCP实现集群外访问。
1. ClusterIP类型Service(集群内访问) 创建postgres-service.yaml文件,定义ClusterIP类型的Service,监听PostgreSQL默认端口5432,实现集群内Pod间的访问:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 apiVersion: v1 kind: Service metadata: name: postgres namespace: postgres labels: app: postgres spec: ports: - port: 5432 targetPort: 5432 protocol: TCP selector: app: postgres type: ClusterIP
ClusterIP类型Service仅允许集群内Pod访问,集群内其他应用可通过服务域名postgres.postgres.svc.cluster.local:5432连接PostgreSQL数据库。
2. IngressRouteTCP(集群外访问) 若需从集群外访问PostgreSQL,可通过Traefik的IngressRouteTCP暴露TCP端口。创建postgres-ingress.yaml文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: postgres-tcp namespace: postgres labels: app: postgres spec: entryPoints: - postgres routes: - match: HostSNI(`*`) services: - name: postgres port: 5432
需先在Traefik控制器中配置postgres入口点(entryPoints),指定监听的主机端口(建议与PostgreSQL默认端口5432保持一致),否则IngressRouteTCP配置无法生效。
执行以下命令创建服务相关资源:
1 2 kubectl apply -f postgres-service.yaml kubectl apply -f postgres-ingress.yaml
五、部署编排:StatefulSet部署PostgreSQL PostgreSQL作为有状态应用,推荐使用StatefulSet而非Deployment部署,可确保Pod拥有稳定的网络标识和持久化存储,避免因Pod重启导致数据丢失或网络地址变更。创建postgres-statefulset.yaml文件(修正原文“deployment.yaml”命名偏差,贴合StatefulSet资源类型):
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 apiVersion: apps/v1 kind: StatefulSet metadata: name: postgres namespace: postgres labels: app: postgres spec: selector: matchLabels: app: postgres replicas: 1 template: metadata: labels: app: postgres spec: containers: - name: postgres image: postgres:16.3 imagePullPolicy: IfNotPresent ports: - containerPort: 5432 envFrom: - configMapRef: name: postgres-config volumeMounts: - name: postgredb mountPath: /var/lib/postgresql/data volumes: - name: postgredb persistentVolumeClaim: claimName: postgres-pvc
使用postgres:16.3稳定版本镜像,通过envFrom批量加载ConfigMap中的环境变量,将PVC挂载到PostgreSQL的数据存储目录/var/lib/postgresql/data,确保数据持久化;镜像拉取策略设为IfNotPresent,避免重复拉取镜像,提升部署效率。
执行以下命令部署PostgreSQL:
1 kubectl apply -f postgres-statefulset.yaml
六、验证部署结果 部署完成后,需通过一系列命令验证各资源状态,确保PostgreSQL正常运行。
检查PVC绑定状态:
1 kubectl get pvc -n postgres
正常情况下,PVC的STATUS列显示为Bound,表示存储绑定成功。
检查StatefulSet与Pod运行状态:
1 2 kubectl get statefulset -n postgres kubectl get pods -n postgres
确保StatefulSet的READY列显示为1/1(副本数为1时),Pod的STATUS列显示为Running,无异常重启记录。
测试数据库连接:
1 2 3 4 kubectl exec -it postgres-0 -n postgres -- bash psql -U postgres -d postgres
若能成功进入PostgreSQL命令行界面(显示postgres=#提示符),说明PostgreSQL部署成功且可正常使用。
总结 本文基于K3s原生资源(PVC/PV、ConfigMap、Service、StatefulSet),完成了PostgreSQL的全流程部署,覆盖了存储配置、配置管理、服务暴露、部署编排及结果验证等核心环节,流程清晰、可操作性强。在实际生产环境中,可根据业务需求灵活调整:如增加副本数实现高可用、使用Secret管理敏感信息、优化Ingress配置实现访问控制等,进一步提升部署的安全性与稳定性。