Patroni, etcd, HAProxy āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ āĻāĻ•āĻŸāĻŋ āĻ…āĻ¤ā§āĻ¯āĻ¨ā§āĻ¤ āĻ‰āĻĒāĻ˛āĻŦā§āĻ§ PostgreSQL āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ° āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻž

āĻāĻŸāĻž āĻ āĻŋāĻ• āĻ¤āĻžāĻ‡ āĻ˜āĻŸā§‡āĻ›ā§‡ āĻ¯ā§‡ āĻ¸āĻŽāĻ¯āĻŧā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻŸāĻŋ āĻ‰āĻ¤ā§āĻĨāĻžāĻĒāĻŋāĻ¤ āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛, āĻ†āĻŽāĻžāĻ° āĻāĻ•āĻž āĻāĻ‡ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨āĻŸāĻŋ āĻŦāĻŋāĻ•āĻžāĻļ āĻāĻŦāĻ‚ āĻšāĻžāĻ˛ā§ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ¯āĻĨā§‡āĻˇā§āĻŸ āĻ…āĻ­āĻŋāĻœā§āĻžāĻ¤āĻž āĻ›āĻŋāĻ˛ āĻ¨āĻžāĨ¤ āĻāĻŦāĻ‚ āĻ¤āĻžāĻ°āĻĒāĻ° āĻ†āĻŽāĻŋ āĻ—ā§āĻ—āĻ˛āĻŋāĻ‚ āĻļā§āĻ°ā§ āĻ•āĻ°āĻŋāĨ¤

āĻ†āĻŽāĻŋ āĻœāĻžāĻ¨āĻŋ āĻ¨āĻž āĻ•ā§āĻ¯āĻžāĻšāĻŸāĻŋ āĻ•ā§€, āĻ¤āĻŦā§‡ āĻ†āĻŽāĻŋ āĻāĻ‡ āĻ¸āĻ¤ā§āĻ¯ā§‡āĻ° āĻŽā§āĻ–ā§‹āĻŽā§āĻ–āĻŋ āĻšāĻ¯āĻŧā§‡āĻ›āĻŋ āĻ¯ā§‡ āĻ†āĻŽāĻŋ āĻ¯āĻĻāĻŋ āĻŸāĻŋāĻ‰āĻŸā§‹āĻ°āĻŋāĻ¯āĻŧāĻžāĻ˛ā§‡āĻ° āĻŽāĻ¤ā§‹ āĻ§āĻžāĻĒā§‡ āĻ§āĻžāĻĒā§‡ āĻ¸āĻŦāĻ•āĻŋāĻ›ā§ āĻ•āĻ°āĻŋ, āĻ˛ā§‡āĻ–āĻ•ā§‡āĻ° āĻŽāĻ¤ā§‹ āĻāĻ•āĻ‡ āĻĒāĻ°āĻŋāĻŦā§‡āĻļ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻŋ, āĻ¤āĻŦā§‡ āĻ•āĻŋāĻ›ā§āĻ‡ āĻ•āĻ–āĻ¨āĻ‡ āĻ•āĻžāĻœ āĻ•āĻ°ā§‡ āĻ¨āĻžāĨ¤ āĻ†āĻŽāĻžāĻ° āĻ•ā§‹āĻ¨ āĻ§āĻžāĻ°āĻŖāĻž āĻ¨ā§‡āĻ‡ āĻŦā§āĻ¯āĻžāĻĒāĻžāĻ°āĻŸāĻž āĻ•āĻŋ, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ¯āĻ–āĻ¨ āĻ†āĻŽāĻŋ āĻ†āĻŦāĻžāĻ° āĻāĻ° āĻ¸āĻŽā§āĻŽā§āĻ–ā§€āĻ¨ āĻšāĻ˛āĻžāĻŽ, āĻ¤āĻ–āĻ¨ āĻ†āĻŽāĻŋ āĻ¸āĻŋāĻĻā§āĻ§āĻžāĻ¨ā§āĻ¤ āĻ¨āĻŋāĻ˛āĻžāĻŽ āĻ¯ā§‡ āĻ¸āĻŦāĻ•āĻŋāĻ›ā§ āĻ āĻŋāĻ• āĻšāĻ¯āĻŧā§‡ āĻ—ā§‡āĻ˛ā§‡ āĻ†āĻŽāĻŋ āĻ†āĻŽāĻžāĻ° āĻ¨āĻŋāĻœā§‡āĻ° āĻŸāĻŋāĻ‰āĻŸā§‹āĻ°āĻŋāĻ¯āĻŧāĻžāĻ˛ āĻ˛āĻŋāĻ–āĻŦāĨ¤ āĻāĻ• āĻ¯ā§‡ āĻ…āĻŦāĻļā§āĻ¯āĻ‡ āĻ•āĻžāĻœ āĻ•āĻ°āĻŦā§‡.

āĻ‡āĻ¨ā§āĻŸāĻžāĻ°āĻ¨ā§‡āĻŸā§‡ āĻ—āĻžāĻ‡āĻĄ

