在k8s中实现posgresql集群及其负载均衡
PostgreSQL是一种特性非常齐全的自由软件的对象-关系型数据库管理系统(
1. Postgresql 及其简介
PostgreSQL是一种特性非常齐全的自由软件的对象-关系型数据库管理系统(ORDBMS),是以加州大学计算机系开发的POSTGRES,4.2版本为基础的对象关系型数据库管理系统。POSTGRES的许多领先概念只是在比较迟的时候才出现在商业数据库中。PostgreSQL支持大部分的SQL标准并且提供了很多其他现代特性,如复杂查询、外键、触发器、视图、事务完整性、多版本并发控制等。同样,PostgreSQL也可以用许多方法扩展,例如通过增加新的数据类型、函数、操作符、聚集函数、索引方法、过程语言等。另外,因为许可证的灵活,任何人都可以以任何目的免费使用、修改和分发PostgreSQL。
本文将介绍如何在k8s部署PostgreSQL集群以及如何实现高可用,集群配置集中管理,实现连接池,查询负载均衡等。
基础环境: centos7.9, k8s 1.26.2, PostgreSQL15, git, CSI longhorn
PostgreSQL Operator(pgo) 是k8s应用控制器,用于在K8s部署生产级PostgreSQL应用,它简化应用的部署,并提供集群配置管理,高可用性,计划备份,灾难恢复,监控和连接池等功能。本文接下采用Crunchy PostgreSQL Operator 在 k8s中进行PostgreSQL的集群部署,
2.1. 下载Crunchy PGO
首先fork git 库,Sign in to GitHub · GitHub
Fork后,下载该库到本地:
YOUR_GITHUB_UN="<your GitHub username>"
git clone --depth 1 "git@github.com:${YOUR_GITHUB_UN}/postgres-operator-examples.git"
cd postgres-operator-examples
2.2. 安装Crunchy PGO
代码仓库中有两个值得注意的目录,install, postgres, install主要是创建k8s namespace及rbac, pgo cluster相关的配置文件,一般不做修改,但是如果你希望部署到不同的namespace, 这就需要把这个目录下所有涉及到namespace的地方修改成你自己的namespace.
下面是建立pgo的namespace,可以自己修改
kubectl apply -k kustomize/install/namespace
下面是部署PGO及其相关的对象
kubectl apply --server-side -k kustomize/install/default
成功安装后,执行以下命令相关相应的pod起来没有,
kubectl -n postgres-operator get pods \
--selector=postgres-operator.crunchydata.com/control-plane=postgres-operator \
--field-selector=status.phase=Running
下面显示表示状态正常
NAME READY STATUS RESTARTS AGE
postgres-operator-9dd545d64-t4h8d 1/1 Running 0 3s
2.3. 创建自己的postgres cluster
在代码库的 postgres目录下,postgres.yaml是创建postgres cluster的配置文件,在实际实用中一般要按自己的项目进行定制更改。
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: postgres-cluster
namespace: default
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-15.3-2
postgresVersion: 15
instances:
- name: ins1
replicas: 3
dataVolumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
affinity:
# 通过亲和性配置使不同的Postgres实例部署在不同的节点上
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
postgres-operator.crunchydata.com/cluster: postgres-cluster
postgres-operator.crunchydata.com/instance-set: ins1
# 初始化数据库的用户,并且创建相应数据库,同时指定用户的SUPERUSER权限
users:
- name: postgres
databases:
- cluster1
- cluster2
- cluster3
options: "SUPERUSER"
# 定制化postgresql的相关配置
patroni:
dynamicConfiguration:
postgresql:
ssl: "off"
pg_hba:
- "host all all 0.0.0.0/0 trust"
backups:
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.45-2
repos:
- name: repo1
volume:
volumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
配置文件中的dataVolumeClaimSpec,需要你建立自己的PV,在这里进行存储的申请,可以自定义申请的空间,这里是1G,databases项目,你要建立的数据库,这里默认建了三个,
pg_hba即PostgreSQL的访问控制权限,"host all all all trust" 这里为了方便测试,即允许一切访问,在实际项目中需要更改,第一个host即能访问的来源主机,可以是local 即本地连接,host 表示主机通过TCP/IP连接,hostssl 表示主机通过ssl连接,第二个all,表示能访问的数据库,可以是all 即所有库,可以某个DBname,可以是 replication即主备复制时的连接,第三个 all 表示能连接的用户,可以是all, user_name,+group_name,一组用户,@file_name即文件中包含的用户列表。 第四个 0.0.0.0/0,表示能连接的客户端,可以是127.0.0.1、32即本地客户端主机,0.0.0.0/0 表示所有客户端主机均可,第五个trust,表示连接方式,trust 即不需要密码任意连接,scram-sha-256,即sha密码方式,md5,即md5摘要码,
Password,即密码明文,ident,将OS的用户映射为DB的用户且不需要提供密码,peer,使用连接发起端的OS名进行身份验证,即支持 Linux,BSD,MAC OS,Solaris.
执行kubectl apply -k kustomize/postgres ,建立cluster,
执行以下命令检查部署结果:
kubectl -n default describe postgresclusters.default.crunchydata.com hippo
部分显示如下:
postgres-cluster-backup-r4h9-fjkdx 0/1 Completed 0 19h
postgres-cluster-ins1-fbv4-0 4/4 Running 0 19h
postgres-cluster-ins1-gkk9-0 4/4 Running 0 19h
postgres-cluster-ins1-htdt-0 4/4 Running 0 19h
postgres-cluster-repo-host-0 2/2 Running 0 19h
默认建立的集群为一写两读,可以使用kubectl exec -ti <podname> bash -n default 进入pod, 并执行 psql -U postgres, 即可进行PostgreSQL命令行。 注意,其中有两个POD是只读状态,所以不能进行写操作。
另外新建立的集群有几个 k8s service:
postgres-cluster-ha ClusterIP 10.11.123.98 <none> 5432/TCP 19h
postgres-cluster-ha-config ClusterIP None <none> <none> 19h
postgres-cluster-pods ClusterIP None <none> <none> 19h
postgres-cluster-primary ClusterIP None <none> 5432/TCP 19h
postgres-cluster-replicas ClusterIP 10.10.154.202 <none> 5432/TCP 19h
使用时,一般使用*primary用于写,而replicas用于读,在后面我们会用到primay, replicas作为pg-tool的后端结果, pg-tool将在后面介绍。
如果只想做HA,或者读写分离在这里就已经达到目的了,但是要实现读/查询负载均衡和连接池等的操作还得引入pg-pool.
2.4 Crunchy PGO的其实方面
1. 高可用
由基于分布式共识的高可用性解决方案支持的安全、自动故障转移。使用 Pod Anti-Affinity 来帮助恢复;您可以配置它的 aggressive! 失败的初选会自动恢复,从而加快恢复时间
High Availability (crunchydata.com)
2 灾难恢复与备份管理
备份和恢复利用开源 pgBackRest 实用程序,包括对完整、增量和差异备份以及高效增量恢复的支持。 设置您希望备份保留多长时间。适用于非常大的数据库
Disaster Recovery (crunchydata.com)
Backup Management (crunchydata.com)
2.5 监控
使用开源 pgMonitor 库跟踪 PostgreSQL 集群的运行状况。
4 注意事项
Crunchy pgo 是开源的,但是pgo使用的docker image不是,只能用在development环境,如果你想用在非development环境,是需要向crunchy公司订阅的。
但是我们可以使用PostgreSQL的社区版来构建自己的私有image.
3. Pgpool-II 的安装及使用
3.1. Pgpool-II介绍
上面的 crunchy PGO已经实现了高可用与读写分离,灾难恢复等,但是没有实现提供查询负载均衡功能。接下来我们使用pgpool-II来实现查询负载均衡及连接池功能。Pgpool-II需要在Crunchy PGO上来实现。
3.2. 部署Pg-pool
由于k8s,pgo 已经能实现健康检查,灾难恢复等功能,我们只需要在pg-pool中实现负载均衡和连接池功能。
Pg-pool有两种部署方式,一种是使用环境变量,别一种是 k8s的config-map, 其实其本质是一样的,都是为pg-pool提供配置,我们采用第二种k8s的方式进行部署。
下载config-map
curl -LO https://raw.githubusercontent.com/pgpool/pgpool2_on_k8s/master/pgpool-configmap.yaml
配置文件主要内容如下:
data:
pgpool.conf: |-
listen_addresses = '*'
port = 9999
socket_dir = '/var/run/pgpool'
pcp_listen_addresses = '*'
pcp_port = 9898
pcp_socket_dir = '/var/run/pgpool'
backend_hostname0 = 'postgres-cluster-primary.default.svc.cluster.local'
backend_port0 = 5432
backend_weight0 = 1
backend_flag0 = 'ALWAYS_PRIMARY|DISALLOW_TO_FAILOVER'
backend_hostname1 = 'postgres-cluster-replicas.default.svc.cluster.local'
backend_port1 = 5432
backend_weight1 = 1
backend_flag1 = 'DISALLOW_TO_FAILOVER'
sr_check_period = 0
health_check_period = 0
backend_clustering_mode = 'streaming_replication'
num_init_children = 32
max_pool = 4
child_life_time = 300
child_max_connections = 0
connection_life_time = 0
client_idle_limit = 0
connection_cache = on
load_balance_mode = on
ssl = off
enable_pool_hba = on
failover_on_backend_error = off
log_min_messages = warning
需要注意的是:backend_hostname0, 这里配置为pgo的写服务,backend_hostname1配置为读服务。backend_flag0 设置为主服务,并且不允许漂移,因为k8s的服务名始终不变。
pool_hba.conf: |-
local all all trust
host all all 0.0.0.0/0 trust
打开这里的配置, 允许所有访问,参考pgo的设置
curl -LO https://raw.githubusercontent.com/pgpool/pgpool2_on_k8s/master/pgpool-deploy.yaml
该文件定义了pg-pool的部署和服务,跟k8s普通部署和服务没有特定的地方,根据config map进行更新即可。
安装好以后,就可以 kubectl get svc
service/pgpool LoadBalancer 10.173.140.164 192.168.3.232 9999:31517/TCP
21h
应用程序在连接时 直接使用 pgpool.default.svc.cluster.local这个k8s服务名连接即可。
更多推荐
所有评论(0)