
首先,如果数据库本身非常重要,或者数据量非常大,一般情况下,并不建议用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