簡體   English   中英

如何在 Google Cloud 上備份 Kubernetes 中的 Postgres 數據庫?

[英]How to backup a Postgres database in Kubernetes on Google Cloud?

備份在Google Cloud Container Engine上運行的 Postgres 數據庫的最佳做法是什么?

我的想法是努力將備份存儲在Google Cloud Storage中,但我不確定如何將 Disk/Pod 連接到存儲桶。

我正在使用以下配置在 Kubernetes 集群中運行 Postgres:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: postgres-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - image: postgres:9.6.2-alpine
          imagePullPolicy: IfNotPresent
          env:
            - name: PGDATA
              value: /var/lib/postgresql/data
            - name: POSTGRES_DB
              value: my-database-name
            - name: POSTGRES_PASSWORD
              value: my-password
            - name: POSTGRES_USER
              value: my-database-user
          name: postgres-container
          ports:
            - containerPort: 5432
          volumeMounts:
            - mountPath: /var/lib/postgresql
              name: my-postgres-volume
      volumes:
        - gcePersistentDisk:
            fsType: ext4
            pdName: my-postgres-disk
          name: my-postgres-volume

我試圖創建一個作業來運行備份:

apiVersion: batch/v1
kind: Job
metadata:
  name: postgres-dump-job
spec:
  template:
    metadata:
      labels:
        app: postgres-dump
    spec:
      containers:
        - command:
            - pg_dump
            - my-database-name
          # `env` value matches `env` from previous configuration.
          image: postgres:9.6.2-alpine
          imagePullPolicy: IfNotPresent
          name: my-postgres-dump-container
          volumeMounts:
            - mountPath: /var/lib/postgresql
              name: my-postgres-volume
              readOnly: true
      restartPolicy: Never
      volumes:
        - gcePersistentDisk:
            fsType: ext4
            pdName: my-postgres-disk
          name: my-postgres-volume

(據我了解)這應該運行pg_dump命令和 output 備份數據到標准輸出(應該出現在kubectl logs中)。

順便說一句,當我檢查 Pod(使用kubectl get pods )時,它顯示 Pod 永遠不會脫離“待定”state,我認為這是因為沒有足夠的資源來啟動 Job。

將此過程作為作業運行是否正確? 如何將作業連接到 Google Cloud Storage? 還是我應該做一些完全不同的事情?

我猜由於性能下降,在數據庫容器(使用kubectl exec )中運行pg_dump是不明智的,但也許這在開發/登台服務器中可以嗎?

正如@Marco Lamina 所說,您可以在 postgres pod 上運行 pg_dump,例如

DUMP
// pod-name         name of the postgres pod
// postgres-user    database user that is able to access the database
// database-name    name of the database
kubectl exec [pod-name] -- bash -c "pg_dump -U [postgres-user] [database-name]" > database.sql


RESTORE
// pod-name         name of the postgres pod
// postgres-user    database user that is able to access the database
// database-name    name of the database
cat database.sql | kubectl exec -i [pod-name] -- psql -U [postgres-user] -d [database-name]

您可以擁有一個運行此命令並將其導出到文件存儲系統(例如 AWS s3)的作業 Pod。

我認為將 pg_dump 作為一項工作運行是個好主意,但直接連接到數據庫的永久磁盤則不然。 嘗試讓 pg_dump 通過網絡連接到您的數據庫! 然后您可以擁有第二個磁盤,您的 pg_dump 命令將備份轉儲到該磁盤上。 為安全起見,您可以為第二個磁盤創建常規快照。

作業 POD 保持Pending狀態的原因是它一直嘗試附加/掛載 GCE 永久磁盤,但未能這樣做,因為它已附加/掛載到另一個 POD。

僅當所有 POD 都以只讀模式附加/掛載卷時,才支持將永久性磁盤附加到多個 POD。 這對您來說當然不是可行的解決方案。

我從未使用過 GCE,但應該可以從 GCE 中的 PD 輕松創建快照。 這不會提供非常干凈的備份,更像是處於“中途崩潰但可恢復”狀態的東西,但這對您來說可能是可以接受的。

在數據庫 POD 內運行pg_dump是一個可行的解決方案,但您已經注意到了一些缺點,尤其是性能。 之后您還必須從 POD 中移出生成的備份,例如通過使用kubectl cp和另一個exec來清理 POD 中的備份。

您可以使用Minio 客戶端

首先使用簡單的 dockerfile 使 docker 鏡像包含 postgres 和 minio 客戶端(讓這個鏡像命名為postgres_backup ):

FROM postgres

RUN apt-get update && apt-get install -y wget

RUN wget https://dl.min.io/client/mc/release/linux-amd64/mc

RUN chmod +x mc

RUN ./mc alias set gcs  https://storage.googleapis.com BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12

現在您可以在您的 CronJob 中使用postgres_backup圖像(我假設您在 Google 存儲中創建了備份存儲桶):

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: backup-job
spec:
  # Backup the database every day at 2AM
  schedule: "0 2 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: postgres-backup
            image: postgres_backup
            env:
            - name: POSTGRES_HOST_AUTH_METHOD
              value: trust
            command: ["/bin/sh"]
            args: ["-c", 'pg_dump -Fc -U [Your Postgres Username] -W [Your Postgres Password] -h [Your Postgres Host] [Your Postgres Database] | ./mc pipe gcs/backups/$(date -Iseconds).dump']
          restartPolicy: Never

很多教程使用kubectl cp或在 pod 內傳輸文件,但您也可以將pg_dump容器輸出直接通過管道傳輸到另一個進程。

kubectl run --env=PGPASSWORD=$PASSWORD --image=bitnami/postgresql postgresql -it --rm -- \
  bash -c "pg_dump -U $USER -h $HOST -d $DATABASE" |\
  gzip > backup.sql.gz

無需在 pod 上存儲任何額外副本即可進行轉儲的最簡單方法:

kubectl -n [namespace] exec -it [pod name] -- bash -c "export PGPASSWORD='[db password]'; pg_dump -U [db user] [db name]" > [database].sql

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM