You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过LoadBalancer暴露PostgreSQL Pod并修复Service配置问题

问题描述
  • 集群环境:裸金属服务器搭建的Kubernetes集群,包含1个master节点和2个worker节点
  • 已部署资源:3副本的PostgreSQL Deployment,MetalLB Layer2负载均衡(已成功暴露Nginx服务,运行正常)
  • 当前状态:3个PostgreSQL Pod均处于Running状态
  • 故障现象:尝试通过LoadBalancer暴露PostgreSQL服务时无法连接,两种方式均失败:
    1. 执行命令:kubectl expose deploy postgres --port 30432 --type LoadBalancer
    2. 使用自定义Service YAML文件(存在配置错误)

原PostgreSQL Deployment配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  selector:
   matchLabels:
    app: postgres
  replicas: 3
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:latest
          imagePullPolicy: "IfNotPresent"
          envFrom:
            - configMapRef:
                name: postgres-config
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: postgredb
      volumes:
        - name: postgredb
          persistentVolumeClaim:
            claimName: postgres-pv-claim
---
kind: PersistentVolume
apiVersion: v1
metadata:
  name: postgres-pv-volume
  labels:
    type: local
    app: postgres
spec:
  storageClassName: standard
  capacity:
    storage: 15Gi
  accessModes:
    - ReadWriteMany
  hostPath:
    path: "/mnt/data"
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: postgres-pv-claim
  labels:
    app: postgres
spec:
  storageClassName: standard
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 15Gi
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-config
  labels:
    app: postgres
data:
  POSTGRES_DB: postgresdb
  POSTGRES_USER: postgres
  POSTGRES_PASSWORD: root
---

原错误Service配置

kind: Service
apiVersion: v1
metadata:
  name: postgres-svc
  labels:
    app: postgres
spec:
  type: LoadBalancer
  ports:
    - port: 5432
      targetPort: 30432
  type: LoadBalancer
  selector:
    metallb-service: postgres

修复方案

1. 修正Service配置文件

原Service存在3个关键错误:

  • 重复定义type: LoadBalancer
  • selector标签不匹配:PostgreSQL Pod的标签是app: postgres,而非metallb-service: postgres
  • 端口映射错误:Postgres容器默认监听5432端口,targetPort应指向容器的5432端口

正确的Service YAML

kind: Service
apiVersion: v1
metadata:
  name: postgres-svc
  labels:
    app: postgres
spec:
  type: LoadBalancer
  ports:
    - port: 5432          # 集群内部访问的端口
      targetPort: 5432    # Postgres容器默认监听的端口
      nodePort: 30432     # 可选:固定节点端口,若不需要可省略,由K8s自动分配
  selector:
    app: postgres         # 匹配PostgreSQL Pod的标签

验证步骤

  1. 应用配置:kubectl apply -f postgres-svc.yaml
  2. 查看服务状态:kubectl get svc postgres-svc,确认EXTERNAL-IP已由MetalLB分配
  3. 测试连接:psql -h <EXTERNAL-IP> -U postgres -d postgresdb,输入密码root即可连接

2. 解决PostgreSQL多副本数据同步问题

当前Deployment存在致命问题:所有3个Postgres Pod共享同一个PVC(对应同一个hostPath目录),多个Postgres实例直接共享数据目录会导致数据损坏,无法实现数据同步。正确的多实例部署需采用主从复制架构:

  • 1个主节点:处理所有写操作,生成WAL日志
  • 2个从节点:通过流复制同步主节点数据,仅处理读操作
  • 分别创建主、从服务:主服务暴露写端口,从服务暴露读端口

核心调整点

  1. 为主节点和从节点创建独立的Deployment和PVC,避免共享数据目录
  2. 配置主节点参数:开启WAL日志,允许从节点连接(在ConfigMap中添加POSTGRES_REPLICATION_MODE=master等参数)
  3. 配置从节点参数:指定主节点地址、复制用户信息,启动复制模式
  4. 主服务用LoadBalancer暴露5432端口(写操作),从服务用ClusterIP或LoadBalancer暴露5432端口(读操作)

内容的提问来源于stack exchange,提问作者user19238163

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 17:15:13