本文共 23812 字,大约阅读时间需要 79 分钟。
在紧迫的期限内使用敏捷方法在压力锅生产环境中使用数据库可能会产生矛盾。 如本文所示,您可以执行许多步骤,并为任何服务范围准备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使用一个特殊的配置文件来定义我们要管理的所有那些主机:
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
登录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" }
( 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 ...
( 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消除了数据库膨胀,所以我邀请您花一些时间来阅读它。
( 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服务器了! 我喜欢逐步建立网络。 这样,如果出现问题,我可以避免调试时的痛苦。
除了初始化数据集群之外,我们还在此剧本中包括以下步骤:
现在,我要花点时间:为了保持更改尽可能整洁和清晰,我在配置文件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 ...
( 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 ...
( hosts.cfg 07.pg1_upgrade_94- 96 .yml )
在最佳情况下从一个版本的Postgres升级到另一个版本可能很棘手。 但是正确配置的剧本甚至可以使这成为一个简单的主张:
ansible-playbook -i hosts.cfg 07.pg1_upgrade_94- 96 .yml
在此示例中,我们通过执行以下步骤来升级在故障转移示例中已关闭的pg1 :
注意:剥皮猫的方法不只一种,所以写这本剧本的方法也很多。 由你决定。
--- - 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模块之一来避免学习的诱惑,您将走得更远,更快。
翻译自:
转载地址:http://rwpzd.baihongyu.com/