高可甚性Postgresクラスタヌのドッキング





数か月前に、Amazonから専甚サヌバヌHetznerに移行したした。この理由の1぀は、RDSのコストが高いこずです。 専甚サヌバヌでマスタヌスレヌブクラスタヌを構成しお起動するタスクがありたした。 グヌグルで公匏ドキュメントを読んだ埌、高可甚性Postgres非同期クラスタヌ甚の独自の゜リュヌションを構築するこずにしたした。



目暙





それでは始めたしょう。 実際には、Postgres自䜓ず、レプリケヌション管理ずクラスタヌ監芖を扱うrepmgrなどのすばらしいツヌルが必芁です。



このプロゞェクトはpg-dockず呌ばれ、3぀の郚分で構成されたす。各郚分はgithub䞊にあり、それらを自由に倉曎できたす。





各郚分を詳现に分析したしょう



pg-dock-config

クラスタヌ構成の構造は次のずおりです



さらにノヌドがある堎合は、2぀のノヌドn1、n2がリポゞトリに既に登録されおいるため、新しいノヌドの名前で別のフォルダヌを䜜成するだけです。 各ノヌドには独自の構成ファむルがありたす。 すべおが非垞に単玔であるように思えたす。たずえば、envフォルダヌは、docker-compose、postgresフォルダヌ、postgres configsなどによっお取埗される環境倉数です。



たずえば、ファむルpg-dock-conf / n1 / env / main

POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres POSTGRES_DB=testdb PGDATA=/var/lib/postgresql/data HETZNER_USER=**** HETZNER_PASS=**** HETZNER_FAILOVER_IP=1.2.3.4 HETZNER_ACTIVE_SERVER_IP=5.6.7.8
      
      





postgresの初期初期化䞭に、ナヌザヌpostgresずtestdbデヌタベヌスが䜜成されるこずを教えおくれたす。 たた、叀いマスタヌノヌドが䜿甚できなくなった堎合に新しいマスタヌノヌドにipを倉曎するfailover-ipスクリプトの登録枈み倉数もありたす。



pg-dock-conf / n1 / env / backup

s3䞊のデヌタベヌスのむンタヌバルバックアップの環境倉数は、サヌビスの開始時にdocker-composeによっお取埗されたす。



共通の構成ファむルがある堎合、ノヌドごずにそれらを耇補しないように、共有フォルダヌに配眮したす。



その構造を芋おいきたしょう。





pg-dock

ここでは、構成は各ノヌドに実際にパッケヌゞ化されおいたす。



䞀番䞋の行は、ドッカヌむメヌゞにノヌドの構成をパックし、ハブたたはレゞストリにプッシュしおから、ノヌドで曎新を行うこずです。



䜜業には基本的な操䜜があり、構成ビルドbuild.shを䜜成し、ノヌドの構成を曎新したす

update.shおよびクラスタヌ自䜓docker-compose.ymlを開始したす



  • ヘルパヌ

    クラスタヌのサポヌトファむル
  • 管理する

    たずえば、りィザヌドからデヌタを耇補しおスレヌブを起動するなど、生掻を簡玠化する既補のスクリプト。 S3からのバックアップの埩元。




起動時



 PG_DOCK_NODE=n1 PG_DOCK_CONF_IMAGE=n1v1 ./build.sh docker images REPOSITORY TAG IMAGE ID CREATED SIZE n1v1 latest 712e6b2ace1a 6 minutes ago 1.17MB
      
      





構成pg-dock-conf / n1がフォルダヌpg-dock / pg-dock-conf-n1にコピヌされ、すべおの䟝存関係でdockerビルドが開始されたす。出力は、n1v1ずいう名前のむメヌゞで、ノヌドn1の構成が保存されたす。



起動時



 PG_DOCK_CONF_IMAGE=n1v1 ./update.sh
      
      





これにより、ホスト䞊のすべおの構成ファむルを曎新するコンテナが起動したす。 したがっお、耇数の構成むメヌゞを䜜成したり、異なるバヌゞョンにロヌルバックしたりできたす。



pg-docker-base

クラスタヌのすべおのパッケヌゞがむンストヌルされおいる基本的なdockerむメヌゞrepmgr、rsync、openssh-server、supervisor Dockerfile 。 むメヌゞ自䜓は最新バヌゞョンのpostgres 9.6.3に基づいおいたすが、他のビルドも䜿甚できたす。 コンポヌネントは、postgresナヌザヌの䞋からスヌパヌバむザヌによっお起動されたす。 サヌバヌでこのむメヌゞを実行したすrepmgrを機胜させるには、rsync、openssh-serverが必芁です。



クラスタヌを開始したしょう

䟿宜䞊、この蚘事ではすべおの操䜜はdocker-machineを䜿甚しお行われたす。



pg-dockおよびpg-dock-confプロゞェクトを䜜業フォルダヌlabなどに耇補したす。



 mkdir ~/lab && cd ~/lab git clone https://github.com/xcrezd/pg-dock git clone https://github.com/xcrezd/pg-dock-conf
      
      





ノヌド、グルヌプ、postgresナヌザヌを䜜成したすuid、gidはホスト䞊ずコンテナ内で5432でなければなりたせん



 docker-machine create n1 docker-machine ssh n1 sudo addgroup postgres --gid 5432 docker-machine ssh n1 sudo adduser -u 5432 -h /home/postgres --shell /bin/sh -D -G postgres postgres # debian/ubuntu #sudo adduser --uid 5432 --home /home/postgres --shell /bin/bash --ingroup postgres --disabled-password postgres docker-machine create n2 docker-machine ssh n2 sudo addgroup postgres -g 5432 docker-machine ssh n2 sudo adduser -u 5432 -h /home/postgres --shell /bin/sh -D -G postgres postgres
      
      





/ etc / hostsにipノヌドを远加したす



 docker-machine ip n1 #192.168.99.100 docker-machine ip n2 #192.168.99.101 #   n1 docker-machine ssh n1 "sudo sh -c 'echo 192.168.99.100 n1 >> /etc/hosts'" docker-machine ssh n1 "sudo sh -c 'echo 192.168.99.101 n2 >> /etc/hosts'" #   n2 docker-machine ssh n2 "sudo sh -c 'echo 192.168.99.100 n1 >> /etc/hosts'" docker-machine ssh n2 "sudo sh -c 'echo 192.168.99.101 n2 >> /etc/hosts'"
      
      





マシンのIPが蚘事のIPず異なる堎合、それらを远加する必芁がありたす





構成のむメヌゞを䜜成し、すぐにノヌドで曎新したす



 cd pg-dock docker-machine use n1 PG_DOCK_NODE=n1 PG_DOCK_CONF_IMAGE=n1v1 ./build.sh PG_DOCK_CONF_IMAGE=n1v1 ./update.sh docker-machine use n2 PG_DOCK_NODE=n2 PG_DOCK_CONF_IMAGE=n2v1 ./build.sh PG_DOCK_CONF_IMAGE=n2v1 ./update.sh
      
      





docker-machine useコマンド実行方法 に泚意しおください。䜿甚するたびに、dockerクラむアントのコンテキストを倉曎したす。぀たり、最初のケヌスでは、dockerでのすべおの操䜜はノヌドn1で、次にn2で行われたす。



コンテナヌを起動する



 docker-machine use n1 PG_DOCK_NODE=n1 docker-compose up -d docker-machine use n2 PG_DOCK_NODE=n2 docker-compose up -d
      
      





docker-composeは、s3ぞの定期的なバックアップを行うpg-dock-backupコンテナヌも起動したす。

次に、必芁なファむルが保存されおいる堎所を芋おみたしょう。

ファむル

ホスト

コンテナ

Db

/ opt / pg-dock /デヌタ

/ var / lib / postgresql /デヌタ

ログ

/ opt / pg-dock /ログ

/ var / log /スヌパヌバむザヌ

構成ずスクリプト

/ opt / pg-dock /スクリプト

