Docker コンテナにおける Patroni の簡単な分析

Docker コンテナにおける Patroni の簡単な分析

前回はRepmgrの構築手順と自動切り替えの実装を紹介しました。今回はコンテナ配下にPatroniクラスタ環境を構築する方法を紹介します。Patroniはすぐに使えるPG高可用性ツールとして、クラウド環境でさまざまなベンダーの導入が増えています。

パトロニの基本的なアーキテクチャを図に示します。

ここに画像の説明を挿入

etcd は分散登録センターとして機能し、クラスター マスターの選出を実行します。vip-manager はマスター ノードのドリフト IP を設定します。patroni はクラスターの作成、操作、管理をガイドする役割を担い、ターミナル アクセスに patentictl を使用できます。

具体的なプロセス:
1. まず、etcd クラスターを起動します。この例では、etcd の数は 3 です。
2. etcd クラスターが正常であることを確認した後、patroni を起動してリーダーの選出を競い、他のフォロワー ノードはデータの同期を実行します。
3. vip-manager を起動し、etcd クラスターの /SERVICENAME/{SERVICE_NAME}/SERVICEN​AME/{CLUSTER_NAME}/leader キーの特定の値にアクセスして、現在のノードがマスター ノード IP であるかどうかを判断します。そうである場合は、外部読み取りおよび書き込みサービスを提供するためにノードに vip を設定します。
注意: 外部サービスを提供するには、実際の環境では別のコンテナに etcd をデプロイすることをお勧めします。

画像を作成する

ファイル構造

このうち、Dockerfile はイメージのメイン ファイルであり、docker サービスはこのファイルを通じてローカル ウェアハウスにイメージを作成します。entrypoint.sh はコンテナー エントリ ファイルであり、ビジネス ロジックの処理を担当します。function はビジネス メソッドを実行するためのエントリ ファイルであり、etcd の起動、etcd クラスターの状態の監視、patoni および vip-manager の起動を担当します。generatefile は、etcd、patoni、vip-manager を含むコンテナー全体の対応する構成ファイルを生成します。

ディレクトリ構造は、おおよそ図のようになります。

ここに画像の説明を挿入

注意: データベースインストールパッケージとpatroniインストールパッケージはご自身で構築してください。

Dockerファイル

Centos:7より

メンテナー wangzhibin <wangzhibin>

環境変数 USER="postgresql" \
    パスワード=123456 \
    グループ=postgresql 
	
実行 useradd ${USER} \
       && chown -R ${USER}:${GROUP} /home/${USER} \
       && yum -y update && yum install -y iptables sudo net-tools iproute openssh-server openssh-clients which vim sudo crontabs
#etcdをインストールする
etcd/etcd /usr/sbin にコピー
etcd/etcdctl /usr/sbin にコピー

#データベースをインストールする
lib/ /home/${USER}/lib をコピーする
コピー include/ /home/${USER}/include
コピー share/ /home/${USER}/share
コピー bin/ /home/${USER}/bin/
コピーpatroni/ /home/${USER}/patroni

#vip-managerをインストールする
vip-manager/vip-manager /usr/sbinにコピー
#実行スクリプトをインストール COPYruntime/ /home/${USER}/runtime
コピー entrypoint.sh /sbin/entrypoint.sh

#環境変数ENV LD_LIBRARY_PATH /home/${USER}/libを設定します
環境変数PATH /home/${USER}/bin:$PATH
環境変数ETCDCTL_API=3

#Patroniをインストールする
実行 yum -y install epel-release python-devel && yum -y install python-pip \
    && pip インストール /home/${USER}/patroni/1/pip-20.3.3.tar.gz \
    && pip インストール /home/${USER}/patroni/1/psycopg2-2.8.6-cp27-cp27mu-linux_x86_64.whl \
    && pip install --no-index --find-links=/home/${USER}/patroni/2/ -r /home/${USER}/patroni/2/requirements.txt \
    && pip インストール /home/${USER}/patroni/3/patroni-2.0.1-py2-none-any.whl

#実行権限を変更する RUN chmod 755 /sbin/entrypoint.sh \ 
&& mkdir /home/${USER}/etcddata \
&& chown -R ${USER}:${GROUP} /home/${USER} \
&& echo 'root:root123456' | chpasswd \
&& chmod 755 /sbin/etcd \
&& chmod 755 /sbin/etcdctl \
&& chmod 755 /sbin/vip-manager