āĻāĻŸāĻŋ āĻ āĻŋāĻ• āĻ¤āĻžāĻ‡ āĻ˜āĻŸā§‡ āĻ¯ā§‡ āĻ‡āĻ¨ā§āĻŸāĻžāĻ°āĻ¨ā§‡āĻŸ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āĻ¨ āĻ—āĻžāĻ‡āĻĄ, āĻŸāĻŋāĻ‰āĻŸā§‹āĻ°āĻŋāĻ¯āĻŧāĻžāĻ˛, āĻ§āĻžāĻĒā§‡ āĻ§āĻžāĻĒā§‡ āĻāĻŦāĻ‚ āĻāĻ° āĻŽāĻ¤ā§‹ āĻ…āĻ­āĻžāĻŦā§‡āĻ° āĻ•āĻžāĻ°āĻŖā§‡ āĻ­ā§‹āĻ—ā§‡ āĻ¨āĻžāĨ¤ āĻāĻŸāĻŋ āĻ āĻŋāĻ• āĻ¤āĻžāĻ‡ āĻ˜āĻŸā§‡āĻ›ā§‡ āĻ¯ā§‡ āĻ†āĻŽāĻžāĻ•ā§‡ āĻāĻ•āĻŸāĻŋ āĻŦā§āĻ¯āĻ°ā§āĻĨāĻ¤āĻž āĻĒā§‹āĻ¸ā§āĻŸāĻ—ā§āĻ°ā§‡āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°āĻ•ā§‡ āĻ¸ā§āĻŦāĻŋāĻ§āĻžāĻœāĻ¨āĻ•āĻ­āĻžāĻŦā§‡ āĻ¸āĻ‚āĻ—āĻ āĻŋāĻ¤ āĻāĻŦāĻ‚ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻžāĻ° āĻĻāĻžāĻ¯āĻŧāĻŋāĻ¤ā§āĻŦ āĻĻā§‡āĻ“āĻ¯āĻŧāĻž āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛, āĻ¯āĻžāĻ° āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ā§€āĻ¯āĻŧāĻ¤āĻžāĻ—ā§āĻ˛āĻŋ āĻ›āĻŋāĻ˛ āĻŽāĻžāĻ¸ā§āĻŸāĻžāĻ° āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ° āĻĨā§‡āĻ•ā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻĒā§āĻ°āĻ¤āĻŋāĻ˛āĻŋāĻĒāĻŋāĻ¤ā§‡ āĻĒā§āĻ°āĻ¤āĻŋāĻ˛āĻŋāĻĒāĻŋ āĻ¸ā§āĻŸā§āĻ°āĻŋāĻŽāĻŋāĻ‚ āĻāĻŦāĻ‚ āĻāĻ•āĻŸāĻŋ āĻŽāĻžāĻ¸ā§āĻŸāĻžāĻ° āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ°ā§‡āĻ° āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡ āĻāĻ•āĻŸāĻŋ āĻ°āĻŋāĻœāĻžāĻ°ā§āĻ­ā§‡āĻ° āĻ¸ā§āĻŦāĻ¯āĻŧāĻ‚āĻ•ā§āĻ°āĻŋāĻ¯āĻŧ āĻŦāĻŋāĻ§āĻžāĻ¨āĨ¤ āĻŦā§āĻ¯āĻ°ā§āĻĨāĻ¤āĻž.

āĻāĻ‡ āĻĒāĻ°ā§āĻ¯āĻžāĻ¯āĻŧā§‡, āĻŦā§āĻ¯āĻŦāĻšā§ƒāĻ¤ āĻĒā§āĻ°āĻ¯ā§āĻ•ā§āĻ¤āĻŋāĻ° āĻ¸ā§āĻŸā§āĻ¯āĻžāĻ• āĻ¨āĻŋāĻ°ā§āĻ§āĻžāĻ°āĻŖ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛:

  • āĻāĻ•āĻŸāĻŋ DBMS āĻšāĻŋāĻ¸āĻžāĻŦā§‡ PostgreSQL
  • āĻĒā§ƒāĻˇā§āĻ āĻĒā§‹āĻˇāĻ• āĻāĻ•āĻŸāĻŋ āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°āĻŋāĻ‚ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻšāĻŋāĻ¸āĻžāĻŦā§‡
  • Patroni āĻœāĻ¨ā§āĻ¯ āĻŦāĻŋāĻ¤āĻ°āĻŖ āĻ¸ā§āĻŸā§‹āĻ°ā§‡āĻœ āĻšāĻŋāĻ¸āĻžāĻŦā§‡ etcd
  • āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ āĻ…ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻ•ā§‡āĻļāĻ¨āĻ—ā§āĻ˛āĻŋāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻāĻ•āĻ• āĻāĻ¨ā§āĻŸā§āĻ°āĻŋ āĻĒāĻ¯āĻŧā§‡āĻ¨ā§āĻŸ āĻ¸āĻ‚āĻ—āĻ āĻŋāĻ¤ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ HAproxy

āĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸

āĻ†āĻĒāĻ¨āĻžāĻ° āĻŽāĻ¨ā§‹āĻ¯ā§‹āĻ—ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ - Patroni, etcd, HAProxy āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ āĻāĻ•āĻŸāĻŋ āĻ‰āĻšā§āĻš āĻ‰āĻĒāĻ˛āĻŦā§āĻ§ PostgreSQL āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ° āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻžāĨ¤

āĻĄā§‡āĻŦāĻŋāĻ¯āĻŧāĻžāĻ¨ 10 āĻ“āĻāĻ¸ āĻ‡āĻ¨āĻ¸ā§āĻŸāĻ˛ āĻ¸āĻš āĻ­āĻžāĻ°ā§āĻšā§āĻ¯āĻŧāĻžāĻ˛ āĻŽā§‡āĻļāĻŋāĻ¨ā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ…āĻĒāĻžāĻ°ā§‡āĻļāĻ¨ āĻ¸āĻžā§āĻšāĻžāĻ˛āĻŋāĻ¤ āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛āĨ¤

āĻ‡āĻ¤ā§āĻ¯āĻžāĻĻāĻŋ

