首先,如果数据库本身非常重要,或者数据量非常大,一般情况下,并不建议用Kubernetes部署数据库,而是采用裸机独立部署的方式。因为Kubernetes的目的是解决计算资源的快速扩展和调度问题,数据可靠性不是它的重点。

但是Postgresql作为轻量级数据库,在互联网服务中得到了广泛应用,所以Kubernetes下也有很多很好的高可用性方案。从stolon、crunchy到CloudNativePG,各种解决方案层出不穷。

其中zalando postgresql operator的安装部署比较简单,推出的时间也比较新,受到了人们的欢迎。

安装步骤如下,操作系统为Debian 12。

1.首先把zalando代码复制到本地

git clone https://github.com/zalando/postgres-operator.git
cd postgres-operator

2.运行下列命令,完成安装

kubectl create -f manifests/configmap.yaml  # configuration
kubectl create -f manifests/operator-service-account-rbac.yaml  # identity and permissions
kubectl create -f manifests/postgres-operator.yaml  # deployment
kubectl create -f manifests/api-service.yaml  # operator API to be used by UI

3.运行

kubectl get pod -l name=postgres-operator

等待pod的状态转为running

4. 把下列内容保存为文件pg-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    pv: pv001
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  hostPath: # where pesistent volume is created on the kubernetes node (needs to be /data for minikube)
    path: "/data"
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    pv: pv002
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  hostPath: # where pesistent volume is created on the kubernetes node (needs to be /data for minikube)
    path: "/data"
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    pv: pv003
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  hostPath: # where pesistent volume is created on the kubernetes node (needs to be /data for minikube)
    path: "/data"

运行 kubectl apply -f pg-pv.yaml生效,为数据库分配三个大小为1GB的存储单元。

5. 复制并修改文件manifests/minimal-postgres-manifest.yaml

apiVersion: "acid.zalan.do/v1"
kind: postgresql
metadata:
  name: acid-minimal-cluster
spec:
  teamId: "acid"
  volume:
    size: 1Gi
  numberOfInstances: 2
  users:
    # database owner
    zalando:
    - superuser
    - createdb

    # role for application foo
    foo_user: # or 'foo_user: []'

  #databases: name->owner
  databases:
    foo: zalando
  postgresql:
    version: "15"

其中name是数据库集群的名字,teamid是团队名,numberofInstances是数据库运行的节点数量,zalando是管理员用户名,foo是数据库名,按照实际情况修改。

6. 运行

kubectl apply -f manifests/minimal-postgres-manifest.yaml

创建数据库集群

7. 运行

kubectl get postgresql
kubectl get pods -l application=spilo -L spilo-role
kubectl get svc -l application=spilo -L spilo-role

观察创建进度,等pod状态都变成running,集群就创建完成了。

8. 连接数据库

首先主机上应该安装过postgresql,如果没有安装过,先安装一下

apt install postgresql

运行

export PGMASTER=$(kubectl get pods -o jsonpath={.items..metadata.name} -l application=spilo,cluster-name=acid-minimal-cluster,spilo-role=master -n default)
kubectl port-forward $PGMASTER 6432:5432 -n default

保留当前终端,再重新建立一个终端会话,运行

export PGPASSWORD=$(kubectl get secret postgres.acid-minimal-cluster.credentials.postgresql.acid.zalan.do -o 'jsonpath={.data.password}' | base64 -d)
export PGSSLMODE=require
psql -U postgres -h localhost -p 6432

连接到数据库。

9. 操作数据库

运行下列命令

select version();
create database my_test_db;
\c my_test_db
create table my_table_1(a varchar(100), b timestamp);
create table my_table_2(a varchar(100), b timestamp);
insert into my_table_1 values('One One One', '2001-01-01 01:01:01');
insert into my_table_1 values('One One One', '2001-01-01 01:01:02');
insert into my_table_1 values('One One One', '2001-01-01 01:01:03');
insert into my_table_1 values('One One One', '2001-01-01 01:01:04');
insert into my_table_2 values('Two Two Two', '2002-02-02 01:01:04');
\d
\q

确认数据库操作正常。

10. 简单测试高可用性

运行

kubectl get pods -l application=spilo -L spilo-role

找到master节点主机,把这台主机关闭

运行

kubectl get pods -l application=spilo -L spilo-role
kubectl logs acid-minimal-cluster-0
kubectl logs acid-minimal-cluster-1

确认master节点已经转移

再运行

export PGMASTER=$(kubectl get pods -o jsonpath={.items..metadata.name} -l application=spilo,cluster-name=acid-minimal-cluster,spilo-role=master -n default)
kubectl port-forward $PGMASTER 6432:5432 -n default

在其他终端会话上,运行

export PGPASSWORD=$(kubectl get secret postgres.acid-minimal-cluster.credentials.postgresql.acid.zalan.do -o 'jsonpath={.data.password}' | base64 -d)
export PGSSLMODE=require
psql -U postgres -h localhost -p 6432
\c my_test_db
\d

如果能够正常连上数据库,完成数据库操作,说明高可用性已经生效。

11. 如果要删除数据库集群,运行

kubectl delete postgresql acid-minimal-cluster

12. 数据库管理员的密码由系统随机生成,个人无法修改,保存在secret {username}.{clustername}.credentials.postgresql.acid.zalan.do中

可以用命令获取

kubectl get secret postgres.acid-minimal-cluster.credentials.postgresql.acid.zalan.do -o 'jsonpath={.data.password}' | base64 -d

上面的postgres是管理员用户名,acid-minimal-cluster是数据库集群名字,按照实际情况调整。

部署应用程序容器的时候,在yaml文件中,可以用

         env:

            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  key: password
                  name: postgres.acid-minimal-cluster.credentials.postgresql.acid.zalan.do

把密码从secret中取出,放到环境变量POSTGRES_PASSWORD中。

如果用python作为编程语言,就可以用os.getenv(‘POSTGRES_PASSWORD’)取出密码,用来连接数据库。

应用程序应该连接数据库的service名称,作为数据库的主机名称,这样可以保证连接的高可用性。

参考:

https://github.com/zalando/postgres-operator/blob/master/docs/quickstart.md

https://medium.com/@dmitry.romanoff/how-to-deploy-a-high-availability-ha-postgres-cluster-in-kubernetes-9d740650c76a

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注