#Sudoを設定する
chmod 777 /etc/sudoers \ を実行します
       && sed -i '/## root がどこでも任意のコマンドを実行できるようにする/a '${USER}' ALL=(ALL) NOPASSWD:ALL' /etc/sudoers \
       && chmod 440 /etc/sudoers

#ユーザー USER ${USER} を切り替える

#作業ディレクトリを切り替える WORKDIR /home/${USER}

#エントリプログラムを起動します CMD ["/bin/bash", "/sbin/entrypoint.sh"]

エントリポイント

#!/bin/bash
セット-e

# シェルチェックソース=runtime/functions
ソース "/home/${USER}/runtime/function"

設定_patroni

関数

#!/bin/bash

セット-e
ソース /home/${USER}/runtime/env-defaults
ソース /home/${USER}/runtime/generatefile

PG_DATADIR=/home/${USER}/pgdata
PG_BINDIR=/home/${USER}/bin

configure_patroni()
{
    #設定ファイルgenerate_etcd_confを生成する
    生成_patroni_conf
    生成vip
    #etcdを起動する
    etcdcount=${ETCD_COUNT}
    カウント=0
    ip_temp=""
    配列=(${HOSTLIST//,/ })
    ${array[@]}内のホスト
    する
        ip_temp+="http://${ホスト}:2380,"
    終わり
    etcd --config-file=/home/${USER}/etcd.yml >/home/${USER}/etcddata/etcd.log 2>&1 &
    [ $count -lt $etcdcount ] の間
    する
      行 = (`etcdctl --endpoints=${ip_temp%?} エンドポイントヘルス -w json`)
      count=`echo $line | awk -F"\"health\":true" '{print NF-1}'`
      echo "etcd クラスターを待機中"
      睡眠5
    終わり
    #パトロニを開始
    パトロニ /home/${USER}/postgresql.yml > /home/${USER}/patroni/patroni.log 2>&1 &
    #vip-managerを起動
    sudo vip-manager --config /home/${USER}/vip.yml
}

ファイルを生成する

#!/bin/bash
セット-e

HOSTNAME="`ホスト名`"
hostip=`ping ${HOSTNAME} -c 1 -w 1 | sed '1{s/[^(]*(//;s/).*//;q}'`

#etcd を生成する
生成する
{
    echo "name : ${HOSTNAME}" >> /home/${USER}/etcd.yml
    echo "データディレクトリ: /home/${USER}/etcddata" >> /home/${USER}/etcd.yml
    echo "listen-client-urls: http://0.0.0.0:2379" >> /home/${USER}/etcd.yml
    echo "advertise-client-urls: http://${hostip}:2379" >> /home/${USER}/etcd.yml
    echo "listen-peer-urls: http://0.0.0.0:2380" >> /home/${USER}/etcd.yml
    echo "初期アドバタイズピア URL: http://${hostip}:2380" >> /home/${USER}/etcd.yml
    ip_temp="初期クラスター: "
    配列=(${HOSTLIST//,/ })  
    ${array[@]}内のホスト
    する
    	ip_temp+="${ホスト}=http://${ホスト}:2380," 
    終わり
    ${ip_temp%?} をエコー >> /home/${USER}/etcd.yml
    echo "初期クラスタートークン: etcd クラスタートークン" >> /home/${USER}/etcd.yml
    echo "初期クラスター状態: new" >> /home/${USER}/etcd.yml
}

#パトロニを生成する
生成する
{
  echo "スコープ: ${CLUSTER_NAME}" >> /home/${USER}/postgresql.yml
  echo "名前空間: /${SERVICE_NAME}/ " >> /home/${USER}/postgresql.yml
  echo "name: ${HOSTNAME} " >> /home/${USER}/postgresql.yml
  echo "restapi: " >> /home/${USER}/postgresql.yml 
  echo " listen: ${hostip}:8008 " >> /home/${USER}/postgresql.yml 
  echo " connect_address: ${hostip}:8008 " >> /home/${USER}/postgresql.yml
  echo "etcd: " >> /home/${USER}/postgresql.yml
  echo " ホスト: ${hostip}:2379 " >> /home/${USER}/postgresql.yml
  echo " ユーザー名: ${ETCD_USER} " >> /home/${USER}/postgresql.yml
  echo " パスワード: ${ETCD_PASSWD} " >> /home/${USER}/postgresql.yml
  echo "bootstrap: " >> /home/${USER}/postgresql.yml
  echo " dcs: " >> /home/${USER}/postgresql.yml
  echo " ttl: 30 " >> /home/${USER}/postgresql.yml
  echo " loop_wait: 10 " >> /home/${USER}/postgresql.yml
  echo " retry_timeout: 10 " >> /home/${USER}/postgresql.yml
  echo " フェイルオーバー時の最大ラグ: 1048576 " >> /home/${USER}/postgresql.yml
  echo " postgresql: " >> /home/${USER}/postgresql.yml
  echo " use_pg_rewind: true " >> /home/${USER}/postgresql.yml
  echo " use_slots: true " >> /home/${USER}/postgresql.yml
  echo " パラメータ: " >> /home/${USER}/postgresql.yml
  echo " initdb: " >> /home/${USER}/postgresql.yml
  echo " - エンコーディング: UTF8 " >> /home/${USER}/postgresql.yml
  echo " - データチェックサム " >> /home/${USER}/postgresql.yml
  echo " pg_hba: " >> /home/${USER}/postgresql.yml
  echo " - ホストレプリケーション ${USER} 0.0.0.0/0 md5 " >> /home/${USER}/postgresql.yml
  echo " - ホストすべて すべて 0.0.0.0/0 md5 " >> /home/${USER}/postgresql.yml
  echo "postgresql: " >> /home/${USER}/postgresql.yml
  echo " listen: 0.0.0.0:5432 " >> /home/${USER}/postgresql.yml
  echo " connect_address: ${hostip}:5432 " >> /home/${USER}/postgresql.yml
  echo " data_dir: ${PG_DATADIR} " >> /home/${USER}/postgresql.yml
  echo " bin_dir: ${PG_BINDIR} " >> /home/${USER}/postgresql.yml
  echo " pgpass: /tmp/pgpass " >> /home/${USER}/postgresql.yml
  echo " 認証: " >> /home/${USER}/postgresql.yml
  echo " レプリケーション: " >> /home/${USER}/postgresql.yml
  echo " ユーザー名: ${USER} " >> /home/${USER}/postgresql.yml
  echo " パスワード: ${PASSWD} " >> /home/${USER}/postgresql.yml
  echo " スーパーユーザー: " >> /home/${USER}/postgresql.yml
  echo " ユーザー名: ${USER} " >> /home/${USER}/postgresql.yml
  echo " パスワード: ${PASSWD} " >> /home/${USER}/postgresql.yml
  echo " 巻き戻し: " >> /home/${USER}/postgresql.yml
  echo " ユーザー名: ${USER} " >> /home/${USER}/postgresql.yml
  echo " パスワード: ${PASSWD} " >> /home/${USER}/postgresql.yml
  echo " パラメータ: " >> /home/${USER}/postgresql.yml
  echo " unix_socket_directories: '.' " >> /home/${USER}/postgresql.yml
  echo " wal_level: hot_standby " >> /home/${USER}/postgresql.yml
  echo " max_wal_senders: 10 " >> /home/${USER}/postgresql.yml
  echo " max_replication_slots: 10 " >> /home/${USER}/postgresql.yml
  echo "タグ: " >> /home/${USER}/postgresql.yml
  echo " nofailover: false " >> /home/${USER}/postgresql.yml
  echo " noloadbalance: false " >> /home/${USER}/postgresql.yml
  echo " clonefrom: false " >> /home/${USER}/postgresql.yml
  echo " nosync: false " >> /home/${USER}/postgresql.yml
}
#....... 一部のコンテンツを省略

イメージを構築する

docker build -t patentani を実行します。

画像を実行する

コンテナノード1を実行します。
docker run --privileged --name patenti1 -itd --hostname patenti1 --net my_net3 --restart always --env 'CLUSTER_NAME=patronicluster' --env 'SERVICE_NAME=service' --env 'ETCD_USER=etcduser' --env 'ETCD_PASSWD=etcdpasswd' --env 'PASSWD=zalando' --env 'HOSTLIST=patroni1,patroni2,patroni3' --env 'VIP=172.22.1.88' --env 'NET_DEVICE=eth0' --env 'ETCD_COUNT=3' patenti
コンテナノード2を実行します。
docker run --privileged --name patenti2 -itd --hostname patenti2 --net my_net3 --restart always --env 'CLUSTER_NAME=patronicluster' --env 'SERVICE_NAME=service' --env 'ETCD_USER=etcduser' --env 'ETCD_PASSWD=etcdpasswd' --env 'PASSWD=zalando' --env 'HOSTLIST=patroni1,patroni2,patroni3' --env 'VIP=172.22.1.88' --env 'NET_DEVICE=eth0' --env 'ETCD_COUNT=3' patenti
コンテナノード3を実行します。
docker run --privileged --name patenti3 -itd --hostname patenti3 --net my_net3 --restart always --env 'CLUSTER_NAME=patronicluster' --env 'SERVICE_NAME=service' --env 'ETCD_USER=etcduser' --env 'ETCD_PASSWD=etcdpasswd' --env 'PASSWD=zalando' --env 'HOSTLIST=patroni1,patroni2,patroni3' --env 'VIP=172.22.1.88' --env 'NET_DEVICE=eth0' --env 'ETCD_COUNT=3' patenti

要約する

この操作プロセスは、etcd+patroni+vipmanager の全体的なコンテナ化を示すために、実験環境に限定されています。実際の環境では、etcd を異なるコンテナにデプロイして独立した分散クラスタを形成し、PG ストレージをローカル ディスクまたはネットワーク ディスクにマッピングする必要があります。また、コンテナ クラスタの構築には、docker-compose、docker-warm、Kubernetes などのオーケストレーション ツールを可能な限り使用する必要があります。

添付写真

etcd クラスターのステータスは以下のとおりです。

ここに画像の説明を挿入

パトロニ クラスターのステータスは次のとおりです。

ここに画像の説明を挿入

VIP マネージャーのステータスは以下のとおりです。

ここに画像の説明を挿入

ここに画像の説明を挿入

Docker コンテナにおける Patroni の詳細な分析に関するこの記事はこれで終わりです。Docker コンテナの Patroni に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Dockerコンテナのいくつかの保存方法の詳細な説明
  • Dockerコンテナ終了エラーコードの手順
  • Docker コンテナ データ ボリュームの名前付きマウントと匿名マウントの問題

<<:  フレックスインサイドボタンの垂直方向の中央揃えが中央揃えにならない問題の解決方法

>>:  HTML入力ドロップダウンメニューを実装する方法

推薦する

Windows 10 に Apache 2.4.41 をインストールするチュートリアル

1. Apache 2.4.41 のインストールと設定最初のステップは、以下に示すように、https...

Linux trコマンドの使い方

01. コマンドの概要tr コマンドは、標準入力からの文字を置換、圧縮、削除できます。ある文字セット...

フォーム送信の更新ページはソースコード設計にジャンプしません

1. ソースコードの設計コードをコピーコードは次のとおりです。 <!DOCTYPE html ...

CSS属性のデフォルト値width: autoとwidth: 100%の違いの詳細な説明

幅: 自動子要素(コンテンツ+パディング+境界線+余白を含む)は、親要素のコンテンツ領域全体を埋めま...

MySQL が大規模トランザクションを避けるべき理由とその解決方法

何が大問題ですか?長時間実行され、長時間コミットされないトランザクションは、大規模トランザクションと...

MySql 5.7.17 winx64 のインストールと設定に関する詳細なチュートリアル

1. ソフトウェアをダウンロードする1. MySQL の公式サイトにアクセスし、Oracle アカウ...

pagodaを使用してionCube拡張機能をインストールする方法

1. まずパゴダを設置するインストール要件: Python バージョン: 2.6/2.7 (Pago...

Vueルータールーティングガードの詳細な説明

目次1. グローバル beforeEach 1. グローバル beforeEach 2. 実装2. ...

Dockerfile に基づいて Tomcat イメージを構築する方法

Dockerfile は Docker イメージを構築するために使用されるファイルです。コマンドパラ...

Vue echarts は水平棒グラフを実現します

この記事では、水平棒グラフを実現するためのvue echartsの具体的なコードを参考までに共有しま...

MySQLログシステムの使い方に関する簡単なチュートリアル

目次序文1. エラーログ2. バイナリログ1. バイナリログを有効にする2. バイナリログ形式3. ...

MySQLデータ損失のトラブルシューティング事例

目次序文現地調査ケースの再現要約する序文最近、友人が突然WeChatで連絡してきて、MySQLでデー...

CSS で要素を垂直方向に中央揃えする 7 つの方法

【1】中央の要素の幅と高さを知る絶対値 + 負のマージンコードの実装 .wrapBox5{ 幅: 3...

Dockerデータ管理とネットワーク通信の使用

Docker をインストールし、Docker コアとインストールを通じて簡単な操作を実行できます。 ...

IIS7 IIS8 http は自動的に HTTPS にジャンプします (ポート 80 はポート 443 にジャンプします)

IIS7 では、「URL REWRITE2」疑似静的モジュールがインストールされているかどうかを確...