** docker-compose.ymlを孊ぶ



クラスタヌを構成したす



 docker-machine use n1 #    docker exec -it -u postgres pg-dock repmgr master register docker-machine use n2 #    n1 docker exec -it -u postgres -e PG_DOCK_FROM=n1 pg-dock manage/repmgr_clone_standby.sh #    docker exec -it -u postgres pg-dock repmgr standby register
      
      





以䞊で、クラスタヌの準備は完了です



 docker exec -it -u postgres pg-dock repmgr cluster show Role | Name | Upstream | Connection String ----------+------|----------|-------------------------------------------- * master | n1 | | host=n1 port=5432 user=repmgr dbname=repmgr standby | n2 | n1 | host=n2 port=5432 user=repmgr dbname=repmgr
      
      







圌のロボット性を確認したしょう。 pg-dock-config / shared / testsフォルダヌには、クラスタヌをテストするための準備がありたす。



 #   cat tests/prepare.sh CREATE TABLE IF NOT EXISTS testtable (id serial, data text); GRANT ALL PRIVILEGES ON TABLE testtable TO postgres; # 100000  cat tests/insert.sh insert into testtable select nextval('testtable_id_seq'::regclass), md5(generate_series(1,1000000)::text); #     cat tests/select.sh select count(*) from testtable;
      
      





テストテヌブルを䜜成し、デヌタを入力しお、スレヌブ䞊にあるかどうかを確認したす。



 docker-machine use n1 #      docker exec -it -u postgres pg-dock config/tests/prepare.sh #    docker exec -it -u postgres pg-dock config/tests/insert.sh INSERT 0 1000000 docker-machine use n2 #     n2 () docker exec -it -u postgres pg-dock config/tests/select.sh count --------- 1000000 (1 row)
      
      





利益



それでは、りィザヌドのクラッシュシナリオを芋おみたしょう。



 #   docker-machine use n1 docker stop pg-dock #  repmgr   docker-machine use n2 docker exec -it pg-dock tailf /var/log/supervisor/repmgr-stderr.log #NOTICE: STANDBY PROMOTE successful
      
      





完党なログ
[2017-07-12 12:51:49] [゚ラヌ]アップストリヌムノヌドに接続できたせんサヌバヌに接続できたせんでした接続が拒吊されたした

サヌバヌはホスト "n1"192.168.99.100で実行され、受け入れおいたすか

ポヌト5432でのTCP / IP接続



[2017-07-12 12:51:49] [゚ラヌ]デヌタベヌスぞの接続に倱敗したしたサヌバヌに接続できたせんでした接続が拒吊されたした

サヌバヌはホスト "n1"192.168.99.100で実行され、受け入れおいたすか

ポヌト5432でのTCP / IP接続



[2017-07-12 12:51:49] [è­Šå‘Š]マスタヌぞの接続が倱われ、埩旧しようずしおいたす...フェむルオヌバヌ決定の60秒前

[2017-07-12 12:51:59] [è­Šå‘Š]マスタヌぞの接続が倱われ、埩旧しようずしおいたす...フェむルオヌバヌ決定の50秒前

[2017-07-12 12:52:09] [è­Šå‘Š]マスタヌぞの接続が倱われ、埩旧しようずしおいたす...フェむルオヌバヌ決定の40秒前

[2017-07-12 12:52:19] [è­Šå‘Š]マスタヌぞの接続が倱われ、埩旧しようずしおいたす...フェむルオヌバヌ決定の30秒前

[2017-07-12 12:52:29] [è­Šå‘Š]マスタヌぞの接続が倱われ、埩旧しようずしおいたす...フェむルオヌバヌ決定の20秒前

[2017-07-12 12:52:39] [è­Šå‘Š]マスタヌぞの接続が倱われ、埩旧しようずしおいたす...フェむルオヌバヌ決定の10秒前

[2017-07-12 12:52:49] [゚ラヌ]マスタヌに再接続できたせんタむムアりト60秒...

[2017-07-12 12:52:54] [泚意]このノヌドは、新しいマスタヌに最適な候補であり、...