āĻ†āĻŽāĻŋ āĻāĻ•āĻ‡ āĻŽā§‡āĻļāĻŋāĻ¨ā§‡ etcd āĻ‡āĻ¨āĻ¸ā§āĻŸāĻ˛ āĻ•āĻ°āĻžāĻ° āĻĒāĻ°āĻžāĻŽāĻ°ā§āĻļ āĻĻāĻŋāĻ‡ āĻ¨āĻž āĻ¯ā§‡āĻ–āĻžāĻ¨ā§‡ āĻĒā§āĻ¯āĻžāĻŸā§āĻ°ā§‹āĻ¨āĻŋ āĻāĻŦāĻ‚ āĻĒā§‹āĻ¸ā§āĻŸāĻ—ā§āĻ°ā§‡āĻ¸ā§āĻ•āĻāĻ˛ āĻĨāĻžāĻ•āĻŦā§‡, āĻ¯ā§‡āĻšā§‡āĻ¤ā§ āĻĄāĻŋāĻ¸ā§āĻ• āĻ˛ā§‹āĻĄ etcd āĻāĻ° āĻœāĻ¨ā§āĻ¯ āĻ–ā§āĻŦāĻ‡ āĻ—ā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖāĨ¤ āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻļāĻŋāĻ•ā§āĻˇāĻžāĻ—āĻ¤ āĻ‰āĻĻā§āĻĻā§‡āĻļā§āĻ¯ā§‡, āĻ†āĻŽāĻ°āĻž āĻ¸ā§‡āĻŸāĻžāĻ‡ āĻ•āĻ°āĻŦāĨ¤
āĻ‡āĻ¤ā§āĻ¯āĻžāĻĻāĻŋ āĻ‡āĻ¨ā§āĻ¸āĻŸāĻ˛ āĻ•āĻ°āĻŋāĨ¤

#!/bin/bash
apt-get update
apt-get install etcd

/etc/default/etcd āĻĢāĻžāĻ‡āĻ˛ā§‡ āĻŦāĻŋāĻˇāĻ¯āĻŧāĻŦāĻ¸ā§āĻ¤ā§ āĻ¯ā§‹āĻ— āĻ•āĻ°ā§āĻ¨

[āĻ¸āĻĻāĻ¸ā§āĻ¯]

āĻ†āĻĒāĻ¨āĻžāĻ° āĻŽā§‡āĻļāĻŋāĻ¨ā§‡āĻ° ETCD_NAME=datanode1 # āĻšā§‹āĻ¸ā§āĻŸāĻ¨āĻžāĻŽ
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"

āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ†āĻ‡āĻĒāĻŋ āĻ āĻŋāĻ•āĻžāĻ¨āĻž āĻŦā§ˆāĻ§ āĻšāĻ“āĻ¯āĻŧāĻž āĻ‰āĻšāĻŋāĻ¤āĨ¤ āĻ˛āĻŋāĻ¸ā§āĻŸāĻžāĻ° āĻĒāĻŋāĻ¯āĻŧāĻžāĻ°, āĻ•ā§āĻ˛āĻžāĻ¯āĻŧā§‡āĻ¨ā§āĻŸ āĻ‡āĻ¤ā§āĻ¯āĻžāĻĻāĻŋ āĻšā§‹āĻ¸ā§āĻŸā§‡āĻ° āĻ†āĻ‡āĻĒāĻŋ āĻ āĻŋāĻ•āĻžāĻ¨āĻžāĻ¯āĻŧ āĻ¸ā§‡āĻŸ āĻ•āĻ°āĻž āĻ‰āĻšāĻŋāĻ¤

ETCD_LISTEN_PEER_URLS="http://192.168.0.143:2380āĻ†āĻĒāĻ¨āĻžāĻ° āĻ—āĻžāĻĄāĻŧāĻŋāĻ° # āĻ āĻŋāĻ•āĻžāĻ¨āĻž
ETCD_LISTEN_CLIENT_URLS="http://192.168.0.143:2379,http://127.0.0.1:2379āĻ†āĻĒāĻ¨āĻžāĻ° āĻ—āĻžāĻĄāĻŧāĻŋāĻ° # āĻ āĻŋāĻ•āĻžāĻ¨āĻž

[āĻ—ā§āĻšā§āĻ›]

ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.0.143:2380āĻ†āĻĒāĻ¨āĻžāĻ° āĻ—āĻžāĻĄāĻŧāĻŋāĻ° # āĻ āĻŋāĻ•āĻžāĻ¨āĻž
ETCD_INITIAL_CLUSTER=ÂģāĻĄā§‡āĻŸāĻžāĻ¨ā§‹āĻĄ1=http://192.168.0.143:2380,datanode2=http://192.168.0.144:2380,datanode3=http://192.168.0.145:2380Âģ# etcd āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°ā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻŽā§‡āĻļāĻŋāĻ¨ā§‡āĻ° āĻ āĻŋāĻ•āĻžāĻ¨āĻž
ETCD_INITIAL_CLUSTER_STATE="āĻ¨āĻ¤ā§āĻ¨"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-1â€ŗ
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.0.143:2379āĻ†āĻĒāĻ¨āĻžāĻ° āĻ—āĻžāĻĄāĻŧāĻŋāĻ° # āĻ āĻŋāĻ•āĻžāĻ¨āĻž

āĻ•āĻŽāĻžāĻ¨ā§āĻĄ āĻšāĻžāĻ˛āĻžāĻ¨

systemctl restart etcd

PostgreSQL 9.6 + āĻĒā§ƒāĻˇā§āĻ āĻĒā§‹āĻˇāĻ•

āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻĒā§āĻ°āĻĨāĻŽā§‡ āĻ¤āĻŋāĻ¨āĻŸāĻŋ āĻ­āĻžāĻ°ā§āĻšā§āĻ¯āĻŧāĻžāĻ˛ āĻŽā§‡āĻļāĻŋāĻ¨ āĻ¸ā§‡āĻŸ āĻ†āĻĒ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡ āĻ¯āĻžāĻ¤ā§‡ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ā§€āĻ¯āĻŧ āĻ¸āĻĢā§āĻŸāĻ“āĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻ‡āĻ¨āĻ¸ā§āĻŸāĻ˛ āĻ•āĻ°āĻž āĻ¯āĻžāĻ¯āĻŧāĨ¤ āĻŽā§‡āĻļāĻŋāĻ¨āĻ—ā§āĻ˛āĻŋ āĻ‡āĻ¨āĻ¸ā§āĻŸāĻ˛ āĻ•āĻ°āĻžāĻ° āĻĒāĻ°ā§‡, āĻ†āĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻ†āĻŽāĻžāĻ° āĻŸāĻŋāĻ‰āĻŸā§‹āĻ°āĻŋāĻ¯āĻŧāĻžāĻ˛āĻŸāĻŋ āĻ…āĻ¨ā§āĻ¸āĻ°āĻŖ āĻ•āĻ°ā§‡āĻ¨, āĻ†āĻĒāĻ¨āĻŋ āĻāĻ‡ āĻ¸āĻšāĻœ āĻ¸ā§āĻ•ā§āĻ°āĻŋāĻĒā§āĻŸāĻŸāĻŋ āĻšāĻžāĻ˛āĻžāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨ āĻ¯āĻž (āĻĒā§āĻ°āĻžāĻ¯āĻŧ) āĻ†āĻĒāĻ¨āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ¸āĻŦāĻ•āĻŋāĻ›ā§ āĻ•āĻ°āĻŦā§‡āĨ¤ āĻ°ā§āĻŸ āĻšāĻŋāĻ¸āĻžāĻŦā§‡ āĻšāĻ˛ā§‡āĨ¤

āĻĻāĻ¯āĻŧāĻž āĻ•āĻ°ā§‡ āĻŽāĻ¨ā§‡ āĻ°āĻžāĻ–āĻŦā§‡āĻ¨ āĻ¯ā§‡ āĻ¸ā§āĻ•ā§āĻ°āĻŋāĻĒā§āĻŸāĻŸāĻŋ PostgreSQL āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖ 9.6 āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡, āĻāĻŸāĻŋ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ•ā§‹āĻŽā§āĻĒāĻžāĻ¨āĻŋāĻ° āĻ…āĻ­ā§āĻ¯āĻ¨ā§āĻ¤āĻ°ā§€āĻŖ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ā§€āĻ¯āĻŧāĻ¤āĻžāĻ° āĻ•āĻžāĻ°āĻŖā§‡āĨ¤ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨āĻŸāĻŋ PostgreSQL āĻāĻ° āĻ…āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖā§‡ āĻĒāĻ°ā§€āĻ•ā§āĻˇāĻž āĻ•āĻ°āĻž āĻšāĻ¯āĻŧāĻ¨āĻŋāĨ¤

#!/bin/bash
apt-get install gnupg -y
echo "deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main" >> /etc/apt/sources.list
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
apt-get update
apt-get install postgresql-9.6 python3-pip python3-dev libpq-dev -y
systemctl stop postgresql
pip3 install --upgrade pip
pip install psycopg2
pip install patroni[etcd]
echo "
[Unit]
Description=Runners to orchestrate a high-availability PostgreSQL
After=syslog.target network.target

[Service]
Type=simple

User=postgres
Group=postgres

ExecStart=/usr/local/bin/patroni /etc/patroni.yml

KillMode=process

TimeoutSec=30

Restart=no

[Install]
WantedBy=multi-user.targ
" > /etc/systemd/system/patroni.service
mkdir -p /data/patroni
chown postgres:postgres /data/patroni
chmod 700 /data/patroniĐŋĐž
touch /etc/patroni.yml

āĻāĻ° āĻĒāĻ°ā§‡, āĻ†āĻĒāĻ¨āĻŋ āĻāĻ‡āĻŽāĻžāĻ¤ā§āĻ° āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻž /etc/patroni.yml āĻĢāĻžāĻ‡āĻ˛āĻŸāĻŋāĻ¤ā§‡, āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻ–āĻŋāĻ¤ āĻŦāĻŋāĻˇāĻ¯āĻŧāĻŦāĻ¸ā§āĻ¤ā§āĻ—ā§āĻ˛āĻŋ āĻ°āĻžāĻ–āĻ¤ā§‡ āĻšāĻŦā§‡, āĻ…āĻŦāĻļā§āĻ¯āĻ‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻœāĻžāĻ¯āĻŧāĻ—āĻžāĻ¯āĻŧ IP āĻ āĻŋāĻ•āĻžāĻ¨āĻžāĻ—ā§āĻ˛āĻŋ āĻ†āĻĒāĻ¨āĻžāĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻž āĻ āĻŋāĻ•āĻžāĻ¨āĻžāĻ—ā§āĻ˛āĻŋāĻ¤ā§‡ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡ā§ˇ
āĻāĻ‡ āĻ‡āĻ¯āĻŧāĻžāĻŽāĻ˛ā§‡āĻ° āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯āĻ—ā§āĻ˛āĻŋāĻ¤ā§‡ āĻŽāĻ¨ā§‹āĻ¯ā§‹āĻ— āĻĻāĻŋāĻ¨āĨ¤ āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°ā§‡āĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ āĻŽā§‡āĻļāĻŋāĻ¨ā§‡ āĻ āĻŋāĻ•āĻžāĻ¨āĻžāĻ—ā§āĻ˛āĻŋ āĻ†āĻĒāĻ¨āĻžāĻ° āĻ¨āĻŋāĻœā§‡āĻ° āĻŽāĻ¤ā§‹ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻ•āĻ°ā§āĻ¨āĨ¤

/etc/patroni.yml

