【K8S部署postgresql全过程】

K8S部署postgresql全过程

1.集群准备工作

[root@mast ~]# kubectl label nodes node1 postgres-env=dev  # 添加节点标签 
node/node1 labeled
[root@mast ~]# kubectl label nodes node1 disk-type=ssd     # 可选:扩展标签用于高级调度 
node/node1 labeled
[root@mast ~]# kubectl create namespace postgres-dev       # 隔离开发环境 
namespace/postgres-dev created

2.创建持久卷

持久卷(Persistent Volume,PV)

PV 是集群层面的存储资源,由集群管理员创建和管理。它是对底层存储系统(如 NFS、iSCSI、Ceph 等)的抽象,为 Pod 提供了独立于节点的持久化存储,他独立与pod ,后台可以用多种存储模式,确的存储容量和访问模式,如 ReadWriteOnce(单节点读写)、ReadOnlyMany(多节点只读)和 ReadWriteMany(多节点读写)

持久卷声明(Persistent Volume Claim,PVC)

PVC 是用户对存储资源的请求,由普通用户创建。它类似于 Pod 对计算资源(CPU 和内存)的请求,PVC 对存储资源(如 PV)提出请求,请求指定的存储容量和访问模式。 Kubernetes 会自动将 PVC 绑定到满足其请求的 PV 上,如果没有合适的 PV,也可以通过动态存储供应(Dynamic Provisioning)来创建新的 PV。

[root@mast ~]# kubectl apply -f pv-pvc.yaml -n postgres-dev 
persistentvolume/postgres-pv-dev created
persistentvolumeclaim/postgres-pvc-dev created
[root@mast ~]# cat pv-pvc.yaml 
#PV
apiVersion: v1 
kind: PersistentVolume 
metadata:
  name: postgres-pv-dev 
  namespace: postgres-dev 
  labels:
    app: postgres-dev       # 标签用于亲和性调度关联 
spec:
  capacity:
    storage: 5Gi            # 存储容量(开发环境建议5Gi)
  storageClassName: manual 
  accessModes:
    - ReadWriteOnce 
  hostPath:
    path: /data/postgres-dev  # 节点本地路径(需提前创建)
  nodeAffinity:             # 关键:PV与节点绑定 
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname  
          operator: In 
          values: [node1]   # 严格绑定到node1 
 
---

#PVC

apiVersion: v1 
kind: PersistentVolumeClaim 
metadata:
  name: postgres-pvc-dev 
  namespace: postgres-dev 
spec:
  storageClassName: manual 
  accessModes: [ReadWriteOnce]
  resources:
    requests:
      storage: 5Gi          # 与PV容量一致 
  selector:                 # 显式选择带标签的PV 
    matchLabels:
      app: postgres-dev 
[root@mast ~]# 

3.创建secret configmap

ConfigMap

ConfigMap 是一种用于存储非敏感配置数据的键值对集合。它允许你将配置信息和容器镜像解耦,使得配置可以在不重新构建镜像的情况下进行修改和更新。可以用于环境变量配置 命令行参数配置和 配置文件挂载

Secret

Secret 也是用于存储键值对数据的对象,但主要用于存储敏感信息,如密码、令牌、SSH 密钥等。Secret 提供了比 ConfigMap 更安全的存储方式,数据在存储和传输过程中会进行加密处理。主要用于认证信息 和加密密钥

[root@mast ~]# vim secret.yaml
[root@mast ~]# kubectl apply -f secret.yaml  -n postgres-dev 
secret/postgres-secret-dev created
[root@mast ~]# cat secret.yaml 
apiVersion: v1 
kind: Secret 
metadata:
  name: postgres-secret-dev 
  namespace: postgres-dev 
type: Opaque 
stringData:                   # 开发环境简化处理 
  POSTGRES_USER: "dev_admin"
  POSTGRES_PASSWORD: "d3v!P@ss"
data:                         # 可选手动编码字段 
  # echo -n "backup" | base64 → YmFja3Vw 
  # POSTGRES_BACKUP_USER: YmFja3Vw 
[root@mast ~]# 

4.创建pg数据库yaml 文件

Pod是容器运行的最小单位,也是最重要的单位,在yaml 中定义了很多重要的信息,对pod 进行限制,如下

[root@mast ~]# kubectl apply -f deployment.yaml  -n postgres-dev 
deployment.apps/postgres-deployment-dev created
[root@mast ~]# cat deployment.yaml 
apiVersion: apps/v1 
kind: Deployment 
metadata:
  name: postgres-deployment-dev 
  namespace: postgres-dev 
spec:
  replicas: 1 
  selector:
    matchLabels:
      app: postgres-dev 
  template:
    metadata:
      labels:
        app: postgres-dev     # 服务选择器标识 
        env: dev 
    spec:
      affinity:               # 亲和性调度配置 
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: postgres-env     # 匹配节点标签 节点有一个 postgres-env 标签
                operator: In 
                values: [dev]
              - key: disk-type        # 多标签匹配 节点有一个 disk-type 标签。
                operator: Exists 
      containers:
      - name: postgres               #Pod 中只运行一个postgres容器
        image: postgres:15-alpine 
        imagePullPolicy: IfNotPresent  #本地没有该镜像时 才从仓库中拉取镜像
        ports:
        - containerPort: 5432 
        envFrom:                     # 批量加载环境变量 
          - secretRef:              #envFrom 用于从外部资源(ConfigMap Secret)中批量加载环境变量到容器中
              name: postgres-secret-dev 
        env:
          - name: POSTGRES_DB 
            value: "dev_core"  #,POSTGRES_DB 环境变量通常指定数据库的名称,将数据库名设置dev_core。
        volumeMounts:  #volumeMounts 用于将卷(Volume)挂载到容器内的指定路径
        - name: postgres-data 
          mountPath: /var/lib/postgresql/data 
        resources:
          limits:
            cpu: "1"                # 硬限制(必须≤节点容量)
            memory: "1Gi"
          requests:
            cpu: "0.7"              # 弹性请求(总和≤节点容量)
            memory: "768Mi"
      volumes:
      - name: postgres-data 
        persistentVolumeClaim:
          claimName: postgres-pvc-dev 