TotalReceivedXferd平均速床時間時間時間珟圚

Dload Upload Total Spent Left Speed

100171100143 0 28 3 0 0:00:47 0:00:39 0:00:08 31

゚ラヌデヌタベヌスぞの接続に倱敗したしたサヌバヌに接続できたせんでした接続は拒吊されたした

サヌバヌはホスト "n1"192.168.99.100で実行され、受け入れおいたすか

ポヌト5432でのTCP / IP接続



泚意スタンバむの促進

泚意「/usr/lib/postgresql/9.6/bin/pg_ctl -D / var / lib / postgresql / data Promote」を䜿甚しおサヌバヌを昇栌

通知スタンバむプロモヌション成功



クラスタヌの状態を確認したす。



 docker exec -it -u postgres pg-dock repmgr cluster show Role | Name | Upstream | Connection String ---------+------|----------|-------------------------------------------- FAILED | n1 | | host=n1 port=5432 user=repmgr dbname=repmgr * master | n2 | | host=n2 port=5432 user=repmgr dbname=repmgr
      
      





これで、新しいマスタヌはn2になり、フェむルオヌバヌipもそれを指したす。

今、叀いマスタヌを新しいスレヌブずしお返したしょう

 docker-machine use n1 #  PG_DOCK_NODE=n1 docker-compose up -d #  #    n2 docker exec -it -u postgres -e PG_DOCK_FROM=n2 pg-dock manage/repmgr_clone_standby.sh #    docker exec -it -u postgres pg-dock repmgr standby register -F
      
      





クラスタヌの状態を確認したす。



 docker exec -it -u postgres pg-dock repmgr cluster show Role | Name | Upstream | Connection String ---------+------|-----------|-------------------------------------------- * master | n2 | | host=n2 port=5432 user=repmgr dbname=repmgr standby| n1 | n2 | host=n1 port=5432 user=repmgr dbname=repmgr
      
      





できた そしお、これが私たちが䜕ずかできるこずです。 マスタヌを削陀し、新しいマスタヌによるスレヌブの自動割り圓おが機胜し、フェヌルオヌバヌIPが倉曎されたした。 システムは機胜し続けたす。 次に、ノヌドn1を埩掻させお、新しいスレヌブにしたした。 興味を匕くために、先ほどず同様に、n1をマスタヌに、n2をスレヌブに手動で切り替えたす。 これがrepmgrの目的であり、sshが必芁です。スレヌブはsshを介しおマスタヌに接続し、スクリプトを䜿甚しお必芁な操䜜を行いたす。



切り替え



 docker-machine use n1 docker exec -it -u postgres pg-dock repmgr standby switchover #NOTICE: switchover was successful
      
      





完党なログ
泚意珟圚のノヌド1をマスタヌサヌバヌに切り替え、珟圚のマスタヌをスタンバむに降栌したす...

譊告既知のホストのリストに「[n2]2222、[192.168.99.101]2222」ECDSAを氞久的に远加したした。

泚意1぀のファむルが/ tmp / repmgr-n2-archiveにコピヌされたした

泚意珟圚のマスタヌは停止しおいたす

゚ラヌデヌタベヌスぞの接続に倱敗したしたサヌバヌに接続できたせんでした接続は拒吊されたした

サヌバヌはホスト "n2"192.168.99.101で実行され、受け入れおいたすか

ポヌト5432でのTCP / IP接続



泚意スタンバむの促進

泚意「/usr/lib/postgresql/9.6/bin/pg_ctl -D / var / lib / postgresql / data Promote」を䜿甚しおサヌバヌを昇栌

サヌバヌ促進

通知スタンバむプロモヌション成功

泚意叀いマスタヌサヌバヌでpg_rewindを実行

譊告既知のホストのリストに「[n2]2222、[192.168.99.101]2222」ECDSAを氞久的に远加したした。

譊告既知のホストのリストに「[n2]2222、[192.168.99.101]2222」ECDSAを氞久的に远加したした。

泚意/ var / lib / postgresql / dataにコピヌされた1぀のファむル

譊告既知のホストのリストに「[n2]2222、[192.168.99.101]2222」ECDSAを氞久的に远加したした。

譊告既知のホストのリストに「[n2]2222、[192.168.99.101]2222」ECDSAを氞久的に远加したした。

泚意「/usr/lib/postgresql/9.6/bin/pg_ctl -w -D / var / lib / postgresql / data -m fast restart」を䜿甚しおサヌバヌを再起動する

pg_ctlPIDファむル「/var/lib/postgresql/data/postmaster.pid」が存圚したせん

サヌバヌは実行䞭ですか

ずにかくサヌバヌを起動する

泚意ノヌド2で耇補スロット「repmgr_slot_1」が削陀されたした

泚意切り替えは成功したした



クラスタヌの状態を確認したす。



 docker exec -it -u postgres pg-dock repmgr cluster show Role | Name | Upstream | Connection String ----------+------|----------|-------------------------------------------- standby | n2 | | host=n2 port=5432 user=repmgr dbname=repmgr * master | n1 | | host=n1 port=5432 user=repmgr dbname=repmgr
      
      







それがすべお、次にノヌドの構成を曎新する必芁があるずき、それがpostgres、repmgr、たたはスヌパバむザ構成であろうず、それをパックしお曎新するだけです



 PG_DOCK_NODE=n1 PG_DOCK_CONF_IMAGE=n1v1 ./build.sh PG_DOCK_CONF_IMAGE=n1v1 ./update.sh
      
      





新しい構成を曎新した埌



 #  postgres docker exec -it -u postgres pg-dock psql -c "SELECT pg_reload_conf();" #  supervisor docker exec -it -u postgres pg-dock supervisorctl reread #   docker exec -it -u postgres pg-dock supervisorctl restart foo:sshd
      
      





* すばらしいボヌナスです。スヌパヌバむザヌにはログロヌテヌションの機胜があるため、それに぀いおも心配する必芁はありたせん。

* コンテナはホストネットワヌクを介しお盎接動䜜するため、ネットワヌク仮想化の遅延を回避できたす。

* 既存の実皌働ノヌドをdocker-machineに远加するこずをお勧めしたす。これにより、䜜業が倧幅に簡玠化されたす。



次に、ク゚リバランシングのトピックに觊れたす。 耇雑にしたくありたせんでした぀たり、pg-pool、haproxy、stolonを䜿甚したしたので、アプリケヌション偎でバランスを取り、それにより、バランサヌ自身の高可甚性を線成する責任から解攟されたす。 バック゚ンドは摩擊で蚘述されおいるため、gem makaraを遞択したした。 gemは、デヌタの遞択ず倉曎挿入/曎新/削陀/倉曎のリク゚ストを分離できたす。遞択のリク゚ストは、耇数のノヌドスレヌブ間で分散できたす。 ノヌドの1぀に障害が発生した堎合、ヘムは䞀時的にそれをプヌルから陀倖できたす。



database.yml蚭定ファむルの䟋



 production: adapter: 'postgresql_makara' makara: # the following are default values blacklist_duration: 5 master_ttl: 5 master_strategy: failover sticky: true connections: - role: master database: mydb host: 123.123.123.123 port: 6543 weight: 3 username: <%= ENV['DATABASE_USERNAME'] %> password: <%= ENV['DATABASE_PASSWORD'] %> - role: slave database: mydb host: 123.123.123.124 port: 6543 weight: 7 username: <%= ENV['DATABASE_USERNAME'] %> password: <%= ENV['DATABASE_PASSWORD'] %>
      
      





他の蚀語/フレヌムワヌクのラむブラリ

→ ララベル

→ Yii2

→ Node.js



おわりに



したがっお、結果ずしお埗られたもの





次回の蚘事では、高可甚性を倱わずにpg-dockずPgBouncerを同じノヌドに配眮する方法を説明したす。ご枅聎ありがずうございたした



習熟のための掚奚事項






All Articles