èšç»ã©ãããä»»æã®ãµãŒããŒãŸãã¯è€æ°ã®ãµãŒããŒã®æå€±ãçµéšããäºæ åŸã«ãµãŒããŒãèªåçã«ã³ããã·ã§ã³ã§ããã¯ã©ã¹ã¿ãŒãååŸãããã£ãã®ã§ãã
ã¯ã©ã¹ã¿ãŒãèšç»ãããšããPostgreSQLã®ã¡ã€ã³ããã¥ã¡ã³ããšHabrãå«ãããŸããŸãªããŠããŒã®äž¡æ¹ããå€ãã®èšäºãç ç©¶ããRepMgrã䜿çšããŠæšæºã¯ã©ã¹ã¿ãŒãæ§æããpgpoolã詊ããŸããã
äžè¬çã«ã¯ããŸããããŸããããæã åãæ¿ãã«åé¡ãçºçããããäºæ ããå埩ããããã«æåã®ä»å ¥ãå¿ èŠã«ãªããŸããã äžè¬çã«ãç§ã¯ããå€ãã®ãªãã·ã§ã³ãæ¢ãããšã«ããŸããã
ãã®çµæãã©ããïŒæ£ç¢ºã«ã¯ã©ãã«ãããã¯èŠããŠããŸããïŒçŸããZalando Patroniãããžã§ã¯ããžã®ãªã³ã¯ãèŠã€ããŠããã¹ãŠããŸãšããŸãã...
ã¯ããã«
Patroniã¯ãããŸããŸãªã¿ã€ãã®ã¬ããªã±ãŒã·ã§ã³ã§PostgreSQLã¯ã©ã¹ã¿ãŒãèªåçã«æäŸããããŒã«ãèªåçã«åãæ¿ããããšãã§ããPythonããŒã¢ã³ã§ãã
ç§ã®æèŠã§ã¯ããã®ç¹å¥ãªçŸããã¯ãã¯ã©ã¹ã¿ãŒãšãŠã£ã¶ãŒãã®éžæã®é¢é£æ§ãç¶æããããã«ã忣DCSãªããžããªãŒã䜿çšãããããšã§ãïŒZookeeperãetcdãConsulã«ãã£ãŠãµããŒããããŸãïŒã
ãããã£ãŠãã¯ã©ã¹ã¿ãŒã¯ã»ãšãã©ãã¹ãŠã®ã·ã¹ãã ã«ç°¡åã«çµ±åã§ããDCSã®èŠæ±ã«ãã£ãŠããŸãã¯httpãä»ããŠPatroniã«çŽæ¥ãçŸåšèª°ããã¹ã¿ãŒã§ããããã¹ãŠã®ãµãŒããŒã®ã¹ããŒã¿ã¹ãåžžã«ç¢ºèªã§ããŸãã
ãŸããããã¯ãã çŸããã§ã:)
Patroniã®äœæ¥ããã¹ããããŠã£ã¶ãŒããšä»ã®ãµãŒããŒãããããããããŸããŸãªããŒã¿ããŒã¹ã泚ã蟌ãããšããŸããïŒæ°åã§25 GBã®ããŒã¹ãèªåçã«0ãã10 GBã®ãããã¯ãŒã¯ã«äžæããŸããïŒã 以äžã«èª¬æããã¹ããŒã ãå®å šã«å®è£ ããåŸãåäžã®ã¢ãã¬ã¹ã§ããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ããåçŽãªãã³ãã£ãŒã§ãã¹ãããã¯ã©ã¹ã¿ãŒã®ãã¹ãŠã®èŠçŽ ïŒãµãŒããŒãã¹ã¿ãŒãhaproxyãkeepalivedïŒã®èœäžãçµéšããŸããã
圹å²ãæ°ãããã¹ã¿ãŒã«è»¢éããéã®é å»¶ã¯æ°ç§ã§ããã 以åã®ãã¹ã¿ãŒãã¯ã©ã¹ã¿ãŒã«æ»ãããæ°ãããµãŒããŒã远å ãããšãããŒã«ã®å€æŽã¯çºçããŸããã
ã¯ã©ã¹ã¿ãŒã®å±éãèªååããæ°ãããµãŒããŒã远å ããããã«ãäœ¿ãæ £ããAnsibleã䜿çšããããšã«ããŸããïŒãã®èšäºã®æåŸã«ãäœæãããããŒã«ãžã®ãªã³ã¯ã瀺ããŸãïŒã DCSãšããŠããã§ã«äœ¿çšãããŠããConsulã䜿çšãããŸãã
ãã®èšäºã«ã¯2ã€ã®äž»ãªç®æšããããŸãïŒPostgreSQLãŠãŒã¶ãŒã«Patroniã®ãããªçŽ æŽããããã®ãããããšã瀺ãããšïŒå®éã«ã¯Runetå šè¬ãšç¹ã«Habrã«èšåããããšã¯ã»ãšãã©ãããŸããïŒãšåæã«ãAnsibleã䜿çšããŠå°ãã®çµéšãå ±æããŸãã
Ansibleã®ããŒã«ãšãã¬ã€ããã¯ãè§£æããäŸã«ããããã¹ãŠã®ã¢ã¯ã·ã§ã³ãäžåºŠã«èª¬æããããšããŸãã Ansibleã䜿çšããªã人ã¯ããã¹ãŠã®ã¢ã¯ã·ã§ã³ãèªåãµãŒããŒç®¡ççšã®ãæ°ã«å ¥ãã®ããŒã«ã«è»¢éããããæåã§å®è¡ã§ããŸãã
yamlã¹ã¯ãªããã®ã»ãšãã©ã¯é·ãã®ã§ãã¹ãã€ã©ãŒã§ã©ããããŸãã
ã¹ããŒãªãŒã¯ããµãŒããŒã®æºåãšã¯ã©ã¹ã¿ãŒèªäœã®å±éã®2ã€ã®éšåã«åãããŸãã
Ansibleã«æ £ããŠãã人ã«ãšã£ãŠã¯ãæåã®éšåã¯ããããããªãã®ã§ã2çªç®ã®éšåã«çŽæ¥åãæ¿ããããšããå§ãããŸãã
ããŒãI
ãã®äŸã§ã¯ãCentos 7ããŒã¹ã®ä»®æ³ãã·ã³ã䜿çšããŠããŸããä»®æ³ãã·ã³ã¯ã宿çã«æŽæ°ããããã³ãã¬ãŒãïŒã«ãŒãã«ãã·ã¹ãã ããã±ãŒãžïŒãããããã€ãããŸããããã®ãããã¯ã¯ãã®èšäºã®ç¯å²å€ã§ãã
ä»®æ³ãã·ã³ã«ã¢ããªã±ãŒã·ã§ã³ãŸãã¯ãµãŒããŒãœãããŠã§ã¢ãäºåã«ã€ã³ã¹ããŒã«ãããŠããªãããšã«æ³šæããŠãã ããã ããšãã°ãAWSãDOãvScaleãªã©ã®ã¯ã©ãŠããªãœãŒã¹ãéåžžã«é©ããŠããŸãã ãããã«ã¯ãåçã€ã³ãã³ããªãšAnsibleãšã®çµ±åçšã®ã¹ã¯ãªããããããŸãããŸãã¯ãTerraformããã蟌ãããšãã§ããããããµãŒããŒãæåããäœæããã³åé€ããããã»ã¹å šäœãèªååã§ããŸãã
ãŸããAnsibleã®äœ¿çšæžã¿ãªãœãŒã¹ã®ã€ã³ãã³ããªãäœæããå¿ èŠããããŸãã ç§ã«ãšã£ãŠïŒãããŠããã©ã«ãã§ã¯ïŒAnsibleã¯/ etc / ansibleã«ãããŸãã / etc / ansible / hostsãã¡ã€ã«ã«ã€ã³ãã³ããªãäœæããŸãã
[pgsql] cluster-pgsql-01.local cluster-pgsql-02.local cluster-pgsql-03.local
å éšãã¡ã€ã³ãŸãŒã³.localã䜿çšããããããµãŒããŒã«ã¯ãããã®ååãä»ããããŸãã
次ã«ãå¿ èŠãªãã¹ãŠã®ã³ã³ããŒãã³ããšäœæ¥ããŒã«ãã€ã³ã¹ããŒã«ããããã«ãåãµãŒããŒãæºåããå¿ èŠããããŸãã
ãã®ç®çã®ããã«ã/ etc / ansible / tasksã§ãã¬ã€ããã¯ãäœæããŸãã
/etc/ansible/tasks/essentialsoftware.yml
--- - name: Install essential software yum: name={{ item }} state=latest tags: software with_items: - ntpdate - bzip2 - zip - unzip - openssl-devel - mc - vim - atop - wget - mytop - screen - net-tools - rsync - psmisc - gdb - subversion - htop - bind-utils - sysstat - nano - iptraf - nethogs - ngrep - tcpdump - lm_sensors - mtr - s3cmd - psmisc - gcc - git - python2-pip - python-devel - name: install the 'Development tools' package group yum: name: "@Development tools" state: present
Essentialããã±ãŒãžã®ããã±ãŒãžã¯ããããããµãŒããŒã§äœ¿ãæ £ããäœæ¥ç°å¢ãäœæããããã«äœ¿çšãããŸãã
éçºããŒã«ããã±ãŒãžã°ã«ãŒããããã€ãã®-develããã³pythonã©ã€ãã©ãªã¯ãpipãPostgreSQLçšã®Pythonã¢ãžã¥ãŒã«ãæ§ç¯ããããã«å¿ èŠã§ãã
VmWare ESXiã«åºã¥ããä»®æ³ãã·ã³ã䜿çšããŸãã管çã容æã«ããããã«ãvmwareãšãŒãžã§ã³ããå®è¡ããå¿ èŠããããŸãã
ãããè¡ãã«ã¯ããªãŒãã³ãšãŒãžã§ã³ãvmtoolsdãèµ·åããå¥ã®ãã¬ã€ããã¯ã§ãã®ã€ã³ã¹ããŒã«ã«ã€ããŠèª¬æããŸãïŒãã¹ãŠã®ãµãŒããŒãä»®æ³ã§ããããã§ã¯ãªããããäžéšã®ãµãŒããŒã§ã¯ãã®ã¿ã¹ã¯ãå¿ èŠãªãå ŽåããããŸãïŒã
/etc/ansible/tasks/open-vm-tools.yml
--- - name: Install open VM tools for VMWARE yum: name={{ item }} state=latest tags: open-vm-tools with_items: - open-vm-tools - name: VmWare service start and enabling service: name=vmtoolsd.service state=started enabled=yes tags: open-vm-tools
ãã®å ŽåããœãããŠã§ã¢ã®äž»èŠéšåãã€ã³ã¹ããŒã«ããããã®ãµãŒããŒã®æºåãå®äºããã«ã¯ãæ¬¡ã®æé ãå¿ èŠã§ãã
1ïŒntpã䜿çšããŠæå»åæãèšå®ãã
2ïŒç£èŠã®ããã«zabbixãšãŒãžã§ã³ããã€ã³ã¹ããŒã«ããŠå®è¡ãã
3ïŒå¿ èŠãªsshããŒãšauthorized_keysãããŒã«ããŸãã
ã¯ã©ã¹ã¿ãŒèªäœã«é¢é£ããªã詳现ã§èšäºãé床ã«èšåŒµãããªãããã«ããããã®ã¿ã¹ã¯ãå®è¡ããansibleãã¬ã€ããã¯ãç°¡åã«åŒçšããŸãã
NTPïŒ
/etc/ansible/tasks/ntpd.yml
--- - name: setting default timezone set_fact: timezone: name=Europe/Moscow when: timezone is not defined - name: setting TZ timezone: name={{ timezone }} when: timezone is defined tags: - tz - tweaks - ntp - ntpd - name: Configurating cron for ntpdate cron: name="ntpdate" minute="*/5" job="/usr/sbin/ntpdate pool.ntp.org" tags: - tz - tweaks - ntp - ntpd - name: ntpd stop and disable service: name=ntpd state=stopped enabled=no tags: - tz - tweaks - ntp - ntpd ignore_errors: yes - name: crond restart and enabled service: name=crond state=restarted enabled=yes tags: - tz - tweaks - ntp - ntpd
æåã«ããµãŒããŒã«å人çšã¿ã€ã ãŸãŒã³ãèšå®ãããŠãããã©ããã確èªãããèšå®ãããŠããªãå Žåã¯ã¢ã¹ã¯ã¯ãèšå®ãããŸãïŒãã®ãããªãµãŒããŒã®å€§éšåããããŸãïŒã
ESXiä»®æ³ãã·ã³ã§ã®æéå€åã«åé¡ããããããntpdã䜿çšããŸããããã®åŸãntpdã¯æéã®åæãæåŠããŸãã ïŒãããŠãããããåããããã¯0ã¯åœ¹ã«ç«ã¡ãŸããïŒã ãããã£ãŠãã¯ã©ãŠã³ã§ntpã¯ã©ã€ã¢ã³ãã5åã«1åèµ·åããã ãã§ãã
ZabbixãšãŒãžã§ã³ãïŒ
/etc/ansible/tasks/zabbix.yml
--- - name: set zabbix ip external set_fact: zabbix_ip: 132.xx.xx.98 tags: zabbix - name: set zabbix ip internal set_fact: zabbix_ip: 192.168.xx.98 when: ansible_all_ipv4_addresses | ipaddr('192.168.0.0/16') tags: zabbix - name: Import Zabbix3 repo yum: name=http://repo.zabbix.com/zabbix/3.0/rhel/7/x86_64/zabbix-release-3.0-1.el7.noarch.rpm state=present tags: zabbix - name: Remove old zabbix yum: name=zabbix2* state=absent tags: zabbix - name: Install zabbix-agent software yum: name={{ item }} state=latest tags: zabbix with_items: - zabbix-agent - zabbix-release - name: Creates directories file: path={{ item }} state=directory tags: - zabbix - zabbix-mysql with_items: - /etc/zabbix/externalscripts - /etc/zabbix/zabbix_agentd.d - /var/lib/zabbix - name: Copy scripts copy: src=/etc/ansible/templates/zabbix/{{ item }} dest=/etc/zabbix/externalscripts/{{ item }} owner=zabbix group=zabbix mode=0755 tags: zabbix with_items: - netstat.sh - iostat.sh - iostat2.sh - iostat_collect.sh - iostat_parse.sh - php_workers_discovery.sh - name: Copy .my.cnf copy: src=/etc/ansible/files/mysql/.my.cnf dest=/var/lib/zabbix/.my.cnf owner=zabbix group=zabbix mode=0700 tags: - zabbix - zabbix-mysql - name: remove default configs file: path={{ item }} state=absent tags: zabbix with_items: - /etc/zabbix_agentd.conf - /etc/zabbix/zabbix_agentd.conf - name: put zabbix-agentd.conf to default place template: src=/etc/ansible/templates/zabbix/zabbix_agentd.tpl dest=/etc/zabbix_agentd.conf owner=zabbix group=zabbix force=yes tags: zabbix - name: link zabbix-agentd.conf to /etc/zabbix file: src=/etc/zabbix_agentd.conf dest=/etc/zabbix/zabbix_agentd.conf state=link tags: zabbix - name: zabbix-agent start and enable service: name=zabbix-agent state=restarted enabled=yes tags: zabbix
Zabbixãã€ã³ã¹ããŒã«ãããšãããšãŒãžã§ã³ãèšå®ã¯ãã³ãã¬ãŒãããããŒã«ãããŸã;ãµãŒããŒã¢ãã¬ã¹ã®ã¿ã倿Žããå¿ èŠããããŸãã
ãããã¯ãŒã¯å ã«ãããµãŒããŒã¯192.168.x.98ã«ã¢ã¯ã»ã¹ããã¢ã¯ã»ã¹ã§ããªããµãŒããŒã¯åããµãŒããŒã®å®éã®ã¢ãã¬ã¹ã«ç§»åããŸãã
sshããŒã®è»¢éãšsshã®èšå®ã¯ãããšãã°ansible-galaxyã«ããå¥ã®ããŒã«ã«ç§»åãããŸããã
å€ãã®ãªãã·ã§ã³ãããã倿Žã®æ¬è³ªã¯éåžžã«ç°¡åã§ãããããããã§ãã¹ãŠã®å 容ãåŒçšããæå³ã¯ãããŸããã
äœæãããæ§æããµãŒããŒã«ããŒã«ããŸãã äžè¬ã«ãç§ã¯ãã¹ãŠã®ã³ã³ããŒãã³ããšã¯ã©ã¹ã¿ãŒèªäœã®ã€ã³ã¹ããŒã«ãã¯ã³ã¹ãããã§å®è¡ããŸããããã§ã«å®å šãªèšå®ãããŠããŸããããã®ãã¥ãŒããªã¢ã«ã®ç®çã®ããã«ãããããã®ç« ã§2ã€ã®ã¹ãããã«åå²ããæ¹ãè¯ããšæãããŸã
ãµãŒããŒã®ã°ã«ãŒãçšã®ãã¬ã€ããã¯ãäœæããŸãã
/etc/ansible/cluster-pgsql.yml
--- - hosts: pgsql pre_tasks: - name: Setting system hostname hostname: name="{{ ansible_host }}" - include: tasks/essentialsoftware.yml - include: tasks/open-vm-tools.yml - include: tasks/ntpd.yml post_tasks: - include: tasks/zabbix.yml roles: - ssh.role - ansible-role-patroni
ãã¹ãŠã®ãµãŒããŒã®åŠçãéå§ããŸãã
é衚瀺ã®ããã¹ã
ãïŒansible-playbook cluster-pgsql.yml --skip-tags patroni
githubãªããžããªããç§ã®äŸãå®å šã«ããŠã³ããŒãããå ŽåãPatroniã®åœ¹å²ãæã€ããšã«ãªããŸãããããã¯ãŸã 解決ããå¿ èŠã¯ãããŸããã
--skip-tagsåŒæ°ã«ãããAnsibleã¯ãã®ã¿ã°ã§ããŒã¯ãããã¹ããããã¹ããããããããansible-role-patroniããŒã«ã¯çŸåšå®è¡ãããŸããã
ãã£ã¹ã¯äžã«ãªãå Žåãã²ã©ãããšã¯äœãèµ·ãããŸãããã¢ãã¹ãã«ã¯ãã®ããŒãç¡èŠããŸãã
Ansibleã¯ããã«ã«ãŒããšããŠãµãŒããŒã«ãã°ã€ã³ããŸããæš©éã®ãªããŠãŒã¶ãŒãšããŠansibleãå®è¡ããå¿ èŠãããå Žåã¯ãã«ãŒãæš©éãå¿ èŠãšããã¹ãããã«ç¹å¥ãªãã©ã°ãbecomeïŒtrueãã远å ããå¿ èŠããããŸãã
æºåã¯çµãããŸããã
ããŒãII
ã¯ã©ã¹ã¿ãŒãçŽæ¥ãããã€ããŸãã
ã¯ã©ã¹ã¿ãŒã®èšå®ïŒPostgreSQLãšãã¹ãŠã®ã³ã³ããŒãã³ãã®ã€ã³ã¹ããŒã«ããããã®åå¥ã®èšå®ã®å ¥åïŒã«ã¯å€ãã®äœæ¥ãå¿ èŠãªããããã®ããã»ã¹å šäœãå¥ã®ããŒã«ã§éžã³ãŸããã
Ansibleã®ããŒã«ã䜿çšãããšãäžé£ã®é£æ¥ã¿ã¹ã¯ãã°ã«ãŒãåã§ãããããã¹ã¯ãªããã®èšè¿°ãšçšŒåç¶æ ã§ã®ã¡ã³ããã³ã¹ãç°¡åã«ãªããŸãã
Patroniãã€ã³ã¹ããŒã«ããããã®ããŒã«ãã³ãã¬ãŒãã¯ã https ïŒ //github.com/gitinsky/ansible-role-patroniã§ããäœæè ã«æè¬ããŸãã
ç§ã®ç®çã®ããã«ãæ¢åã®ãã®ãäœãçŽããhaproxyãškeepalivedãã¬ã€ããã¯ã远å ããŸããã
ç§ã®åœ¹å²ã¯/ etc / ansible / rolesãã£ã¬ã¯ããªã«ãããŸãã æ°ããããŒã«ã®ãã£ã¬ã¯ããªãšãã®ã³ã³ããŒãã³ãã®ãµããã£ã¬ã¯ããªãäœæããŸãã
~# mkdir /etc/ansible/roles/ansible-role-patroni/tasks ~# mkdir /etc/ansible/roles/ansible-role-patroni/templates
PostgreSQLã«å ããŠãã¯ã©ã¹ã¿ã¯æ¬¡ã®ã³ã³ããŒãã³ãã§æ§æãããŸãã
1ïŒãµãŒããŒã®ã¹ããŒã¿ã¹ãç£èŠãããªã¯ãšã¹ãããã¹ã¿ãŒãµãŒããŒã«ãªãã€ã¬ã¯ãããhaproxyã
2ïŒkeepalivedã䜿çšããŠãã¯ã©ã¹ã¿ãŒãžã®åäžã®ãšã³ããªãã€ã³ã-ä»®æ³IPã確ä¿ããŸãã
ããã©ã«ãã§ansibleã«ãã£ãŠå®è¡ããããã¡ã€ã«ã«ããã®ããŒã«ã«ãã£ãŠå®è¡ããããã¹ãŠã®ãã¬ã€ããã¯ããªã¹ãããŸãã
/etc/ansible/roles/ansible-role-patroni/tasks/main.yml
- include: postgres.yml - include: haproxy.yml - include: keepalived.yml
次ã«ãåã ã®ã¿ã¹ã¯ã«ã€ããŠèª¬æããŸãã
æåã®ãã¬ã€ããã¯ã§ã¯ããã€ãã£ããªããžããªããPostgreSQL 9.6ãããã³Patroniãå¿ èŠãšãã远å ããã±ãŒãžãã€ã³ã¹ããŒã«ããGitHubããPatronièªäœãããŠã³ããŒãããŸãã
/etc/ansible/roles/ansible-role-patroni/tasks/postgres.yml
--- - name: Import Postgresql96 repo yum: name=https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-3.noarch.rpm state=present tags: patroni when: install is defined - name: Install PGsql96 yum: name={{ item }} state=latest tags: patroni with_items: - postgresql96 - postgresql96-contrib - postgresql96-server - python-psycopg2 - repmgr96 when: install is defined - name: checkout patroni git: repo=https://github.com/zalando/patroni.git dest=/opt/patroni tags: patroni when: install is defined - name: create /etc/patroni file: state=directory dest=/etc/patroni tags: patroni when: install is defined - name: put postgres.yml template: src=postgres0.yml dest=/etc/patroni/postgres.yml backup=yes tags: patroni when: install is defined - name: install python packages pip: name={{ item }} tags: patroni with_items: - python-etcd - python-consul - dnspython - boto - mock - requests - six - kazoo - click - tzlocal - prettytable - PyYAML when: install is defined - name: put patroni.service systemd unit template: src=patroni.service dest=/etc/systemd/system/patroni.service backup=yes tags: patroni when: install is defined - name: Reload daemon definitions command: /usr/bin/systemctl daemon-reload tags: patroni - name: restart service: name=patroni state=restarted enabled=yes tags: patroni
ãœãããŠã§ã¢ã®ã€ã³ã¹ããŒã«ã«å ããŠããã®ãã¬ã€ããã¯ã¯çŸåšã®PatroniãµãŒããŒã®æ§æãã¢ããããŒãããŸããsystemdã«ã¯ã·ã¹ãã ã«ããŒã¢ã³ãèµ·åããããã®ãŠããããããããã®åŸã§PatroniããŒã¢ã³ãèµ·åããŸãã æ§æãã³ãã¬ãŒããšsystemdãŠãããã¯ãããŒã«å ã®ãã³ãã¬ãŒããã£ã¬ã¯ããªã«ååšããå¿ èŠããããŸãã
Patroniæ§æãã³ãã¬ãŒãïŒ
/etc/ansible/roles/ansible-role-patroni/templates/postgres.yml.j2
name: {{ patroni_node_name }} scope: &scope {{ patroni_scope }} consul: host: consul.services.local:8500 restapi: listen: 0.0.0.0:8008 connect_address: {{ ansible_default_ipv4.address }}:8008 auth: 'username:{{ patroni_rest_password }}' bootstrap: dcs: ttl: &ttl 30 loop_wait: &loop_wait 10 maximum_lag_on_failover: 1048576 # 1 megabyte in bytes postgresql: use_pg_rewind: true use_slots: true parameters: archive_mode: "on" wal_level: hot_standby archive_command: mkdir -p ../wal_archive && cp %p ../wal_archive/%f max_wal_senders: 10 wal_keep_segments: 8 archive_timeout: 1800s max_replication_slots: 5 hot_standby: "on" wal_log_hints: "on" pg_hba: # Add following lines to pg_hba.conf after running 'initdb' - host replication replicator 192.168.0.0/16 md5 - host all all 0.0.0.0/0 md5 postgresql: listen: 0.0.0.0:5432 connect_address: {{ ansible_default_ipv4.address }}:5432 data_dir: /var/lib/pgsql/9.6/data pg_rewind: username: superuser password: {{ patroni_postgres_password }} pg_hba: - host all all 0.0.0.0/0 md5 - hostssl all all 0.0.0.0/0 md5 replication: username: replicator password: {{ patroni_replicator_password }} network: 192.168.0.0/16 superuser: username: superuser password: {{ patroni_postgres_password }} admin: username: admin password: {{ patroni_postgres_password }} restore: /opt/patroni/patroni/scripts/restore.py
åã¯ã©ã¹ã¿ãŒãµãŒããŒã«ã¯åå¥ã®Patroniæ§æãå¿ èŠãªããããã®æ§æã¯jinja2ãã³ãã¬ãŒãïŒpostgres0.yml.j2ãã¡ã€ã«ïŒã®åœ¢åŒã§ããããã³ãã¬ãŒãã¹ãããã§ã¯ããã®ãã³ãã¬ãŒãã倿°ã®çœ®æã§åŒ·å¶çã«å€æã§ããŸãã
ã€ã³ãã³ããªå ã§ã¯ã©ã¹ã¿å šäœã«å ±éã®å€æ°ãçŽæ¥ç€ºããŸããããã¯æ¬¡ã®åœ¢åŒã«ãªããŸãã
/ etc / ansible /ãã¹ã
[pgsql] cluster-pgsql-01.local cluster-pgsql-02.local cluster-pgsql-03.local [pgsql:vars] patroni_scope: "cluster-pgsql" patroni_rest_password: flsdjkfasdjhfsd patroni_postgres_password: flsdjkfasdjhfsd patroni_replicator_password: flsdjkfasdjhfsd cluster_virtual_ip: 192.xx.xx.125 </spoiler> - host_vars/_: <spoiler title="/etc/ansible/host_vars/pgsql-cluster-01.local/main.yml"> <source lang="yaml"> patroni_node_name: cluster_pgsql_01 keepalived_priority: 99
ãªãããã€ãã®å€æ°ãå¿ èŠãªã®ããè§£èªããŸãã
patroni_scope-Consulã«ç»é²ãããšãã®ã¯ã©ã¹ã¿ãŒå
patroni_node_name-Consulãžã®ç»é²æã®ãµãŒããŒå
patroni_rest_password-Patroni httpã€ã³ã¿ãŒãã§ã€ã¹ã®ãã¹ã¯ãŒãïŒã¯ã©ã¹ã¿ãŒã倿Žããã³ãã³ããéä¿¡ããããã«å¿ èŠïŒ
patroni_postgres_passwordïŒpostgresãŠãŒã¶ãŒã®ãã¹ã¯ãŒãã æ°ããããŒã¹ãpatroniã«ãã£ãŠäœæãããå Žåã«ã€ã³ã¹ããŒã«ãããŸãã
patroni_replicator_password-ãŠãŒã¶ãŒã¬ããªã±ãŒã¿ãŒã®ãã¹ã¯ãŒãã 圌ã«ä»£ãã£ãŠãã¹ã¬ãŒããžã®è€è£œãå®è¡ãããŸãã
ãŸãããã®ãã¡ã€ã«ã«ã¯ãä»ã®ãã¬ã€ããã¯ãŸãã¯ããŒã«ã§äœ¿çšãããä»ã®å€æ°ããªã¹ããããŠããŸããç¹ã«ãsshèšå®ïŒããŒããŠãŒã¶ãŒïŒããµãŒããŒã®ã¿ã€ã ãŸãŒã³ãkeepalivedã¯ã©ã¹ã¿ãŒã®ãµãŒããŒåªå é äœãªã©ããããŸãã
ä»ã®ãµãŒããŒã®æ§æãåæ§ã§ããµãŒããŒåãšåªå é äœã¯ããã«å¿ããŠå€æŽãããŸãïŒããšãã°ã3ã€ã®ãµãŒããŒã®å Žåã¯99-100-101ïŒã
haproxyãã€ã³ã¹ããŒã«ããŠæ§æããŸãã
/etc/ansible/roles/ansible-role-patroni/tasks/haproxy.yml
--- - name: Install haproxy yum: name={{ item }} state=latest tags: - patroni - haproxy with_items: - haproxy when: install is defined - name: put config template: src=haproxy.cfg.j2 dest=/etc/haproxy/haproxy.cfg backup=yes tags: - patroni - haproxy - name: restart and enable service: name=haproxy state=restarted enabled=yes tags: - patroni - haproxy
Haproxyã¯åãã¹ãã«ã€ã³ã¹ããŒã«ããããã®æ§æã«ãã¹ãŠã®PostgreSQLãµãŒããŒãžã®ãªã³ã¯ãå«ãŸããã©ã®ãµãŒããŒãçŸåšãã¹ã¿ãŒã§ãããã確èªããèŠæ±ãéä¿¡ããŸãã
ãã®ãã¹ãã§ã¯ãPatroniã®çŽ æŽãããæ©èœã§ããRESTã€ã³ã¿ãŒãã§ãŒã¹ã䜿çšãããŸãã
ãµãŒããŒã«ã¢ã¯ã»ã¹ããå ŽåïŒ8008 URLïŒ8008ãããã©ã«ãããŒãïŒPatroniã¯jsonã®ã¯ã©ã¹ã¿ãŒã®ç¶æ ã«é¢ããã¬ããŒããè¿ãããµãŒããŒããã¹ã¿ãŒã§ãããã©ããã®å¿çã³ãŒãhttpãåæ ããŸãã ããã§ããå Žåãã³ãŒã200ã®å¿çããããŸããããã§ãªãå Žåãã³ãŒã503ã®å¿çããããŸãã
Patroniã®ããã¥ã¡ã³ããåç §ããããšã匷ããå§ãããŸããhttpã€ã³ã¿ãŒãã§ã€ã¹ã¯éåžžã«è峿·±ããã®ã§ãããããŒã«ã匷å¶çã«åãæ¿ããããã¯ã©ã¹ã¿ãŒã管çãããããããšãã§ããŸãã
åæ§ã«ãããã¯Patroniã®patronyctl.pyã³ã³ãœãŒã«ãŠãŒãã£ãªãã£ã䜿çšããŠå®è¡ã§ããŸãã
haproxyã®èšå®ã¯éåžžã«ç°¡åã§ãïŒ
/etc/ansible/roles/ansible-role-patroni/templates/haproxy.cfg
global maxconn 800 defaults log global mode tcp retries 2 timeout client 30m timeout connect 4s timeout server 30m timeout check 5s frontend ft_postgresql bind *:5000 default_backend postgres-patroni backend postgres-patroni option httpchk http-check expect status 200 default-server inter 3s fall 3 rise 2 server {{ patroni_node_name }} {{ patroni_node_name }}.local:5432 maxconn 300 check port 8008 server {{ patroni_node_name }} {{ patroni_node_name }}.local:5432 maxconn 300 check port 8008 server {{ patroni_node_name }} {{ patroni_node_name }}.local:5432 maxconn 300 check port 8008
ãã®æ§æã«ããã°ãhaproxyã¯ããŒã5000ã§ãªãã¹ã³ãããããããã¹ã¿ãŒãµãŒããŒã«ãã©ãã£ãã¯ãéä¿¡ããŸãã
ã¹ããŒã¿ã¹ã®ãã§ãã¯ã¯1ç§ééã§è¡ããããµãŒããŒãããŠã³ã«è»¢éããã«ã¯3åã®å€±æããå¿çïŒã³ãŒã500ïŒããµãŒããŒãåãæ¿ããã«ã¯2åã®æåããå¿çïŒã³ãŒã200ïŒãå¿ èŠã§ãã
ãã€ã§ããä»»æã®haproxyã«çŽæ¥æ¥ç¶ã§ãããã©ãã£ãã¯ã¯ãã¹ã¿ãŒãµãŒããŒã«æ£ãã転éãããŸãã
Patroniã«ã¯ãconfdããŒã¢ã³ãæ§æããããã®ãã³ãã¬ãŒããšetcdãšã®çµ±åã®äŸãå«ãŸããŠããŸããããã«ãããæ°ãããµãŒããŒãåé€ãŸãã¯è¿œå ãããšãã«haproxyæ§æãåçã«å€æŽã§ããŸãã
ç§ã¯ãŸã ããªãéçãªã¯ã©ã¹ã¿ãŒãäœæããŠããŸããããã®ç¶æ³ã§ã®äžå¿ èŠãªèªååãç§èŠã¯äºæããªãåé¡ã«ã€ãªããå¯èœæ§ããããŸãã
ã¯ã©ã€ã¢ã³ãã®ç¹æ®ãªããžãã¯ã®å€æŽã掻æ°ã®ãããµãŒããŒã®è¿œè·¡ãªã©ãå¿ èŠã§ãã å¿ é ã§ã¯ãªãã£ããããkeepalivedã䜿çšããŠã¯ã©ã¹ã¿ãŒãžã®åäžã®ãšã³ããªãã€ã³ããäœæããŸãã
keepalivedããŒã¢ã³ã¯ããã®è¿é£ã§vrrpãããã³ã«ã䜿çšããããŒã¢ã³ã®1ã€ãã¡ã€ã³ã®ããŒã¢ã³ãšããŠéžæããçµæïŒåªå é äœã¯configã§æå®ãããåãµãŒããŒã®host_varsã®keepalived_priority倿°ã«ãã³ãã¬ãŒãåãããŸãïŒãä»®æ³IPã¢ãã¬ã¹ãäžããŸãã
æ®ãã®æªéã¯èŸæ±åŒ·ãåŸ ã¡ãŸãã çŸåšã®ã¡ã€ã³keepalivedãµãŒããŒãäœããã®çç±ã§æ»ãã ããè¿é£ã«äºæ ãç¥ãããããããšãåéžæãè¡ãããæ¬¡ã«åªå é äœã®é«ããµãŒããŒãä»®æ³IPã¢ãã¬ã¹ãååŸããŸãã
haproxyã®ã¯ã©ãã·ã¥ããä¿è·ããããã«ãkeepalivedããŒã¢ã³ã¯killall -0 haproxyã³ãã³ãã1ç§ã«1åå®è¡ããŠãã§ãã¯ãå®è¡ããŸãã haproxyããã»ã¹ãããå Žåã¯ã³ãŒã0ãè¿ãããªãå Žåã¯1ãè¿ããŸãã
haproxyãæ¶ãããšãkeepalivedããŒã¢ã³ã¯vrrpãä»ããŠã¯ã©ãã·ã¥ãéç¥ããä»®æ³IPãåé€ããŸãã
ä»®æ³IPã¯ãã©ã€ãhaproxyã䜿çšããŠã次ã«åªå é äœã®é«ããµãŒããŒãããã«éžæããŸãã
keepalivedãã€ã³ã¹ããŒã«ããŠæ§æããŸãã
/etc/ansible/roles/ansible-role-patroni/tasks/keepalived.yml
--- - name: Install keepalived yum: name={{ item }} state=latest tags: - patroni - keepalived with_items: - keepalived when: install is defined - name: put alert script template: src=alert.sh.j2 dest=/usr/local/sbin/alert.sh backup=yes mode=755 tags: - patroni - keepalived when: install is defined - name: put config template: src=keepalived.conf.j2 dest=/etc/keepalived/keepalived.conf backup=yes tags: - patroni - keepalived - name: restart and enable service: name=keepalived state=restarted enabled=yes tags: - patroni - keepalived
keepalivedã®ã€ã³ã¹ããŒã«ã«å ããŠããã®ãã¬ã€ããã¯ã¯ãé»å ±ãä»ããŠã¢ã©ãŒããéä¿¡ããããã®ç°¡åãªã¹ã¯ãªãããã³ããŒããŸãã ã¹ã¯ãªããã¯ã¡ãã»ãŒãžã倿°ã®åœ¢åŒã§åãåããcurlçªç®ã®ãã¬ã°ã©ã APIãååŸããŸãã
ãã®ã¹ã¯ãªããã§ã¯ãã¢ã©ãŒããéä¿¡ããããã«ããŒã¯ã³ãšãã¬ã°ã©ã ã°ã«ãŒãIDãæå®ããã ãã§ãã
keepalivedã®æ§æã¯ãjinja2ãã³ãã¬ãŒããšããŠèª¬æãããŠããŸãã
/etc/ansible/roles/ansible-role-patroni/templates/keepalived.conf.j2
global_defs { router_id {{ patroni_node_name }} } vrrp_script chk_haproxy { script "killall -0 haproxy" interval 1 weight -20 debug fall 2 rise 2 } vrrp_instance {{ patroni_node_name }} { interface ens160 state BACKUP virtual_router_id 150 priority {{ keepalived_priority }} authentication { auth_type PASS auth_pass secret_for_vrrp_auth } track_script { chk_haproxy weight 20 } virtual_ipaddress { {{ cluster_virtual_ip }}/32 dev ens160 } notify_master "/usr/bin/sh /usr/local/sbin/alert.sh '{{ patroni_node_name }} became MASTER'" notify_backup "/usr/bin/sh /usr/local/sbin/alert.sh '{{ patroni_node_name }} became BACKUP'" notify_fault "/usr/bin/sh /usr/local/sbin/alert.sh '{{ patroni_node_name }} became FAULT'" }
倿°patroni_node_nameãcluster_virtual_ipãããã³keepalived_priorityã¯ãhost_varsããã®å¯Ÿå¿ããããŒã¿ã倿ããŸãã
keepalivedæ§æã«ã¯ãã¹ããŒã¿ã¹ã®å€æŽã«é¢ããã¡ãã»ãŒãžãé»å ±ãã£ãã«ã«éä¿¡ããããã®ã¹ã¯ãªãããå«ãŸããŠããŸãã
å®å šãªã¯ã©ã¹ã¿ãŒæ§æããµãŒããŒã«ããŒã«ããŸãã
~# ansible-playbook cluster-pgsql.yml
Ansibleã¯ã¹ãçã§ãããããã€ãŸã 以åã«å®äºããŠããªãå Žåã«ã®ã¿ã¹ããããå®è¡ãã远å ã®ãã©ã¡ãŒã¿ãŒãªãã§ãã¬ã€ããã¯ãéå§ã§ããŸãã
é·ãåŸ ãŠãªãå ŽåããŸãã¯ãµãŒããŒã®æºåãå®å šã«æŽã£ãŠããããšã確å®ãªå Žåã¯ã-t patroniã¹ã€ããã䜿çšããŠansible-playbookãå®è¡ã§ããŸãã
ãã®åŸãPatroniããŒã«ã®ã¹ãããã®ã¿ãå®è¡ãããŸãã
ãµãŒããŒã®åœ¹å²ïŒãã¹ã¿ãŒãŸãã¯ã¹ã¬ãŒãïŒãåå¥ã«ç€ºããŠããªãããšã«æ³šæããŠãã ããã ãã®æ§æã«ããã空ã®ããŒã¿ããŒã¹ãäœæãããæåã«æ§æããããµãŒããŒãåã«ãã¹ã¿ãŒã«ãªããŸãã
æ°ãããµãŒããŒã远å ãããšãPatroniã¯DCSãä»ããŠã¯ã©ã¹ã¿ãŒãã¹ã¿ãŒãæ¢ã«ååšããããšã確èªããçŸåšã®ãã¹ã¿ãŒããããŒã¿ããŒã¹ãèªåçã«ã³ããŒããã¹ã¬ãŒããããã«æ¥ç¶ããŸãã
ãã°ãããŠã£ã¶ãŒãã®èåŸã«ããã¹ã¬ãŒããèµ·åãããšãPatroniã¯pg_rewindã䜿çšããŠå€æŽãèªåçã«ã¢ããããŒãããŸãã
ãã¹ãŠã®ãµãŒããŒãéå§ããã圹å²ãéžæãããŠããããšã確èªããŸãã
~# journalctl -f -u patroni
ã¹ã¬ãŒãããã®ã¡ãã»ãŒãžïŒãµãŒããŒcluster-pgsql-01ïŒïŒ
ãã¿ãã¬
Feb 17 23:50:32 cluster-pgsql-01.local patroni.py[100626]: 2017-02-17 23:50:32,254 INFO: Lock owner: cluster_pgsql_02; I am cluster_pgsql_01
Feb 17 23:50:32 cluster-pgsql-01.local patroni.py[100626]: 2017-02-17 23:50:32,255 INFO: Lock owner: cluster_pgsql_02; I am cluster_pgsql_01
Feb 17 23:50:32 cluster-pgsql-01.local patroni.py[100626]: 2017-02-17 23:50:32,255 INFO: does not have lock
Feb 17 23:50:32 cluster-pgsql-01.local patroni.py[100626]: 2017-02-17 23:50:32,255 INFO: no action. i am a secondary and i am following a leader
ãŠã£ã¶ãŒãããã®ã¡ãã»ãŒãžïŒãã®å ŽåããµãŒããŒã¯cluster-pgsql-02ã§ãïŒïŒ
ãã¿ãã¬
Feb 17 23:52:23 cluster-pgsql-02.local patroni.py[4913]: 2017-02-17 23:52:23,457 INFO: Lock owner: cluster_pgsql_02; I am cluster_pgsql_02
Feb 17 23:52:23 cluster-pgsql-02.local patroni.py[4913]: 2017-02-17 23:52:23,874 INFO: Lock owner: cluster_pgsql_02; I am cluster_pgsql_02
Feb 17 23:52:24 cluster-pgsql-02.local patroni.py[4913]: 2017-02-17 23:52:24,082 INFO: no action. i am the leader with the lock
Feb 17 23:52:33 cluster-pgsql-02.local patroni.py[4913]: 2017-02-17 23:52:33,458 INFO: Lock owner: cluster_pgsql_02; I am cluster_pgsql_02
Feb 17 23:52:33 cluster-pgsql-02.local patroni.py[4913]: 2017-02-17 23:52:33,884 INFO: Lock owner: cluster_pgsql_02; I am cluster_pgsql_02
Feb 17 23:52:34 cluster-pgsql-02.local patroni.py[4913]: 2017-02-17 23:52:34,094 INFO: no action. i am the leader with the lock
ãã°ã¯ãåãµãŒããŒããã®ã¹ããŒã¿ã¹ãšãã¹ã¿ãŒã®ã¹ããŒã¿ã¹ãåžžã«ç£èŠããŠããããšãæç¢ºã«ç€ºããŠããŸãã
ãã¹ã¿ãŒã忢ããŠã¿ãŸãããã
~# systemctl stop patroni
ãã¿ãã¬
Feb 17 23:54:03 cluster-pgsql-02.local patroni.py[4913]: 2017-02-17 23:54:03,457 INFO: Lock owner: cluster_pgsql_02; I am cluster_pgsql_02
Feb 17 23:54:03 cluster-pgsql-02.local patroni.py[4913]: 2017-02-17 23:54:03,880 INFO: Lock owner: cluster_pgsql_02; I am cluster_pgsql_02
Feb 17 23:54:04 cluster-pgsql-02.local patroni.py[4913]: 2017-02-17 23:54:04,092 INFO: no action. i am the leader with the lock
Feb 17 23:54:11 cluster-pgsql-02.local systemd[1]: Stopping Runners to orchestrate a high-availability PostgreSQL...
Feb 17 23:54:13 cluster-pgsql-02.local patroni.py[4913]: waiting for server to shut down.... done
Feb 17 23:54:13 cluster-pgsql-02.local patroni.py[4913]: server stopped
ãããããã®ç¬éã«ã¹ã¬ãŒãã§äœãèµ·ãã£ãã®ãïŒ
ãã¿ãã¬
Feb 17 19:54:12 cluster-pgsql-01 patroni.py: 2017-02-17 23:54:12,353 INFO: does not have lock
Feb 17 19:54:12 cluster-pgsql-01 patroni.py: 2017-02-17 23:54:12,776 INFO: no action. i am a secondary and i am following a leader
Feb 17 19:54:13 cluster-pgsql-01 patroni.py: 2017-02-17 23:54:13,440 WARNING: request failed: GET http://192.xx.xx.121:8008/patroni (HTTPConnectionPool(host='192.xx.xx.121', port=8008
): Max retries exceeded with url: /patroni (Caused by NewConnectionError('<requests.packages.urllib3.connection.HTTPConnection object at 0x1f12750>: Failed to establish a new connection: [Er
rno 111] Connection refused',)))
Feb 17 19:54:13 cluster-pgsql-01 patroni.py: 2017-02-17 23:54:13,444 INFO: Got response from cluster_pgsql_03 http://192.xx.xx.122:8008/patroni: {"database_system_identifier": "63847
30077944883705", "postmaster_start_time": "2017-02-17 05:36:52.388 MSK", "xlog": {"received_location": 34997272728, "replayed_timestamp": null, "paused": false, "replayed_location": 34997272
728}, "patroni": {"scope": "clusters-pgsql", "version": "1.2.3"}, "state": "running", "role": "replica", "server_version": 90601}
Feb 17 19:54:13 cluster-pgsql-01 patroni.py: server promoting
Feb 17 19:54:13 cluster-pgsql-01 patroni.py: 2017-02-17 23:54:13,961 INFO: cleared rewind flag after becoming the leader
Feb 17 19:54:14 cluster-pgsql-01 patroni.py: 2017-02-17 23:54:14,179 INFO: promoted self to leader by acquiring session lock
Feb 17 19:54:23 cluster-pgsql-01 patroni.py: 2017-02-17 23:54:23,436 INFO: Lock owner: cluster_pgsql_01; I am cluster_pgsql_01
Feb 17 19:54:23 cluster-pgsql-01 patroni.py: 2017-02-17 23:54:23,857 INFO: Lock owner: cluster_pgsql_01; I am cluster_pgsql_01
Feb 17 19:54:24 cluster-pgsql-01 patroni.py: 2017-02-17 23:54:24,485 INFO: no action. i am the leader with the lock
ãã®ãµãŒããŒã¯ããã¹ã¿ãŒã®åœ¹å²ãååããŸããã
次ã«ããµãŒããŒ2ãã¯ã©ã¹ã¿ãŒã«æ»ããŸãã
~# systemctl start patroni
ãã¿ãã¬èŠåºã
Feb 18 00:02:11 cluster-pgsql-02.local systemd[1]: Started Runners to orchestrate a high-availability PostgreSQL.
Feb 18 00:02:11 cluster-pgsql-02.local systemd[1]: Starting Runners to orchestrate a high-availability PostgreSQL...
Feb 18 00:02:13 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:13,186 INFO: Lock owner: cluster_pgsql_01; I am cluster_pgsql_02
Feb 18 00:02:13 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:13,190 WARNING: Postgresql is not running.
Feb 18 00:02:13 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:13,190 INFO: Lock owner: cluster_pgsql_01; I am cluster_pgsql_02
Feb 18 00:02:13 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:13,398 INFO: Lock owner: cluster_pgsql_01; I am cluster_pgsql_02
Feb 18 00:02:13 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:13,400 INFO: starting as a secondary
Feb 18 00:02:13 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:13,412 INFO: rewind flag is set
Feb 18 00:02:13 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:13,609 INFO: Lock owner: cluster_pgsql_01; I am cluster_pgsql_02
Feb 18 00:02:13 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:13,609 INFO: Lock owner: cluster_pgsql_01; I am cluster_pgsql_02
Feb 18 00:02:13 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:13,609 INFO: changing primary_conninfo and restarting in progress
Feb 18 00:02:13 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:13,631 INFO: running pg_rewind from user=superuser host=192.xx.xx.120 port=5432 dbname=postgres sslmode=prefer sslcompression=1
Feb 18 00:02:13 cluster-pgsql-02.local patroni.py[56855]: servers diverged at WAL position 8/26000098 on timeline 25
Feb 18 00:02:13 cluster-pgsql-02.local patroni.py[56855]: rewinding from last common checkpoint at 8/26000028 on timeline 25
Feb 18 00:02:14 cluster-pgsql-02.local patroni.py[56855]: Done!
Feb 18 00:02:14 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:14,535 INFO: postmaster pid=56893
Feb 18 00:02:14 cluster-pgsql-02.local patroni.py[56855]: < 2017-02-18 00:02:14.554 MSK > LOG: redirecting log output to logging collector process
Feb 18 00:02:14 cluster-pgsql-02.local patroni.py[56855]: < 2017-02-18 00:02:14.554 MSK > HINT: Future log output will appear in directory "pg_log".
Feb 18 00:02:15 cluster-pgsql-02.local patroni.py[56855]: localhost:5432 - accepting connections
Feb 18 00:02:15 cluster-pgsql-02.local patroni.py[56855]: localhost:5432 - accepting connections
Feb 18 00:02:15 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:15,790 INFO: Lock owner: cluster_pgsql_01; I am cluster_pgsql_02
Feb 18 00:02:15 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:15,791 INFO: Lock owner: cluster_pgsql_01; I am cluster_pgsql_02
Feb 18 00:02:15 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:15,791 INFO: does not have lock
Feb 18 00:02:15 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:15,791 INFO: establishing a new patroni connection to the postgres cluster
Feb 18 00:02:16 cluster-pgsql-02.local patroni.py[56855]: 2017-02-18 00:02:16,014 INFO: no action. i am a secondary and i am following a leader
Patroniã¯ãæ¢åã®ãã¹ã¿ãŒã䜿çšããŠã¯ã©ã¹ã¿ãŒã«æ¥ç¶ããããŒã¿ããŒã¹ãçŸåšã®ç¶æ ã«æŽæ°ããŠããããšãçºèŠããã¹ã¬ãŒãã®åœ¹å²ãæ£ããåŒãç¶ããŸããã
ã¡ã€ã³keepalivedãµãŒããŒã§haproxyã忢ããŠãã¯ã©ã¹ã¿ãŒã®å¥ã®ã¬ã€ã€ãŒã§ãšã©ãŒãäœæããŠã¿ãŸãããã
åªå é äœã«ããã2çªç®ã®ãµãŒããŒã¯ãã®åœ¹å²ãåãå ¥ããŸãã
[root@cluster-pgsql-02 ~]# ip a
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:50:56:a9:b8:7b brd ff:ff:ff:ff:ff:ff
inet 192.xx.xx.121/24 brd 192.168.142.255 scope global ens160
valid_lft forever preferred_lft forever
inet 192.xx.xx.125/32 scope global ens160 <----
valid_lft forever preferred_lft forever
inet6 fe80::xxx::4895:6d90/64 scope link
valid_lft forever preferred_lft forever
haproxyã忢ããŸãã
~# systemctl stop haproxy ; journalctl -fl
Feb 18 00:18:54 cluster-pgsql-02.local Keepalived_vrrp[25018]: VRRP_Script(chk_haproxy) failed
Feb 18 00:18:56 cluster-pgsql-02.local Keepalived_vrrp[25018]: VRRP_Instance(cluster_pgsql_02) Received higher prio advert
Feb 18 00:18:56 cluster-pgsql-02.local Keepalived_vrrp[25018]: VRRP_Instance(cluster_pgsql_02) Entering BACKUP STATE
Feb 18 00:18:56 cluster-pgsql-02.local Keepalived_vrrp[25018]: VRRP_Instance(cluster_pgsql_02) removing protocol VIPs.
Feb 18 00:18:56 cluster-pgsql-02.local Keepalived_vrrp[25018]: Opening script file /usr/bin/sh
Feb 18 00:18:56 cluster-pgsql-02.local Keepalived_healthcheckers[25017]: Netlink reflector reports IP 192.xx.xx.125 removed
Keepalivedã¯åé¡ããã£ããããä»®æ³ã¢ãã¬ã¹ãèªèº«ããåé€ããããã«ã€ããŠè¿é£ã«ä¿¡å·ãéããŸããã
2çªç®ã®ãµãŒããŒã§äœãèµ·ãã£ãã®ããèŠãŠã¿ãŸãããã
Feb 18 00:18:56 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) forcing a new MASTER election
Feb 18 00:18:56 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) forcing a new MASTER election
Feb 18 00:18:56 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) forcing a new MASTER election
Feb 18 00:18:56 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) forcing a new MASTER election
Feb 18 00:18:57 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) Transition to MASTER STATE
Feb 18 00:18:58 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) Entering MASTER STATE
Feb 18 00:18:58 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) setting protocol VIPs.
Feb 18 00:18:58 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) Sending gratuitous ARPs on ens160 for 192.xx.xx.125
Feb 18 00:18:58 cluster-pgsql-01.local Keepalived_vrrp[41190]: Opening script file /usr/bin/sh
Feb 18 00:18:58 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) Received lower prio advert, forcing new election
Feb 18 00:18:58 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) Sending gratuitous ARPs on ens160 for 192.xx.xx.125
Feb 18 00:18:58 cluster-pgsql-01.local Keepalived_healthcheckers[41189]: Netlink reflector reports IP 192.xx.xx.125 added
Feb 18 00:18:58 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) Received lower prio advert, forcing new election
Feb 18 00:18:58 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) Sending gratuitous ARPs on ens160 for 192.xx.xx.125
Feb 18 00:19:03 cluster-pgsql-01.local Keepalived_vrrp[41190]: VRRP_Instance(cluster_pgsql_01) Sending gratuitous ARPs on ens160 for 192.xx.xx.125
åéžåºã2åè¡ãããããïŒã¯ã©ã¹ã¿ãŒã®3çªç®ã®ãµãŒããŒãæåã®éžåºåã«ã¢ããŠã³ã¹ãéä¿¡ã§ããããïŒããµãŒããŒ1ããªãŒããŒã®åœ¹å²ãåŒãåããä»®æ³IPãèšå®ããŸããã
ç§ãã¡ã¯ããã確信ããŠããŸãïŒ
[root@cluster-pgsql-01 log]# ip a
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:50:56:a9:f0:90 brd ff:ff:ff:ff:ff:ff
inet 192.xx.xx.120/24 brd 192.xx.xx.255 scope global ens160
valid_lft forever preferred_lft forever
inet 192.xx.xx.125/32 scope global ens160 <---- !
valid_lft forever preferred_lft forever
inet6 fe80::1d75:40f6:a14e:5e27/64 scope link
valid_lft forever preferred_lft forever
ä»®æ³IPã¯ãã¬ããªã±ãŒã·ã§ã³ãã¹ã¿ãŒã§ã¯ãªããµãŒããŒã«ååšããããã«ãªããŸããã ãã ããhaproxyãä»ããŠããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ããã¯ã©ã¹ã¿ãŒã®ç¶æ ãåå¥ã«ç£èŠããåžžã«ãã¹ã¿ãŒã«èŠæ±ãéä¿¡ãããããããã¯éèŠã§ã¯ãããŸããã
haproxyãã·ã¹ãã ã«è¿ããããšãåéžåºãåã³è¡ããïŒæé«ã®åªå é äœã§ããŒãã¢ã©ã€ããåäœããããã«ãªããŸãïŒãä»®æ³IPããã®å Žæã«æ»ããŸãã
ãŸãã«ãã¹ã¬ãŒãããã¹ã¿ãŒã«è¿œãä»ããªãããšããããŸãïŒããšãã°ãããªãåã«èœã¡ãŠãwalãã°ãéšåçã«ãªã¿ã€ã¢ããããšããããŸããïŒã ãã®å Žåãã¹ã¬ãŒãã®ããŒã¹ã䜿çšããŠãã£ã¬ã¯ããªãå®å šã«ã¯ãªã¢ã§ããŸãã
ãã®å ŽåãpatronictlãŠãŒãã£ãªãã£ã䜿çšããå¿ èŠããããŸãã reinitã³ãã³ãã䜿çšãããšãç¹å®ã®ã¯ã©ã¹ã¿ãŒããŒããå®å šã«ã¯ãªãŒãã³ã°ã§ããŸããããŠã£ã¶ãŒãã§ã¯å®è¡ãããŸããã
CyberââDemonã远å ããŠããã ãããããšãããããŸãã
patronictlãŠãŒãã£ãªãã£èªäœã䜿çšãããšãDCSã«ã¢ã¯ã»ã¹ããã«ãã³ãã³ãã©ã€ã³ããã¯ã©ã¹ã¿ãŒã®çŸåšã®ç¶æ³ã確èªããã¯ã©ã¹ã¿ãŒã管çã§ããŸãã
ã¯ã©ã¹ã¿ãŒã¹ããŒã¿ã¹ã¬ããŒãã®äŸïŒ
/opt/patroni/patronictl.py -c /etc/patroni/postgres.yml list cluster-pgsqlïŒ
+ --------------- + ------------------ + -------------- --- + -------------- + ------------------ + ----------- + | ã¯ã©ã¹ã¿ãŒ| ã¡ã³ããŒ| ãã¹ã| 圹å²| å·| MBã®ã©ã°| + --------------- + ------------------ + -------------- --- + -------------- + ------------------ + ----------- + | cluster-pgsql | cluster_pgsql_01 | 192.xxx.xxx.120 | ãªãŒããŒ| ã©ã³ãã³ã°| 0.0 | | cluster-pgsql | cluster_pgsql_02 | 192.xxx.xxx.121 | åæã¹ã¿ã³ãã€| ã©ã³ãã³ã°| 0.0 | | cluster-pgsql | cluster_pgsql_03 | 192.xxx.xxx.122 | | ã¬ããªã«ã®äœæ| 33712.0 | + --------------- + ------------------ + -------------- --- + -------------- + ------------------ + ----------- +
ãã®å Žåã3çªç®ã®ããŒããæ³šããããã¹ã¿ãŒããã®é å»¶ã¯33 GBã§ãã
ãã®ããã»ã¹ãå®äºãããšããŒãã©ã°ã§å®è¡ç¶æ ã«ãªããŸãã
Stateãã£ãŒã«ãã空ã§ããããšã«ã泚æããŠãã ãããããã¯ãç§ã®å Žåã®ã¯ã©ã¹ã¿ãŒãåæã¢ãŒãã§åäœããããã§ããåæã¬ããªã±ãŒã·ã§ã³ã®é å»¶ãæžããããã«ãäžæ¹ã®ã¹ã¬ãŒãã¯åæã¢ãŒãã§åäœããããäžæ¹ã¯éåžžã®éåæã§åäœããŸãããã¹ã¿ãŒãæ¶ãããšãããŒã«ãã·ãããã2çªç®ã®ã¹ã¬ãŒãããã¹ã¿ãŒã«ãªã£ãæåã®ã¹ã¬ãŒããšåæã¢ãŒãã«å ¥ããŸãã
ããšãã
ç§ã®æèŠã§ã¯ããã®ã¯ã©ã¹ã¿ãŒã幞çŠã«ååã§ã¯ãªãå¯äžã®ããšã¯ãæ¥ç¶ããŒãªã³ã°ãšãã¹ãŠã®ã¹ã¬ãŒããžã®èªã¿åãèŠæ±ã®ãããã·ãŒã§èªã¿åãããã©ãŒãã³ã¹ãåäžããããŠã£ã¶ãŒãã®ã¿ã«èŠæ±ãæ¿å ¥ããã³æŽæ°ããããšã§ãã
éåæã¬ããªã±ãŒã·ã§ã³ã䜿çšããæ§æã§ã¯ãèªã¿èŸŒã¿è² è·ãã¢ã³ããŒããããšäºæããªãå¿çãçºçããå¯èœæ§ããããŸããã¹ã¬ãŒãããã¹ã¿ãŒããé ããŠããå Žåããããèæ ®ããå¿ èŠããããŸãã
ã¹ããªãŒãã³ã°ïŒéåæïŒã¬ããªã±ãŒã·ã§ã³ã¯ãåžžã«ã¯ã©ã¹ã¿ãŒã®äžè²«æ§ãæäŸããŸãããããã«ã¯åæã¬ããªã±ãŒã·ã§ã³ãå¿ èŠã§ãã
ãã®ã¢ãŒãã§ã¯ããã¹ã¿ãŒãµãŒããŒã¯ãã©ã³ã¶ã¯ã·ã§ã³ã®ã³ããŒãšã¹ã¬ãŒããžã®é©çšã®ç¢ºèªãåŸ æ©ããããŒã¿ããŒã¹ã®é床ãäœäžããŸãããã ãããã©ã³ã¶ã¯ã·ã§ã³ã®æå€±ã蚱容ã§ããªãå ŽåïŒäžéšã®éèã¢ããªã±ãŒã·ã§ã³ãªã©ïŒãåæã¬ããªã±ãŒã·ã§ã³ãéžæãããŸãã
Patroniã¯ãã¹ãŠã®ãªãã·ã§ã³ããµããŒãããŠãããåæã¬ããªã±ãŒã·ã§ã³ãããé©ããŠããå Žåã¯ãPatroni configsã®ããã€ãã®ãã£ãŒã«ãã®å€ã倿Žããã ãã§ãã
ããŸããŸãªè€è£œæ¹æ³ã«é¢ãã質åã¯ãPatroniã®ããã¥ã¡ã³ãã«è©³ããèšèŒãããŠããŸãã
å®éããã®ã·ã¹ãã ã®ãã¹ãŠã®æ©èœãã«ããŒããpgpoolã䜿çšããããšããå§ãããŸããããŒã¿ããŒã¹ããããã·èŠæ±ãç£èŠããä»®æ³IPãèšå®ããã¯ã©ã€ã¢ã³ãæ¥ç¶ã®ããŒãªã³ã°ãå®è£ ã§ããŸãã
ã¯ãã圌ã¯ããããã¹ãŠè¡ãããšãã§ããŸããããããç§ã®æèŠã§ã¯ããããããšã®ã¹ããŒã ã¯ã¯ããã«éæã§ãïŒãã¡ããããã¯ç§ã®æèŠã§ãïŒãpgpoolã§ã®å®éšäžã«ããŠã©ããããã°ãšä»®æ³ã¢ãã¬ã¹ã§å¥åŠãªåäœãèŠã€ããŸããã
ãã¡ãããåé¡ãç§ã®æã«ããã ãã§ãããåŸã§pgpoolã®ãã¹ãã«æ»ãäºå®ã§ãã
ãã ãããããã«ããŠããpgpoolã¯ã¯ã©ã¹ã¿ãŒãå®å šã«èªåçã«ç®¡çããæ°ãããµãŒããŒãå ¥åããŠïŒç¹ã«ïŒå€±æãããµãŒããŒãè¿ããDCSãæäœããããšã¯ã§ããŸãããç§ã®æèŠã§ã¯ãããã¯Patroniã®æãè峿·±ãæ©èœã§ãã
ãæž èŽããããšãããããŸããããã®ãœãªã¥ãŒã·ã§ã³ã®ãããªãæ¹åã®ããã®ææ¡ãã芧ããã ããã³ã¡ã³ãã§è³ªåã«ãçãããŸãã
Zalando Patroniã®ããã«ã©ããããããšãããããŠå ã®ãããžã§ã¯ãã®äœè ç¥äº Patroniã®åºç€ãåãããããŠã¢ã¬ãã¯ã¹Chistyakov Ansibleã®ããã®ãã³ãã¬ãŒãã®åœ¹å²ã®ããã«ã
èšäºã§èª¬æãããŠãããã¬ã€ããã¯ãšAnsibleãã³ãã¬ãŒãã®å®å šãªã³ãŒãã¯ãã¡ãã«ãããŸãã AnsibleãšPostgreSQLã®é人ããã®æ¹åã«æè¬ããŸãã :)
ïŒäž»ãªèšäºãæ å ±æºã䜿çš
ããã€ãã®ãªãã·ã§ã³ã¯ã©ã¹ã¿ãŒPgSQLã¯ïŒ
â https://habrahabr.ru/post/301370/
â https://habrahabr.ru/post/213409/
â https://habrahabr.ru/company/etagi/ã/ 314000 /ããã°
â Zalandoã§patroniäžã®ãã¹ãã¯ããã°
â ãããžã§ã¯ãpatroni
â Ansible-圹å²patroniã¢ã¬ãã¯ã¹Chistyakov
â ç¥äºé·æåçµã®ãæ®å¿µãªããéçºã- ã
â Ansble for Devopsã¯ã倿°ã®Ansibleã®äŸãå«ãçŽ æŽããããã¥ãŒããªã¢ã«ã§ãã