如何使用Ansible管理PostgreSQL

在紧迫的期限内使用敏捷方法在压力锅生产环境中使用数据库可能会产生矛盾。 如本文所示,您可以执行许多步骤,并为任何服务范围准备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.ymlpostgres.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.confserver.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.confserver.confpg_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参考

Postgres参考

翻译自: https://opensource.com/article/17/6/ansible-postgresql-operations

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值