「在 Kubernetes 上运行 Pgpool-Il」实现 PostgreSQL 查询(读)负载均衡和连接池
介绍如何在 Kubernetes
上运行 Pgpool-II
实现 PostgreSQL
读查询负载均衡和连接池。
介绍
因为 PostgreSQL
是一个有状态的应用程序,并且管理 PostgreSQL
有非常具体的要求(例如备份、恢复、自动故障转移等),Kubernetes
的内置功能无法处理这些任务。 因此,需要一个扩展 Kubernetes
功能以创建和管理 PostgreSQL
的 Operator
。
PostgreSQL operator
有好几种,比如 Crunchy PostgreSQL Operator、Zalando PostgreSQL Operator 和 KubeDB。但是,这些 operator
不提供查询负载均衡功能。
Crunchy PostgreSQL Operator
Zalando PostgreSQL Operator
KubeDB
结合 PostgreSQL Operator
和 Pgpool-II
在 Kubernetes
上部署具有查询负载均衡和连接池能力的 PostgreSQL
集群。Pgpool-II
可以与上面提到的任何 PostgreSQL Operator
结合使用。
架构
前提条件
在开始配置过程之前,请检查以下前提条件。
- 确保你有一个
Kubernetes
集群,并且安装了kubectl
。 PostgreSQL Operator
和PostgreSQL cluster
已安装。
部署 Pgpool-II
Kubernetes
不需要 Pgpool-II
的健康检查、自动故障转移、watchdog
和在线恢复功能。 您只需要启用负载平衡和连接池。
Pgpool-II pod
应该使用以下最低配置:
backend_hostname0 = '<primary service name>'
backend_hostname1 = '<replica service name>'
backend_port0 = '5432'
backend_port1 = '5432'
backend_flag0 = 'ALWAYS_PRIMARY|DISALLOW_TO_FAILOVER'
backend_flag1 = 'DISALLOW_TO_FAILOVER'
failover_on_backend_error = off
sr_check_period = 10 (when using streaming replication check)
sr_check_user='username of PostgreSQL user' (when using streaming replication check)
load_balance_mode = on
connection_cache = on
listen_addresses = '*'
有两种配置 Pgpool-II
的方法。
您可能需要在生产环境中配置客户端身份验证和更多参数。在生产环境中,我们建议使用 ConfigMap
来配置 pgpool.conf
和 pool_hba.conf
。
使用环境变量配置 Pgpool-II
Kubernetes
环境变量可以传递给 pod
中的容器。您可以在部署清单中定义环境变量来配置 Pgpool-II
的参数。pgpool-deploy-minimal.yaml
是一个示例清单,包括环境变量的最小设置。您可以下载 pgpool-deploy-minimal.yaml
并修改此清单中的环境变量。
$ curl -LO https://raw.githubusercontent.com/pgpool/pgpool2_on_k8s/master/pgpool-deploy-minimal.yaml
以 PGPOOL_PARAMS_
开头的环境变量可以转换为 Pgpool-II
的配置参数,这些值可以覆盖默认设置。
在 Kubernetes
上,您只需要指定两个后端节点。根据您的 PostgreSQL
集群信息更新 pgpool-deploy-minimal.yaml
。将主服务名称指定为 backend_hostname
0。将副本服务名称指定为 backend_hostname
1。因为故障转移由 Kubernetes
管理,所以将 DISALLOW_TO_FAILOVER
标志指定给两个节点的 backend_flag
,并将 ALWAYS_PRIMARY
标志指定给 backend_flag
0。 backend_data_directory
的设置不是必需的。
backend_hostname
backend_flag
backend_data_directory
例如,清单中定义的以下环境变量,
env:
- name: PGPOOL_PARAMS_BACKEND_HOSTNAME0
value: "mypostgres"
- name: PGPOOL_PARAMS_BACKEND_HOSTNAME1
value: "mypostgres-replica"
- name: PGPOOL_PARAMS_BACKEND_FLAG0
value: "ALWAYS_PRIMARY|DISALLOW_TO_FAILOVER"
- name: PGPOOL_PARAMS_BACKEND_FLAG1
value: "DISALLOW_TO_FAILOVER"
将在 pgpool.conf
中转换为以下配置参数。
backend_hostname0 = 'mypostgres'
backend_hostname1 = 'mypostgres-replica'
backend_flag0 = 'ALWAYS_PRIMARY|DISALLOW_TO_FAILOVER'
backend_flag1 = 'DISALLOW_TO_FAILOVER'
然后,您需要定义包含 PostgreSQL
用户的用户名和密码的环境变量,用于客户端身份验证。
配置清单后,运行以下命令部署 Pgpool-II
。
kubectl apply -f pgpool-deploy-minimal.yaml
使用 ConfigMap
配置 Pgpool-II
或者,您可以使用 Kubernetes ConfigMap
来存储整个 pgpool.conf
和 pool_hba.conf
。ConfigMap
可以作为卷挂载到 Pgpool-II
的容器中。
您可以从以下存储库下载定义 ConfigMap
和 Deployment
的示例清单文件。
pgpool2_on_k8s
curl -LO https://raw.githubusercontent.com/pgpool/pgpool2_on_k8s/master/pgpool-configmap.yaml
curl -LO https://raw.githubusercontent.com/pgpool/pgpool2_on_k8s/master/pgpool-deploy.yaml
定义 ConfigMap
的清单采用以下格式。您可以根据您的配置偏好对其进行更新。要使用 pool_hba.conf
进行客户端身份验证,您需要打开 enable_pool_hba
。 默认为关闭。
enable_pool_hba
apiVersion: v1
kind: ConfigMap
metadata:
name: pgpool-config
labels:
name: pgpool-config
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'
...
pool_hba.conf: |-
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
hostssl all all 0.0.0.0/0 md5
然后,您需要定义包含 PostgreSQL
用户的用户名和密码的环境变量,用于客户端身份验证。
运行以下命令创建 ConfigMap
并部署引用此 ConfigMap
的 Pgpool-II
pod。
kubectl apply -f pgpool-configmap.yaml
kubectl apply -f pgpool-deploy.yaml
部署 Pgpool-II
后,您可以使用 kubectl get pod
和 kubectl get svc
命令查看 Pgpool-II
pod 和服务。
Pgpool-II 配置
后端设置
在 Kubernetes
上,您只需要指定两个后端节点。指定主服务名称为 backend_hostname0
,副本服务名称为 ackend_hostname1
。
backend_hostname0 = '<primary service name>'
backend_hostname1 = '<replica service name>'
backend_port0 = '5432'
backend_port1 = '5432'
自动故障转移
Pgpool-II
能够定期连接到已配置的 PostgreSQL
后端并检查 PostgreSQL
的状态。 如果检测到错误,Pgpool-II
将触发故障转移。在 Kubernetes
上,Kubernetes
会监控 PostgreSQL
的 Pod
,如果一个 Pod
宕机,Kubernetes
会重启一个新的 Pod
。您需要禁用 Pgpool-II
的自动故障转移,因为 Kubernetes
不需要 Pgpool-II
的自动故障转移。
将 PostgreSQL
node 0 指定为主节点 (ALWAYS_PRIMARY
),因为即使主节点或副本 pod
扩展、重新启动或发生故障转移,服务名称也不会更改。
backend_flag0 ='ALWAYS_PRIMARY|DISALLOW_TO_FAILOVER'
backend_flag1 ='DISALLOW_TO_FAILOVER'
failover_on_backend_error = off
将密码注册到 pool_passwd
Pgpool-II
使用包含 PostgreSQL
用户密码的 pool_passwd
文件执行身份验证。
在 Pgpool-II
pod 启动时,Pgpool-II
自动执行 pg_md5
命令,根据 <some string>_USERNAME
和 <some string>_PASSWORD
格式定义的环境变量生成 pool_passwd
。
代表 PostgreSQL
用户的用户名和密码的环境变量必须按以下格式定义:
username: <some string>_USERNAME
password: <some string>_PASSWORD
使用 Secret
定义环境变量是保证用户凭据安全的推荐方法。在大多数 PostgreSQL Operators
中,创建 PostgreSQL
集群时会自动创建几个定义 PostgreSQL
用户凭据的 Secret
。 使用 kubectl get secret
命令检查现有的 Secret
。
例如,创建 mypostgres-postgres-secret
来存储 postgres
用户的用户名和密码。 要引用这个 secret
,您可以定义如下环境变量:
env:
- name: POSTGRES_USERNAME
valueFrom:
secretKeyRef:
name: mypostgres-postgres-secret
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: mypostgres-postgres-secret
key: password
启动 Pgpool-II
pod 时,会在 /opt/pgpool-II/etc
下自动生成 pool_passwd
和 pcp.conf
。
$ kubectl exec <pgpool pod> -it -- cat /opt/pgpool-II/etc/pool_passwd
postgres:md53175bce1d3201d16594cebf9d7eb3f9d
$ kubectl exec <pgpool pod> -it -- cat /opt/pgpool-II/etc/pcp.conf
postgres:e8a48653851e28c69d0506508fb27fc5
流复制检查
Pgpool-II
能够定期连接到已配置的 PostgreSQL
后端并检查复制延迟。要使用此功能,需要 sr_check_user
和 sr_check_password
。如果 sr_check_password
留空,Pgpool-II
将尝试从 pool_passwd
获取 sr_check_user
的密码。
sr_check_user
sr_check_password
下面是一个使用 postgres
用户每隔 10
秒连接到 PostgreSQL
以执行流式复制检查的示例。因为 sr_check_password
留空,所以 Pgpool-II
会从 pool_passwd
中获取 postgres
用户的密码。
sr_check_period = 10
sr_check_user='postgres'
创建 secret
存储 sr_check_user
中指定的 PostgreSQL
用户的用户名和密码,并配置环境变量以引用创建的 Secret
。 在大多数 PostgreSQL Operators
中,创建 PostgreSQL
集群时会自动创建几个定义 PostgreSQL
用户凭据的 secret
。使用 kubectl get secret
命令检查现有的 secret
。
例如,下面的环境变量引用了 Secret mypostgres-postgres-secret
。
env:
- name: POSTGRES_USERNAME
valueFrom:
secretKeyRef:
name: mypostgres-postgres-secret
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: mypostgres-postgres-secret
key: password
但是,在 Kubernetes
上,Pgpool-II
连接到任何副本,而不是连接到所有副本。 即使有多个副本,Pgpool-II
也将它们作为一个副本进行管理。因此,Pgpool-II
可能无法正确确定复制延迟。要禁用此功能,请配置以下参数:
sr_check_period = 0
SSL 设置
打开 ssl
以启用 SSL
连接。
ssl = on
当 ssl = on
时,在 Pgpool-II
启动时,会在 /opt/pgpool-II/certs/
下自动生成私钥文件和证书文件。 ssl_key
和 ssl_cert
会自动配置私钥文件和证书文件的路径。
此外,要仅允许 SSL
连接,请将以下记录添加到 pool_hba.conf
中。
hostssl all all 0.0.0.0/0 md5
带监控的 Pgpool-II
Pgpool-II Exporter
是 Pgpool-II
指标的 Prometheus
导出器。
Pgpool-II Exporter
示例清单 pgpool-deploy-metrics.yaml
用于在 Pgpool-II
Pod 中部署 Pgpool-II
容器和 Pgpool-II Exporter
容器。
spec:
containers:
- name: pgpool
image: pgpool/pgpool
...
- name: pgpool-stats
image: pgpool/pgpool2_exporter
...
下载示例清单 pgpool-deploy-metrics.yaml
。
$ curl -LO https://raw.githubusercontent.com/pgpool/pgpool2_on_k8s/master/pgpool-deploy-metrics.yaml
然后,配置 Pgpool-II
和 Pgpool-II Exporter
。以下是 Pgpool-II Exporter
容器中用于连接 Pgpool-II
的环境变量的设置。
env:
- name: POSTGRES_USERNAME
valueFrom:
secretKeyRef:
name: mypostgres-postgres-secret
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: mypostgres-postgres-secret
key: password
- name: PGPOOL_SERVICE
value: "localhost"
- name: PGPOOL_SERVICE_PORT
value: "9999"
配置 Pgpool-II
和 Pgpool-II Exporter
后,部署 Pgpool-II Pod
。
kubectl apply -f pgpool-configmap.yaml
kubectl apply -f pgpool-deploy-metrics.yaml
更多
云原生 PostgreSQL - CrunchyData PGO 教程:创建、连接、删除 Postgres 集群
「在 Kubernetes 上运行 Pgpool-Il」实现 PostgreSQL 查询(读)负载均衡和连接池的更多相关文章
- 在Kubernetes上运行SAP UI5应用(下): 一个例子体会Kubernetes内容器的高可用性和弹性伸缩
上一篇文章 在Kubernetes上运行SAP UI5应用(上),我介绍了如何在Docker里运行一个简单的SAP UI5应用,并且已经成功地将一个包含了这个UI5应用的docker镜像上传到Dock ...
- 在kubernetes上运行WASM负载
在kubernetes上运行WASM负载 WASM一般用在前端业务中,但目前有扩展到后端服务的趋势.本文使用Krustlet 将WASM服务部署到kubernetes. 简介 Krustlet 是一个 ...
- 在Docker和Kubernetes上运行MongoDB微服务
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟.容器是完全使用沙箱机制,相互之间不会有任何接 ...
- 在Kubernetes上运行SAP UI5应用(上)
2018年只剩最后30天了.Jerry在2017年的最后一天,曾经立下一个目标:这个微信公众号在2018年保证至少每周发布一篇SAP原创技术文章. 从Jerry在后台统计的2018全年文章数量来看,这 ...
- 在Kubernetes上运行有状态应用:从StatefulSet到Operator
一开始Kubernetes只是被设计用来运行无状态应用,直到在1.5版本中才添加了StatefulSet控制器用于支持有状态应用,但它直到1.9版本才正式可用.本文将介绍有状态和无状态应用,一个通过K ...
- 在 Kubernetes 上运行高可用的 Kafka 集群
转载自:https://www.qikqiak.com/post/deploy-kafka-ha-on-k8s/ Apache Kafka 是目前最流行的分布式消息发布订阅系统,虽然 Kafka 非常 ...
- 史上最全Spring Cloud Alibaba--Nacos教程(涵盖负载均衡、配置管理、多环境切换、配置共享/刷新、灰度、集群)
能够实现Nacos安装 基于Nacos能实现应用负载均衡 能基于Nacos实现配置管理 配置管理 负载均衡 多环境切换 配置共享 配置刷新 灰度发布 掌握Nacos集群部署 1 Nacos安装 Nac ...
- kubernetes云平台管理实战: 自动加载到负载均衡(七)
一.如何实现外界能访问 外界访问不了 1.启动svc [root@k8s-master ~]# cat myweb-svc.yaml apiVersion: v1 kind: Service meta ...
- 实例演示:如何在Kubernetes上大规模运行CI/CD
本周四晚上8:30,第二期k3s在线培训如约开播!本期课程将介绍k3s的核心架构,如高可用架构以及containerd.一起来进阶探索k3s吧! 报名及观看链接:http://z-mz.cn/PmwZ ...
随机推荐
- Solon Web 开发,五、数据访问、事务与缓存应用
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- WebGPU | 相关知识概述
首先看下WebGPU的目标: 同时支持实时屏幕渲染和离屏渲染. 使通用计算能够在 GPU 上高效执行. 支持针对各种原生 GPU API 的实现:Microsoft 的 D3D12.Apple 的 M ...
- pytest文档1-环境搭建
1.安装方法 pip install -U pytest 2.查看安装版本 pip show pytest pytest -version 3.快速开始 新建test开头py文件 打开test_sam ...
- For Update 加锁分析
MySQL InnoDB 锁 - For Update 加锁分析: 1. InnoDB锁 简单介绍 2. 当前读加锁分析:REPEATABLE-READ 可重复读.READ-COMMITTED 读已提 ...
- linux搭建本地和网络yum源
[mirrors.163.com] name=mirrors.163.com baseurl=http://mirrors.163.com/centos/7/os/x86_64/ enabled=1 ...
- @ResponeBody 和 @RequestBody
一.补充注解?1.@ResponseBody 将数据转成json 并输出到响应流中2.@RequestBody 将请求中的json数据转换成java对象.1.1 jsp页面 增添两个点击事件. 1.2 ...
- Redis实现延迟对列
一.应用场景: 订单超过 30 分钟未支付,则自动取消. 外卖商家超时未接单,则自动取消. 医生抢单电话点诊,超过 30 分钟未打电话,则自动退款.等等场景都可以用定时任务去轮询实现,但是当数据量过大 ...
- bom-setTimeout
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- tomcat访问所有的资源,都是用Servlet来实现的
感谢大佬:https://www.zhihu.com/question/57400909 tomcat访问所有的资源,都是用Servlet来实现的. 在Tomcat看来,资源分3种 静态资源,如css ...
- Java语言中的访问权限修饰符
一个Java应用有很多类,但是有些类,并不希望被其他类使用.每个类中都有数据成员和方法成员,但是并不是每个数据和方法,都允许在其他类中调用.如何能做到访问控制呢?就需要使用访问权限修饰符. Java语 ...