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入力ドロップダウンメニューを実装する方法

推薦する

RHEL7.5 mysql 8.0.11 インストールチュートリアル

この記事はRHEL7.5でのMySQL 8.0.11のインストールチュートリアルを記録しています。具...

MySQL における主キーが 0 であることと主キーの自己選択制約の関係についての詳しい説明 (詳細)

序文この記事は主にMySQLの主キー0と主キー自己排除制約の関係を紹介し、皆さんの参考と学習のために...

WindowsでcmdからDOSウィンドウに入り、MySQLデータベースにアクセスします。

1. win + R を押して cmd と入力し、DOS ウィンドウに入ります。 2. MySQL...

Echarts 凡例コンポーネントのプロパティとソース コード

凡例コンポーネントは、ECharts でよく使用されるコンポーネントです。シリーズ マーカーの名前を...

MySQL 8.0.21 の最新バージョンのダウンロード、インストール、設定に関する詳細なチュートリアル

1. ダウンロード1. インストールパッケージをダウンロードするMySQL ダウンロード パス: h...

CentOS7.3 での MySQL 8.0.13 のインストールと設定のチュートリアル

1. 基本環境1. オペレーティングシステム: CentOS 7.3 2. MySQL: 8.0.1...

MySQL/MariaDB でピボット テーブルを実装する方法のサンプル コード

前回の記事では、Oracle でピボット テーブルを実装するいくつかの方法を紹介しました。今日は、同...

MySQL NULLがピットを引き起こした

比較演算子でNULLを使用する mysql> 1>NULLを選択します。 +------...

生年月日を年齢に変換し、グループ化して人数を数えるMySQLの例

データベースのクエリ `学生`から*を選択 クエリ結果id名前誕生日1張三1970-10-01 2李...

MySQL 基本チュートリアル パート 1 MySQL5.7.18 のインストールと接続チュートリアル

この記事から、MySQL を紹介し学習するための新しい一連の記事がスタートします。なぜ MySQL ...

ウェブページ経由で jar パッケージを Nexus にアップロードする方法

Maven を使用してプロジェクトを管理する場合、jar パッケージをプライベート ウェアハウスにア...

CentOS8でyumソースを変更した後にウェアハウスキャッシュの同期に失敗する問題の詳細な説明

問題の原因: 最初は CentOS 8 のデフォルトの yum ソースを正常に使用できますが、次のコ...

vue+iviewのメニューとタブの連携方法

Vue+iview メニューとタブのリンク現在、vue+iview を使用してバックエンド管理システ...

Vue での keepAlive の使用例の詳細な説明

開発においては、一覧から詳細ページにジャンプし、また詳細ページに戻る際に一覧ページの状態(スクロール...

MySQL IFNULL判定問題の解決方法

問題: mybatis によって返される null 型のデータが消え、フロントエンドの表示にエラーが...