scope: pgsql # Đ´ĐžĐģĐļĐŊĐž ĐąŅ‹Ņ‚ŅŒ ОдиĐŊĐ°ĐēОвŅ‹Đŧ ĐŊĐ° вŅĐĩŅ… ĐŊОдаŅ…
namespace: /cluster/ # Đ´ĐžĐģĐļĐŊĐž ĐąŅ‹Ņ‚ŅŒ ОдиĐŊĐ°ĐēОвŅ‹Đŧ ĐŊĐ° вŅĐĩŅ… ĐŊОдаŅ…
name: postgres1 # Đ´ĐžĐģĐļĐŊĐž ĐąŅ‹Ņ‚ŅŒ Ņ€Đ°ĐˇĐŊŅ‹Đŧ ĐŊĐ° вŅĐĩŅ… ĐŊОдаŅ…

restapi:
    listen: 192.168.0.143:8008 # Đ°Đ´Ņ€ĐĩŅ Ņ‚ОК ĐŊОдŅ‹, в ĐēĐžŅ‚ĐžŅ€ĐžĐš ĐŊĐ°Ņ…ОдиŅ‚ŅŅ ŅŅ‚ĐžŅ‚ Ņ„Đ°ĐšĐģ
    connect_address: 192.168.0.143:8008 # Đ°Đ´Ņ€ĐĩŅ Ņ‚ОК ĐŊОдŅ‹, в ĐēĐžŅ‚ĐžŅ€ĐžĐš ĐŊĐ°Ņ…ОдиŅ‚ŅŅ ŅŅ‚ĐžŅ‚ Ņ„Đ°ĐšĐģ

etcd:
    hosts: 192.168.0.143:2379,192.168.0.144:2379,192.168.0.145:2379 # ĐŋĐĩŅ€ĐĩŅ‡Đ¸ŅĐģиŅ‚Đĩ СдĐĩŅŅŒ вŅĐĩ ваŅˆĐ¸ ĐŊОдŅ‹, в ŅĐģŅƒŅ‡Đ°Đĩ ĐĩŅĐģи вŅ‹ ŅƒŅŅ‚Đ°ĐŊавĐģиваĐĩŅ‚Đĩ etcd ĐŊĐ° ĐŊиŅ… ĐļĐĩ

# this section (bootstrap) will be written into Etcd:/<namespace>/<scope>/config after initializing new cluster
# and all other cluster members will use it as a `global configuration`
bootstrap:
    dcs:
        ttl: 100
        loop_wait: 10
        retry_timeout: 10
        maximum_lag_on_failover: 1048576
        postgresql:
            use_pg_rewind: true
            use_slots: true
            parameters:
                    wal_level: replica
                    hot_standby: "on"
                    wal_keep_segments: 5120
                    max_wal_senders: 5
                    max_replication_slots: 5
                    checkpoint_timeout: 30

    initdb:
    - encoding: UTF8
    - data-checksums
    - locale: en_US.UTF8
    # init pg_hba.conf Đ´ĐžĐģĐļĐĩĐŊ ŅĐžĐ´ĐĩŅ€ĐļĐ°Ņ‚ŅŒ Đ°Đ´Ņ€ĐĩŅĐ° ВСЕĐĨ ĐŧĐ°ŅˆĐ¸ĐŊ, иŅĐŋĐžĐģŅŒĐˇŅƒĐĩĐŧŅ‹Ņ… в ĐēĐģĐ°ŅŅ‚ĐĩŅ€Đĩ
    pg_hba:
    - host replication postgres ::1/128 md5
    - host replication postgres 127.0.0.1/8 md5
    - host replication postgres 192.168.0.143/24 md5
    - host replication postgres 192.168.0.144/24 md5
    - host replication postgres 192.168.0.145/24 md5
    - host all all 0.0.0.0/0 md5

    users:
        admin:
            password: admin
            options:
                - createrole
                - createdb

postgresql:
    listen: 192.168.0.143:5432 # Đ°Đ´Ņ€ĐĩŅ Ņ‚ОК ĐŊОдŅ‹, в ĐēĐžŅ‚ĐžŅ€ĐžĐš ĐŊĐ°Ņ…ОдиŅ‚ŅŅ ŅŅ‚ĐžŅ‚ Ņ„Đ°ĐšĐģ
    connect_address: 192.168.0.143:5432 # Đ°Đ´Ņ€ĐĩŅ Ņ‚ОК ĐŊОдŅ‹, в ĐēĐžŅ‚ĐžŅ€ĐžĐš ĐŊĐ°Ņ…ОдиŅ‚ŅŅ ŅŅ‚ĐžŅ‚ Ņ„Đ°ĐšĐģ
    data_dir: /data/patroni # ŅŅ‚Ņƒ диŅ€ĐĩĐēŅ‚ĐžŅ€Đ¸ŅŽ ŅĐžĐˇĐ´Đ°ŅŅ‚ ŅĐēŅ€Đ¸ĐŋŅ‚, ĐžĐŋиŅĐ°ĐŊĐŊŅ‹Đš вŅ‹ŅˆĐĩ и ŅƒŅŅ‚Đ°ĐŊОвиŅ‚ ĐŊŅƒĐļĐŊŅ‹Đĩ ĐŋŅ€Đ°Đ˛Đ°
    bin_dir:  /usr/lib/postgresql/9.6/bin # ŅƒĐēĐ°ĐļиŅ‚Đĩ ĐŋŅƒŅ‚ŅŒ Đ´Đž ваŅˆĐĩĐš диŅ€ĐĩĐēŅ‚ĐžŅ€Đ¸Đ¸ Ņ postgresql
    pgpass: /tmp/pgpass
    authentication:
        replication:
            username: postgres
            password: postgres
        superuser:
            username: postgres
            password: postgres
    create_replica_methods:
        basebackup:
            checkpoint: 'fast'
    parameters:
        unix_socket_directories: '.'

