diff --git a/README.rst b/README.rst index 7b2c332a..e176034f 100644 --- a/README.rst +++ b/README.rst @@ -1,27 +1,27 @@ |Build Status| |Coverage Status| Patroni: A Template for PostgreSQL HA with ZooKeeper, etcd or Consul ------------------------------------------------------------- +-------------------------------------------------------------------- You can find a version of this documentation that is searchable and also easier to navigate at `patroni.readthedocs.io `__. There are many ways to run high availability with PostgreSQL; for a list, see the `PostgreSQL Documentation `__. -Patroni is a template for you to create your own customized, high-availability solution using Python and - for maximum accessibility - a distributed configuration store like `ZooKeeper `__, `etcd `__ or `Consul `__. Database engineers, DBAs, DevOps engineers, and SREs who are looking to quickly deploy HA PostgreSQL in the datacenter-or anywhere else-will hopefully find it useful. +Patroni is a template for you to create your own customized, high-availability solution using Python and - for maximum accessibility - a distributed configuration store like `ZooKeeper `__, `etcd `__, `Consul `__ or `Kubernetes `__. Database engineers, DBAs, DevOps engineers, and SREs who are looking to quickly deploy HA PostgreSQL in the datacenter-or anywhere else-will hopefully find it useful. We call Patroni a "template" because it is far from being a one-size-fits-all or plug-and-play replication system. It will have its own caveats. Use wisely. -**Note to Kubernetes users**: We're currently developing Patroni to be as useful as possible for teams running Kubernetes on top of Google Compute Engine; Patroni can be the HA solution for Postgres in such an environment. To this end, there is a `Helm chart `__ that uses Patroni and `Spilo `__ to provision a five-node PostgreSQL HA cluster in a Kubernetes+GCE environment. (The Helm chart deploys Spilo Docker images, not just "bare" Patroni.) +**Note to Kubernetes users**: Patroni can run natively on top of Kubernetes. Take a look at the `Kubernetes `__ chapter of the Patroni documentation. .. contents:: :local: :depth: 1 :backlinks: none -============== +================= How Patroni Works -============== +================= Patroni originated as a fork of `Governor `__, the project from Compose. It includes plenty of new features. @@ -33,30 +33,60 @@ For additional background info, see: * `PostgreSQL HA with Kubernetes and Patroni `__, talk by Josh Berkus at KubeCon 2016 (video) * `Feb. 2016 Zalando Tech blog post `__ -================ +================== Development Status -================ +================== Patroni is in active development and accepts contributions. See our `Contributing `__ section below for more details. We report new releases information `here `__. -=========================== +=================================== Technical Requirements/Installation -=========================== +=================================== -**For Mac** +**Pre-requirements for Mac OS** To install requirements on a Mac, run the following: :: brew install postgresql etcd haproxy libyaml python - pip install psycopg2 pyyaml -=================== +**General installation for pip** + +Patroni can be installed with pip: + +:: + + pip install patroni[dependencies] + +where dependencies can be either empty, or consist of one or more of the following: + +etcd + `python-etcd` module in order to use Etcd as DCS +consul + `python-consul` module in order to use Consul as DCS +zookeeper + `kazoo` module in order to use Zookeeper as DCS +exhibitor + `kazoo` module in order to use Exhibitor as DCS (same dependencies as for Zookeeper) +kubernetes + `kubernetes` module in order to use Kubernetes as DCS in Patroni +aws + `boto` in order to use AWS callbacks + +For example, the command in order to install Patroni together with dependencies for Etcd as a DCS and AWS callbacks is: + +:: + + pip install patroni[etcd,aws] + +Note that external tools to call in the replica creation or custom bootstap scripts (i.e. WAL-E) should be installed independently of Patroni. + +======================= Running and Configuring -=================== +======================= To get started, do the following from different terminals: :: @@ -80,9 +110,9 @@ run: > psql --host 127.0.0.1 --port 5000 postgres -=============== +================== YAML Configuration -=============== +================== Go `here `__ for comprehensive information about settings for etcd, consul, and ZooKeeper. And for an example, see `postgres0.yml `__. @@ -92,15 +122,15 @@ Environment Configuration Go `here `__ for comprehensive information about configuring(overriding) settings via environment variables. -=============== +=================== Replication Choices -=============== +=================== Patroni uses Postgres' streaming replication, which is asynchronous by default. Patroni's asynchronous replication configuration allows for ``maximum_lag_on_failover`` settings. This setting ensures failover will not occur if a follower is more than a certain number of bytes behind the leader. This setting should be increased or decreased based on business requirements. It's also possible to use synchronous replication for better durability guarantees. See `replication modes documentation `__ for details. -=============================== +====================================== Applications Should Not Use Superusers -=============================== +====================================== When connecting from an application, always use a non-superuser. Patroni requires access to the database to function properly. By using a superuser from an application, you can potentially use the entire connection pool, including the connections reserved for superusers, with the ``superuser_reserved_connections`` setting. If Patroni cannot access the Primary because the connection pool is full, behavior will be undesirable. diff --git a/docs/ENVIRONMENT.rst b/docs/ENVIRONMENT.rst index a5a66aa1..20bdbead 100644 --- a/docs/ENVIRONMENT.rst +++ b/docs/ENVIRONMENT.rst @@ -1,6 +1,5 @@ .. _environment: -================================== Environment Configuration Settings ================================== @@ -52,6 +51,18 @@ Exhibitor - **PATRONI\_EXHIBITOR\_HOSTS**: initial list of Exhibitor (ZooKeeper) nodes in format: 'host1,host2,etc...'. This list updates automatically whenever the Exhibitor (ZooKeeper) cluster topology changes. - **PATRONI\_EXHIBITOR\_PORT**: Exhibitor port. +.. _kubernetes_environment: + +Kubernetes +---------- +- **PATRONI\_KUBERNETES\_NAMESPACE**: (optional) Kubernetes namespace where the operator is running. Default value is `default`. +- **PATRONI\_KUBERNETES\_LABELS**: Labels in format ``{label1: value1, label2: value2}``. These labels will be used to find existing objects (Pods and either Endpoints or ConfigMaps) associated with the current cluster. Also Patroni will set them on every object (Endpoint or ConfigMap) it creates. +- **PATRONI\_KUBERNETES\_SCOPE\_LABEL**: (optional) name of the label containing cluster name. Default value is `cluster-name`. +- **PATRONI\_KUBERNETES\_ROLE\_LABEL**: (optional) name of the label containing Postgres role (`master` or `replica`). Patroni will set this label on the pod it is running in. Default value is `role`. +- **PATRONI\_KUBERNETES\_USE\_ENDPOINTS**: (optional) if set to true, Patroni will use Endpoints instead of ConfigMaps to run leader elections and keep cluster state. +- **PATRONI\_KUBERNETES\_POD\_IP**: (optional) IP address of the pod Patroni is running in. This value is required when `PATRONI_KUBERNETES_USE_ENDPOINTS` is enabled and is used to populate the leader endpoint subsets when the pod's PostgreSQL is promoted. +- **PATRONI\_KUBERNETES\_PORTS**: (optional) if the Service object has the name for the port, the same name must appear in the Endpoint object, otherwise service wont work. For example, if your service is defined as ``{Kind: Service, spec: {ports: [{name: postgresql, port: 5432, targetPort: 5432}]}}``, then you have to set ``PATRONI_KUBERNETES_PORTS='{[{"name": "postgresql", "port": 5432}]}'`` and Patroni will use it for updating subsets of the leader Endpoint. This parameter is used only if `PATRONI_KUBERNETES_USE_ENDPOINTS` is set. + PostgreSQL ---------- - **PATRONI\_POSTGRESQL\_LISTEN**: IP address + port that Postgres listens to. Multiple comma-separated addresses are permitted, as long as the port component is appended after to the last one with a colon, i.e. ``listen: 127.0.0.1,127.0.0.2:5432``. Patroni will use the first address from this list to establish local connections to the PostgreSQL node. diff --git a/docs/README.rst b/docs/README.rst index c27615ad..bd75c168 100644 --- a/docs/README.rst +++ b/docs/README.rst @@ -1,8 +1,8 @@ .. _readme: -================= -How Patroni Works -================= +============ +Introduction +============ Patroni originated as a fork of `Governor `__, the project from Compose. It includes plenty of new features. @@ -13,17 +13,17 @@ For additional background info, see: * `PostgreSQL HA with Kubernetes and Patroni `__, talk by Josh Berkus at KubeCon 2016 (video) * `Feb. 2016 Zalando Tech blog post `__ -================== + Development Status -================== +------------------ Patroni is in active development and accepts contributions. See our :ref:`Contributing ` section below for more details. We report new releases information :ref:`here `. -=================================== + Technical Requirements/Installation -=================================== +----------------------------------- **Pre-requirements for Mac OS** @@ -65,9 +65,9 @@ For example, the command in order to install Patroni together with dependencies Note that external tools to call in the replica creation or custom bootstap scripts (i.e. WAL-E) should be installed independently of Patroni. -======================= + Running and Configuring -======================= +----------------------- The following section assumes Patroni repository as being cloned from https://github.com/zalando/patroni. Namely, you will need example configuration files `postgres0.yml` and `postgres1.yml`. If you installed Patroni with pip, you can @@ -95,27 +95,27 @@ run: > psql --host 127.0.0.1 --port 5000 postgres -================== + YAML Configuration -================== +------------------ Go :ref:`here ` for comprehensive information about settings for etcd, consul, and ZooKeeper. And for an example, see `postgres0.yml `__. -========================= + Environment Configuration -========================= +------------------------- Go :ref:`here ` for comprehensive information about configuring(overriding) settings via environment variables. -=================== + Replication Choices -=================== +------------------- Patroni uses Postgres' streaming replication, which is asynchronous by default. Patroni's asynchronous replication configuration allows for ``maximum_lag_on_failover`` settings. This setting ensures failover will not occur if a follower is more than a certain number of bytes behind the leader. This setting should be increased or decreased based on business requirements. It's also possible to use synchronous replication for better durability guarantees. See :ref:`replication modes documentation ` for details. -====================================== + Applications Should Not Use Superusers -====================================== +-------------------------------------- When connecting from an application, always use a non-superuser. Patroni requires access to the database to function properly. By using a superuser from an application, you can potentially use the entire connection pool, including the connections reserved for superusers, with the ``superuser_reserved_connections`` setting. If Patroni cannot access the Primary because the connection pool is full, behavior will be undesirable. diff --git a/docs/SETTINGS.rst b/docs/SETTINGS.rst index d2598bb7..979fd882 100644 --- a/docs/SETTINGS.rst +++ b/docs/SETTINGS.rst @@ -83,6 +83,18 @@ Exhibitor - **poll\_interval**: how often the list of ZooKeeper and Exhibitor nodes should be updated from Exhibitor - **port**: Exhibitor port. +.. _kubernetes_settings: + +Kubernetes +---------- +- **namespace**: (optional) Kubernetes namespace where we are running. Default value is `default`. +- **labels**: Labels in format ``{label1: value1, label2: value2}``. These labels will be used to find existing objects (Pods and either Endpoints or ConfigMaps) associated with the current cluster. Also Patroni will set them on every object (Endpoint or ConfigMap) it creates. +- **scope\_label**: (optional) name of the label containing cluster name. Default value is `cluster-name`. +- **role\_label**: (optional) name of the label containing role (master or replica). Patroni will set this label on the pod it runs in. Default value is ``role``. +- **use\_endpoints**: (optional) if set to true, Patroni will use Endpoints instead of ConfigMaps to run leader elections and keep cluster state. +- **pod\_ip**: (optional) IP address of the pod Patroni is running in. This value is required when `use_endpoints` is enabled and is used to populate the leader endpoint subsets when the pod's PostgreSQL is promoted. +- **ports**: (optional) if the Service object has the name for the port, the same name must appear in the Endpoint object, otherwise service wont work. For example, if your service is defined as ``{Kind: Service, spec: {ports: [{name: postgresql, port: 5432, targetPort: 5432}]}}``, then you have to set ``kubernetes.ports: {[{"name": "postgresql", "port": 5432}]}`` and Patroni will use it for updating subsets of the leader Endpoint. This parameter is used only if `kubernetes.use_endpoints` is set. + .. _postgresql_settings: PostgreSQL diff --git a/docs/index.rst b/docs/index.rst index f46babb9..3e91ef62 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -6,11 +6,11 @@ Introduction ============ -Patroni is a template for you to create your own customized, high-availability solution using Python and - for maximum accessibility - a distributed configuration store like `ZooKeeper `__, `etcd `__ or `Consul `__. Database engineers, DBAs, DevOps engineers, and SREs who are looking to quickly deploy HA PostgreSQL in the datacenter-or anywhere else-will hopefully find it useful. +Patroni is a template for you to create your own customized, high-availability solution using Python and - for maximum accessibility - a distributed configuration store like `ZooKeeper `__, `etcd `__, `Consul `__ or `Kubernetes `__. Database engineers, DBAs, DevOps engineers, and SREs who are looking to quickly deploy HA PostgreSQL in the datacenter-or anywhere else-will hopefully find it useful. We call Patroni a "template" because it is far from being a one-size-fits-all or plug-and-play replication system. It will have its own caveats. Use wisely. There are many ways to run high availability with PostgreSQL; for a list, see the `PostgreSQL Documentation `__. -**Note to Kubernetes users**: We're currently developing Patroni to be as useful as possible for teams running Kubernetes on top of Google Compute Engine; Patroni can be the HA solution for Postgres in such an environment. To this end, we've created a `Helm Chart `__ that enables you to deploy a five-node Patroni cluster using a Kubernetes PetSet. +**Note to Kubernetes users**: Patroni can run natively on top of Kubernetes. Take a look at the :ref:`Kubernetes ` chapter of the Patroni documentation. .. toctree:: @@ -24,6 +24,8 @@ We call Patroni a "template" because it is far from being a one-size-fits-all or replica_bootstrap replication_modes pause + kubernetes + watchdog releases CONTRIBUTING @@ -33,5 +35,3 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` * :ref:`search` - - diff --git a/docs/kubernetes.rst b/docs/kubernetes.rst new file mode 100644 index 00000000..b61634a0 --- /dev/null +++ b/docs/kubernetes.rst @@ -0,0 +1,53 @@ +.. _kubernetes: + +Using Patroni with Kubernetes +============================= + +Patroni can use Kubernetes objects in order to store the state of the cluster and manage the leader key. That makes it +capable of operating Postgres in Kubernetes environment without any consistency store, namely, one doesn't +need to run an extra Etcd deployment. There are two different type of Kubernetes objects Patroni can use to store the +leader and the configuration keys, they are configured with the `kubernetes.use_endpoints` or `PATRONI_KUBERNETES_USE_ENDPOINTS` +environment variable. + +Use Endpoints +------------- + +Despite the fact that this is the recommended mode, it is turned off by default for compatibility reasons. When it is on, Patroni stores +the cluster configuration and the leader key in the `metadata: annotations` fields of the respective `Endpoints` it creates. +Changing the leader is safer than when using `ConfigMaps`, since both the annotations, containing the leader information, and the actual addresses +pointing to the running leader pod are updated simultaneously in one go. + +Use ConfigMaps +-------------- + +In this mode, Patroni will create ConfigMaps instead of Endpoints and store keys inside meta-data of those ConfigMaps. +Changing the leader takes at least two updates, one to the leader ConfigMap and another to the respective Endpoint. + +There are two ways to direct the traffic to the Postgres master: + +- use the `callback script `_ provided by Patroni +- configure the Kubernetes Postgres service to use the label selector with the `role_label` (configured in patroni configuration). + +Note that in some cases, for instance, when running on OpenShift, there is no alternative to using ConfigMaps. + +Configuration +------------- + +Patroni Kubernetes :ref:`settings ` and :ref:`environment variables ` are described in the general chapters of the documentation. + +Examples +-------- + +- The `kubernetes `__ folder of the Patroni repository contains + examples of the Docker image, the Kubernetes manifest and the callback script in order to test Patroni Kubernetes setup. + Note that in the current state it will not be able to use PersistentVolumes because of permission issues. + +- You can find the full-featured Docker image that can use Persistent Volumes in the + `Spilo Project `_. + +- There is also a `Helm chart `_ + to deploy the Spilo image configured with Patroni running using Kubernetes. + +- In order to run your database clusters at scale using Patroni and Spilo, take a look at the + `postgres-operator `_ project. It implements the operator pattern + to manage Spilo clusters. diff --git a/docs/releases.rst b/docs/releases.rst index cee3e70c..d2f65f96 100644 --- a/docs/releases.rst +++ b/docs/releases.rst @@ -3,6 +3,88 @@ Release notes ============= +Version 1.4 +----------- + +This version adds support for using Kubernetes as a DCS, allowing to run Patroni as a cloud-native agent in Kubernetes without any additional deployments of Etcd, Zookeeper or Consul. + +**Upgrade notice** + +Installing Patroni via pip will no longer bring in dependencies for (such as libraries for Etcd, Zookeper, Consul or Kubernetes, or support for AWS). In order to enable them one need to list them in pip install command explicitely, for instance `pip install patroni[etcd,kubernetes]`. + +**Kubernetes support** + +Implement Kubernetes-based DCS. The endpoints meta-data is used in order to store the configuration and the leader key. The meta-data field inside the pods definition is used to store the member-related data. +In addition to using Endpoints, Patroni supports ConfigMaps. You can find more information about this feature in the :ref:`Kubernetes chapter of the documentation ` + +**Stability improvements** + +- Factor out postmaster process into a separate object (Ants Aasma) + + This object identifies a running postmaster process via pid and start time and simplifies detection (and resolution) of situations when the postmaster was restarted behind our back or when postgres directory disappeared from the file system. + +- Minimize the amount of SELECT's issued by Patroni on every loop of HA cylce (Alexander Kukushkin) + + On every iteration of HA loop Patroni needs to know recovery status and absolute wal position. From now on Patroni will run only single SELECT to get this information instead of two on the replica and three on the master. + +- Remove leader key on shutdown only when we have the lock (Ants) + + Unconditional removal was generating unnecessary and missleading exceptions. + +**Improvements in patronictl** + +- Add version command to patronictl (Ants) + + It will show the version of installed Patroni and versions of running Patroni instances (if the cluster name is specified). + +- Make optional specifying cluster_name argument for some of patronictl commands (Alexander, Ants) + + It will work if patronictl is using usual Patroni configuration file with the ``scope`` defined. + +- Show information about scheduled switchover and maintenance mode (Alexander) + + Before that it was possible to get this information only from Patroni logs or directly from DCS. + +- Improve ``patronictl reinit`` (Alexander) + + Sometimes ``patronictl reinit`` refused to proceed when Patroni was busy with other actions, namely trying to start postgres. `patronictl` didn't provide any commands to cancel such long running actions and the only (dangerous) workarond was removing a data directory manually. The new implementation of `reinit` forcefully cancells other long-running actions before proceeding with reinit. + +- Implement ``--wait`` flag in ``patronictl pause`` and ``patronictl resume`` (Alexander) + + It will make ``patronictl`` wait until the requested action is acknowledged by all nodes in the cluster. + Such behaviour is achieved by exposing the ``pause`` flag for every node in DCS and via the REST API. + +- Rename ``patronictl failover`` into ``patronictl switchover`` (Alexander) + + The previous ``failover`` was actually only capable of doing a switchover; it refused to proceed in a cluster without the leader. + +- Alter the behavior of ``patronictl failover`` (Alexander) + + It will work even if there is no leader, but in that case you will have to explicitely specify a node which should become the new leader. + +**Expose information about timeline and history** + +- Expose current timeline in DCS and via API (Alexander) + + Store information about the current timeline for each member of the cluster. This information is accessible via the API and is stored in the DCS + +- Store promotion history in the /history key in DCS (Alexander) + + In addition, store the timeline history enriched with the timestamp of the corresponding promotion in the /history key in DCS and update it with each promote. + +**Add endpoints for getting synchronous and asynchronous replicas** + +- Add new /sync and /async endpoints (Alexander, Oleksii Kliukin) + + Those endpoints (also accessible as /synchronous and /asynchronous) return 200 only for synchronous and asynchornous replicas correspondingly (exclusing those marked as `noloadbalance`). + +**Allow multiple hosts for Etcd** + +- Add a new `hosts` parameter to Etcd configuration (Alexander) + + This parameter should contain the initial list of hosts that will be used to discover and populate the list of the running etcd cluster members. If for some reason during work this list of discovered hosts is exhausted (no available hosts from that list), Patroni will return to the initial list from the `hosts` parameter. + + Version 1.3.6 ------------- diff --git a/docs/replica_bootstrap.rst b/docs/replica_bootstrap.rst index 1aecf629..77f27e66 100644 --- a/docs/replica_bootstrap.rst +++ b/docs/replica_bootstrap.rst @@ -95,4 +95,3 @@ running master or replicas. In that case, an empty string will be passed in a co restoring the formerly running cluster from the binary backup. If all replica creation methods fail, Patroni will try again all methods in order during the next event loop cycle. - diff --git a/docs/replication_modes.rst b/docs/replication_modes.rst index 805735d7..9495bb51 100644 --- a/docs/replication_modes.rst +++ b/docs/replication_modes.rst @@ -65,4 +65,4 @@ On each HA loop iteration Patroni re-evaluates synchronous standby choice. If th .. [1] The data is still there, but recovering it requires a manual recovery effort by data recovery specialists. When Patroni is allowed to rewind with ``use_pg_rewind`` the forked timeline will be automatically erased to rejoin the failed master with the cluster. -.. [2] Clients can change the behavior per transaction using PostgreSQL's ``synchronous_commit`` setting. Transactions with ``synchronous_commit`` values of ``off`` and ``local`` may be lost on fail over, but will not be blocked by replication delays. \ No newline at end of file +.. [2] Clients can change the behavior per transaction using PostgreSQL's ``synchronous_commit`` setting. Transactions with ``synchronous_commit`` values of ``off`` and ``local`` may be lost on fail over, but will not be blocked by replication delays. diff --git a/docs/watchdog.rst b/docs/watchdog.rst index e56025b6..7c91a935 100644 --- a/docs/watchdog.rst +++ b/docs/watchdog.rst @@ -1,6 +1,5 @@ .. _watchdog: -================ Watchdog support ================ diff --git a/patroni/version.py b/patroni/version.py index 594fa812..0f663085 100644 --- a/patroni/version.py +++ b/patroni/version.py @@ -1 +1 @@ -__version__ = '1.3.6' +__version__ = '1.4'