[root@mast ~]# 

5.创建service

Service:Service 为 Pod 提供了稳定的网络访问入口。它可以将多个 Pod 抽象成一个统一的服务,使得外部应用或其他 Pod 可以通过 Service 访问这些 Pod,而无需关心具体的 Pod 实例。

[root@mast ~]# kubectl apply -f service.yaml -n postgres-dev 
service/postgres-service-dev created
[root@mast ~]# cat service.yaml 
apiVersion: v1 
kind: Service 
metadata:
  name: postgres-service-dev 
  namespace: postgres-dev 
spec:
  type: ClusterIP 
  selector:
    app: postgres-dev 
  ports:
  - name: postgres 
    port: 5432 
    targetPort: 5432 

6.查验pod

[root@mast ~]# kubectl get pods -n postgres-dev -o wide | grep -E "NAME|postgres"
NAME                                       READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
postgres-deployment-dev-69475b468c-9w5sl   1/1     Running   0          41s   10.244.1.23   node1   <none>           <none>


[root@mast ~]# kubectl describe pod postgres-deployment-dev-69475b468c-9w5sl  -n postgres-dev
Name:         postgres-deployment-dev-69475b468c-9w5sl
Namespace:    postgres-dev
Priority:     0
Node:         node1/10.0.0.27
Start Time:   Wed, 19 Mar 2025 15:06:29 +0800
Labels:       app=postgres-dev
              env=dev
              pod-template-hash=69475b468c
Annotations:  <none>
Status:       Running
IP:           10.244.1.23
IPs:
  IP:           10.244.1.23
Controlled By:  ReplicaSet/postgres-deployment-dev-69475b468c
Containers:
  postgres:
    Container ID:   docker://a012f1f0116d6357b48fed82a3f91100d9547b117f49c0a701a1d5c884e939b9
    Image:          postgres:15-alpine
    Image ID:       docker-pullable://postgres@sha256:ef9d1517df69c4d27dbb9ddcec14f431a2442628603f4e9daa429b92ae6c3cd1
    Port:           5432/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Wed, 19 Mar 2025 15:06:29 +0800
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     1
      memory:  1Gi
    Requests:
      cpu:     700m
      memory:  768Mi
    Environment Variables from:
      postgres-secret-dev  Secret  Optional: false
    Environment:
      POSTGRES_DB:  dev_core
    Mounts:
      /var/lib/postgresql/data from postgres-data (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-tr7gt (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  postgres-data:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  postgres-pvc-dev
    ReadOnly:   false
  default-token-tr7gt:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-tr7gt
    Optional:    false
QoS Class:       Burstable
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age        From               Message
  ----    ------     ----       ----               -------
  Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned postgres-dev/postgres-deployment-dev-69475b468c-9w5sl to node1
  Normal  Pulled     4m35s      kubelet, node1     Container image "postgres:15-alpine" already present on machine
  Normal  Created    4m35s      kubelet, node1     Created container postgres
  Normal  Started    4m35s      kubelet, node1     Started container postgres
[root@mast ~]# 

[root@mast ~]# kubectl exec -it  postgres-deployment-dev-69475b468c-9w5sl -n postgres-dev -- psql -U dev_admin -d dev_core 
psql (15.12)
Type "help" for help.

dev_core=# \l
                                                  List of databases
   Name    |   Owner   | Encoding |  Collate   |   Ctype    | ICU Locale | Locale Provider |    Access privileges    
-----------+-----------+----------+------------+------------+------------+-----------------+-------------------------
 dev_core  | dev_admin | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | 
 postgres  | dev_admin | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | 
 template0 | dev_admin | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | =c/dev_admin           +
           |           |          |            |            |            |                 | dev_admin=CTc/dev_admin
 template1 | dev_admin | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | =c/dev_admin           +
           |           |          |            |            |            |                 | dev_admin=CTc/dev_admin
(4 rows)

dev_core=# 

[root@mast ~]# kubectl edit pod postgres-deployment-dev-69475b468c-9w5sl -n  postgres-dev
Edit cancelled, no changes made.
root@mast ~]# kubectl get pod postgres-deployment-dev-69475b468c-9w5sl -n  postgres-dev -o yaml


7.单机部署完成,如果需要集群的时候就需要configmap

# postgres-configmap.yaml  
apiVersion: v1 
kind: ConfigMap 
metadata:
  name: postgres-config 
  namespace: postgres-dev 
data:
  # 主库专用配置 
  postgresql-master.conf:  |
    wal_level = replica 
    max_wal_senders = 3 
    hot_standby = on 
 
  # 从库专用配置 
  postgresql-replica.conf:  |
    hot_standby = on 
    primary_conninfo = 'host=postgres-master user=repluser password=${REPL_PASSWORD}'
 
  # 初始化脚本(创建复制用户)
  init-replication.sql:  |
    CREATE ROLE repluser WITH REPLICATION LOGIN PASSWORD '${REPL_PASSWORD}';

今天朋友问我pg数据库和nginx 的pod 区别是什莫?

答:

 pg数据库应该是有状态服务 ,需要做持久化。必须挂载postgresql/data,而nginx 只需要经常备份配置文件,nginx一般需要外部通信,需要https,而pg经常内部通讯,只需要tcp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值