Thank you for reading this post, don't forget to subscribe!
Patroni — это демон на python, позволяющий автоматически обслуживать кластеры PostgreSQL с различными типами репликации, и автоматическим переключением ролей.
схема такая 2 балансировщика haproxy между ними виртуальный ip адрес и 2 базы(мастер/слейв).
есть следующие тачки:
192.168.1.120 балансировщик
192.168.1.121 балансировщик
192.168.1.122 база
192.168.1.123 база
192.168.1.124 виртуальный ip адрес
[root@ansible ~]# cat /etc/ansible/hosts
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[patronicluster:children] etcd patroni balance [etcd] 192.168.1.122 192.168.1.123 192.168.1.121 [patroni] 192.168.1.122 192.168.1.123 [balance] 192.168.1.120 192.168.1.121 |
[/codesyntax]
правим данный файл, указывая где какой etcd, patroni, balance
также указываем будет ли установка идти через прокси или нет:
[root@ansible ~]# cat /etc/ansible/playbooks/roles_play/patroni.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
- hosts: patronicluster become: true ignore_errors: yes become_method: sudo gather_facts: yes vars: - etcd1: "192.168.1.122" # кворум etcd который будет решать кто является мастером - etcd2: "192.168.1.123" # кворум etcd который будет решать кто является мастером - etcd3: "192.168.1.121" # кворум etcd который будет решать кто является мастером - patroni1: "192.168.1.122" # тут будет установлена сама база postgresql - patroni2: "192.168.1.123" # тут будет установлена сама база postgresql - ip_addr: "{{ ansible_default_ipv4.address }}" - patroni_cluster_name: "cluster_patrony" # имя нашего кластера - balance1: "192.168.1.120" # балансировщик - balance2: "192.168.1.121" # балансировщик - keepalived_id: "2" # данные id не должен совпадать с другими id keepalived в одной подсети. - virtual_ip: "192.168.1.124" # виртуальный адрес на который будут идти все обращения - proxy: false # (true/false) ставим кластер через прокси сервер или с открытым доступом - http_proxy: "http://192.168.1.179:3128" - https_proxy: "http://192.168.1.179:3128" roles: - patroni |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/templates/etcd.conf
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 |
ETCD_NAME="{{ etcd_check }}" ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" ETCD_ADVERTISE_CLIENT_URLS="http://{{ ansible_default_ipv4.address }}:2379" ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://{{ ansible_default_ipv4.address }}:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcdKuberNeTesCluster" ETCD_INITIAL_CLUSTER="etcd1=http://{{etcd1}}:2380,etcd2=http://{{etcd2}}:2380,etcd3=http://{{etcd3}}:2380" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/templates/haproxy.cfg
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
global maxconn 100 nbproc 2 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 *:5432 option httpchk http-check expect status 200 default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions server postgresql_{{patroni1}}_5432 {{patroni1}}:5432 maxconn 100 check port 8008 server postgresql_{{patroni2}}_5432 {{patroni2}}:5432 maxconn 100 check port 8008 |
[/codesyntax]
у кипелайва правим имя сетевого интерфейса и если будет юзазать pgbouncer то раскоменчиваем соответствующие строки
[root@ansible ~]# cat /etc/ansible/roles/patroni/templates/keepalived.conf
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
! Configuration File for keepalived global_defs { !notification_email { ! ababkin@test.ru !} !notification_email_from keepalived@{{ansible_hostname}}.test.ru ! smtp_server 192.168.1.56 ! smtp_connect_timeout 30 } vrrp_script chk_haproxy { script "/usr/sbin/pidof haproxy" interval 2 } !#vrrp_script chk_pgbouncer { !# script "/usr/sbin/pidof pgbouncer" !# interval 2 !#} vrrp_instance VI_1 { state {{ keepalived_check }} interface enp0s3 garp_master_refresh 15 virtual_router_id {{keepalived_id}} priority {{ keepalived_priority_check }} advert_int 5 smtp_alert authentication { auth_type PASS auth_pass 111werfgfgqwer3gfh567 } virtual_ipaddress { {{virtual_ip}} dev enp0s3 label enp0s3:vip } track_script { chk_haproxy !# chk_pgbouncer } } |
[/codesyntax]
[root@ansible ~]# ll /etc/ansible/roles/patroni/templates/keepalived
-rwxr-xr-x 1 root root 416672 Sep 20 10:00 /etc/ansible/roles/patroni/templates/keepalived
так же у нас скомпилирован keepalived версии 2 - это помогает от split brain его кладём туда же в темплейт:
[root@ansible ~]# cat /etc/ansible/roles/patroni/templates/patroni.service
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[Unit] Description=Runners to orchestrate a high-availability PostgreSQL After=syslog.target network.target [Service] Type=simple User=postgres Group=postgres ExecStart=/usr/bin/patroni /etc/patroni.yml KillMode=process TimeoutSec=30 Restart=on-failure RestartSec=5s [Install] WantedBy=multi-user.target |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/templates/patroni.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
[Unit] Description=Runners to orchestrate a high-availability PostgreSQL After=syslog.target network.target [Service] Type=simple User=postgres Group=postgres ExecStart=/usr/bin/patroni /etc/patroni.yml KillMode=process TimeoutSec=30 Restart=on-failure RestartSec=5s [Install] WantedBy=multi-user.target [root@ansible ~]# cat /etc/ansible/roles/patroni/templates/patroni.yml scope: {{ patroni_cluster_name }} name: {{patroni_check}} restapi: listen: {{ ansible_default_ipv4.address }}:8008 connect_address: {{ ansible_default_ipv4.address }}:8008 etcd: hosts: {{etcd1}}:2379, {{etcd2}}:2379, {{etcd3}}:2379 bootstrap: dcs: ttl: 30 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: 8 max_wal_senders: 5 max_replication_slots: 5 checkpoint_timeout: 30 initdb: - encoding: UTF8 - data-checksums pg_hba: - host replication repl {{patroni1}}/32 md5 - host replication repl {{patroni2}}/32 md5 - host all all {{patroni1}}/32 md5 - host all all {{patroni2}}/32 md5 users: dba: password: secret options: - createrole - createdb repl: password: secret options: - replication - replication postgresql: listen: {{ ansible_default_ipv4.address }}:5432 connect_address: {{ ansible_default_ipv4.address }}:5432 data_dir: /var/lib/pgsql/10/data config_dir: /var/lib/pgsql/10/data bin_dir: /usr/pgsql-10/bin authentication: replication: username: repl password: pass superuser: username: postgres password: pass parameters: unix_socket_directories: '.' |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/templates/pgbouncer.ini
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 |
;;; ;;;; PgBouncer configuration file ;;;; ; ;;; database name = connect string ;;; ;;; connect string params: ;;; dbname= host= port= user= password= auth_user= ;;; client_encoding= datestyle= timezone= ;;; pool_size= reserve_pool= max_db_connections= ;;; pool_mode= connect_query= application_name= [databases] ;; foodb over Unix socket ;;foodb = ; ;;; redirect bardb to bazdb on localhost ;;bardb = host=localhost dbname=bazdb ; ;;; access to dest database will go with single user ;;forcedb = host=127.0.0.1 port=300 user=baz password=foo client_encoding=UNICODE datestyle=ISO connect_query='SELECT 1' ; ;;; use custom pool sizes ;;nondefaultdb = pool_size=50 reserve_pool=10 ; ;;; use auth_user with auth_query if user not present in auth_file ;;; auth_user must exist in auth_file ;; foodb = auth_user=bar ; ;;; fallback connect string ;;* = host=testserver ;;pgbouncer_bench = host=10.230.17.147 dbname=pgbouncer_bench user=postgres port=5432 ;#zabbix = host=10.230.17.145 dbname=zabbix user=zabbix port=5432 ;#zabbix = host=10.230.17.144 dbname=zabbix user=zabbix port=5432 #paymentdb = host=10.230.17.145 dbname=paymentdb user=app2user port=5432 ;; User-specific configuration [users] ;user1 = pool_mode=transaction max_user_connections=10 ; ;;; Configuration section [pgbouncer] ;;; ;;;; Administrative settings ;;;; logfile = /var/log/pgbouncer/pgbouncer.log pidfile = /var/run/pgbouncer/pgbouncer.pid ;;; ;;;; Where to wait for clients ;;;; ; ;;; IP address or * which means all IPs listen_addr = * listen_port = 6432 ;; Unix socket is also used for -R. ;;; On Debian it should be /var/run/postgresql ;;unix_socket_dir = /tmp ;;unix_socket_mode = 0777 ;;unix_socket_group = ; ;;;; ;;;; TLS settings for accepting clients ;;;; ; ;;; disable, allow, require, verify-ca, verify-full ;;client_tls_sslmode = disable ; ;;; Path to file that contains trusted CA certs ;;client_tls_ca_file = <system default> ; ;;; Private key and cert to present to clients. ;;; Required for accepting TLS connections from clients. ;;client_tls_key_file = ;;client_tls_cert_file = ; ;;; fast, normal, secure, legacy, <ciphersuite string> ;;client_tls_ciphers = fast ; ;;; all, secure, tlsv1.0, tlsv1.1, tlsv1.2, tlsv1.3 ;;client_tls_protocols = all ; ;;; none, auto, legacy ;;client_tls_dheparams = auto ; ;;; none, auto, <curve name> ;;client_tls_ecdhcurve = auto ; ;;;; ;;;; TLS settings for connecting to backend databases ;;;; ; ;;; disable, allow, require, verify-ca, verify-full ;;server_tls_sslmode = disable ; ;;; Path to that contains trusted CA certs ;;server_tls_ca_file = <system default> ; ;;; Private key and cert to present to backend. ;;; Needed only if backend server require client cert. ;;server_tls_key_file = ;server_tls_cert_file = ; ;;; all, secure, tlsv1.0, tlsv1.1, tlsv1.2, tlsv1.3 ;;server_tls_protocols = all ; ;;; fast, normal, secure, legacy, <ciphersuite string> ;;server_tls_ciphers = fast ; ;;;; ;;;; Authentication settings ;;;; ; ;;; any, trust, plain, md5, cert, hba, pam auth_type = md5 auth_file = /etc/pgbouncer/userlist.txt ;; Path to HBA-style auth config ;;auth_hba_file = ; ;;; Query to use to fetch password from database. Result ;;; must have 2 columns - username and password hash. ;;auth_query = SELECT usename, passwd FROM pg_shadow WHERE usename=$1 ; ;;;; ;;;; Users allowed into database 'pgbouncer' ;;;; ; ;;; comma-separated list of users who are allowed to change settings admin_users = postgres ;; comma-separated list of users who are just allowed to use SHOW command stats_users = stats, postgres ;;; ;;;; Pooler personality questions ;;;; ; ;;; When server connection is released back to pool: ;;; session - after client disconnects (default) ;;; transaction - after transaction finishes ;;; statement - after statement finishes ;;pool_mode = session pool_mode = transaction ;; Query for cleaning connection immediately after releasing from ;;; client. No need to put ROLLBACK here, pgbouncer does not reuse ;;; connections where transaction is left open. ;;server_reset_query = DISCARD ALL ; ;;; Whether server_reset_query should run in all pooling modes. If it ;;; is off, server_reset_query is used only for session-pooling. ;;server_reset_query_always = 0 ; ;;; Comma-separated list of parameters to ignore when given in startup ;;; packet. Newer JDBC versions require the extra_float_digits here. ignore_startup_parameters = extra_float_digits ;; When taking idle server into use, this query is run first. ;;server_check_query = select 1 ; ;;; If server was used more recently that this many seconds ago, ;; skip the check query. Value 0 may or may not run in immediately. ;;server_check_delay = 30 ; ;;; Close servers in session pooling mode after a RECONNECT, RELOAD, ;;; etc. when they are idle instead of at the end of the session. ;;server_fast_close = 0 ; ;;; Use <appname - host> as application_name on server. ;;application_name_add_host = 0 application_name_add_host = 1 ;; Period for updating aggregated stats. ;;stats_period = 60 ; ;;;; ;;;; Connection limits ;;;; ; ;;; Total number of clients that can connect max_client_conn = 100 ;; Default pool size. 20 is good number when transaction pooling ;;; is in use, in session pooling it needs to be the number of ;;; max clients you want to handle at any moment default_pool_size = 20 ;; Minimum number of server connections to keep in pool. ;;min_pool_size = 0 ; ;; how many additional connection to allow in case of trouble ;;reserve_pool_size = 0 ; ;;; If a clients needs to wait more than this many seconds, use reserve ;;; pool. ;;reserve_pool_timeout = 5 ; ;;; How many total connections to a single database to allow from all ;;; pools ;;max_db_connections = 0 ;;max_user_connections = 0 ; ;;; If off, then server connections are reused in LIFO manner ;;server_round_robin = 0 ; ;;;; ;;;; Logging ;;;; ; ;;; Syslog settings ;;syslog = 0 ;;syslog_facility = daemon ;;syslog_ident = pgbouncer ;; log if client connects or server connection is made ;;log_connections = 1 ; ;;; log if and why connection was closed ;;log_disconnections = 1 ; ;;; log error messages pooler sends to clients ;;log_pooler_errors = 1 ; ;;; write aggregated stats into log ;;log_stats = 1 ; ;;; Logging verbosity. Same as -v switch on command line. ;;verbose = 0 ; ;;;; ;;;; Timeouts ;;;; ; ;;; Close server connection if its been connected longer. ;;server_lifetime = 3600 ; ;;; Close server connection if its not been used in this time. Allows ;;; to clean unnecessary connections from pool after peak. ;;server_idle_timeout = 600 ; ;;; Cancel connection attempt if server does not answer takes longer. ;;server_connect_timeout = 15 ; ;;; If server login failed (server_connect_timeout or auth failure) ;;; then wait this many second. ;;server_login_retry = 15 ; ;;; Dangerous. Server connection is closed if query does not return in ;;; this time. Should be used to survive network problems, _not_ as ;;; statement_timeout. (default: 0) ;;query_timeout = 0 ; ;;; Dangerous. Client connection is closed if the query is not ;;; assigned to a server in this time. Should be used to limit the ;;; number of queued queries in case of a database or network ;;; failure. (default: 120) ;;query_wait_timeout = 120 ; ;;; Dangerous. Client connection is closed if no activity in this ;;; time. Should be used to survive network problems. (default: 0) ;;client_idle_timeout = 0 ; ;;; Disconnect clients who have not managed to log in after connecting ;;; in this many seconds. ;client_login_timeout = 60 ; ;;; Clean automatically created database entries (via "*") if they stay ;;; unused in this many seconds. ;; autodb_idle_timeout = 3600 ; ;;; Close connections which are in "IDLE in transaction" state longer ;;; than this many seconds. ;;idle_transaction_timeout = 0 ; ;;; How long SUSPEND/-R waits for buffer flush before closing ;;; connection. ;;suspend_timeout = 10 ; ;;;; ;;;; Low-level tuning options ;;;; ; ;;; buffer for streaming packets ;;pkt_buf = 4096 ; ;;; man 2 listen ;;listen_backlog = 128 ; ;;; Max number pkt_buf to process in one event loop. ;;sbuf_loopcnt = 5 ; ;;; Maximum PostgreSQL protocol packet size. ;;max_packet_size = 2147483647 ; ;;; Set SO_REUSEPORT socket option ;;so_reuseport = 0 ; ;;; networking options, for info: man 7 tcp ; ;;; Linux: Notify program about new connection only if there is also ;;; data received. (Seconds to wait.) On Linux the default is 45, on ;;; other OS'es 0. ;;tcp_defer_accept = 0 ; ;;; In-kernel buffer size (Linux default: 4096) ;;tcp_socket_buffer = 0 ; ;;; whether tcp keepalive should be turned on (0/1) ;;tcp_keepalive = 1 ; ;;; The following options are Linux-specific. They also require ;; tcp_keepalive=1. ; ;;; Count of keepalive packets ;;tcp_keepcnt = 0 ; ;;; How long the connection can be idle before sending keepalive ;;; packets ;;tcp_keepidle = 0 ; ;;; The time between individual keepalive probes ;;tcp_keepintvl = 0 ; ;;; DNS lookup caching time ;;dns_max_ttl = 15 ; ;;; DNS zone SOA lookup period ;;dns_zone_check_period = 0 ; ;;; DNS negative result caching time ;;dns_nxdomain_ttl = 15 ; ;;; Custom resolv.conf file, to set custom DNS servers or other options ;;; (default: empty = use OS settings) ;;resolv_conf = /etc/pgbouncer/resolv.conf ; ;;;; ;;;; Random stuff ;;;; ; ;;; Hackish security feature. Helps against SQL injection: when PQexec ;;; is disabled, multi-statement cannot be made. ;;disable_pqexec = 0 ; ;;; Config file to use for next RELOAD/SIGHUP ;;; By default contains config file from command line. ;;conffile ; ;;; Windows service name to register as. job_name is alias for ;;; service_name, used by some Skytools scripts. ;;service_name = pgbouncer ;;job_name = pgbouncer ; ;;; Read additional config from other file ;;%include /etc/pgbouncer/pgbouncer-other.ini |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/handlers/main.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 |
--- - name: restart ntpd service: name=ntpd state=restarted enabled=yes - name: restart keepalived service: name=keepalived state=restarted enabled=yes - name: restart haproxy service: name=haproxy state=restarted enabled=yes |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/add_etcd_config.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 |
- name: check etcd set_fact: etcd_check: "{% if ip_addr==etcd1 %}etcd1{% elif ip_addr==etcd2 %}etcd2{% else %}etcd3{% endif %}" - name: put etcd_config template: src: ../templates/etcd.conf dest: /etc/etcd/etcd.conf backup: yes - name: restart etcd service service: name=etcd state=restarted enabled=yes tags: etcd |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/add_haproxy_config.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 |
- name: put haproxy_config template: src: ../templates/haproxy.cfg dest: /etc/haproxy/haproxy.cfg backup: yes |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/add_keepalived_config.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 |
- name: check keepalived set_fact: keepalived_check: "{% if ip_addr==balance1 %}MASTER{% else %}BACKUP{% endif %}" keepalived_priority_check: "{% if ip_addr==balance1 %}100{% else %}90{% endif %}" - name: put keepalived_config template: src: ../templates/keepalived.conf dest: /etc/keepalived/keepalived.conf backup: yes |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/add_patroni_config.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 |
- name: check patroni node set_fact: patroni_check: "{% if ip_addr==patroni1 %}db-1{% else %}db-2{% endif %}" - name: put patroni_config template: src: ../templates/patroni.yml dest: /etc/patroni.yml backup: yes - name: restart patroni service: name=patroni state=restarted enabled=yes tags: etcd |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/add_pgbouncer_config.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 |
- name: put pgboucer_config template: src: ../templates/pgbouncer.ini dest: /etc/pgbouncer/pgbouncer.ini backup: yes - name: restart pgbouncer service service: name=pgbouncer state=restarted enabled=yes tags: pgbouncer |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/create_patroni_service.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 |
- name: put patroni.service systemd unit template: src: ../templates/patroni.service dest: /etc/systemd/system/patroni.service backup: yes - name: Reload daemon definitions command: /usr/bin/systemctl daemon-reload tags: patroni |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/install_etcd.yml
[codesyntax lang="php"]
1 2 3 4 5 |
- name: Install etcd yum: name: ['gcc', 'python-devel', 'etcd', 'python-requests', 'python-urllib3' ] state: present |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/install_haproxy.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 |
- name: Install haproxy yum: name: haproxy state: present notify: - restart haproxy |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/install_keepalived.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
- name: Install keepalived yum: name: keepalived state: present notify: - restart keepalived - name: put keepalived service version 2 copy: src: ../templates/keepalived dest: /usr/sbin/ backup: yes |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/install_patroni-without-proxy.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
- name: install pip yum: name: python-pip - name: install the package, force upgrade pip: name: pip executable: pip state: latest - name: install setuptools pip: name: setuptools - name: install the package, force upgrade pip: name: setuptools extra_args: --upgrade - name: install python packages flake8 pip: name: "flake8" - name: install python packages psycopg2-binary pip: name: "psycopg2-binary" - name: install python packages urllib3 patroni[etcd] pip: name: ['urllib3>=1.19.1', 'patroni[etcd]', 'cryptography', 'certifi', 'idna', 'pyOpenSSL'] |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/install_patroni.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
- name: install pip through proxy "{{ http_proxy }}" yum: name: python-pip environment: http_proxy: "{{ http_proxy }}" https_proxy: "{{ https_proxy }}" - name: install the package, force upgrade through proxy "{{ http_proxy }}" pip: name: pip executable: pip state: latest environment: http_proxy: "{{ http_proxy }}" https_proxy: "{{ https_proxy }}" - name: install setuptools through proxy "{{ http_proxy }}" pip: name: setuptools environment: http_proxy: "{{ http_proxy }}" https_proxy: "{{ https_proxy }}" - name: install the package, force upgrade through proxy "{{ http_proxy }}" pip: name: setuptools extra_args: --upgrade environment: http_proxy: "{{ http_proxy }}" https_proxy: "{{ https_proxy }}" - name: install python packages flake8 through proxy "{{ http_proxy }}" pip: name: "flake8" environment: http_proxy: '{{ http_proxy }}' https_proxy: '{{ https_proxy }}' - name: install python packages psycopg2-binary through proxy "{{ http_proxy }}" pip: name: "psycopg2-binary" environment: http_proxy: "{{ http_proxy }}" https_proxy: "{{ https_proxy }}" - name: install python packages urllib3 patroni[etcd] through proxy "{{ http_proxy }}" pip: name: ['urllib3>=1.19.1', 'patroni[etcd]', 'cryptography', 'certifi', 'idna', 'pyOpenSSL'] environment: http_proxy: "{{ http_proxy }}" https_proxy: "{{ https_proxy }}" |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/install_pgbouncer-without-proxy.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 |
- name: install RPM from pgbouncer yum: name: https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm state: present - name: Install pgbouncer yum: name: pgbouncer state: present |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/install_pgbouncer.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
- name: install RPM from pgbouncer yum: # name: https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-centos10-10-2.noarch.rpm name: https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm state: present environment: http_proxy: "{{ http_proxy }}" https_proxy: "{{ https_proxy }}" - name: Install pgbouncer yum: name: pgbouncer state: present environment: http_proxy: "{{ http_proxy }}" https_proxy: "{{ https_proxy }}" |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/install_postgres-without-proxy.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
- name: yum install Postgres 10 yum: name: https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm state: present - name: Install PGsql10 yum: name: "{{ packages }}" state: present vars: packages: - postgresql10 - postgresql10-contrib - postgresql10-server - python-psycopg2 - repmgr10 |
[/codesyntax]
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/install_postgres.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
- name: yum install Postgres 10 through proxy "{{ http_proxy }}" yum: # name: https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-centos10-10-2.noarch.rpm name: https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm state: present environment: http_proxy: "{{ http_proxy }}" https_proxy: "{{ https_proxy }}" - name: Install PGsql10 through proxy "{{ http_proxy }}" yum: name: "{{ packages }}" state: present vars: packages: - postgresql10 - postgresql10-contrib - postgresql10-server - python-psycopg2 - repmgr10 environment: http_proxy: "{{ http_proxy }}" https_proxy: "{{ https_proxy }}" |
[/codesyntax]
тут мы можем раскоментить pgbouncer но лучше не надо с ним понты
[root@ansible ~]# cat /etc/ansible/roles/patroni/tasks/main.yml
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
--- - name: Set facts etcd set_fact: etcd_check: "{% if ip_addr==etcd1 %}etcd1{% elif ip_addr==etcd2 %}etcd2{% else %}etcd3{% endif %}" - import_tasks: install_postgres.yml tags: install postgres package when: - inventory_hostname in groups['patroni'] - proxy - import_tasks: install_postgres-without-proxy.yml tags: install postgres package when: - inventory_hostname in groups['patroni'] - not proxy - import_tasks: install_etcd.yml tags: install etcd package when: inventory_hostname in groups['etcd'] - import_tasks: add_etcd_config.yml tags: add etcd config when: inventory_hostname in groups['etcd'] - import_tasks: install_patroni.yml tags: install patroni when: - inventory_hostname in groups['patroni'] - proxy - import_tasks: install_patroni-without-proxy.yml tags: install patroni when: - inventory_hostname in groups['patroni'] - not proxy - import_tasks: create_patroni_service.yml tags: create patroni service when: inventory_hostname in groups['patroni'] - import_tasks: add_patroni_config.yml tags: add patroni config when: inventory_hostname in groups['patroni'] - import_tasks: install_haproxy.yml tags: install haproxy when: inventory_hostname in groups['balance'] - import_tasks: add_haproxy_config.yml tags: add haproxy config when: inventory_hostname in groups['balance'] #- import_tasks: install_pgbouncer.yml # tags: install pgbouncer # when: # - inventory_hostname in groups['balance'] # - proxy #- import_tasks: install_pgbouncer-without-proxy.yml # tags: install pgbouncer # when: # - inventory_hostname in groups['balance'] # - not proxy #- import_tasks: add_pgbouncer_config.yml # tags: add pgbouncer config # when: inventory_hostname in groups['balance'] - import_tasks: install_keepalived.yml tags: install keepalived when: inventory_hostname in groups['balance'] - import_tasks: add_keepalived_config.yml tags: add keepalived config when: inventory_hostname in groups['balance'] |
[/codesyntax]
ну и можно запускать установку:
[root@ansible ~]# ansible-playbook -u root /etc/ansible/playbooks/roles_play/patroni.yml --ask-pass