From 007b891320a157a902870d6960d10546d18c9c9f Mon Sep 17 00:00:00 2001 From: Jason Lynch Date: Wed, 29 Apr 2026 13:41:44 -0400 Subject: [PATCH] docs: additions to systemd installation doc Adds sections to describe the limitations in the current release and how to uninstall the control plane. Also cleans up some of the formatting to comply with our documentation standards. PLAT-560 --- docs/installation/systemd.md | 277 ++++++++++++++++++++++++++--------- 1 file changed, 210 insertions(+), 67 deletions(-) diff --git a/docs/installation/systemd.md b/docs/installation/systemd.md index 147e5ec7..1e674db5 100644 --- a/docs/installation/systemd.md +++ b/docs/installation/systemd.md @@ -2,32 +2,49 @@ !!! warning "Preview Feature" - System package-based installation is a preview feature. Not all Control Plane - features are supported, and some aspects of this - installation method are subject to change. We do not recommend it for - production environments yet. We'd love your feedback - please share your + System package-based installation is a preview feature that is under active + development. The core database management API is fully functional and tested, + but some features are not yet supported (see [Limitations](#limitations) below). + The installation method and upgrade process between releases may change before + this feature is finalized. We'd love your feedback - please share your experience in our [GitHub issues](https://github.com/pgedge/control-plane/issues) or join our [Discord](https://discord.com/invite/pgedge/login). -This guide covers installing the pgEdge Control Plane on RPM-based Linux hosts -(e.g. RHEL, Rocky Linux, AlmaLinux) using the RPM package attached to each -[GitHub release](https://github.com/pgedge/control-plane/releases). Support for +This guide covers installing the pgEdge Control Plane on Linux hosts that use +the RPM Package Manager (RPM) package format (e.g. Red Hat Enterprise Linux +(RHEL), Rocky Linux, AlmaLinux) using the RPM package attached to each [GitHub +release](https://github.com/pgedge/control-plane/releases). Support for Debian-based hosts is coming in a future release. Unlike the Docker Swarm installation method, the system package installation -runs the Control Plane directly on the host. The Control Plane will use systemd -to manage Postgres instances rather than Docker containers. +runs the Control Plane directly on the host. The Control Plane uses systemd to +manage Postgres instances rather than Docker containers. + +## Limitations + +The systemd installation method has the following known limitations in the +current release. + +- The Postgres version of a database must not be changed after the database is + created; support for package upgrades is coming in a subsequent release. +- Supporting Services are not yet supported on systemd clusters; support is + coming in a subsequent release. +- All hosts in a cluster must use the same orchestrator (either `swarm` or + `systemd`); the orchestrator must not change after the cluster is initialized. ## Prerequisites +The Control Plane requires specific ports and packages to be configured on each +host before installation. + ### Ports -By default, the Control Plane uses these ports, which must be accessible on each -machine by other cluster members: +The Control Plane uses these ports by default; each must be accessible to other +cluster members on each host. - - Port `3000` TCP for HTTP communication - - Port `2379` TCP for Etcd peer communication - - Port `2380` TCP for Etcd client communication +- Port `3000` uses TCP for HTTP and HTTPS communication. +- Port `2379` uses TCP for Etcd client communication. +- Port `2380` uses TCP for Etcd peer communication. You can configure alternate ports by modifying the [configuration file](#configuration) after installing the `pgedge-control-plane` @@ -35,42 +52,39 @@ RPM. ### Packages -The Control Plane depends on the pgEdge Enterprise Postgres Packages. It does -not yet install Postgres or its supporting packages automatically. You must -install them on each host before starting the Control Plane. +The Control Plane depends on the pgEdge Enterprise Postgres packages. The +Control Plane does not yet install Postgres or its supporting packages +automatically; install the packages on each host before starting the Control +Plane. -Run the following on each host as root: +Run the following commands on each host: ```sh # Install prerequisites for the pgEdge Enterprise Postgres packages -dnf install -y epel-release dnf -dnf config-manager --set-enabled crb +sudo dnf install -y epel-release dnf +sudo dnf config-manager --set-enabled crb # Install the pgEdge Enterprise Postgres repository -dnf install -y https://dnf.pgedge.com/reporpm/pgedge-release-latest.noarch.rpm +sudo dnf install -y https://dnf.pgedge.com/reporpm/pgedge-release-latest.noarch.rpm # Install the required packages for your Postgres version. We currently support -# versions 16, 17, and 18. Set postgres_major_version to your desired version. +# versions 16, 17, and 18. Set POSTGRES_MAJOR_VERSION to your desired version. POSTGRES_MAJOR_VERSION='<16|17|18>' -dnf install -y \ +sudo dnf install -y \ pgedge-postgresql${POSTGRES_MAJOR_VERSION} \ pgedge-spock50_${POSTGRES_MAJOR_VERSION} \ pgedge-postgresql${POSTGRES_MAJOR_VERSION}-contrib \ pgedge-pgbackrest \ - pgedge-python3-psycopg2 - -# Install Patroni -dnf install -y python3-pip -pip install 'patroni[etcd,jsonlogger]==4.1.0' + pgedge-patroni ``` ## Installing the RPM -We publish RPMs with our releases on the -[GitHub releases page](https://github.com/pgedge/control-plane/releases). RPMs -are available for both `amd64` and `arm64`. +The pgEdge Control Plane RPM is published with each release on the [GitHub +releases page](https://github.com/pgedge/control-plane/releases) for both +`amd64` and `arm64` architectures. -Install the RPM with: +Use the following commands to download and install the RPM: ```sh # Detect architecture @@ -83,19 +97,20 @@ VERSION="v0.7.0" curl -LO "https://github.com/pgedge/control-plane/releases/download/${VERSION}/pgedge-control-plane_${VERSION#v}_linux_${ARCH}.rpm" # Install the RPM -rpm -i pgedge-control-plane_${VERSION#v}_linux_${ARCH}.rpm +sudo rpm -i pgedge-control-plane_${VERSION#v}_linux_${ARCH}.rpm ``` -The RPM installs: +The RPM installs the following files: -- `/usr/sbin/pgedge-control-plane` - the Control Plane binary -- `/usr/lib/systemd/system/pgedge-control-plane.service` - the systemd service unit -- `/etc/pgedge-control-plane/config.json` - the default configuration file +- The Control Plane binary is installed at `/usr/sbin/pgedge-control-plane`. +- The systemd service unit is installed at `/usr/lib/systemd/system/pgedge-control-plane.service`. +- The default configuration file is installed at `/etc/pgedge-control-plane/config.json`. ## Configuration -The default configuration file is located at -`/etc/pgedge-control-plane/config.json`: +The Control Plane reads its configuration from a JSON file at +`/etc/pgedge-control-plane/config.json`. The following example shows the +default configuration: ```json { @@ -105,11 +120,11 @@ The default configuration file is located at ``` The `orchestrator` field must be set to `"systemd"` for this installation -method. The `data_dir` is where the Control Plane stores its state, including -the embedded Etcd data. +method. The `data_dir` field specifies where the Control Plane stores its +state, including the embedded Etcd data. -The host ID defaults to the machine's short hostname. To set an explicit host -ID, add a `host_id` field to the config file: +The host ID defaults to the machine's short hostname. Add the `host_id` field +to set an explicit host ID: ```json { @@ -124,30 +139,31 @@ You can find the full list of configuration settings in the ## Starting the Control Plane -Start and enable the Control Plane service: +The Control Plane runs as a systemd service. Use the following command to start +and enable the service: ```sh -systemctl enable --now pgedge-control-plane.service +sudo systemctl enable --now pgedge-control-plane.service ``` -To check the service status: +Use the following command to check the service status: ```sh -systemctl status pgedge-control-plane.service +sudo systemctl status pgedge-control-plane.service ``` -To tail the logs: +Use the following command to follow the service logs: ```sh -journalctl -u pgedge-control-plane.service --follow +sudo journalctl -u pgedge-control-plane.service --follow ``` ## Initializing the Control Plane -Once the service is running on all hosts, initialize and join them the same way -as a Docker Swarm installation. +Once the service is running on all hosts, initialize and join each host the +same way as a Docker Swarm installation. -Initialize the cluster on the first host: +Use the following command to initialize the cluster on the first host: ```sh curl http://localhost:3000/v1/cluster/init @@ -162,9 +178,8 @@ The response contains a join token and server URL: } ``` -Join each additional host to the cluster by submitting a `POST` request to that -host's `/v1/cluster/join` endpoint with the token and server URL from the -previous step: +Submit a `POST` request to each additional host's `/v1/cluster/join` endpoint +with the token and server URL from the previous step: ```sh curl -i -X POST http://:3000/v1/cluster/join \ @@ -175,23 +190,151 @@ curl -i -X POST http://:3000/v1/cluster/join \ }' ``` -Repeat for each host. Once all hosts have joined, you can interact with the API -from any host in the cluster. +Submit the join command to each remaining host; once all hosts have joined, you +can interact with the API from any host in the cluster. For example, you could +run the following command against any host to create a database in a three-host +cluster: + +```sh +curl -X POST http://:3000/v1/databases \ + -H 'Content-Type:application/json' \ + --data '{ + "id": "example", + "spec": { + "database_name": "example", + "database_users": [ + { + "username": "admin", + "password": "password", + "db_owner": true, + "attributes": ["SUPERUSER", "LOGIN"] + } + ], + "port": 5432, + "patroni_port": 8888, + "nodes": [ + { "name": "n1", "host_ids": [""] }, + { "name": "n2", "host_ids": [""] }, + { "name": "n3", "host_ids": [""] } + ] + } + }' +``` + +Refer to the [Creating a database](../using/create-db.md) document and other +pages in the "Using Control Plane" of our docs for more complete usage +instructions. + +> [!NOTE] +> By default, each host's ID is the machine's short hostname, such as you would +> get by running `hostname -s`. You can get the host IDs for all hosts in the +> cluster from the "list hosts" endpoint on any host: +> `curl http://localhost:3000/v1/hosts`. + +> [!NOTE] +> Unlike with the Swarm orchestrator, `patroni_port` is a required field in +> systemd clusters. As with other port fields, you can specify `0` to +> assign a random port. ## Updating the Control Plane -To update to a newer version, download the new RPM from the -[GitHub releases page](https://github.com/pgedge/control-plane/releases) and -run: +Updating the Control Plane requires stopping the service, installing the new +RPM, and restarting the service. Download the new RPM from the [GitHub releases +page](https://github.com/pgedge/control-plane/releases) and run the following +commands: ```sh -systemctl stop pgedge-control-plane.service -rpm -U pgedge-control-plane-..rpm -systemctl start pgedge-control-plane.service +sudo systemctl stop pgedge-control-plane.service +sudo rpm -U pgedge-control-plane-..rpm +sudo systemctl start pgedge-control-plane.service ``` -!!! note +> [!NOTE] +> The RPM upgrade (`rpm -U`) preserves your existing configuration file at +> `/etc/pgedge-control-plane/config.json` because the RPM marks it as a +> non-replaceable configuration file. + +## Uninstalling the Control Plane + +This section describes how to fully remove the Control Plane and its data from +your hosts. + +### Standard Uninstallation + +Follow these steps to remove the Control Plane after deleting all databases: + +1. Delete all databases via the API. + + Use the following command to list all databases and retrieve their IDs: + + ```sh + curl http://localhost:3000/v1/databases + ``` + + Use the following command to delete each database by ID: + + ```sh + curl -X DELETE http://localhost:3000/v1/databases/ + ``` + + Deletions are asynchronous; wait for each task to complete before deleting + the next database. + +2. Stop and disable the Control Plane service with the following command: + + ```sh + sudo systemctl disable --now pgedge-control-plane.service + ``` + +3. Use the following command to uninstall the `pgedge-control-plane` package: + + ```sh + sudo rpm -e pgedge-control-plane + ``` + +4. Remove the Control Plane data and configuration directories. + + The data directory defaults to `/var/lib/pgedge-control-plane`; use the + path configured in `data_dir` if you specified a custom location. Use the + following commands to remove both directories: + + ```sh + sudo rm -rf /var/lib/pgedge-control-plane + sudo rm -rf /etc/pgedge-control-plane + ``` + +### Manually Removing Databases + +If the API cannot delete a database due to errors, remove the database manually +on each host that holds an instance. + +1. Stop the Patroni services for the database instances. + + The Control Plane creates a systemd service for each Patroni instance using + the `patroni-` prefix. Use the following command to list all Patroni + services and identify the ones to stop: + + ```sh + sudo systemctl list-units 'patroni-*' + ``` + + Use the following command to stop and disable each service associated with + the database: + + ```sh + sudo systemctl disable --now patroni-.service + ``` + +2. Delete the instance data directories. + + By default, the Control Plane stores instance data at + `/var/lib/pgsql//`; use the path from your + configuration file if you set a custom instance data directory. The + following example command removes the data directory for a Postgres 17 + instance with ID `my-instance`: + + ```sh + sudo rm -rf /var/lib/pgsql/17/my-instance + ``` - The RPM upgrade (`rpm -U`) preserves your existing configuration file at - `/etc/pgedge-control-plane/config.json` because it is marked as a - non-replaceable config file. +Repeat these steps on each host that has an instance of the database.