在紧迫的期限内使用敏捷方法在压力锅生产环境中使用数据库可能会产生矛盾。 如本文所示,您可以执行许多步骤,并为任何服务范围准备Postgres。 关键是Ansible,这是一个用于软件供应,配置管理和应用程序部署的开源自动化引擎。
如何在开发人员工作站上管理数据库服务器集群
作为根,我创建模板容器:
lxc-create -t download -n template_centos6 -- --dist centos --release 6 --arch amd64
让我们启动容器,添加以下包:
lxc-start
-n template_centos6
lxc-attach
-n template_centos6
--
<< _eof_
yum update
-y
yum install openssh-server
screen mlocate
man
vim python-psycopg2
sudo
-y
/ usr
/ sbin
/ makewhatis
/ usr
/ bin
/
updatedb
useradd ansible
echo ansible
|
passwd
--stdin ansible
echo
-e
'\n\n# ANSIBLE GLOBAL PERMISSIONS FOR DEMO PURPOSES ONLY\nansible ALL=(ALL) PASSWD:ALL'
>>
/ etc
/ sudoers
_eof_
现在我们准备制作实际的容器:
lxc-stop
-n template_centos6
for u
in ansible pg1 pg2 pg3
do
lxc-copy
-n template_centos6
-N
$u
done
让我们准备容器Ansible :
lxc-start
-n ansible
lxc-attach
-n ansible
<< _eof_
rpm
-Uvh http:
// download.fedoraproject.org
/ pub
/ epel
/
6
/ i386
/ epel-release-
6 -
8 .noarch.rpm
yum install ansible
-y
/ usr
/ sbin
/ makewhatis
/ usr
/ bin
/
updatedb
su
-c
"ssh-keygen -t rsa -N '' -f /home/ansible/.ssh/id_rsa" ansible
_eof_
让我们打开一切:
for u
in $
(
seq
3
)
do
lxc-start
-n pg
$u
done
看看我们的环境是什么样的:
root
@ wolven:~
# lxc-ls --fancy
NAME STATE AUTOSTART GROUPS IPV4 IPV6
ansible RUNNING
0 - 10.0.3.7 -
pg1 RUNNING
0 - 10.0.3.6 -
pg2 RUNNING
0 - 10.0.3.168 -
pg3 RUNNING
0 - 10.0.3.17 -
template_centos6 RUNNING
0 - 10.0.3.173 -
恭喜,您的Linux机器上的网络已经正常运行!
配置我们的Ansible容器
现在,让我们开始工作并在来宾主持人Ansible上创建剧本。 Ansible使用一个特殊的配置文件来定义我们要管理的所有那些主机:
lxc-attach
-n ansible
su - ansible
mkdir
-p
$HOME
/ playbooks
echo
"
pg1 ansible_ssh_pass=ansible ansible_sudo_pass=ansible
pg2 ansible_ssh_pass=ansible ansible_sudo_pass=ansible
pg3 ansible_ssh_pass=ansible ansible_sudo_pass=ansible
"
>
$HOME
/ playbooks
/ host.cfg
ping pg服务器
登录Ansible主机后,我们现在将使用adhoq命令对PostgreSQL主机( pg )进行ping操作。 有关命令行上使用的各种开关的更多信息,请参见手册页:
ansible -i $HOME / playbooks / hosts.cfg all -m ping
这是输出:
pg3
| SUCCESS =
>
{
"changed" :
false ,
"ping" :
"pong"
}
pg2
| SUCCESS =
>
{
"changed" :
false ,
"ping" :
"pong"
}
pg1
| SUCCESS =
>
{
"changed" :
false ,
"ping" :
"pong"
}
添加存储库:PostgreSQL 9.4和9.6版
( 01.install_repo.yml )
剧本01.install_repo.yml将postgres.org存储库安装到每个来宾主机上。 注意,我们将安装两个版本的Postgres(版本9.4和9.6),这使得执行内联升级成为可能:
ansible-playbook -i hosts.cfg 01.install_repo.yml
---
- hosts: dbservers
remote_user: ansible
become:
yes
tasks:
- name:
install repo
for PostgreSQL
9.4
yum:
name: https:
// download.postgresql.org
/ pub
/ repos
/ yum
/
9.4
/ redhat
/ rhel-
6 -x86_64
/ pgdg-centos94-
9.4 -
3 .noarch.rpm
state: present
- name:
install repo
for PostgreSQL
9.6
yum:
name: https:
// download.postgresql.org
/ pub
/ repos
/ yum
/
9.6
/ redhat
/ rhel-
6 -x86_64
/ pgdg-centos96-
9.6 -
3 .noarch.rpm
state: present
...
安装9.4的Postgres软件包
( 02.install_94.yml )
配置了仓库之后,我们现在可以安装rpms了 。 注意在我们的剧本调用中变量的使用和with_items循环:
ansible-playbook -i hosts.cfg 02.install_94.yml --extra-vars "host=dbservers"
---
- hosts:
"{{ host }}"
remote_user: ansible
become:
yes
tasks:
- name:
install PostgreSQL version
9.4
yum:
name:
"{{ item }}"
state: latest
with_items:
- postgresql94-server
- postgresql94-contrib
- pg_repack94
...
注意:尽管没有讨论, pg_repack94消除了数据库膨胀,所以我邀请您花一些时间来阅读它。
在所有数据库服务器上为Unix帐户Ansible添加公钥
( 03.install_key.yml )
添加公开密钥是我几年前采用的一种做法。 这是一种访问计算机的安全,简便的方法,更不用说对于在紧急情况下因输入密码错误而引起恐慌并意外将自己锁定在服务器之外的情况非常有用。
这是我们的剧本install_key.yml :
---
- hosts: dbservers
remote_user: ansible
become:
yes
tasks:
- name:
install repo
for PostgreSQL
9.4
yum:
name: https:
// download.postgresql.org
/ pub
/ repos
/ yum
/
9.4
/ redhat
/ rhel-
6 -x86_64
/ pgdg-centos94-
9.4 -
3 .noarch.rpm
state: present
- name:
install repo
for PostgreSQL
9.6
yum:
name: https:
// download.postgresql.org
/ pub
/ repos
/ yum
/
9.6
/ redhat
/ rhel-
6 -x86_64
/ pgdg-centos96-
9.6 -
3 .noarch.rpm
state: present
...
这是我们的调用。 注意使用额外的变量来标识Unix帐户Ansible :
ansible-playbook -i hosts.cfg install_key.yml --extra-vars "user=ansible"
将每个主机配置为独立服务
( 04.configure_standalone_94.yml )
现在所有组件都准备就绪,现在该创建我们的Postgres服务器了! 我喜欢逐步建立网络。 这样,如果出现问题,我可以避免调试时的痛苦。
除了初始化数据集群之外,我们还在此剧本中包括以下步骤:
- 启动Postgres服务
- 使用密码创建角色副本
- 更新pg_hba.conf允许远程访问
- 更新postgresql.conf以进行主/从服务
现在,我要花点时间:为了保持更改尽可能整洁和清晰,我在配置文件postgresql.conf后面附加了一行,描述了包含文件,我们将在其中找到所有在单独的文件中进行更改,从而提高清晰度。 Ansible关键字blockinfile很酷,因为它在一个不错的,带有大标签的块内将自己标识的文件中添加了文本。
主站和从站之间的连接权限在pg_hba.conf中更新。 请记住,真正安全的环境中经常使用复制服务器,我们不是在这里做什么之间的SSL加密。
这是我们的调用。 注意,我们已经输入了复制密码作为参数。 它不仅安全,而且现在我们为脚本增加了灵活性:
ansible-playbook -i hosts.cfg 04.configure_standalone_94.yml --extra-vars "host=dbservers passwd=mypassword"
---
- hosts:
"{{ host }}"
remote_user: ansible
become:
yes
tasks:
- name: create data cluster
command: service postgresql-
9.4 initdb
- service:
name: postgresql-
9.4
state: started
- hosts:
"{{ host }}"
remote_user: postgres
tasks:
- name: create ROLE replicant
postgresql_user:
db: postgres
login_unix_socket:
/ tmp
name: replicant
password:
"{{ passwd }}"
role_attr_flags: LOGIN,REPLICATION
- name: add new configuration to
"postgresql.conf"
blockinfile:
dest:
/ var
/ lib
/ pgsql
/
9.4
/ data
/ postgresql.conf
block:
|
include
'server.conf'
- name: add new configuration to
"server.conf"
blockinfile:
create:
yes
dest:
/ var
/ lib
/ pgsql
/
9.4
/ data
/ server.conf
block:
|
listen_addresses =
'*'
wal_level = hot_standby
checkpoint_segments =
10
max_wal_senders =
6
wal_keep_segments =
10
hot_standby = on
- name: add new configuration to
"pg_hba.conf"
blockinfile:
dest:
/ var
/ lib
/ pgsql
/
9.4
/ data
/ pg_hba.conf
block:
|
host all all 0.0.0.0
/
0 md5
host replication replicant 0.0.0.0
/
0 md5
- name: update environment variables
in UNIX account postgres
blockinfile:
create:
yes
dest:
/ var
/ lib
/ pgsql
/ .pgsql_profile
block:
|
export
PGHOST =
/ tmp
PAGER =
less
PGDATA =
/ var
/ lib
/ pgsql
/
9.2
/ data
- hosts:
"{{ host }}"
remote_user: ansible
become:
yes
tasks:
- service:
name: postgresql-
9.4
state: restarted
- name: configure init
for startup on bootup
shell: chkconfig
--level
2345 postgresql-
9.4 on
...
配置Postgres从属
( 05.configure_slave_94.yml )
以前的将服务器准备为独立模式的脚本实际上是通过使用配置文件postgresql.conf和server.conf预先配置/启用从属主机,从而杀死了两只小鸟,使用pg_basebackup命令将其复制到从属主机 。 在这个示例中,特别有趣的是我们如何创建级联的复制从属pg3 ,它从从属pg2获取其数据。 注意脚本的第二部分; 我们通过直接登录Postgres而不是Sudo来利用先前脚本中安装的Ansible公钥:
ansible-playbook
-i hosts.cfg 05.configure_slave_94.yml
--extra-vars
"master=pg1 slave=pg2 passwd=mypassword"
ansible-playbook
-i hosts.cfg 05.configure_slave_94.yml
--extra-vars
"master=pg2 slave=pg3 passwd=mypassword"
---
- hosts:
"{{ slave }}"
remote_user: ansible
become:
yes
tasks:
- service:
name: postgresql-
9.4
state: stopped
- file:
path:
/ var
/ lib
/ pgsql
/
9.4
/ data
/
state: absent
- file:
path:
/ var
/ lib
/ pgsql
/
9.4
/ data
/
owner: postgres
group: postgres
mode: 0700
state: directory
- hosts:
"{{ slave }}"
remote_user: postgres
tasks:
- name: execute base backup
shell:
export
PGPASSWORD =
"{{ passwd }}"
&&
/ usr
/ pgsql-
9.4
/ bin
/ pg_basebackup
-h pg1
-U replicant
-D
/ var
/ lib
/ pgsql
/
9.4
/ data
-P
-v
--xlog-method =stream
2
>&
1
- name: add new configuration
"recovery.conf"
blockinfile:
create:
yes
dest:
/ var
/ lib
/ pgsql
/
9.4
/ data
/ recovery.conf
block:
|
standby_mode =
'on'
primary_conninfo =
'user=replicant password={{ passwd }} host={{ master }} port=5432 sslmode=prefer'
recovery_target_timeline =
'latest'
- hosts:
"{{ slave }}"
remote_user: ansible
become:
yes
tasks:
- service:
name: postgresql-
9.4
state: started
...
调用故障转移
( 06.failover_94.yml )
危险威尔·罗宾逊,危险!!
实际上,我们只是将其关闭。
故障转移和升级非常容易; 只需对pg2执行一个命令就可以了。 由于pg3被配置为级联从属服务器,它将自动从新提升的主服务器复制。 秘密位于recovery.conf文件中,在该文件中,我们将其配置为始终读取最新的时间轴:
ansible-playbook -i hosts.cfg 06.failover_94.yml
---
- hosts: pg1
remote_user: ansible
become:
yes
tasks:
- service:
name: postgresql-
9.4
state: stopped
- hosts: pg2
remote_user: postgres
tasks:
- name: promote data cluster pg4
command:
/ usr
/ pgsql-
9.4
/ bin
/ pg_ctl
-D
/ var
/ lib
/ pgsql
/
9.4
/ data
/ promote
...
将服务器从9.4升级到9.6
( hosts.cfg 07.pg1_upgrade_94- 96 .yml )
在最佳情况下从一个版本的Postgres升级到另一个版本可能很棘手。 但是正确配置的剧本甚至可以使这成为一个简单的主张:
ansible-playbook -i hosts.cfg 07.pg1_upgrade_94- 96 .yml
在此示例中,我们通过执行以下步骤来升级在故障转移示例中已关闭的pg1 :
- 将Postgres 9.6版二进制文件安装到我们的三台主机上
- 关闭9.4服务,并在服务器重新启动后禁用二进制文件的启动
- 如果需要重新启动计算机,请启用9.6二进制文件
- 为Postgres的升级版本创建一个空的数据集群; 可以选择删除任何以前存在的
- 使用pg_upgrade实用程序执行升级过程; 注意使用两个不同的端口号
- 使用一组更新的配置(即postgresql.conf , server.conf和pg_hba.conf)更新版本9.6数据集群。
- 登录Unix Postgres帐户时更新运行时环境变量,以简化管理
- 启动我们新的Postgres版本9.6服务
注意:剥皮猫的方法不只一种,所以写这本剧本的方法也很多。 由你决定。
---
- hosts: all
remote_user: ansible
become:
yes
tasks:
- name:
install repo
for PostgreSQL
9.6
yum:
name: https:
// download.postgresql.org
/ pub
/ repos
/ yum
/
9.6
/ redhat
/ rhel-
6 -x86_64
/ pgdg-centos96-
9.6 -
3 .noarch.rpm
state: present
- name:
install PostgreSQL version
9.6
yum:
name:
"{{ item }}"
state: latest
with_items:
- postgresql96-server
- postgresql96-contrib
- pg_repack96
- name: disable init
for
9.4
shell: chkconfig
--level
2345 postgresql-
9.4 off
- name:
enable init
for
9.6
shell: chkconfig
--level
2345 postgresql-
9.6 on
- hosts: pg1
remote_user: ansible
become:
yes
tasks:
- service:
name: postgresql-
9.6
state: stopped
- file:
path:
/ var
/ lib
/ pgsql
/
9.6
/ data
/
state: absent
- name: create data cluster
command: service postgresql-
9.6 initdb
- hosts: pg1
remote_user: postgres
tasks:
- name: execute the upgrade from
9.4 to
9.6
shell:
|
/ usr
/ pgsql-
9.6
/ bin
/ pg_upgrade \
-d
/ var
/ lib
/ pgsql
/
9.4
/ data \
-D
/ var
/ lib
/ pgsql
/
9.6
/ data \
-b
/ usr
/ pgsql-
9.4
/ bin \
-B
/ usr
/ pgsql-
9.6
/ bin \
-p
10094 \
-P
5432
exit
0
- name: add new configuration to
"postgresql.conf"
blockinfile:
dest:
/ var
/ lib
/ pgsql
/
9.6
/ data
/ postgresql.conf
block:
|
include
'server.conf'
- name: add new configuration to
"server.conf"
blockinfile:
create:
yes
dest:
/ var
/ lib
/ pgsql
/
9.6
/ data
/ server.conf
block:
|
listen_addresses =
'*'
wal_level = hot_standby
max_wal_senders =
6
wal_keep_segments =
10
hot_standby = on
- name: add new configuration to
"pg_hba.conf"
blockinfile:
dest:
/ var
/ lib
/ pgsql
/
9.6
/ data
/ pg_hba.conf
block:
|
host all all 0.0.0.0
/
0 md5
host replication replicant 0.0.0.0
/
0 md5
- name: update environment variables
in UNIX account postgres
blockinfile:
create:
yes
dest:
/ var
/ lib
/ pgsql
/ .pgsql_profile
block:
|
export
PGHOST =
/ tmp
PAGER =
less
PGDATA =
/ var
/ lib
/ pgsql
/
9.6
/ data
- hosts: pg1
remote_user: ansible
become:
yes
tasks:
- service:
name: postgresql-
9.6
state: started
...
调用故障转移
( 08.configure_slave_96.yml )
该脚本实际上与脚本05.configure_slave_94.yml相同。 您甚至可能想要对其进行编辑,从而从您的集合中删除一个脚本:
ansible-playbook
-i hosts.cfg 08.configure_slave_96.yml
--extra-vars
"master=pg1 slave=pg2 passwd=mypassword"
ansible-playbook
-i hosts.cfg 08.configure_slave_96.yml
--extra-vars
"master=pg2 slave=pg3 passwd=mypassword"
---
- hosts:
"{{ slave }}"
remote_user: ansible
become:
yes
tasks:
- service:
name: postgresql-
9.4
state: stopped
- service:
name: postgresql-
9.6
state: stopped
- file:
path:
/ var
/ lib
/ pgsql
/
9.6
/ data
/
state: absent
- file:
path:
/ var
/ lib
/ pgsql
/
9.6
/ data
/
owner: postgres
group: postgres
mode: 0700
state: directory
- hosts:
"{{ slave }}"
remote_user: postgres
tasks:
- name: execute base backup
shell:
|
export
PGPASSWORD =
"{{ passwd }}"
&& \
/ usr
/ pgsql-
9.6
/ bin
/ pg_basebackup \
-h pg1 \
-U replicant \
-D
/ var
/ lib
/ pgsql
/
9.6
/ data \
-P
-v
--xlog-method =stream
2
>&
1
exit
0
- name: add new configuration
"recovery.conf"
blockinfile:
create:
yes
dest:
/ var
/ lib
/ pgsql
/
9.6
/ data
/ recovery.conf
block:
|
standby_mode =
'on'
primary_conninfo =
'user=replicant password={{ passwd }} host={{ master }} port=5432 sslmode=prefer'
recovery_target_timeline =
'latest'
- name: update environment variables
in UNIX account postgres
blockinfile:
create:
yes
dest:
/ var
/ lib
/ pgsql
/ .pgsql_profile
block:
|
export
PGHOST =
/ tmp
PAGER =
less
PGDATA =
/ var
/ lib
/ pgsql
/
9.6
/ data
- hosts:
"{{ slave }}"
remote_user: ansible
become:
yes
tasks:
- service:
name: postgresql-
9.6
state: started
...
结论
使用关系数据库管理系统成功进行编码通常被认为是任何值得他付出代价的开发人员的性感能力。 然而,当我回顾我多年来的所有对话,站立和会议时,它常常被证明是所有活动中最关键,最耗时和最神奇的。 整个开发团队将花费数小时来讨论数据在前端和后端之间的移动方式。 在成功设计和实现用户界面与其持久存储之间的数据移动之后,摇滚明星开发人员将一马当先。 从来没有像RDBMS这么平凡的东西依赖它。 在这个大数据和分析时代,PostgreSQL在其悠久的历史中从未有过像今天这样的广泛采用和对基础架构的关键意义。
不要在这里停下来! 无论如何,请继续阅读出色的在线文档,并创建自己的剧本。 一点建议,通过使用Ansible Galaxy中可用的众多Postgres模块之一来避免学习的诱惑,您将走得更远,更快。
Ansible参考
- 入门
- 安装
- 临时命令简介
- 关于模块
- 所有模块清单
- 有关Ansible模块的Ansible-doc文档
- Ansible手册页
Postgres参考
翻译自: https://opensource.com/article/17/6/ansible-postgresql-operations