tags:
    nofailover: false
    noloadbalance: false
    clonefrom: false
    nosync: false

āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°ā§‡āĻ° āĻ¤āĻŋāĻ¨āĻŸāĻŋ āĻŽā§‡āĻļāĻŋāĻ¨ā§‡āĻ‡ āĻ¸ā§āĻ•ā§āĻ°āĻŋāĻĒā§āĻŸāĻŸāĻŋ āĻšāĻžāĻ˛āĻžāĻ¤ā§‡ āĻšāĻŦā§‡, āĻāĻŦāĻ‚ āĻ‰āĻĒāĻ°ā§‡āĻ° āĻ•āĻ¨āĻĢāĻŋāĻ—āĻžāĻ°ā§‡āĻļāĻ¨āĻŸāĻŋ āĻ…āĻŦāĻļā§āĻ¯āĻ‡ /etc/patroni.yml āĻĢāĻžāĻ‡āĻ˛ā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻŽā§‡āĻļāĻŋāĻ¨ā§‡ āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡āĨ¤

āĻāĻ•āĻŦāĻžāĻ° āĻ†āĻĒāĻ¨āĻŋ āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°ā§‡āĻ° āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻŽā§‡āĻļāĻŋāĻ¨ā§‡ āĻāĻ‡ āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ•āĻ˛āĻžāĻĒāĻ—ā§āĻ˛āĻŋ āĻ¸āĻŽā§āĻĒāĻ¨ā§āĻ¨ āĻ•āĻ°āĻžāĻ° āĻĒāĻ°ā§‡, āĻ¤āĻžāĻĻā§‡āĻ° āĻ¯ā§‡ āĻ•ā§‹āĻ¨āĻ“āĻŸāĻŋāĻ¤ā§‡ āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻ–āĻŋāĻ¤ āĻ•āĻŽāĻžāĻ¨ā§āĻĄāĻŸāĻŋ āĻšāĻžāĻ˛āĻžāĻ¨

systemctl start patroni
systemctl start postgresql

āĻĒā§āĻ°āĻžāĻ¯āĻŧ 30 āĻ¸ā§‡āĻ•ā§‡āĻ¨ā§āĻĄ āĻ…āĻĒā§‡āĻ•ā§āĻˇāĻž āĻ•āĻ°ā§āĻ¨, āĻ¤āĻžāĻ°āĻĒāĻ° āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°ā§‡āĻ° āĻ…āĻŦāĻļāĻŋāĻˇā§āĻŸ āĻŽā§‡āĻļāĻŋāĻ¨āĻ—ā§āĻ˛āĻŋāĻ¤ā§‡ āĻāĻ‡ āĻ•āĻŽāĻžāĻ¨ā§āĻĄāĻŸāĻŋ āĻšāĻžāĻ˛āĻžāĻ¨āĨ¤

āĻšā§āĻ¯āĻžāĻĒā§āĻ°āĻ•ā§āĻ¸āĻŋ

āĻ†āĻŽāĻ°āĻž āĻĒā§āĻ°āĻŦā§‡āĻļā§‡āĻ° āĻāĻ•āĻ• āĻĒāĻ¯āĻŧā§‡āĻ¨ā§āĻŸ āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŽā§ŽāĻ•āĻžāĻ° HAproxy āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻŋāĨ¤ āĻŽāĻžāĻ¸ā§āĻŸāĻžāĻ° āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ° āĻ¸āĻ°ā§āĻŦāĻĻāĻž āĻŽā§‡āĻļāĻŋāĻ¨ā§‡āĻ° āĻ āĻŋāĻ•āĻžāĻ¨āĻžāĻ¯āĻŧ āĻ‰āĻĒāĻ˛āĻŦā§āĻ§ āĻĨāĻžāĻ•āĻŦā§‡ āĻ¯ā§‡āĻ–āĻžāĻ¨ā§‡ HAproxy āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡āĨ¤

HAproxy āĻ¸āĻš āĻŽā§‡āĻļāĻŋāĻ¨āĻŸāĻŋāĻ•ā§‡ āĻŦā§āĻ¯āĻ°ā§āĻĨāĻ¤āĻžāĻ° āĻāĻ•āĻ• āĻĒāĻ¯āĻŧā§‡āĻ¨ā§āĻŸ āĻ¨āĻž āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯, āĻ†āĻŽāĻ°āĻž āĻāĻŸāĻŋāĻ•ā§‡ āĻāĻ•āĻŸāĻŋ āĻĄāĻ•āĻžāĻ° āĻ•āĻ¨ā§āĻŸā§‡āĻ‡āĻ¨āĻžāĻ°ā§‡ āĻšāĻžāĻ˛ā§ āĻ•āĻ°āĻŦ; āĻ­āĻŦāĻŋāĻˇā§āĻ¯āĻ¤ā§‡ āĻāĻŸāĻŋ K8 āĻāĻ° āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°ā§‡ āĻšāĻžāĻ˛ā§ āĻ•āĻ°āĻž āĻ¯ā§‡āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ āĻāĻŦāĻ‚ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻŦā§āĻ¯āĻ°ā§āĻĨāĻ¤āĻž āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°āĻ•ā§‡ āĻ†āĻ°āĻ“ āĻ¨āĻŋāĻ°ā§āĻ­āĻ°āĻ¯ā§‹āĻ—ā§āĻ¯ āĻ•āĻ°ā§‡ āĻ¤ā§āĻ˛āĻŦā§‡ā§ˇ

