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

推薦する

LinuxベースのApacheウェブサイトサービス構成の詳細な説明

オープンソース ソフトウェアである Apache は、最も広く使用されている Web アプリケーショ...

Nginx 外部ネットワーク アクセス イントラネット サイト構成操作

背景:サイトはフロントエンドとバックエンドから分離されています: vue+springbootフロン...

Linux 環境変数とプロセス アドレス空間の概要

目次Linux 環境変数とプロセスアドレス空間コードを通じて環境変数を取得するプロセスアドレス空間な...

Alibaba Cloud イメージリポジトリを使用して外部 Docker イメージを構築する方法の詳細な説明

Alibaba Cloud Image Repositoryを使用して外部イメージをダウンロードする...

Django プロジェクトを作成して MySQL に接続する方法

1: django-admin.py startproject プロジェクト名2: cd プロジェク...

CSS で画像アダプティブ コンテナを実装するためのサンプル コード

多くの場合、画像をコンテナのサイズに合わせて調整する必要があります。 1. imgタグ方式幅と高さを...

Linux echo テキスト処理コマンドの使用法と例

Linux ヘルプ ドキュメントでの echo の説明は、Python や Java などのプログラ...

MySQL で union all を使用してユニオンソートを取得する方法

プロジェクトでは、何らかの不可逆的な理由により、テーブルに保存されたデータがページの表示要件を満たす...

ウェブページを最適化してメモリとCPUの使用率を削減

一部の Web ページは大きく見えなくても開くのに非常に時間がかかる場合があります。一方、他の We...

Vuex環境の詳細な説明

目次Vuex環境を構築する要約するVuex環境を構築するsrcディレクトリにフォルダstoreを作成...

独自の FTP および SFTP サーバーを構築するプロセスの紹介

FTP と SFTP はファイル転送プロトコルとして広く使用されています。関連する機能を開発するには...

Tencent Cloud 上で Hadoop 3.x 疑似クラスターを構築する方法を説明します

1. 環境整備CentOS Linux リリース 7.5.1804 (コア)インストールフォルダを作...

フォームデータを取得するための Node.js メソッドの 3 つの例

序文Nodejs はサーバーサイド言語です。開発中、登録やログインなどでは、判断のためにフォームを通...

チェックボックスとラジオボタンの配置を実装する方法

ブラウザによって動作が異なるだけでなく、フォントやテキスト サイズによっても動作が異なります。フォー...

MySQLにデータを素早くインポートする方法

序文:日々の勉強や仕事の中で、データをエクスポートする必要に迫られることがよくあります。たとえば、デ...