āĻāĻ•āĻŸāĻŋ āĻĄāĻŋāĻ°ā§‡āĻ•ā§āĻŸāĻ°āĻŋ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°ā§āĻ¨ āĻ¯ā§‡āĻ–āĻžāĻ¨ā§‡ āĻ†āĻĒāĻ¨āĻŋ āĻĻā§āĻŸāĻŋ āĻĢāĻžāĻ‡āĻ˛ āĻ¸āĻ‚āĻ°āĻ•ā§āĻˇāĻŖ āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨ - Dockerfile āĻāĻŦāĻ‚ haproxy.cfgāĨ¤ āĻāĻŸāĻž āĻ¯āĻžāĻ¨.

Dockerfile

FROM ubuntu:latest

RUN apt-get update 
    && apt-get install -y haproxy rsyslog 
    && rm -rf /var/lib/apt/lists/*

RUN mkdir /run/haproxy

COPY haproxy.cfg /etc/haproxy/haproxy.cfg

CMD haproxy -f /etc/haproxy/haproxy.cfg && tail -F /var/log/haproxy.log

āĻ¸āĻ¤āĻ°ā§āĻ• āĻĨāĻžāĻ•ā§āĻ¨, haproxy.cfg āĻĢāĻžāĻ‡āĻ˛ā§‡āĻ° āĻļā§‡āĻˇ āĻ¤āĻŋāĻ¨āĻŸāĻŋ āĻ˛āĻžāĻ‡āĻ¨ āĻ†āĻĒāĻ¨āĻžāĻ° āĻŽā§‡āĻļāĻŋāĻ¨ā§‡āĻ° āĻ āĻŋāĻ•āĻžāĻ¨āĻž āĻ¤āĻžāĻ˛āĻŋāĻ•āĻžāĻ­ā§āĻ•ā§āĻ¤ āĻ•āĻ°āĻž āĻ‰āĻšāĻŋāĻ¤āĨ¤ HAproxy Patroni-āĻāĻ° āĻ¸āĻžāĻĨā§‡ āĻ¯ā§‹āĻ—āĻžāĻ¯ā§‹āĻ— āĻ•āĻ°āĻŦā§‡, HTTP āĻļāĻŋāĻ°ā§‹āĻ¨āĻžāĻŽā§‡ āĻŽāĻžāĻ¸ā§āĻŸāĻžāĻ° āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ° āĻ¸āĻ°ā§āĻŦāĻĻāĻž 200 āĻĢā§‡āĻ°āĻ¤ āĻĻā§‡āĻŦā§‡, āĻāĻŦāĻ‚ āĻĒā§āĻ°āĻ¤āĻŋāĻ°ā§‚āĻĒ āĻ¸āĻ°ā§āĻŦāĻĻāĻž 503 āĻĢā§‡āĻ°āĻ¤ āĻĻā§‡āĻŦā§‡āĨ¤

haproxy.cfg

global
    maxconn 100

defaults
    log global
    mode tcp
    retries 2
    timeout client 30m
    timeout connect 4s
    timeout server 30m
    timeout check 5s

listen stats
    mode http
    bind *:7000
    stats enable
    stats uri /

listen postgres
    bind *:5000
    option httpchk
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server postgresql1 192.168.0.143:5432 maxconn 100 check port 8008
    server postgresql2 192.168.0.144:5432 maxconn 100 check port 8008
    server postgresql3 192.168.0.145:5432 maxconn 100 check port 8008

āĻ¯ā§‡ āĻĄāĻŋāĻ°ā§‡āĻ•ā§āĻŸāĻ°āĻŋāĻ¤ā§‡ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ‰āĻ­āĻ¯āĻŧ āĻĢāĻžāĻ‡āĻ˛āĻ‡ "āĻŽāĻŋāĻĨā§āĻ¯āĻž" āĻĨāĻžāĻ•ā§‡, āĻ†āĻ¸ā§āĻ¨ āĻ†āĻŽāĻ°āĻž āĻ•āĻ¨ā§āĻŸā§‡āĻ‡āĻ¨āĻžāĻ° āĻĒā§āĻ¯āĻžāĻ• āĻ•āĻ°āĻžāĻ° āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ā§€āĻ¯āĻŧ āĻĒā§‹āĻ°ā§āĻŸāĻ—ā§āĻ˛āĻŋ āĻĢāĻ°ā§‹āĻ¯āĻŧāĻžāĻ°ā§āĻĄ āĻ•āĻ°āĻžāĻ° āĻ¸āĻžāĻĨā§‡ āĻāĻŸāĻŋ āĻšāĻžāĻ˛ā§ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ•ā§āĻ°āĻŽāĻžāĻ¨ā§āĻ¸āĻžāĻ°ā§‡ āĻ†āĻĻā§‡āĻļāĻ—ā§āĻ˛āĻŋ āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ° āĻ•āĻ°āĻŋ:

docker build -t my-haproxy .
docker run -d -p5000:5000 -p7000:7000 my-haproxy 

āĻāĻ–āĻ¨, āĻŦā§āĻ°āĻžāĻ‰āĻœāĻžāĻ°ā§‡ HAproxy āĻĻāĻŋāĻ¯āĻŧā§‡ āĻ†āĻĒāĻ¨āĻžāĻ° āĻŽā§‡āĻļāĻŋāĻ¨ā§‡āĻ° āĻ āĻŋāĻ•āĻžāĻ¨āĻž āĻ–ā§āĻ˛āĻ˛ā§‡ āĻāĻŦāĻ‚ āĻĒā§‹āĻ°ā§āĻŸ 7000 āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ•āĻ°ā§‡, āĻ†āĻĒāĻ¨āĻŋ āĻ†āĻĒāĻ¨āĻžāĻ° āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ°ā§‡ āĻĒāĻ°āĻŋāĻ¸āĻ‚āĻ–ā§āĻ¯āĻžāĻ¨ āĻĻā§‡āĻ–āĻ¤ā§‡ āĻĒāĻžāĻŦā§‡āĻ¨āĨ¤

āĻ¯ā§‡ āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ°āĻŸāĻŋ āĻŽāĻžāĻ¸ā§āĻŸāĻžāĻ° āĻ¤āĻž āĻšāĻŦā§‡ UP āĻ°āĻžāĻœā§āĻ¯ā§‡, āĻāĻŦāĻ‚ āĻĒā§āĻ°āĻ¤āĻŋāĻ˛āĻŋāĻĒāĻŋāĻ—ā§āĻ˛āĻŋ āĻĄāĻžāĻ‰āĻ¨ āĻ…āĻŦāĻ¸ā§āĻĨāĻžāĻ¯āĻŧ āĻĨāĻžāĻ•āĻŦā§‡ā§ˇ āĻāĻŸāĻŋ āĻ¸ā§āĻŦāĻžāĻ­āĻžāĻŦāĻŋāĻ•, āĻ†āĻ¸āĻ˛ā§‡ āĻ¤āĻžāĻ°āĻž āĻ•āĻžāĻœ āĻ•āĻ°ā§‡, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ¤āĻžāĻ°āĻž āĻāĻ‡āĻ­āĻžāĻŦā§‡ āĻ‰āĻĒāĻ¸ā§āĻĨāĻŋāĻ¤ āĻšāĻ¯āĻŧ āĻ•āĻžāĻ°āĻŖ āĻ¤āĻžāĻ°āĻž HAproxy āĻĨā§‡āĻ•ā§‡ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ 503 āĻĢā§‡āĻ°āĻ¤ āĻĻā§‡āĻ¯āĻŧāĨ¤ āĻāĻŸāĻŋ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ¸āĻ°ā§āĻŦāĻĻāĻž āĻœāĻžāĻ¨āĻ¤ā§‡ āĻĻā§‡āĻ¯āĻŧ āĻ¯ā§‡ āĻ¤āĻŋāĻ¨āĻŸāĻŋ āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ°ā§‡āĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻ•ā§‹āĻ¨āĻŸāĻŋ āĻŦāĻ°ā§āĻ¤āĻŽāĻžāĻ¨ āĻŽāĻžāĻ¸ā§āĻŸāĻžāĻ°āĨ¤

āĻ‰āĻĒāĻ¸āĻ‚āĻšāĻžāĻ°

āĻ¤ā§āĻŽāĻŋ āĻšāĻŽā§ŽāĻ•āĻžāĻ°! āĻŽāĻžāĻ¤ā§āĻ° 30 āĻŽāĻŋāĻ¨āĻŋāĻŸā§‡āĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻ†āĻĒāĻ¨āĻŋ āĻ¸ā§āĻŸā§āĻ°āĻŋāĻŽāĻŋāĻ‚ āĻĒā§āĻ°āĻ¤āĻŋāĻ˛āĻŋāĻĒāĻŋ āĻāĻŦāĻ‚ āĻ¸ā§āĻŦāĻ¯āĻŧāĻ‚āĻ•ā§āĻ°āĻŋāĻ¯āĻŧ āĻĢāĻ˛āĻŦā§āĻ¯āĻžāĻ• āĻ¸āĻš āĻāĻ•āĻŸāĻŋ āĻšāĻŽā§ŽāĻ•āĻžāĻ° āĻ¤ā§āĻ°ā§āĻŸāĻŋ-āĻ¸āĻšāĻ¨āĻļā§€āĻ˛ āĻāĻŦāĻ‚ āĻ‰āĻšā§āĻš-āĻĒāĻžāĻ°āĻĢāĻ°āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¸ āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ° āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻ•āĻ°ā§‡āĻ›ā§‡āĻ¨āĨ¤ āĻ†āĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻāĻ‡ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨āĻŸāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻžāĻ° āĻĒāĻ°āĻŋāĻ•āĻ˛ā§āĻĒāĻ¨āĻž āĻ•āĻ°āĻ›ā§‡āĻ¨ āĻ¤āĻŦā§‡ āĻšā§‡āĻ• āĻ†āĻ‰āĻŸ āĻ•āĻ°ā§āĻ¨ āĻ¸āĻ°āĻ•āĻžāĻ°ā§€ Patroni āĻĄāĻ•ā§āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāĻ¨ āĻ¸āĻš, āĻāĻŦāĻ‚ āĻŦāĻŋāĻļā§‡āĻˇ āĻ•āĻ°ā§‡ āĻĒā§āĻ¯āĻžāĻŸā§āĻ°ā§‹āĻ¨āĻŋāĻ•āĻŸāĻ˛ āĻ‡āĻ‰āĻŸāĻŋāĻ˛āĻŋāĻŸāĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•āĻŋāĻ¤ āĻāĻ° āĻ…āĻ‚āĻļā§‡āĻ° āĻ¸āĻžāĻĨā§‡, āĻ¯āĻž āĻ†āĻĒāĻ¨āĻžāĻ° āĻ•ā§āĻ˛āĻžāĻ¸ā§āĻŸāĻžāĻ° āĻĒāĻ°āĻŋāĻšāĻžāĻ˛āĻ¨āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ¸ā§āĻŦāĻŋāĻ§āĻžāĻœāĻ¨āĻ• āĻ…ā§āĻ¯āĻžāĻ•ā§āĻ¸ā§‡āĻ¸ āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻ•āĻ°ā§‡āĨ¤

āĻ…āĻ­āĻŋāĻ¨āĻ¨ā§āĻĻāĻ¨!

āĻ‰āĻ¤ā§āĻ¸: www.habr.com

āĻāĻ•āĻŸāĻŋ āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻœā§āĻĄāĻŧā§āĻ¨