From b58d57164eb3b94f73ef0834424d4f2d47f3f9cd Mon Sep 17 00:00:00 2001 From: cgenier Date: Thu, 18 Apr 2024 18:27:43 +0200 Subject: [PATCH 01/41] HA 24.04 --- .../centreon-ha/acceptance-guide.md | 770 +++++------- .../centreon-ha/monitoring-guide.md | 70 +- .../centreon-ha/operating-guide.md | 283 ++--- .../centreon-ha/troubleshooting-guide.md | 59 +- .../installation-of-centreon-ha/faq.md | 43 + .../installation.md | 1093 +++++++++++++++++ .../integrating-pollers.md | 13 +- .../installation-of-centreon-ha/overview.md | 185 +-- .../version-24.04-sidebars.json | 21 +- 9 files changed, 1625 insertions(+), 912 deletions(-) create mode 100644 versioned_docs/version-24.04/installation/installation-of-centreon-ha/faq.md create mode 100644 versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md diff --git a/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md index d5c14b95920b..d7eead1d63cb 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md @@ -1,26 +1,21 @@ --- id: acceptance-guide -title: Cluster acceptance guide +title: Testing the cluster --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -> Please note that all commands presented in this document should be run as `root` unless otherwise stated. - - - +This page provides you with a procedure to validate that your cluster is working properly: you will perform a failover, simulate a network failure, and check that the cluster behaves as expected. -> This document will refer to parameters that vary from one installation to another (e.g., names and IP addresses of nodes) via [macros defined here](../../installation/installation-of-centreon-ha/installation-2-nodes.md#defining-hosts-names-and-addresses) +> Please note that all commands presented in this document should be run as `root` unless otherwise stated. -## Requirements of the tests +On this page, we will use the macros @NODE1_NAME@ and @NODE2_NAME@ to represent the hostnames of node 1 and 2. Bear in mind that depending on the situation, either node 1 or node 2 can be the active or the passive node (if node 1 is the active node, node 2 is the passive node, and vice versa). -To verify the proper functioning of your cluster, you will get all the commands to perform a failover test and simulate network failures. +## Check the state of the cluster -It is necessary to check the state of the cluster before performing the acceptance tests. +After completing the installation procedure and before starting any tests, the active node should be node 1 and the passive node should be node 2. -### Check the state of the cluster - -To check the general state of the cluster, run the command: +To check the general state of the cluster, run the following command: ```bash pcs status @@ -28,46 +23,37 @@ pcs status The command should return the following information: - - - ```text Cluster Summary: * Stack: corosync - * Current DC: @CENTRAL_MASTER_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum + * Current DC: @NODE1_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @CENTRAL_MASTER_NAME@ + * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @NODE1_NAME@ * 2 nodes configured - * 14 resource instances configured + * 12 resource instances configured Node List: - * Online: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Online: [ @NODE1_NAME@ @NODE2_NAME@ ] Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @CENTRAL_MASTER_NAME@ ] - * Slaves: [ @CENTRAL_SLAVE_NAME@ ] * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_MASTER_NAME@ - * http (systemd:httpd): Started @CENTRAL_MASTER_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_MASTER_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_MASTER_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_MASTER_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_MASTER_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_MASTER_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_MASTER_NAME@ + * vip (ocf::heartbeat:IPaddr2): Started @NODE1_NAME@ + * http (systemd:httpd): Started @NODE1_NAME@ + * gorgone (systemd:gorgoned): Started @NODE1_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @NODE1_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @NODE1_NAME@ + * centengine (systemd:centengine): Started @NODE1_NAME@ + * centreontrapd (systemd:centreontrapd): Started @NODE1_NAME@ + * snmptrapd (systemd:snmptrapd): Started @NODE1_NAME@ ``` - - - -> Check the resources for `Failed` errors and correct them with the help of the [troubleshooting guide](troubleshooting-guide.md). +> This command should return no errors. If there are "Failed actions" on any resource, troubleshoot them using the [troubleshooting guide](troubleshooting-guide.md). ### Check the constraints -To check that there are no `Location Constraints`, execute the command: +If a failover has occurred at some point, there may be some leftover `Location Constraints`. Run the following command: ```bash pcs constraint @@ -75,45 +61,30 @@ pcs constraint The command should return this: - - - ```text Location Constraints: Ordering Constraints: Colocation Constraints: - centreon with ms_mysql-clone (score:INFINITY) (rsc-role:Started) (with-rsc-role:Master) - ms_mysql-clone with centreon (score:INFINITY) (rsc-role:Master) (with-rsc-role:Started) Ticket Constraints: ``` - - +## Test 1: Centreon resource failover -### Check the status of the database synchronization +### Perform a failover -To verify that the database synchronization is working, execute the following command: +Before performing the tests, [check the state of the cluster](#check-the-state-of-the-cluster). -```bash -/usr/share/centreon-ha/bin/mysql-check-status.sh -``` - -The command should return the following information: +When you move all resources from node 1 to node 2 (i.e., the **centreon** resource group), node 2 will become the active node and node 1 will become the passive node. Run the following command: -```text -Connection MASTER Status '@CENTRAL_MASTER_NAME@' [OK] -Connection SLAVE Status '@CENTRAL_SLAVE_NAME@' [OK] -Slave Thread Status [OK] -Position Status [OK] +```bash +pcs resource move centreon ``` -> If the synchronization shows `KO`, you must fix it with the help of the [operating-guide](operating-guide.md). +In another terminal, you can also use the `crm_mon -fr` command to watch the failover as it happens. It will be necessary to use Ctrl+c to exit the command. -## Centreon resource failover +> Warning: The `pcs resource move centreon` command sets an `-INFINITY` constraint on node 1. This means that the resource is no longer allowed to be running on that node. -### State of the cluster before the failover - -Before running a failover test, check the status of the cluster with the following command: +The resources move to node 2. To check that the resources have indeed moved, run the following command: ```bash pcs status @@ -121,249 +92,138 @@ pcs status The expected output is: - - - ```text Cluster Summary: * Stack: corosync - * Current DC: @CENTRAL_MASTER_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum + * Current DC: @NODE1_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @CENTRAL_MASTER_NAME@ + * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @NODE1_NAME@ * 2 nodes configured - * 14 resource instances configured + * 12 resource instances configured Node List: - * Online: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Online: [ @NODE1_NAME@ @NODE2_NAME@ ] Full List of Resources: * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @CENTRAL_MASTER_NAME@ ] - * Slaves: [ @CENTRAL_SLAVE_NAME@ ] + * Masters: [ @NODE1_NAME@ ] + * Slaves: [ @NODE2_NAME@ ] * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_MASTER_NAME@ - * http (systemd:httpd): Started @CENTRAL_MASTER_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_MASTER_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_MASTER_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_MASTER_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_MASTER_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_MASTER_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_MASTER_NAME@ -``` - - - - -### Perform a failover - -To move the resources, run the command: - -```bash -pcs resource move centreon + * vip (ocf::heartbeat:IPaddr2): Started Started @NODE2_NAME@ + * http (systemd:httpd): Started Started @NODE2_NAME@ + * gorgone (systemd:gorgoned): Started Started @NODE2_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @NODE2_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @NODE2_NAME@ + * centengine (systemd:centengine): Started @NODE2_NAME@ + * centreontrapd (systemd:centreontrapd): Started @NODE2_NAME@ + * snmptrapd (systemd:snmptrapd): Started @NODE2_NAME@ ``` -You can also use the `crm_mon -fr` command to watch the failover as it happens. It will be necessary to use Ctrl+c to exit the command. - -> Warning: The `pcs resource move centreon` command sets an `-INFINITY` constraint on the node hosting the resource, no longer allowed to be running on that node. - -As a result, the resources move to another node. Following this manipulation, it is, thus, necessary to execute the command `pcs resource clear centreon` to ensure the resources can be moved back to this node in the future. - -To verify that the resources have moved to the second node, performs the command: +Once the failover is completed, execute the following command to ensure the resources can be moved back to their original node in the future. ```bash -pcs status +pcs resource clear centreon ``` -The expected output is: +This will remove the constraints established during the failover. - - +### Go back to the nominal situation -```text -Cluster Summary: - * Stack: corosync - * Current DC: @CENTRAL_MASTER_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum - * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @CENTRAL_MASTER_NAME@ - * 2 nodes configured - * 14 resource instances configured -Node List: - * Online: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] -Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @CENTRAL_MASTER_NAME@ ] - * Slaves: [ @CENTRAL_SLAVE_NAME@ ] - * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] - * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] - * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started Started @CENTRAL_SLAVE_NAME@ - * http (systemd:httpd): Started Started @CENTRAL_SLAVE_NAME@ - * gorgone (systemd:gorgoned): Started Started @CENTRAL_SLAVE_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_SLAVE_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_SLAVE_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_SLAVE_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_SLAVE_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_SLAVE_NAME@ -``` +If you want to return to the nominal situation, you must perform a second resource failover. - - +1. If you have `Location Constraints`, run the constraint cleanup command: -You may notice that like the `centreon` resources, the secondary node has also been promoted to `master` for the `ms_mysql` resource. This behavior is intended and due to `Colocation Constraints` between the `centreon` resources and `msq_mysql`. + ```bash + pcs resource clear centreon + ``` -> The `Colocation Constraints` are unfound on a 4-node cluster! +2. Then, execute the failover command: -Once the failover is completed, execute the command: + ```bash + pcs resource move centreon + ``` -```bash -pcs resource clear centreon -``` +As before, you can follow the failover with the `crm_mon -fr` command. -> This will remove the constraints established during the failover. +3. Finally, remove the constraints with the command: -Also, check that MySQL replication is still operational using the command: + ```bash + pcs resource clear centreon + ``` -```bash -/usr/share/centreon-ha/bin/mysql-check-status.sh -``` +## Test 2: Simulate the loss of the passive node -The command should return the following information: +If the passive node goes down, the cluster should carry on working as before, as the resources are managed by the active node. You will see your passive node as down in Resources Status. -```text -Connection MASTER Status '@CENTRAL_MASTER_NAME@' [OK] -Connection SLAVE Status '@CENTRAL_SLAVE_NAME@' [OK] -Slave Thread Status [OK] -Position Status [OK] -``` +To simulate a network failure that would isolate the passive node, you can use `iptables` to drop traffic from and to the passive node. The passive node will be completely excluded from the cluster. The active node keeps the majority with the quorum device. -> If the synchronization is `KO`, you must fix it with the help of the [operating-guide](operating-guide.md). +### Perform the test -### Back to the nominal situation +We're assuming that node 1 is the active node and node 2 is the passive node ([check the state of the cluster](#check-the-state-of-the-cluster) if you need to). -To return to the nominal situation, you must launch the resource failover. - -Execute the command: +To perform this test, launch the `iptables` commands on the active node: ```bash -pcs status +iptables -A INPUT -s @IP_PASSIVE_NODE@ -j DROP +iptables -A OUTPUT -d @IP_PASSIVE_NODE@ -j DROP ``` -The output should be: +The passive node is now excluded from the cluster. - - +If you run `pcs status` on the active node: + +* The resources and the cluster are still working. +* The passive node is seen `offline` on the active node: ```text +Cluster name: centreon_cluster Cluster Summary: * Stack: corosync - * Current DC: @CENTRAL_MASTER_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum - * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @CENTRAL_MASTER_NAME@ + * Current DC: @NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum + * Last updated: Tue Nov 8 15:19:52 2022 + * Last change: Tue Nov 8 14:25:58 2022 by root via crm_resource on @NODE1_NAME@ * 2 nodes configured - * 14 resource instances configured + * 12 resource instances configured Node List: - * Online: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Online: [ @NODE1_NAME@ ] + * OFFLINE: [ @NODE2_NAME@ ] Full List of Resources: * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @CENTRAL_MASTER_NAME@ ] - * Slaves: [ @CENTRAL_SLAVE_NAME@ ] - * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] - * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] - * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_SLAVE_NAME@ - * http (systemd:httpd): Started @CENTRAL_SLAVE_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_SLAVE_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_SLAVE_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_SLAVE_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_SLAVE_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_SLAVE_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_SLAVE_NAME@ -``` - - - - -If you have `Location Constraints`, run the constraint cleanup command: - -```bash -pcs resource clear centreon -``` - -Then, execute the failover command: - -```bash -pcs resource move centreon -``` - -As before, you can follow the failover with the `crm_mon -fr` command. - -Finally, remove the constraints with the command: - -```bash -pcs resource clear centreon -``` - -Also check that MySQL replication is still operational using the following command: - -```bash -/usr/share/centreon-ha/bin/mysql-check-status.sh -``` - -The command should return the following information: - -```text -Connection MASTER Status '@CENTRAL_MASTER_NAME@' [OK] -Connection SLAVE Status '@CENTRAL_SLAVE_NAME@' [OK] -Slave Thread Status [OK] -Position Status [OK] -``` - -> If the synchronization is `KO`, you must fix it with the help of the [operating-guide](operating-guide.md). - -## Simulate the loss of the secondary node - -To simulate a network failure that would isolate the secondary node, you can use `iptables` to drop traffic from and to the secondary node. -The secondary node will be completely excluded from the cluster. The primary node keeps the majority with the QDevice. - -### Processing - -To perform this test, launch the `iptables` commands on the primary node: - -```bash -iptables -A INPUT -s @IP_SECONDARY_NODE@ -j DROP -iptables -A OUTPUT -d @IP_SECONDARY_NODE@ -j DROP + * Masters: [ @NODE1_NAME@ ] + @@ -545,40 +609,51 @@ Full List of Resources: + * centengine (systemd:centengine): Started @NODE1_NAME@ + * centreontrapd (systemd:centreontrapd): Started @NODE1_NAME@ + * snmptrapd (systemd:snmptrapd): Started @NODE1_NAME@ +Daemon Status: + corosync: active/enabled + pacemaker: active/enabled + pcsd: active/enabled ``` -Executing the command `pcs status` on the secondary node results in stopped resources being seen on the secondary node and the primary node being seen as `offline`: +If you run `pcs status` on the passive node: - - +* The resources (php-clone and cbd_rrd-clone) appear stopped on the passive node +* The active node is seen as `offline`: ```text Cluster name: centreon_cluster Cluster Summary: * Stack: corosync - * Current DC: @CENTRAL_SLAVE_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition WITHOUT quorum + * Current DC: @NODE2_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition WITHOUT quorum * Last updated: Tue Nov 8 14:33:00 2022 - * Last change: Tue Nov 8 14:25:58 2022 by root via crm_resource on @CENTRAL_MASTER_NAME@ + * Last change: Tue Nov 8 14:25:58 2022 by root via crm_resource on @NODE1_NAME@ * 2 nodes configured - * 14 resource instances configured + * 12 resource instances configured Node List: - * Online: [ @CENTRAL_SLAVE_NAME@ ] - * OFFLINE: [ @CENTRAL_MASTER_NAME@ ] + * Online: [ @NODE2_NAME@ ] + * OFFLINE: [ @NODE1_NAME@ ] Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Stopped: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] * Clone Set: php-clone [php]: - * Stopped: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Stopped: [ @NODE1_NAME@ @NODE2_NAME@ ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Stopped: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Stopped: [ @NODE1_NAME@ @NODE2_NAME@ ] * Resource Group: centreon: * vip (ocf::heartbeat:IPaddr2): Stopped * http (systemd:httpd): Stopped @@ -379,45 +239,11 @@ Daemon Status: pcsd: active/enabled ``` - - - -The resources and the cluster are still working by performing a `pcs status` on the primary node. -The secondary node is seen `offline` on the primary. - - - - -```text -Cluster name: centreon_cluster -Cluster Summary: - * Stack: corosync - * Current DC: @CENTRAL_MASTER_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum - * Last updated: Tue Nov 8 15:19:52 2022 - * Last change: Tue Nov 8 14:25:58 2022 by root via crm_resource on @CENTRAL_MASTER_NAME@ - * 2 nodes configured - * 14 resource instances configured -Node List: - * Online: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] -Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @CENTRAL_MASTER_NAME@ ] - @@ -545,40 +609,51 @@ Full List of Resources: - * centengine (systemd:centengine): Started @CENTRAL_MASTER_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_MASTER_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_MASTER_NAME@ -Daemon Status: - corosync: active/enabled - pacemaker: active/enabled - pcsd: active/enabled -``` - - - +### Go back to the nominal situation -### Back to nominal situation +If you want to go back to the nominal situation, remove the iptables rules. -To check the various iptables rules configured on the primary node, run the following command: +To view the various iptables rules configured on the active node, run the following command: ```bash iptables -L @@ -428,14 +254,14 @@ The command should return the following information: ```text Chain INPUT (policy ACCEPT) target prot opt source destination -DROP all -- @CENTRAL_SLAVE_NAME@ anywhere +DROP all -- @NODE2_NAME@ anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination -DROP all -- anywhere @CENTRAL_SLAVE_NAME@ +DROP all -- anywhere @NODE2_NAME@ ``` If you do not have any other iptables rules configured, you can execute the following command to remove the rules related to the test: @@ -444,127 +270,99 @@ If you do not have any other iptables rules configured, you can execute the foll iptables -F ``` -Otherwise, it will be necessary to list the rule numbers with the specific command: +Otherwise, you will have to list the rule numbers with the following command: ```bash iptables -L --line-numbers ``` -And delete it with the command: +And delete them with the following command: ```bash iptables -D INPUT @RULE_NUMBER@ iptables -D OUTPUT @RULE_NUMBER@ ``` -The secondary node is again seen `online` by the cluster: - - - +If you run `pcs status` on the active node, the passive node is seen as `online` again: ```text Cluster Summary: * Stack: corosync - * Current DC: @CENTRAL_MASTER_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum + * Current DC: @NODE1_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @CENTRAL_MASTER_NAME@ + * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @NODE1_NAME@ * 2 nodes configured - * 14 resource instances configured + * 12 resource instances configured Node List: - * Online: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Online: [ @NODE1_NAME@ @NODE2_NAME@ ] Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @CENTRAL_MASTER_NAME@ ] - * Slaves: [ @CENTRAL_SLAVE_NAME@ ] * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_MASTER_NAME@ - * http (systemd:httpd): Started @CENTRAL_MASTER_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_MASTER_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_MASTER_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_MASTER_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_MASTER_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_MASTER_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_MASTER_NAME@ + * vip (ocf::heartbeat:IPaddr2): Started @NODE1_NAME@ + * http (systemd:httpd): Started @NODE1_NAME@ + * gorgone (systemd:gorgoned): Started @NODE1_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @NODE1_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @NODE1_NAME@ + * centengine (systemd:centengine): Started @NODE1_NAME@ + * centreontrapd (systemd:centreontrapd): Started @NODE1_NAME@ + * snmptrapd (systemd:snmptrapd): Started @NODE1_NAME@ ``` - - +## Test 3: Simulate the loss of the active node -Also check MySQL replication is still operational using the command: +This test checks that the resources are switched to the passive node if the active node is unavailable, allowing for continuity of service. -```bash -/usr/share/centreon-ha/bin/mysql-check-status.sh -``` - -The order must return the following information: +### Perform the test -```text -Connection MASTER Status '@CENTRAL_MASTER_NAME@' [OK] -Connection SLAVE Status '@CENTRAL_SLAVE_NAME@' [OK] -Slave Thread Status [OK] -Position Status [OK] -``` +We're assuming that node 1 is the active node and node 2 is the passive node ([check the state of the cluster](#check-the-state-of-the-cluster) if you need to). -## Simulate the loss of the primary node - -### Processing - -To perform this test, run the commands on the primary server: +To perform this test, run the commands on the active node: ```bash -iptables -A INPUT -s @IP_SECONDARY_NODE@ -j DROP -iptables -A OUTPUT -d @IP_SECONDARY_NODE@ -j DROP +iptables -A INPUT -s @IP_PASSIVE_NODE@ -j DROP +iptables -A OUTPUT -d @IP_PASSIVE_NODE@ -j DROP iptables -A INPUT -s @QDEVICE_IP@ -j DROP iptables -A OUTPUT -d @QDEVICE_IP@ -j DROP ``` -Resources on the primary node should stop and should start on the secondary node. You can use the `crm_mon -fr` command on the secondary node to watch the startup of resources: - - - +Resources on the active node should stop. The passive node becomes the active node and all the resources switch to it. You can use the `crm_mon -fr` command on the passive node to watch the startup of resources: ```text Cluster Summary: * Stack: corosync - * Current DC: @CENTRAL_SLAVE_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum + * Current DC: @NODE2_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @CENTRAL_SLAVE_NAME@ + * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @NODE2_NAME@ * 2 nodes configured - * 14 resource instances configured + * 12 resource instances configured Node List: - * Online: [ @CENTRAL_SLAVE_NAME@ ] - * OFFLINE [ @CENTRAL_MASTER_NAME@ ] + * Online: [ @NODE2_NAME@ ] + * OFFLINE [ @NODE1_NAME@ ] Full List of Resources: * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @CENTRAL_MASTER_NAME@ ] - * Slaves: [ @CENTRAL_SLAVE_NAME@ ] + * Masters: [ @NODE1_NAME@ ] + * Slaves: [ @NODE2_NAME@ ] * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_SLAVE_NAME@ - * http (systemd:httpd): Started @CENTRAL_SLAVE_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_SLAVE_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_SLAVE_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_SLAVE_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_SLAVE_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_SLAVE_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_SLAVE_NAME@ + * vip (ocf::heartbeat:IPaddr2): Started @NODE2_NAME@ + * http (systemd:httpd): Started @NODE2_NAME@ + * gorgone (systemd:gorgoned): Started @NODE2_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @NODE2_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @NODE2_NAME@ + * centengine (systemd:centengine): Started @NODE2_NAME@ + * centreontrapd (systemd:centreontrapd): Started @NODE2_NAME@ + * snmptrapd (systemd:snmptrapd): Started @NODE2_NAME@ ``` - - - -This test checks that resources will be switched to the secondary node if the primary node is unavailable and allows for continuity of service. - -### Back to nominal situation +### Go back to the nominal situation -To check the various iptables rules configured on the primary node, run the following command: +To check the various iptables rules configured on the active node, run the following command: ```bash iptables -L @@ -575,7 +373,7 @@ The command should return the following information: ```text Chain INPUT (policy ACCEPT) target prot opt source destination -DROP all -- @CENTRAL_SLAVE_NAME@ anywhere +DROP all -- @NODE2_NAME@ anywhere DROP all -- @QDEVICE_NAME@ anywhere Chain FORWARD (policy ACCEPT) @@ -583,7 +381,7 @@ target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination -DROP all -- anywhere @CENTRAL_SLAVE_NAME@ +DROP all -- anywhere @NODE2_NAME@ DROP all -- anywhere @QDEVICE_NAME@ ``` @@ -599,54 +397,54 @@ Otherwise, it will be necessary to list the rule numbers with the specific comma iptables -L --line-numbers ``` -And delete it with the command: +And delete them with the following command: ```bash iptables -D INPUT @RULE_NUMBER@; iptables -D OUTPUT @RULE_NUMBER@ ``` -By running the `crm_mon` command on the second node, you will see the primary node move up in the cluster but staying as SLAVE node. +By running the `crm_mon` command on the second node, you will see the active node move up in the cluster but staying as SLAVE node. ```text Cluster Summary: * Stack: corosync - * Current DC: @CENTRAL_MASTER_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum + * Current DC: @NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum * Last updated: Tue Nov 8 17:27:28 2022 - * Last change: Tue Nov 8 17:23:19 2022 by root via crm_attribute on @CENTRAL_SLAVE_NAME@ + * Last change: Tue Nov 8 17:23:19 2022 by root via crm_attribute on @NODE2_NAME@ * 2 nodes configured - * 14 resource instances configured + * 12 resource instances configured Node List: - * Online: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Online: [ @NODE1_NAME@ @NODE2_NAME@ ] Full List of Resources: * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * ms_mysql (ocf::heartbeat:mariadb-centreon): Stopped @CENTRAL_MASTER_NAME@ (Monitoring) - * Masters: [ @CENTRAL_SLAVE_NAME@ ] - * Stopped: [ @CENTRAL_MASTER_NAME@ ] + * ms_mysql (ocf::heartbeat:mariadb-centreon): Stopped @NODE1_NAME@ (Monitoring) + * Masters: [ @NODE2_NAME@ ] + * Stopped: [ @NODE1_NAME@ ] * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_SLAVE_NAME@ - * http (systemd:httpd): Started @CENTRAL_SLAVE_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_SLAVE_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_SLAVE_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_SLAVE_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_SLAVE_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_SLAVE_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_SLAVE_NAME@ + * vip (ocf::heartbeat:IPaddr2): Started @NODE2_NAME@ + * http (systemd:httpd): Started @NODE2_NAME@ + * gorgone (systemd:gorgoned): Started @NODE2_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @NODE2_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @NODE2_NAME@ + * centengine (systemd:centengine): Started @NODE2_NAME@ + * centreontrapd (systemd:centreontrapd): Started @NODE2_NAME@ + * snmptrapd (systemd:snmptrapd): Started @NODE2_NAME@ Migration Summary: - * Node: @CENTRAL_MASTER_NAME@: + * Node: @NODE1_NAME@: * ms_mysql: migration-threshold=1000000 fail-count=1000000 last-failure='Tue Nov 8 17:27:25 2 022' Failed Resource Actions: - * ms_mysql_start_0 on @CENTRAL_MASTER_NAME@ 'error' (1): call=440, status='complete', exitreason='M + * ms_mysql_start_0 on @NODE1_NAME@ 'error' (1): call=440, status='complete', exitreason='M ariaDB slave io has failed (1236): Got fatal error 1236 from master when reading data from binary log: 'Error: connecting slave', last-rc-change='Tue Nov 8 17:27:21 2022', queued=0ms, exec=4060ms ``` -If you want to switch to the primary node, you must do a failover. +If you want to switch to the active node, you must do a failover. So, **before you do this, you must check the cluster and database replication status**. First, check the constraints: @@ -657,9 +455,6 @@ pcs constraint The command should return this: - - - ```text Location Constraints: Ordering Constraints: @@ -669,34 +464,31 @@ Colocation Constraints: Ticket Constraints: ``` - - - then check the database replication ```bash /usr/share/centreon-ha/bin/mysql-check-status.sh ``` -At this time, the cluster is in degraded mode with two slave nodes. -In this particular case, it returns the following information because the ms_mysql resource is stopped on @CENTRAL_MASTER_NAME@: +At this time, the cluster is in degraded mode with two passive nodes. +In this particular case, it returns the following information because the ms_mysql resource is stopped on node 1: ```text -Connection SLAVE Status '@CENTRAL_MASTER_NAME@' [KO] +Connection SLAVE Status '@NODE1_NAME@' [KO] Error reports: - ERROR 2002 (HY000): Can't connect to MySQL server on '@CENTRAL_MASTER_NAME@' (115) -Impossible de se connecter au serveur '@CENTRAL_MASTER_NAME@'. -Connection SLAVE Status '@CENTRAL_SLAVE_NAME@' [OK] + ERROR 2002 (HY000): Can't connect to MySQL server on '@NODE1_NAME@' (115) +Impossible de se connecter au serveur '@NODE1_NAME@'. +Connection SLAVE Status '@NODE2_NAME@' [OK] Slave Thread Status [KO] Error reports: - Skip check on '@CENTRAL_MASTER_NAME@'. + Skip check on '@NODE1_NAME@'. No slave (maybe because we cannot check a server). Position Status [SKIP] Error reports: Skip because we can't identify a unique slave. ``` -You must do a database synchronization from @CENTRAL_SLAVE_NAME@ to @CENTRAL_MASTER_NAME@ by launching the "sync-bigdb" script on the **Slave node**. +You must do a database synchronization from @NODE2_NAME@ to @NODE1_NAME@ by launching the "sync-bigdb" script on the **Slave node**. ```shell /usr/share/centreon-ha/bin/mysql-sync-bigdb.sh @@ -711,7 +503,7 @@ Start MySQL Slave OK Start Replication Id User Host db Command Time State Info Progress -5 centreon-repl @CENTRAL_SLAVE_NAME@:51850 NULL Query 0 starting show processlist 0.000 +5 centreon-repl @NODE2_NAME@:51850 NULL Query 0 starting show processlist 0.000 6 centreon localhost centreon_storage Sleep 0 NULL 0.000 7 system user NULL Connect 0 Connecting to master NULL 0.000 8 system user NULL Slave_SQL 0 Slave has read all relay log; waiting for more updates NULL 0.000 @@ -726,8 +518,8 @@ Database replication should now be OK. Check this. The result should be: ```text -Connection MASTER Status '@CENTRAL_SLAVE_NAME@' [OK] -Connection SLAVE Status '@CENTRAL_MASTER_NAME@' [OK] +Connection MASTER Status '@NODE2_NAME@' [OK] +Connection SLAVE Status '@NODE1_NAME@' [OK] Slave Thread Status [OK] Position Status [OK] ``` @@ -738,7 +530,7 @@ Now, you can perform a failover to return to the initial situation. pcs resource clear centreon ``` -Do a cleanup to clear errors and restart the ms_mysql resource on @CENTRAL_MASTER_NAME@. +Do a cleanup to clear errors and restart the ms_mysql resource on @NODE1_NAME@. ```shell pcs resource cleanup @@ -755,35 +547,34 @@ The **centreon** resource is now relocated and the cluster is OK. Check this wit ```text Cluster Summary: * Stack: corosync - * Current DC: @CENTRAL_MASTER_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum + * Current DC: @NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum * Last updated: Wed Nov 9 10:23:54 2022 - * Last change: Wed Nov 9 10:23:26 2022 by root via crm_attribute on @CENTRAL_MASTER_NAME@ + * Last change: Wed Nov 9 10:23:26 2022 by root via crm_attribute on @NODE1_NAME@ * 2 nodes configured - * 14 resource instances configured + * 12 resource instances configured Node List: - * Online: [ @CENTRAL_MASTER_NAME@ centreon-rhel8-sec ] + * Online: [ @NODE1_NAME@ centreon-rhel8-sec ] Full List of Resources: * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @CENTRAL_MASTER_NAME@ ] + * Masters: [ @NODE1_NAME@ ] * Slaves: [ centreon-rhel8-sec ] * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_MASTER_NAME@ centreon-rhel8-sec ] + * Started: [ @NODE1_NAME@ centreon-rhel8-sec ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_MASTER_NAME@ centreon-rhel8-sec ] + * Started: [ @NODE1_NAME@ centreon-rhel8-sec ] * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_MASTER_NAME@ - * http (systemd:httpd): Started @CENTRAL_MASTER_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_MASTER_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_MASTER_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_MASTER_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_MASTER_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_MASTER_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_MASTER_NAME@ + * vip (ocf::heartbeat:IPaddr2): Started @NODE1_NAME@ + * http (systemd:httpd): Started @NODE1_NAME@ + * gorgone (systemd:gorgoned): Started @NODE1_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @NODE1_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @NODE1_NAME@ + * centengine (systemd:centengine): Started @NODE1_NAME@ + * centreontrapd (systemd:centreontrapd): Started @NODE1_NAME@ + * snmptrapd (systemd:snmptrapd): Started @NODE1_NAME@ Migration Summary: ``` - - - + diff --git a/versioned_docs/version-24.04/administration/centreon-ha/monitoring-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/monitoring-guide.md index 484e73be4f80..50a9e3dafab7 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/monitoring-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/monitoring-guide.md @@ -1,62 +1,24 @@ --- id: monitoring-guide -title: Monitoring Centreon-HA +title: Monitoring Centreon HA --- -## Monitoring the cluster processes and resources +Monitoring your HA setup using Centreon itself helps you keep track of the health of your cluster. It is strongly recommended to implement it. -First, please refer to the [Linux SNMP Plugin-Pack documentation page](/pp/integrations/plugin-packs/procedures/operatingsystems-linux-snmp) to install all the required components and monitor the basic system health indicators of both of the central nodes. +## What to monitor -Then refer to the [Centreon-HA Plugin-Pack documentation page](/pp/integrations/plugin-packs/procedures/applications-monitoring-centreon-ha) to monitor the clustering services and cluster resources on both of the central nodes. +All elements of the cluster must be monitored by a poller, not by a central (to avoid having resources in a **Pending** status when the cluster fails over). For the same reason, each poller should be monitored by another poller. -## Monitoring the MariaDB Replication - -Refer to the [MySQL/MariaDB Plugin-Pack documentation page](/pp/integrations/plugin-packs/procedures/applications-databases-mysql) to install all the required components and monitor the standard MariaDB health indicators of both of the central nodes. - -The poller's IP address must be a recognized login source for the databases. These *GRANT* requests must therefore be run on the primary database and they will be immediately replicated to the secondary node (replace the fields between brackets): - -```sql -CREATE USER ''@'' IDENTIFIED BY ''; -GRANT SELECT on centreon.* TO ''@'' ; -GRANT SELECT on centreon_storage.* TO ''@'' ; -GRANT REPLICATION CLIENT on *.* TO ''@'' ; -``` - -After applying the *App-DB-MySQL-custom* host template and setting the correct values for *PORT*, *USERNAME* and *PASSWORD* macros, make sure that all the default services are checked successfully (no *UNKNOWN* states). - -Then add a new service by browsing to **Configuration > Services > Services by host** and clicking **Add**, and then complete the form according to this table: - -| Field | Value | -|:--------------------|:----------------------------------------------------------------| -| *Description* | MariaDB-Replication | -| *Linked with Hosts* | Central node | -| *Template* | App-DB-MySQL-MariaDB-Replication-custom | -| `PEERHOST` | IP address of the other central node | -| `PEERPORT` | Port of the other central node's MariaDB server (default: 3306) | -| `PEERUSERNAME` | Login of the other central node's MariaDB server | -| `PEERPASSWORD` | Password of the other central node's MariaDB server | - -Then click `Save` and export and apply your poller's configuration. - -The output of this service should look like this: - -```text -OK: No problems. Replication is ok. -Connection Status 'mysql:host=;port=3306' [OK] -Connection Status 'mysql:host=;port=3306' [OK] -Slave Thread Status [OK] -Position Status [OK] -``` - -## Monitoring the Quorum Device - -First refer to the [Linux SNMP Plugin-Pack documentation page](/pp/integrations/plugin-packs/procedures/operatingsystems-linux-snmp) to install all the required components and monitor the basic system health indicators of the server supporting the Quorum Device. - -Then add a new service by browsing to **Configuration > Services > Services by host** and clicking **Add**, and then complete the form according to this table: - -| Field | Value | -|:--------------------|:---------------------------------------------------------| -| *Description* | proc-corosync-qnetd | -| *Linked with Hosts* | Server supporting the Quorum Device | -| *Template* | App-Monitoring-Centreon-HA-Process-corosync-qnetd-custom | +* Create 1 host for the VIP, and monitor it with: + * the [Centron Central monitoring connector](/pp/integrations/plugin-packs/procedures/applications-monitoring-centreon-central). + * the [HTTP Server monitoring connector](/pp/integrations/plugin-packs/procedures/applications-protocol-http) to check the interface's response time. +* Create 1 host for each central node, and monitor it with: + * the [Linux SNMP monitoring connector](/pp/integrations/plugin-packs/procedures/operatingsystems-linux-snmp), to monitor the system of the host machine. + * the [Centreon HA monitoring connector](/pp/integrations/plugin-packs/procedures/applications-monitoring-centreon-ha) to monitor the clustering services. +* Create 1 host per poller and monitor them with the [Centreon Poller monitoring connector](/pp/integrations/plugin-packs/procedures/applications-monitoring-centreon-poller). +* Create 1 host per database and monitor them with the [Centreon Database monitoring connector](/pp/integrations/plugin-packs/procedures/applications-monitoring-centreon-database). +* Monitor the quorum device: + * if your quorum device is one of your pollers, create a service called something like **proc-corosync-qnetd** and apply the **App-Monitoring-Centreon-HA-Process-corosync-qnetd-custom** service template to it. + * if your quorum device is hosted on another server, monitor its system with the [Linux SNMP monitoring connector](/pp/integrations/plugin-packs/procedures/operatingsystems-linux-snmp), then add the **proc-corosync-qnetd** service mentioned above. +Make sure all the prerequisites are satisfied for all instances of these monitoring connectors (e.g. that the correct key exchanges have been made and the correct users have been authorized on each monitored server). diff --git a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md index 9e3015cdd6c8..c5fd5f3ccf16 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md @@ -3,121 +3,147 @@ id: operating-guide title: Operating guide --- +Once you have completed the installation procedure, make sure the cluster is running smoothly. + > Unless otherwise stated, all commands in this document must be passed as `root`. -> In this document, we will refer to characteristics that are bound to change from one platform to another (such as IP addresses and host names) by the [macros defined here](../../installation/installation-of-centreon-ha/installation-2-nodes.md#defining-hosts-names-and-addresses). +> In this page, we will refer to characteristics that are bound to change from one platform to another (such as IP addresses and host names) by the [macros defined here](../../installation/installation-of-centreon-ha/installation.md#convention-for-names-and-ip-addresses). -## Cluster Management +### In Resource Status, how do I know the state of the cluster? -The following set of commands can be run from any member of the cluster. +On both central nodes, the **PCS-Status** service gives you the detailed state of the cluster. The output of the service in the details panel is the output of the `pcs status` command. -### Display cluster status +### In Resource status, how do I know which central is the active node? -To view the general state of the cluster, run this command: +You can know which central is the active node by looking at which node is carrying the cluster resources in the output of the **PCS-Status** service on each central. -```bash -crm_mon -``` +### What happens when the cluster fails over? -> Check the "Failed actions" on the resources and troubleshoot them using the [troubleshooting guide](troubleshooting-guide.md). +When the cluster fails over (e.g. when the active node is affected by a network outage, if its Broker partitions are full...): -### View the status of a resource +* The host for the VIP should be OK (it may temporarily go down in a SOFT state if the corresponding monitoring check is performed at the exact same time the cluster fails over.) +* The host for the central node that failed will show up as DOWN and/or with CRITICAL services. +* You may receive notifications if you have configured them. +* You may have to log on to the interface again. -To find out the status of a specific resource, run this command: +## Cluster Management -```bash -pcs resource show -``` +The following set of commands can be run from any member of the cluster (central nodes, quorum device). -For example, to find out the status of the **centengine** resource, run this command: +### Display the status of the cluster -```bash -pcs resource show centengine -``` +To view the general state of the cluster, you can run the following commands: -### View cluster configuration +* `pcs status`, which has a static output: it displays the state of the cluster as it is at the time you run the command. -To view the cluster configuration, run this command: +* `crm_mon`, which has a dynamic output: the state of the cluster is displayed in real time. You can watch the resources being stopped and transferred to the other node. Use `crm_mon -fr` to keep displaying stopped resources. + +Example of output when the cluster is working properly: -```bash -pcs config show ``` +Cluster Summary: + * Stack: corosync (Pacemaker is running) + * Current DC: @CENTRAL_PASSIVE_NAME@ (version 2.1.6-9.1.el8_9-6fdc9deea29) - partition with quorum + * Last updated: Wed Apr 17 10:24:25 2024 on @CENTRAL_ACTIVE_NAME@ + * Last change: Tue Apr 16 05:47:37 2024 by hacluster via crmd on @CENTRAL_PASSIVE_NAME@ + * 2 nodes configured + * 12 resource instances configured -### Test the configuration +Node List: + * Online: [ @CENTRAL_PASSIVE_NAME@ @CENTRAL_ACTIVE_NAME@ ] -To test the cluster configuration, run this command: +Active Resources: + * Clone Set: php-clone [php]: + * Started: [ @CENTRAL_PASSIVE_NAME@ @CENTRAL_ACTIVE_NAME@ ] + * Clone Set: cbd_rrd-clone [cbd_rrd]: + * Started: [ @CENTRAL_PASSIVE_NAME@ @CENTRAL_ACTIVE_NAME@ ] + * Resource Group: centreon: + * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_ACTIVE_NAME@ + * http (systemd:httpd): Started @CENTRAL_ACTIVE_NAME@ + * gorgone (systemd:gorgoned): Started @CENTRAL_ACTIVE_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_ACTIVE_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_ACTIVE_NAME@ + * centengine (systemd:centengine): Started @CENTRAL_ACTIVE_NAME@ + * centreontrapd (systemd:centreontrapd): Started @CENTRAL_ACTIVE_NAME@ + * snmptrapd (systemd:snmptrapd): Started @CENTRAL_ACTIVE_NAME@ -```bash -crm_verify -L -V ``` -### Save & import configuration +These commands should return no errors. If there are "Failed actions" on any resource, troubleshoot them using the [troubleshooting guide](troubleshooting-guide.md). -#### Export/import in XML format +### View the status of a resource -To save the cluster configuration in XML format, run this command: +If you suspect that a specific process is causing problems, find out the status of the corresponding resource by running this command: ```bash -cibadmin --query > /tmp/cluster_configuration.xml +pcs resource show ``` -> The following commands perform important modifications to the cluster's configuration and might break it. Use them wisely. - -After modifying the XML configuration file, reimport it: +For example, to find out the status of the **centengine** resource, run this command: ```bash -cibadmin --replace --xml-file /tmp/cluster_configuration.xml +pcs resource show centengine ``` -To completely reset your cluster's configuration, run this command: +OUTPUT: -```bash -cibadmin --force --erase ``` - -#### Export/import in binary format - -The cluster's configuration can be backed up to a binary file: - -```bash -pcs config backup export +Warning: This command is deprecated and will be removed. Please use 'pcs resource config' instead. +Resource: centengine (class=systemd type=centengine) + Meta Attributes: centengine-meta_attributes + multiple-active=stop_start + target-role=started + Operations: + monitor: centengine-monitor-interval-5s + interval=5s + timeout=30s + start: centengine-start-interval-0s + interval=0s + timeout=90s + stop: centengine-stop-interval-0s + interval=0s + timeout=90s ``` -This backup can then be re-imported: +### View the cluster's configuration + +To display a very detailed description the cluster's configuration (including xxxxxxx), run this command: ```bash -pcs config restore export.tar.bz2 +pcs config show ``` -### Check the "switchability" of a resource +### Test the configuration -To simulate the ability to toggle a resource from one node to another, run this command: +To test the cluster's configuration, run this command: ```bash -crm_simulate -L -s +crm_verify -L -V ``` -Then check the scores displayed. +NO OUTPUT (-> because no problem?) -## Resource management +## Switching resources/resource groups from one node to another -### Switch a resource from one node to another +To toggle the `centreon` resource group: -To move a resource from the node where it is currently running to the other, run this command: +1. Move the resource group to the other node: -```bash -pcs resource move -``` + ```bash + pcs resource move centreon + ``` -> Warning: the `pcs resource move` adds a constraint that will prevent the resource from moving back to the node where it used to be running. + This command sets an "-Inf" constraint on the node hosting the resource. As a result, the resource group switches to another node. -Once the resource is done moving, run this command: +2. Clear the constraint: -```bash -pcs resource clear -``` + ```bash + pcs resource clear centreon + ``` + +If you move a single resource from the centreon resource group from one node to the other, all the other resources in the group will switch too. -### Remove an error displayed in the cluster status +## Remove an error displayed in the cluster status Once the cause of the error has been identified and fixed ([troubleshooting guide](troubleshooting-guide.md)), you must manually delete the error message: @@ -131,12 +157,12 @@ Or, if you want to remove only the errors linked to one resource: pcs resource cleanup ``` -### View cluster logs +## View cluster logs The cluster logs are located in `/var/log/cluster/corosync.log`: ```bash -tailf /var/log/cluster/corosync.log +tail -f /var/log/cluster/corosync.log ``` Useful logs can also be found in `/var/log/messages`. @@ -148,104 +174,44 @@ To change the verbosity level of the cluster logs, edit the following files: * `/etc/sysconfig/pacemaker` * `/etc/rsyslog.d/centreon-cluster.conf` -## Management of the MariaDB resource - -This chapter discusses the operating procedures for the `ms_mysql` resource. The procedures are to be performed on the `@CENTRAL_MASTER_NAME@` and `@CENTRAL_SLAVE_NAME@` servers. - -### Check the status of MariaDB replication - -Run the following command on one of the database servers: +## Advanced commands -```bash -/usr/share/centreon-ha/bin/mysql-check-status.sh -``` - -```text -Connection Status '@CENTRAL_MASTER_NAME@' [OK] -Connection Status '@CENTRAL_SLAVE_NAME@' [OK] -Slave Thread Status [OK] -Position Status [OK] -``` - -If errors are displayed on the third or fourth line, it means that the database replication has been broken for some reason. The procedure below explains how to manually re-enable MariaDB replication. - -### Restore MariaDB master-slave replication - -> This procedure should be applied in the event of a breakdown in the MariaDB databases' replication thread or a server crash if it cannot be recovered by running `pcs resource cleanup ms_mysql` or `pcs resource restart ms_mysql`. +### Save & import the configuration of the cluster -Prevent the cluster from managing the MariaDB resource during the operation (to be run from any node): - -```bash -pcs resource unmanage ms_mysql -``` - -Connect to the MariaDB slave server and shut down the MariaDB service: - -```bash -mysqladmin -p shutdown -``` - -Connect to the MariaDB master server and run the following command to overwrite the slave's data with the master's: - -```bash -/usr/share/centreon-ha/bin/mysql-sync-bigdb.sh -``` - -Re-enable the cluster to manage the MariaDB resource: - -```bash -pcs resource manage ms_mysql -``` +#### Export/import in XML format -Run the following command on one of the database servers to make sure that the replication has been successfully restored: +To save the cluster configuration in XML format, run this command: ```bash -/usr/share/centreon-ha/bin/mysql-check-status.sh -``` - -```text -Connection Status '@CENTRAL_MASTER_NAME@' [OK] -Connection Status '@CENTRAL_SLAVE_NAME@' [OK] -Slave Thread Status [OK] -Position Status [OK] +cibadmin --query > /tmp/cluster_configuration.xml ``` -### Reverse the direction of the MariaDB master-slave replication - -> Before performing this operation, it is mandatory to make sure that the MariaDB replication thread [is running well](operating-guide.md#check-the-status-of-mariadb-replication). - -> **Warning:** Following this procedure on a two-node cluster installed using [this procedure](../../installation/installation-of-centreon-ha/installation-2-nodes.md) will move the `centreon` resource group as well, because it **must** run on the node that has the `ms_mysql-master` meta attribute. +> The following commands perform important modifications to the cluster's configuration and might break it. Use them wisely. -To make the resource move from one node to the other, run this command: +After modifying the XML configuration file, reimport it: ```bash -pcs resource move ms_mysql-master +cibadmin --replace --xml-file /tmp/cluster_configuration.xml ``` -This command sets an "-Inf" constraint on the node hosting the resource. As a result, the resource switches to another node. - -Wait until all the resources have switched to the other node and then clear the constraint: +To completely reset your cluster's configuration, run this command: ```bash -pcs resource clear ms_mysql-master +cibadmin --force --erase ``` -## Managing the Centreon resource group - -### Toggle the `centreon` resource group - -> **Warning:** As in [this chapter](operating-guide.md#reverse-the-direction-of-the-mariadb-master-slave-replication), following this procedure on a two-node cluster installed using [this procedure](../../installation/installation-of-centreon-ha/installation-2-nodes.md) will switch the MariaDB master as well, because it **must** run on the node that has the `ms_mysql-master` meta attribute. +#### Export/import in binary format -Move the resource group to the other node: +The cluster's configuration can be backed up to a binary file: ```bash -pcs resource move centreon +pcs config backup export ``` -This command sets an "-Inf" constraint on the node hosting the resource. As a result, the resource group switches to another node. Following this manipulation, it is necessary to clear the constraint: +This backup can then be re-imported: ```bash -pcs resource clear centreon +pcs config restore export.tar.bz2 ``` ### Delete a Pacemaker resource group @@ -273,42 +239,3 @@ pcs resource cleanup centreon ``` To create the resources again, follow the installation procedure [from this point](../../installation/installation-of-centreon-ha/installation-2-nodes.md#creating-the-centreon-resource-group) - -## Monitoring a Centreon-HA cluster - -A high-availability platform is basically a LAMP platform (Linux Apache MariaDB PHP) managed by the [ClusterLabs](https://clusterlabs.org/) tools. The platform's monitoring must therefore include the same indicators as with any Centreon platform, and some cluster-specific ones. **The monitoring of the cluster must be performed from an external poller.** - -### System indicators and processes - -The easiest part consists in monitoring the basic system indicators, mostly using SNMP Protocol, which is made quite simple thanks to the [Linux Monitoring Connector](/pp/integrations/plugin-packs/procedures/operatingsystems-linux-snmp). - -* System metrics - * LOAD Average - * CPU usage - * Memory usage - * SWAP usage - * File systems usage - * Networking traffic - * NTP synchronization with the reference time server -* Processes - * System processes `crond`, `ntpd`, `rsyslogd` - * Centreon processes `gorgoned`, `centengine`, `centreontrapd`, `httpd24-httpd`, `snmptrapd`, `mysqld`, `php-fpm` - -### Application monitoring - -* Control access to the URL `http://@VIP_IPADDR@/centreon` using the [HTTP Protocol Monitoring Connector](/pp/integrations/plugin-packs/procedures/applications-protocol-http) -* MariaDB, using the [MySQL/MariaDB Database Monitoring Connector](/pp/integrations/plugin-packs/procedures/applications-databases-mysql) - * MariaDB Server Connection Control - * MariaDB / InnoDB buffers and caches - * Index usage - * MariaDB replication - -### Cluster monitoring - -The cluster-specific health checks can be monitored using the [Pacemaker Monitoring Connector](/pp/integrations/plugin-packs/procedures/applications-pacemaker-ssh): - -* Resource constraints: only for `ms_mysql` and `centreon` resources -* Failed actions - -> Note: a Monitoring Connector dedicated to Centreon-HA might be released in the future to make this easier. - diff --git a/versioned_docs/version-24.04/administration/centreon-ha/troubleshooting-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/troubleshooting-guide.md index 1340c2a87c84..b095aef761d5 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/troubleshooting-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/troubleshooting-guide.md @@ -7,9 +7,6 @@ import TabItem from '@theme/TabItem'; ## A failed action is displayed in `crm_mon` but the resource seems to be working fine - - - ```bash Cluster Summary: * Stack: corosync @@ -42,37 +39,25 @@ Failed Resource Actions: last-rc-change='Wed Sep 15 13:42:19 2021', queued=1ms, exec=2122ms ``` - - +### Solution -## Resource not starting +The errors do not go away automatically even if the problem is resolved. To remove the error, run the following command: -In the event of a Centreon resource (e.g. `centreontrapd`) failing to start, *failed actions* will appear at the bottom of the `crm_mon` command's output **and** the resources that are supposed to be started are listed after it. It will look like this: +```shell +pcs resource cleanup +``` - - +In the example above, the command would be: -```bash -Cluster Summary: - * Stack: corosync - * Current DC: @CENTRAL_MASTER_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum - * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @CENTRAL_MASTER_NAME@ - * 2 nodes configured - * 14 resource instances configured -Node List: - * Online: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] -Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Slaves: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] - * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] - * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] +```shell +pcs resource cleanup centreontrapd ``` - - +## A resource is not starting + +In the event of a Centreon resource (e.g. `centreontrapd`) failing to start, **Failed actions** will appear at the bottom of the `crm_mon` command's output. + +### Solution To obtain more information regarding this failure, you should first check the service's status by running this command on the node **where the service should be currently running**: @@ -96,9 +81,6 @@ pcs resource cleanup centreontrapd If the following situation occurs after a failover, whether a manual one or after a server shutdown: - - - ```bash Stack: corosync Current DC: @CENTRAL_SLAVE_NAME@ (version 1.1.20-5.el8_7.2-3c4c782f70) - partition with quorum @@ -120,17 +102,17 @@ Active resources: Started: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] ``` - - +No error is displayed, but the centreon group no longer appears in the output and none of its resources are started. This mostly happens when there were multiple failovers (`pcs resource move ....`) without deleting the constraint. + +### Solution -No error is displayed, but the centreon group no longer shows up and none of its resources is started. This mostly happens when there were multiple failovers (`pcs resource move ....`) without deleting the constraint. To check that: +To check whether some constraints are active, run the following command: ```bash -pcs constraint show +pcs constraint config ``` - - +The output will look like this: ```bash Location Constraints: @@ -143,9 +125,6 @@ Colocation Constraints: Ticket Constraints: ``` - - - We notice that the centreon group is not authorized to start on any node. To free the resource group from its constraints, run the following command: diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/faq.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/faq.md new file mode 100644 index 000000000000..d78b871e8e3d --- /dev/null +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/faq.md @@ -0,0 +1,43 @@ +--- +id: ha-faq +title: Centreon HA general FAQ +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +## When do I need HA? + +HA is relevant when it is critical for your Centreon platform to be up without interruption - because the resources you are monitoring must be functional at all times. + +Centreon HA is an active-passive cluster. It does not perform load balancing. + +## Can I implement HA myself? + +It is strongly recommended that your HA is installed by Centreon Professional Services. You may implement HA yourself **only** if: + +* you are able to set up replicated databases with a dedicated VIP. The [installation procedure described in this documentation](installation.md) only applies if you already have a database cluster. +* you have a strong knowledge of the Pacemaker-Corosync clustering tools, of networks, of Linux OS and of Centreon, in order to have a proper understanding of what is being done and to be able to correct any mistakes that might occur. + +> **WARNING:** Anyone following the installation procedure does so at their own risk. Under no circumstances shall Centreon be liable for any breakdown or loss of data. + +## Do I need a licence for Centreon HA? + +Extensions need specific license files to work on both nodes smoothly. If you have an IT or Business subscription, please get in touch with your Centreon sales representative or Technical Account Manager before implementing high availability. + +## What is supported, and what isn't? + +With Centreon 24.04, HA clusters are supported on Alma/RHEL/Oracle Linux 8 and 9 and Debian 11, and the only supported DBMS is MariaDB 10.11. Debian 12 and MySQL8 are not supported yet: if you need to use them, please contact your Centreon sales representative. + +Support for HA setups is not included in the Centreon standard support. If you want support for your HA system, your HA setup must be installed by Centreon Professional Services, and you need to purchase a specific HA support pack. Moreover, Centreon can only support Centreon software and does not offer support on your database redundancy setup. + +From version 24.04 on, you need a remote database in all cases. The redundancy of the database is the responsibility of the customer. MariaDB and MySQL have their own redundancy system: set up a database redundancy system using the tools provided by MariaDB or MySQL. + +## What modules can I set up HA on? + +HA can be set up on: + +* Your central servers (that includes BAM automatically). +* A Centreon MAP server: please contact your Centreon sales representative if you want to implement this. +* It is unnecessary to set up redundancy on an MBI server as all of MBI's data is already present on the database connected to the central server. + +HA is not supported on pollers. diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md new file mode 100644 index 000000000000..850c6339f95b --- /dev/null +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -0,0 +1,1093 @@ +--- +id: installation +title: Installing Centreon HA +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +> Debian 12 and MySQL 8 are not supported yet for HA installations using Centreon version 24.04. If you wish to install an HA platform with this configuration, please contact your Centreon sales representative. + +## Before you start + +### Disclaimer + +It is strongly recommended that your HA is installed by Centreon Professional Services. You may implement HA yourself **only** if: + +* you are able to set up replicated databases with a dedicated VIP. The following procedure only applies if you already have a database cluster. +* you have a strong knowledge of the Pacemaker-Corosync clustering tools, of networks, of Linux OS and of Centreon, in order to have a proper understanding of what is being done and to be able to correct any mistakes that might occur. + +See also "[What is supported, and what isn't?](faq.md#what-is-supported-and-what-isnt)". + +> **WARNING:** Anyone following this procedure does so at their own risk. Under no circumstances shall Centreon be liable for any breakdown or data loss. + +### Convention for names and IP addresses + +In this procedure, we will refer to characteristics that are bound to change from one platform to another (such as IP addresses) by the following macros: + +* `@CENTRAL_ACTIVE_IPADDR@`: active central server's IP address +* `@CENTRAL_ACTIVE_NAME@`: active central server's name (must be identical to `hostname -s`) +* `@CENTRAL_PASSIVE_IPADDR@`: passive central server's IP address +* `@CENTRAL_PASSIVE_NAME@`: passive central server's name (must be identical to `hostname -s`) +* `@QDEVICE_IPADDR@`: quorum device's IP address +* `@QDEVICE_NAME@`: quorum device's name (must be identical to `hostname -s`) +* `@VIP_IPADDR@`: virtual IP address of the cluster +* `@VIP_IFNAME@`: network device carrying the cluster's VIP (name of the interface the VIP must send the flows to. The interface must have the same name on both central nodes). +* `@VIP_CIDR_NETMASK@`: subnet mask length in bits (e.g. 24) +* `@VIP_BROADCAST_IPADDR@`: cluster's VIP broadcast address +* `@CENTREON_CLUSTER_PASSWD@`: `hacluster` user's password + +During the installation procedure, node 1 will be the active node and node 2 will be the passive node. Of course, the roles will be able to be switched later. + +### How should I organize my Centreon HA? + +Ideally, the two central nodes should be running on different geographical sites. The quorum device should communicate with both sites independently. All members of the cluster (active and passive nodes, quorum device) need to communicate with each other. + +To reduce the probability of an interruption of service occurring, it is not recommended to set up a Centreon HA cluster where all your servers are running in the same datacenter or (even more so) within the same rack. + +In the case of a highly available architecture the Centreon central servers must not monitor resources. If this recommendation is not followed, the centengine service will take too long to restart and it may cause the functional Centreon group to failover. + +Make sure to give your servers clear, relevant hostnames so that you know which is which. + +## Step 1: Prepare the elements of the cluster + +### Installation checklist + +#### Set up VIPs for the central servers and for the databases + +* Reserve an IP address in your network to act as a VIP so that pollers can always send data to the active central node. +* Reserve another VIP through which the central servers will access the replicated databases. + +#### Install and set up replication for the databases + +1. If you have a Centreon with already existing data, make a dump of the database first. +2. Install 2 blank Centreon databases [using our installation procedure for remote databases](../installation-of-a-central-server/using-packages.md#step-2-installation). +3. Set up replication for the databases using the official replication tools for MariaDB or MySQL. +4. Configure the databases so that they can communicate with their dedicated VIP. + +#### Install the central servers + +[Install the two central nodes using packages](../installation-of-a-central-server/using-packages.md) with the exact same version of Centreon on them ([update](../../update/update-centreon-platform.md) your version if needed). Use the procedure for an installation with remote databases, but skip all steps concerning the databases themselves as you already installed them. At [step 6 of the web installation procedure](../web-and-post-installation.md#step-6-database-information), make sure you enter the address of the VIP dedicated to your databases in the **Database Host Address** field. + +* Node 1 can be an existing Centreon that already monitors resources; however, node 2 should be a freshly installed Centreon. +* Both central servers should have an **admin** account with the same password. +* If you have an IT or Business edition, remember that license files for HA are specific. Please contact your Centreon sales representative to obtain your license files. + +#### Install the pollers + +Install the host machines and [install the pollers from packages](../installation-of-a-poller/using-packages.md) or [using the unattended script](../installation-of-a-poller/unattended.md). Do not register the poller to a central server yet. + +#### Choose a quorum device + +Choose which server in your infrastructure should act as a quorum device. This can be a poller. (The actual configuration will be done later: see [Preparing the server that will function as the quorum device](#preparing-the-server-that-will-function-as-the-quorum-device) and [Defining the quorum device](#defining-the-quorum-device).) + +### Configure centreon-broker on the central servers + +#### Change the link to the cbd service + +On a standard Centreon platform, there are two `cbd` services: + +* `central-broker-master`: also called "central broker" or "SQL broker", redirects input-output from pollers to the database, to RRD broker, and so on. +* `central-rrd-master`: also called "RRD broker", receives the stream from the central broker and updates the RRD binary data files (used to display graphs). + +In the context of a Centreon HA cluster, both broker processes will be handled by a separate service, managed by the cluster. + +* `central-broker-master` is replaced by `cbd_central_broker` (linked to *systemd* service `cbd-sql`) +* `central-rrd-master` is replaced by `cbd_rrd` (linked to *systemd* `cbd` service), the standard broker service for Centreon. + +On both central servers: + +1. Go to **Configuration > Pollers > Broker configuration**, then select **central-broker-master**. +2. On the **General** tab, in the **Main options** section, set **Link to cbd service** to **No**. + +This will result in the **Last Update** column of the **Configuration > Pollers > Pollers** page to become yellow, as Broker is temporarily stopped. An error will also appear in the **Pollers** section of the header bar: this is normal. Things will come back to normal at the end of the installation procedure (after you have defined all the resource groups, including sql_broker). + +#### Double the output stream toward RRD + +In the event of a cluster switch, you will expect the newly elected active central server to be able to display the metrics graphs, which requires all RRD data files to be up to date on both nodes. In order to fulfill this condition, you will double the central broker output stream and send it to both RRD broker processes. + +1. Go to **Configuration > Pollers > Broker configuration**, then select **central-broker-master**. +2. On the **Output** tab, select **Output 2 - IPv4**. The name of this output is **centreon-broker-master-rrd**. +3. In the **Host to connect to** field, replace **localhost** with the IP address of the active node (`@CENTRAL_ACTIVE_IPADDR@`). +4. Select **TCP - IPv4** from the dropdown list at the top of the page, then click **Add**. +5. Fill in the following details for this new output: + +| Output IPv4 | | +| ------------------ | ------------------------- | +| Name | centreon-broker-slave-rrd | +| Connection port | 5670 | +| Host to connect to | `@CENTRAL_PASSIVE_IPADDR@` | + +#### Export the configuration + +Once the above actions have been done ([Change the link to the cbd service](#change-the-link-to-the-cbd-service) and [Double the output stream toward RRD](#double-the-output-stream-toward-rrd)), export the configuration of the central server to apply these changes. The **Move Export Files** option must be checked. + +All the above actions should be applied either to both nodes or to `@CENTRAL_ACTIVE_NAME@` only, and the exported files should be copied to `@CENTRAL_PASSIVE_NAME@`: + +```bash +rsync -a /etc/centreon-broker/*json @CENTRAL_PASSIVE_IPADDR@:/etc/centreon-broker/ +``` + +Check that the files have been properly copied to node 2. If you just copied the json files from node 1 to node 2, for the moment, the changes do not appear in node 2's interface. + +### Customize the poller reload command + +In Centreon, the central broker daemon is reloaded every time you export your configuration. In the context of a HA setup, the central broker service is managed by the cluster and is called `cbd-sql`, [as described earlier](#change-the-link-to-the-cbd-service). This means that the service that needs to be reloaded when you export the configuration is `cbd-sql`, and no longer `cbd`: you need to configure this on central node 1. + +1. Go to **Configuration > Pollers > Pollers**, then click on the central server. +2. In section **Centreon Broker**, set the **Centreon Broker reload command** parameter to `service cbd-sql reload`. + +### Tune kernel network settings + +In order to improve the reliability of the cluster, and since Centreon HA only supports IPv4, we recommend applying the following kernel settings to all your Centreon servers (including pollers): + + + + +```bash +cat >> /etc/sysctl.conf < + + + +```bash +cat >> /etc/sysctl.conf < + + + +```bash +cat >> /etc/sysctl.conf < + + +### Allow for server name resolution + +So that the Centreon HA cluster can stay in operation in the event of a DNS service breakdown, all members of the cluster must know each other by name, using `/etc/hosts`. + +Run the following command on the two central nodes and on the quorum device: + +```bash +cat >/etc/hosts <<"EOF" +127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 +@CENTRAL_ACTIVE_IPADDR@ @CENTRAL_ACTIVE_NAME@ +@CENTRAL_PASSIVE_IPADDR@ @CENTRAL_PASSIVE_NAME@ +@QDEVICE_IPADDR@ @QDEVICE_NAME@ +EOF +``` + +### Install HA tools on the central servers + +Install the following packages on both central nodes. They provide all the files and dependencies required by a Centreon cluster. + + + + +```bash +dnf config-manager --enable ha +dnf install centreon-ha-web pcs pacemaker corosync corosync-qdevice +``` + + + + +> To install Pacemaker and Corosync packages on RedHat systems, servers must have access to the **Red Hat Enterprise Linux High Availability** licensed repository. + +```bash +dnf -y install dnf-plugins-core https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm +subscription-manager repos --enable rhel-8-for-x86_64-highavailability-rpms +dnf install centreon-ha-web pcs pacemaker corosync corosync-qdevice +``` + + + + +```bash +dnf config-manager --enable ol8_addons +dnf install centreon-ha-web pcs pacemaker corosync corosync-qdevice +``` + + + + +```bash +dnf config-manager --enable highavailability +dnf install centreon-ha-web pcs pacemaker corosync corosync-qdevice +``` + + + + +> To install Pacemaker and Corosync packages on RedHat systems, servers must have access to the **Red Hat Enterprise Linux High Availability** licensed repository. + +```bash +dnf -y install dnf-plugins-core https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm +subscription-manager repos --enable rhel-9-for-x86_64-highavailability-rpms +dnf install centreon-ha-web pcs pacemaker corosync corosync-qdevice +``` + + + + +```bash +dnf config-manager --enable ol9_addons +dnf install centreon-ha-web pcs pacemaker corosync corosync-qdevice +``` + + + + +```bash +apt update && apt install centreon-ha-web pcs pacemaker corosync corosync-qdevice +``` + + + + +### Configure SSH keys exchange + +SSH key-based authentication must be set up so that files and commands can be sent from one node to another by the **centreon** Unix account. + +There are two ways of exchanging such keys: + +* By using the `ssh-copy-id` command: needs to be able to log in to remote host using a password. It is however unsafe for such system accounts to have a password authentication available. If you choose this method, we advise you to revoke the password afterward with these commands: `passwd -d centreon` and `passwd -d mysql`. +* By manually copying the public key in `~/.ssh/authorized_keys`. This method is safer. + +The second method will be documented below. + +Switch to `centreon`'s bash environment on both nodes: + +```bash +su - centreon +``` + +Then run this command on both nodes: + +```bash +ssh-keygen -t ed25519 -a 100 +``` + +Display the contents of the key file in your terminal using this command: + +```bash +cat ~/.ssh/id_ed25519.pub +``` + +Once done, copy the content of the public key file displayed by `cat` and paste it to the `~/.ssh/authorized_keys` file (must be created) on the other node, and then apply the correct file permissions (still as user `centreon`): + +```bash +chmod 600 ~/.ssh/authorized_keys +``` + +The key exchange must be validated by an initial connection from each node to the other in order to accept and register the peer node's SSH fingerprint (still as user `centreon`): + +```bash +ssh +``` + +Exit the SSH session (`Ctrl D`), then exit the `centreon` session by typing `exit` or `Ctrl D`. + +### Open network flows + +In addition to the necessary flows described in the [official documentation](../architectures.md#Tables_of_network_flows), +you will need to open the following flows: + +| From | Destination | Protocol | Port | Application | +| :------------------------ | :------------------------ | :------- | :------- | :----------------------------------------------------------------------------------------- | +| Active Node | Passive Node | SSH | TCP 22 | Synchronization of configuration files (Must also be open from passive to active node) | +| Active Node | Passive Node | BDDO | TCP 5670 | RRDs synchronization (Must also be from passive to active node) | +| Active Node | Passive Node | MySQL | TCP 3306 | MySQL synchronization (Must also be open from passive to active node) | +| Central Servers + QDevice | Central Servers + QDevice | Corosync | UDP 5404 | Communication inside the cluster (Multicast) | +| Central Servers + QDevice | Central Servers + QDevice | Corosync | UDP 5405 | Communication inside the cluster (Unicast) | +| Central Servers + QDevice | Central Servers + QDevice | PCS | TCP 2224 | Communication inside the cluster | +| Central Servers + QDevice | Central Servers + QDevice | Corosync | TCP 5403 | Communication with the QDevice | + +## Step 2: Set up the Centreon cluster + +**Note**: unless otherwise stated, each of the following steps must be run **on both central nodes**. + +### Configure the file synchronization service + +Each central node must know the IP address of the other central node so that data can be synced between them. To be more specific, the `centreon-central-sync` file synchronization service needs the IP address of the peer node to be entered in its configuration file (`/etc/centreon-ha/centreon_central_sync.pm`). + +So, on the `@CENTRAL_ACTIVE_NAME@` server, the configuration file should look like this: + +```perl +our %centreon_central_sync_config = ( + peer_addr => "@CENTRAL_PASSIVE_IPADDR@" +); +1; +``` + +And on `@CENTRAL_PASSIVE_NAME@`: + +```perl +our %centreon_central_sync_config = ( + peer_addr => "@CENTRAL_ACTIVE_IPADDR@" +); +1; +``` + +### Remove legacy Centreon cron jobs + +In a high-availability setup, all cron-based scheduled tasks are managed by the gorgone daemon. This means that all Centreon-related crons on both central nodes are unnecessary and must be removed from the **/etc/cron.d/** directory, otherwise the metrics will be incorrect. Run the following commands: + +```bash +rm -f /etc/cron.d/centreon +rm -f /etc/cron.d/centstorage +rm -f /etc/cron.d/centreon-auto-disco +rm -f /etc/cron.d/centreon-ha-mysql +``` + +### Modify permissions on directories + +Modifications must be made to the permissions for the `/var/log/centreon-engine` and `/tmp/centreon-autodisco` directories. This is mandatory so that file sync and discovery scheduled tasks are fully functional. + +* Files synchronization + +```bash +chmod 775 /var/log/centreon-engine/ +mkdir /var/log/centreon-engine/archives +chown centreon-engine: /var/log/centreon-engine/archives +chmod 775 /var/log/centreon-engine/archives/ +find /var/log/centreon-engine/ -type f -exec chmod 664 {} \; +find /usr/share/centreon/www/img/media -type d -exec chmod 775 {} \; +find /usr/share/centreon/www/img/media -type f \( ! -iname ".keep" ! -iname ".htaccess" \) -exec chmod 664 {} \; +``` + +* Services discovery + + + + +```bash +mkdir /tmp/centreon-autodisco/ +chown apache: /tmp/centreon-autodisco/ +chmod 775 /tmp/centreon-autodisco/ +``` + + + + +```bash +mkdir /tmp/centreon-autodisco/ +chown apache: /tmp/centreon-autodisco/ +chmod 775 /tmp/centreon-autodisco/ +``` + + + + +```bash +mkdir /tmp/centreon-autodisco/ +chown www-data: /tmp/centreon-autodisco/ +chmod 775 /tmp/centreon-autodisco/ +``` + + + + +### Stop and disable services + +The central nodes must no longer launch services at boot time: this will be done by the clustering tools, and only them. Stop and disable the following services on each central node: + + + + +```bash +systemctl stop centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon mysql +systemctl disable centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon mysql +``` + + + + +```bash +systemctl stop centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon mariadb +systemctl disable centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon mariadb +``` + + + + +```bash +systemctl stop centengine snmptrapd centreontrapd gorgoned cbd apache2 php8.1-fpm centreon mariadb +systemctl disable centengine snmptrapd centreontrapd gorgoned cbd apache2 php8.1-fpm centreon mariadb +``` + + + + +At this point, you no longer have access to the central servers' interfaces (as you have stopped the corresponding service). The interfaces will be up again at the end of the installation procedure. + +### Activate the clustering services + +Start `pcsd` on both central nodes: + +```bash +systemctl start pcsd +``` + +### Prepare the server that will function as the quorum device + +You can use one of your pollers to play the role of quorum device. + +> **WARNING:** Make sure Selinux and Firewalld are disabled on this machine. + +Run the following commands to install all required packages on the quorum device: + + + + +```bash +dnf config-manager --enable ha +dnf install pcs corosync-qnetd +systemctl start pcsd.service +systemctl enable pcsd.service +pcs qdevice setup model net --enable --start +pcs qdevice status net --full +``` + + + + +```bash +dnf -y install dnf-plugins-core https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm +subscription-manager repos --enable rhel-8-for-x86_64-highavailability-rpms +dnf install pcs corosync-qnetd +systemctl start pcsd.service +systemctl enable pcsd.service +pcs qdevice setup model net --enable --start +pcs qdevice status net --full +``` + + + + +```bash +dnf config-manager --enable ol8_addons +dnf install pcs corosync-qnetd +systemctl start pcsd.service +systemctl enable pcsd.service +pcs qdevice setup model net --enable --start +pcs qdevice status net --full +``` + + + + +```bash +dnf config-manager --enable ha +dnf install pcs corosync-qnetd +systemctl start pcsd.service +systemctl enable pcsd.service +pcs qdevice setup model net --enable --start +pcs qdevice status net --full +``` + + + + +```bash +dnf -y install dnf-plugins-core https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm +subscription-manager repos --enable rhel-9-for-x86_64-highavailability-rpms +dnf install pcs corosync-qnetd +systemctl start pcsd.service +systemctl enable pcsd.service +pcs qdevice setup model net --enable --start +pcs qdevice status net --full +``` + + + + +```bash +dnf config-manager --enable ol9_addons +dnf install pcs corosync-qnetd +systemctl start pcsd.service +systemctl enable pcsd.service +pcs qdevice setup model net --enable --start +pcs qdevice status net --full +``` + + + + +```bash +apt install pcs corosync-qnetd +systemctl start pcsd.service +systemctl enable pcsd.service +pcs qdevice setup model net --enable --start +pcs qdevice status net --full +``` + + + + +RETOUR de qdevice status + +```shell +[root@ip-172-16-5-171 ~]# pcs qdevice status net --full +QNetd address: *:5403 +TLS: Supported (client certificate required) +Connected clients: 0 +Connected clusters: 0 +Maximum send/receive size: 32768/32768 bytes +``` + + + + + +Modify the parameter `COROSYNC_QNETD_OPTIONS` in the file `/etc/sysconfig/corosync-qnetd` to make sure the service will be listening to the connections on Ipv4 only. + +```bash +COROSYNC_QNETD_OPTIONS="-4" +``` + + + + + +```bash +COROSYNC_QNETD_OPTIONS="-4" +``` + + + + +Modify the parameter `COROSYNC_QNETD_OPTIONS` in the file `/etc/default/corosync-qnetd` to make sure the service will be listening to the connections on Ipv4 only. + +```bash +COROSYNC_QNETD_OPTIONS="-4" +``` + + + + +### Authenticate the hacluster user to the cluster's members + +A user called **hacluster** has been automatically created when you installed Pacemaker and Corosync. This user will run the Corosync and Pacemaker processes on all 3 members of the cluster. +For the sake of simplicity, the **hacluster** user will be assigned the same password on both central nodes and on the quorum device. Run the following command on each machine and set the password you want. + +```bash +passwd hacluster +``` + +Now that all members of the cluster (both central nodes and the quorum device server) share the same password, run this command **only on one of the central nodes** in order to authenticate the **hacluster** user to all members of the cluster. + + + + +```bash +pcs host auth \ + "@CENTRAL_ACTIVE_NAME@" \ + "@CENTRAL_PASSIVE_NAME@" \ + "@QDEVICE_NAME@" \ + -u "hacluster" \ + -p '@CENTREON_CLUSTER_PASSWD@' +``` + + + + +```bash +pcs host auth \ + "@CENTRAL_ACTIVE_NAME@" \ + "@CENTRAL_PASSIVE_NAME@" \ + "@QDEVICE_NAME@" \ + -u "hacluster" \ + -p '@CENTREON_CLUSTER_PASSWD@' +``` + + + + +On Debian, the cluster is autoconfigured with default values. In order to install our cluster, we need to remove the default values using the following command: + +```bash +pcs cluster destroy +``` + +Then you can start the authentication of the cluster: + +```bash +pcs host auth \ + "@CENTRAL_ACTIVE_NAME@" \ + "@CENTRAL_PASSIVE_NAME@" \ + "@QDEVICE_NAME@" \ + -u "hacluster" \ + -p '@CENTREON_CLUSTER_PASSWD@' +``` + + + + +If the authentication has succeeded on all nodes, you will get a message similar to this: + +```shell +@CENTRAL_PASSIVE_NAME@: Authorized +@CENTRAL_PASSIVE_NAME@: Authorized +@QDEVICE_NAME@: Authorized +``` + +### Create the cluster + +The following command creates the cluster. Run it **only on one of the central nodes**. + + + + +```bash +pcs cluster setup \ + centreon_cluster \ + "@CENTRAL_ACTIVE_NAME@" \ + "@CENTRAL_PASSIVE_NAME@" \ + --force +``` + + + + +```bash +pcs cluster setup \ + centreon_cluster \ + "@CENTRAL_ACTIVE_NAME@" \ + "@CENTRAL_PASSIVE_NAME@" \ + --force +``` + + + + +```bash +pcs cluster setup \ + centreon_cluster \ + "@CENTRAL_ACTIVE_NAME@" \ + "@CENTRAL_PASSIVE_NAME@" \ + --force +``` + + + + +You should get the following message: + +```shell +[root@ip-@CENTRAL_ACTIVE_IPADDR@ ~]# pcs cluster setup centreon_cluster "@CENTRAL_ACTIVE_IPADDR@" "@CENTRAL_PASSIVE_IPADDR@" --force +No addresses specified for host '@CENTRAL_ACTIVE_IPADDR@', using '@CENTRAL_ACTIVE_IPADDR@' +No addresses specified for host '@CENTRAL_PASSIVE_IPADDR@', using '@CENTRAL_PASSIVE_IPADDR@' +Destroying cluster on hosts: '@CENTRAL_ACTIVE_IPADDR@', '@CENTRAL_PASSIVE_IPADDR@'... +@CENTRAL_ACTIVE_IPADDR@: Successfully destroyed cluster +@CENTRAL_PASSIVE_IPADDR@: Successfully destroyed cluster +Requesting remove 'pcsd settings' from '@CENTRAL_ACTIVE_IPADDR@', '@CENTRAL_PASSIVE_IPADDR@' +@CENTRAL_ACTIVE_IPADDR@: successful removal of the file 'pcsd settings' +@CENTRAL_PASSIVE_IPADDR@: successful removal of the file 'pcsd settings' +Sending 'corosync authkey', 'pacemaker authkey' to '@CENTRAL_ACTIVE_IPADDR@', '@CENTRAL_PASSIVE_IPADDR@' +@CENTRAL_ACTIVE_IPADDR@: successful distribution of the file 'corosync authkey' +@CENTRAL_ACTIVE_IPADDR@: successful distribution of the file 'pacemaker authkey' +@CENTRAL_PASSIVE_IPADDR@: successful distribution of the file 'corosync authkey' +@CENTRAL_PASSIVE_IPADDR@: successful distribution of the file 'pacemaker authkey' +Sending 'corosync.conf' to '@CENTRAL_ACTIVE_IPADDR@', '@CENTRAL_PASSIVE_IPADDR@' +@CENTRAL_ACTIVE_IPADDR@: successful distribution of the file 'corosync.conf' +@CENTRAL_PASSIVE_IPADDR@: successful distribution of the file 'corosync.conf' +Cluster has been successfully set up. +``` + +Then start the `pacemaker` service **on both central nodes**: + +```bash +systemctl enable pacemaker pcsd corosync +systemctl start pacemaker +``` + +And afterward define these properties **only on one node**: + +```bash +pcs property set symmetric-cluster="true" +pcs property set stonith-enabled="false" +pcs resource defaults update resource-stickiness="100" +``` + +You can now monitor the state of the cluster with the `crm_mon -f` command: it will display [the new cluster resources as you create them](#create-the-centreon-resource-group). + +At this stage, no resources have been added to the cluster, so the resultst of the command run from node 1 should look like this: + +```shell +Cluster Summary: + * Stack: corosync (Pacemaker is running) + * Current DC: @CENTRAL_ACTIVE_IPADDR@ (version 2.1.6-9.1.el8 +_9-6fdc9deea29) - partition with quorum + * Last updated: Fri Mar 29 10:47:22 2024 on @CENTRAL_ACTIVE_IPADDR@ + * Last change: Thu Mar 28 16:38:56 2024 by root via cibadmin on @CENTRAL_ACTIVE_IPADDR@ + * 2 nodes configured + * 0 resource instances configured + +Node List: + * Online: [ @CENTRAL_ACTIVE_IPADDR@ @CENTRAL_PASSIVE_IPADDR@ ] + +Active Resources: + * No active resources + +Migration Summary: +``` + +### Define the quorum device + +To let the central nodes know which server is the quorum device, run this command on one of the central nodes: + +```bash +pcs quorum device add model net \ + host="@QDEVICE_NAME@" \ + algorithm="ffsplit" +``` + +The results should look like this: + +```shell +Setting up qdevice certificates on nodes... +@CENTRAL_ACTIVE_IPADDR@: Succeeded +@CENTRAL_PASSIVE_IPADDR@: Succeeded +Enabling corosync-qdevice... +@CENTRAL_ACTIVE_IPADDR@: corosync-qdevice enabled +@CENTRAL_PASSIVE_IPADDR@: corosync-qdevice enabled +Sending updated corosync.conf to nodes... +@CENTRAL_PASSIVE_IPADDR@: Succeeded +@CENTRAL_ACTIVE_IPADDR@: Succeeded +@CENTRAL_ACTIVE_IPADDR@: Corosync configuration reloaded +Starting corosync-qdevice... +@CENTRAL_ACTIVE_IPADDR@: corosync-qdevice started +@CENTRAL_PASSIVE_IPADDR@: corosync-qdevice started +``` + +### Define the clone resources + +RRD broker and PHP8 will run on both central nodes at the same time. For this to work properly, they must be declared as clone resources. + +> **Warning:** All the commands in this section should be run only once on the central node of your choice. + +##### PHP8 resource + + + + +```bash +pcs resource create "php" \ + systemd:php-fpm \ + meta target-role="started" \ + op start interval="0s" timeout="30s" \ + stop interval="0s" timeout="30s" \ + monitor interval="5s" timeout="30s" \ + clone +``` + + + + +```bash +pcs resource create "php" \ + systemd:php-fpm \ + meta target-role="started" \ + op start interval="0s" timeout="30s" \ + stop interval="0s" timeout="30s" \ + monitor interval="5s" timeout="30s" \ + clone +``` + + + + +```bash +pcs resource create "php" \ + systemd:php8.1-fpm \ + meta target-role="started" \ + op start interval="0s" timeout="30s" \ + stop interval="0s" timeout="30s" \ + monitor interval="5s" timeout="30s" \ + clone +``` + + + + +##### RRD broker resource + +```bash +pcs resource create "cbd_rrd" \ + systemd:cbd \ + meta target-role="started" \ + op start interval="0s" timeout="90s" \ + stop interval="0s" timeout="90s" \ + monitor interval="20s" timeout="30s" \ + clone +``` + +### Create the centreon resource group + +The **centreon** [resource group](overview.md#what-processes-are-synchronized-by-centreon-ha) is the list of processes that Pacemaker will have to manage. These processes will not be managed by the central nodes themselves (most of them have been [disabled](#stop-and-disable-services) on the central servers). + +#### Define the VIP address + +Run the following command on the active node to let it know the address of the VIP. + +```bash +pcs resource create vip \ + ocf:heartbeat:IPaddr2 \ + ip="@VIP_IPADDR@" \ + nic="@VIP_IFNAME@" \ + cidr_netmask="@VIP_CIDR_NETMASK@" \ + broadcast="@VIP_BROADCAST_IPADDR@" \ + flush_routes="true" \ + meta target-role="started" \ + op start interval="0s" timeout="20s" \ + stop interval="0s" timeout="20s" \ + monitor interval="10s" timeout="20s" \ + --group centreon +``` + +From now on, when you connect using SSH to the active node, your terminal will show the IP address of the VIP. + +#### httpd service + +This will enable the web server. + + + + +```bash +pcs resource create http \ + systemd:httpd \ + meta target-role="started" \ + op start interval="0s" timeout="40s" \ + stop interval="0s" timeout="40s" \ + monitor interval="5s" timeout="20s" \ + --group centreon \ + --force +``` + + + + +```bash +pcs resource create http \ + systemd:httpd \ + meta target-role="started" \ + op start interval="0s" timeout="40s" \ + stop interval="0s" timeout="40s" \ + monitor interval="5s" timeout="20s" \ + --group centreon \ + --force +``` + + + + +```bash +pcs resource create http \ + systemd:apache2 \ + meta target-role="started" \ + op start interval="0s" timeout="40s" \ + stop interval="0s" timeout="40s" \ + monitor interval="5s" timeout="20s" \ + --group centreon \ + --force +``` + + + + +#### Gorgone service + +```bash +pcs resource create gorgone \ + systemd:gorgoned \ + meta target-role="started" \ + op start interval="0s" timeout="90s" \ + stop interval="0s" timeout="90s" \ + monitor interval="5s" timeout="20s" \ + --group centreon +``` + +#### centreon-central-sync service + +This service only exists in the context of Centreon HA. It provides real-time synchronization for configuration files, images, etc. + +```bash +pcs resource create centreon_central_sync \ + systemd:centreon-central-sync \ + meta target-role="started" \ + op start interval="0s" timeout="90s" \ + stop interval="0s" timeout="90s" \ + monitor interval="5s" timeout="20s" \ + --group centreon +``` + +#### SQL Broker + +```bash +pcs resource create cbd_central_broker \ + systemd:cbd-sql \ + meta target-role="started" \ + op start interval="0s" timeout="90s" \ + stop interval="0s" timeout="90s" \ + monitor interval="5s" timeout="30s" \ + --group centreon +``` + +#### Centengine service + +```bash +pcs resource create centengine \ + systemd:centengine \ + meta multiple-active="stop_start" target-role="started" \ + op start interval="0s" timeout="90s" stop interval="0s" timeout="90s" \ + monitor interval="5s" timeout="30s" \ + --group centreon +``` + +#### Centreontrapd service + +```bash +pcs resource create centreontrapd \ + systemd:centreontrapd \ + meta target-role="started" \ + op start interval="0s" timeout="30s" \ + stop interval="0s" timeout="30s" \ + monitor interval="5s" timeout="20s" \ + --group centreon +``` + +#### Snmptrapd service + +```bash +pcs resource create snmptrapd \ + systemd:snmptrapd \ + meta target-role="started" \ + op start interval="0s" timeout="30s" \ + stop interval="0s" timeout="30s" \ + monitor interval="5s" timeout="20s" \ + --group centreon +``` + +### Activate the resources + +```bash +pcs resource enable php-clone +pcs resource enable cbd_rrd-clone +pcs resource meta vip target-role="started" +pcs resource meta centreontrapd target-role="started" +pcs resource meta snmptrapd target-role="started" +pcs resource meta centengine target-role="started" +pcs resource meta cbd_central_broker target-role="started" +pcs resource meta gorgone target-role="started" +pcs resource meta centreon_central_sync target-role="started" +pcs resource meta http target-role="started" +``` + +At this stage, you can connect to the interface of the active node using the VIP's address. [avec la base déportée j'ai plus rien parce que mon utilisateur autorisé pointait vers l'adresse directe de la base et pas vers une vip] + +étape proxy de l'interface +qu'est-ce qui me dit dans la ui où est la base? In Configuration > Pollers > Broker configuration, Open “central-broker-master” and in the “Output” tab, you have to change the “DB host” -> ça m'avait mis la base 2 au lieu de la base 1 + +### Check the state of the cluster + +#### Check the state of the resources + +You can monitor the cluster's resources in real time using the `crm_mon -f` command. Here is an exmaple of output: + +```bash +Cluster Summary: + * Stack: corosync + * Current DC: @CENTRAL_ACTIVE_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum + * Last updated: Wed Sep 15 16:35:47 2021 + * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @CENTRAL_ACTIVE_NAME@ + * 2 nodes configured + * 12 resource instances configured +Node List: + * Online: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] +Full List of Resources: + * Clone Set: php-clone [php]: + * Started: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] + * Clone Set: cbd_rrd-clone [cbd_rrd]: + * Started: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] + * Resource Group: centreon: + * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_ACTIVE_NAME@ + * http (systemd:httpd): Started @CENTRAL_ACTIVE_NAME@ + * gorgone (systemd:gorgoned): Started @CENTRAL_ACTIVE_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_ACTIVE_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_ACTIVE_NAME@ + * centengine (systemd:centengine): Started @CENTRAL_ACTIVE_NAME@ + * centreontrapd (systemd:centreontrapd): Started @CENTRAL_ACTIVE_NAME@ + * snmptrapd (systemd:snmptrapd): Started @CENTRAL_ACTIVE_NAME@ +``` + +If **centreon_central_sync** won't start, check if the folder `/usr/share/centreon-broker/lua` exists. + +If not, you can create it with this command: `mkdir -p /usr/share/centreon-broker/lua`. And launch a cleanup with this command: `pcs resource cleanup`. + +#### Disabled resources + +When you do a `crm_mon -fr` and you have a resource that is disabled: + +```text +... + Master/Slave Set: ms_mysql-master [ms_mysql] + Masters: [ @DATABASE_MASTER_NAME@ ] + Slaves: [ @DATABASE_SLAVE_NAME@ ] + Stopped: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] +ms_mysql (ocf::heartbeat:IPaddr2): Stopped (disabled) +... +``` + +You must enable the resource with the following command: + +```bash +pcs resource enable @RESSOURCE_NAME@ +``` + +In our case: + +```bash +pcs resource enable ms_mysql +``` + +## Step 3: Integrate your pollers + +1. If you haven't already done so, apply the necessary [kernel network tuning](#kernel-network-tuning) to the host machines for your pollers. +2. [Install your pollers](../installation-of-a-poller/using-packages.md) and register them using the VIP as the address of the central server. The password is that of the admin account for node 1? - Then run the wizard to [attach the poller](../../monitoring/monitoring-servers/add-a-poller-to-configuration.md) to the VIP. +3. [Add your pollers](./integrating-pollers.md) to the platform's HA architecture. + +You can now start your monitoring. + +## Step 4: Monitor your cluster + +See [Monitoring Centreon HA](../../administration/centreon-ha/monitoring-guide.md). diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/integrating-pollers.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/integrating-pollers.md index 2e45eda850f7..b5116efec711 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/integrating-pollers.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/integrating-pollers.md @@ -3,14 +3,17 @@ id: integrating-pollers title: Integrating new pollers in a Centreon-HA cluster --- -## Obtaining central nodes' thumbprints +## Obtaining the central nodes' thumbprints -The Gorgone services of both central nodes will need to be authorized by the pollers' Gorgone services. +The Gorgone services of both central nodes will need to be authorized by the pollers' Gorgone services. * First, obtain each central node's key: ```bash wget -O /root/gorgone_key_thumbprint.pl https://raw.githubusercontent.com/centreon/centreon-gorgone/master/contrib/gorgone_key_thumbprint.pl +``` + +``` perl /root/gorgone_key_thumbprint.pl --key-path /var/lib/centreon-gorgone/.keys/rsakey.priv.pem ``` @@ -20,11 +23,11 @@ The command output should look like this: 2020-09-25 10:47:35 - INFO - File '/var/lib/centreon-gorgone/.keys/rsakey.priv.pem' JWK thumbprint: RsfNibuDdOvzwP75G72rpIKIG2nRhkyGQrQXE4pXa_s ``` -* You must have two keys; one for each central node. Copy the last part of the printed lines (what is displayed after `JWK thumbprint:`) and keep it for later. +* You must have two keys; one for each central node. Copy the last part of the printed lines (what is displayed after `JWK thumbprint:`) and keep it for [later](#configuring-gorgone-on-the-poller). ## Adding the Poller to the configuration -* Add your poller to the configuration "the standard way" [following these steps with ZeroMQ protocol](../../monitoring/monitoring-servers/add-a-poller-to-configuration.md) +* Add your poller to the configuration "the standard way" [following these steps with the ZeroMQ protocol](../../monitoring/monitoring-servers/add-a-poller-to-configuration.md). Make sure you declare the VIP as the address of the central server the poller will be attached to. * You should now have overwritten the `/etc/centreon-gorgone/config.d/40-gorgoned.yaml` file, and it should contain lines like these: @@ -49,4 +52,4 @@ The command output should look like this: systemctl restart gorgoned ``` -At this point, any of your central nodes should be allowed to connect to your poller's Gorgone service and send configurations, retrieve statistics, restart services, etc. +At this point, both your central nodes should be allowed to connect to your poller's Gorgone service and send configurations, retrieve statistics, restart services, etc. diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md index a462eeb0dd02..87f9de18fd86 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md @@ -1,75 +1,81 @@ --- id: overview -title: Centreon HA +title: How Centreon HA works --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -## Introduction +## What are the elements of Centreon HA? -Centreon-HA is the only official and supported solution to set up a highly available monitoring cluster. It -includes the following: -* Documentation, mainly to describe how to set up your Cluster on top of your Centreon solution. -* Script collection enabling safe and efficient management of Centreon-related resources. -* Additional files that extend the default Centreon capabilities. +Centreon HA consists of a set of clustering tools on top of twin Centreon central servers that manage pollers (in a [distributed architecture](../../installation/architectures.md#distributed-architecture)). -Its architecture relies on the [ClusterLabs](https://clusterlabs.org/) components pacemaker and corosync, -allowing fault tolerance on the following components: +* Members of the Centreon HA cluster: -* Central Server applicative daemons - * centreon-engine (scheduler) - * centreon-broker (multiplexer) - * centreon-gorgone (task manager) - * centreon-central-sync (config file replication) - * snmptrapd and centreontrapd (system and applicative trap management processes) -* Central Server third-party daemons - * php-fpm (FastCGI PHP cache) - * apache server (webserver) -* Databases - * Active/Passive binlog replication (storage) -* Host failures - * Virtual machines or Physical servers + * 2 Centreon central servers: 1 active node, 1 passive node. Thanks to synchronization scripts, the same data will exist on both servers so that if the active node goes down, the passive node will take its place. The central servers do not monitor your resources (the pollers do). In this documentation, we may call the central servers "node 1" and "node 2" to differentiate them: bear in mind that both of them can have the role of active or passive node. + * 1 server called "quorum device", whose sole purpose is to decide which central server is the active node and which is the passive node. This is mandatory to avoid split-brain issues. You can define one of your pollers as the quorum device. + +* Clustering tools: + - Centreon high availability scripts, contained in the **centreon-ha-web** package. They include the **centreon_central_sync** service, that synchronizes all the necessary processes ("resources"). + - Corosync: allows the members of the cluster to communicate in real time, to check if the active node is up, and take the decision to failover if needed. + - Pacemaker: starts, stops and controls the state of Centreon processes. You need to tell Pacemaker which processes should be checked: these processes are called "resources". + - crm_mon: a command-line tool that allows you to know the state of the cluster in real time. + - pcs: a command-line tool that allows you to configure Corosync and Pacemaker. -> **Warning:** If you have an IT or Business subscription, please get in touch with your Centreon Sales -representative or Technical Account Manager before implementing this. Extensions need specific license -files to work on both nodes smoothly. +* Pollers, which do the actual monitoring. -## Concepts +* A VIP, to which the pollers send the data, so that the VIP can forward the data to the current active node. -The solution implements three different kinds of resources: +* Remote databases. Setting up redundancy for the database is [the responsibility of the customer](faq.md#what-is-supported-and-what-isnt). The [installation procedure](installation.md) describes the case where you already have a database cluster set up. The Centreon cluster and the database cluster are independent. The Centreon cluster communicates with the database cluster through a dedicated VIP. -* _Multi-state_ resource running on both nodes with different roles. -* _Clone_ resources, running on both primary and secondary nodes. -* _Unique_ resources, part of a _group_, and running on only one node. +![image](../../assets/integrations/centreon-ha/centreon-ha-2-nodes-arch.png) -The cluster services are divided into two functional groups. +## How does the HA cluster work? -### MariaDB functional group +In an HA cluster, all processes ("resources") are managed by the clustering tools (Pacemaker and Corosync). -The `ms_mysql` functional group is a _multi-state_ resource. This resource can be in active/primary mode -on one node and in secondary/passive mode on another node. +1. Everything is OK : Node 1 (the current active node) receives data from the pollers, and all relevant files are synchronized by a dedicated script (**centreon_central_sync**) onto node 2 (the current passive node) so that the passive node is ready to become the active node at all times. +2. An incident occurs and node 1 (the active node) goes down. + - Corosync detects that it is down: after consulting with the quorum device, it tells node 2 to become the active node. + - An operator is notified that node 1 is down, thanks to the Centreon monitoring that has been set up on the poller. +3. Node 2 is now the active node. It receives data from the pollers. During this time, the operator tries to understand why node 1 is down. They must fix the problem using the cluster management tool pcs, not by manipulating node 1 directly. +4. Node 1 is fixed and comes back online. The **centreon_central_sync** script synchronizes all relevant files from node 2 to node 1, so that node 1 can catch up on what has happened during its down time. Node 1 is ready to become the active node if node 2 goes down. -The `ms_mysql-master` meta-resource is assigned to the primary database. +## How do I know the state of the cluster? -### Centreon functional group +The installation procedure includes a step where you set up the monitoring of the members of the cluster by a poller. This way, you can be notified if a member of the cluster goes down. -The `centreon` functional group gathers all Centreon resources to manage them. +You access the interface of the active node via the IP address of the VIP. This means that you always use the same URL to access the interface, whether the interface is that of node 1 or of node 2. -### Resources type description +You can also [know the state of the cluster at all times](../../administration/centreon-ha/operating-guide.md#display-the-status-of-the-cluster) by using the `crm_mon` command, or the `pcs status`command. + +## What processes are synchronized by Centreon HA? + +Here is the list of processes (resources) that will be managed by the HA tools: + +* Central server applicative daemons + * centreon-engine (scheduler) + * centreon-broker (multiplexer) + * centreon-gorgone (task manager) + * all configuration files (replicated using the centreon-central-sync process) + * snmptrapd and centreontrapd (system and applicative trap management processes) +* Central Server third-party daemons + * php-fpm + * Apache server (webserver) All these resources are described in the table below. +* Clone resources run on both active and passive nodes. +* Unique resources (primitive services), part of the `centreon` functional group, run on only one node. + | Name | Type | Description | | ----------------------- | -------------------- | ---------------------------------------------------- | -| `ms_mysql` | multi-state resource | Handles the `mysql` process and data replication | -| `ms_mysql-master` | location | Set MariaDB Master server rule preference | | `php8` | clone service | FastCGI Process Manager service (`php-fpm`) | | `cbd_rrd` | clone service | Broker RRD service (`cbd`) | | `centreon` | group | Centreon "primitive services" group | | `vip` | primitive service | VIP address for centreon | | `http` | primitive service | Apache service (`httpd24-httpd`) | | `gorgone` | primitive service | Gorgone service (`gorgoned`) | -| `centreon_central_sync` | primitive service | File synchronization service | +| `centreon_central_sync` | primitive service | File synchronization service | | `cbd_central_broker` | primitive service | Central Broker service (`cbd-sql`) | | `centengine` | primitive service | Centreon-Engine service (`centengine`) | | `centreontrapd` | primitive service | SNMP Traps management service (`centreontrapd`) | @@ -77,99 +83,6 @@ All these resources are described in the table below. **Note:** The resources of the `centreon` group are started one after the other in the list order. -### Resource constraints - -Pacemaker offers various types of constraints: -* Location: where the resource should or shouldn't run. -* Colocation: how resources behave to each other. - -For example, Centreon-HA uses location constraints to specify to Pacemaker that the database process -needs to be up on backend nodes but not on frontend nodes. - -Regarding colocation constraints, they can ensure a Virtual IP sticks to the master nodes and/or role. -Therefore Users, Pollers, and Daemons constantly interact with the primary node. - -### QDevice and votes - -The configuration of a qdevice is **mandatory** to avoid split-brain and other situations nobody wants -to face in a Cluster. The server with the `quorum-device` role aims to obtain an absolute majority in a vote -to elect a master node or resource role. - -## Support - -### Software & operating systems - -Centreon officially supports clustering on the following products: - -* Any Centreon Licensed Editions -* Centreon Map Server - -And on the following Operating Systems: - -* Alma / RHEL / Oracle Linux 8 -* Debian 11 - -*Important:* To install pacemaker and corosync packages on RedHat systems, servers must have access to -the _Red Hat Enterprise Linux High Availability_ licensed repository. - -The only official database server Centreon supports is MariaDB. - -Nevertheless, note that we validated that the whole solution can run on MySQL 8 *with some -modifications*; only the [community](https://github.com/centreon-ha/issues) (or your DBAs) -can help and support you in running a cluster on top of an Oracle MySQL server. - -For both MariaDB and Oracle MySQL, the replication configuration might be intrusive. We *strongly discourage you* from setting -up a cluster on a server holding other application databases, and we won't support it. - -### Architectures - -Centreon supports both two- and four-node architectures. We recommend using a two-node architecture, unless -your organization requires a systematic split of front and back servers or your monitoring -scope is above 5k Hosts. - -The schemas below show both the architecture flavor and network flows between servers. To get the complete network -flow matrix, refer to the architecture dedicated installation page. - - - - -![image](../../assets/integrations/centreon-ha/centreon-ha-2-nodes-arch.png) - -Go to [this page](../../installation/installation-of-centreon-ha/installation-2-nodes.md) to start your two-node setup! - - - - -![image](../../assets/integrations/centreon-ha/centreon-ha-4-nodes-arch.png) - -Go to [this page](../../installation/installation-of-centreon-ha/installation-4-nodes.md) to start your four-node setup! - - - - -## Additional information - -### Server organization - -Setting up a Centreon-HA cluster might be overkill, or at least not optimal, when all your servers are running in -the same datacenter or (even more so) within the same rack. - -In a perfect world, the primary and secondary nodes would be running on different (geographical) sites, and the qdevice -would communicate with both sites independently. Obviously, all nodes need to communicate with each other. - -### Role of the Centreon central server - -In the case of a highly available architecture the **Centreon central cluster must not be used as a poller**. -In other words, it should not monitor resources. Its monitoring ability should only be used to monitor its pollers. -If this recommendation is not followed, the `centengine` service will take too long to restart -and **it may cause the functional `centreon` group to failover**. - -### VIP and load balancing - -Centreon recommends using VIP addresses. - -Using a load balancer is an option, but it should support custom rules to route application flows. +## Active/passive nodes or master/slave nodes? -For example, in a four-node setup, a load balancer can rely on: -* frontend-vip: the listening port or the apache process state to route Users and Pollers' communication toward frontend servers. -* backend-vip: the value of the "read_only" flag on both database servers to determine which is the primary one. \ No newline at end of file +In this chapter, we will refer to active/passive nodes. You may notice that the output of some commands use the terms master and slave: these are Pacemaker and Corosync terms. Master means the active node and slave the passive node. diff --git a/versioned_sidebars/version-24.04-sidebars.json b/versioned_sidebars/version-24.04-sidebars.json index 690540203aec..bde8f4dd2b5b 100644 --- a/versioned_sidebars/version-24.04-sidebars.json +++ b/versioned_sidebars/version-24.04-sidebars.json @@ -1461,10 +1461,17 @@ "type": "category", "label": "Centreon HA", "link": { - "type": "doc", - "id": "version-24.04/installation/installation-of-centreon-ha/overview" + "type": "generated-index" }, "items": [ + { + "type": "doc", + "id": "version-24.04/installation/installation-of-centreon-ha/ha-faq" + }, + { + "type": "doc", + "id": "version-24.04/installation/installation-of-centreon-ha/overview" + }, { "type": "category", "label": "Installing Centreon HA", @@ -1474,15 +1481,15 @@ "items": [ { "type": "doc", - "id": "version-24.04/installation/installation-of-centreon-ha/installation-2-nodes" + "id": "version-24.04/installation/installation-of-centreon-ha/installation" }, { "type": "doc", - "id": "version-24.04/installation/installation-of-centreon-ha/installation-4-nodes" + "id": "version-24.04/installation/installation-of-centreon-ha/integrating-pollers" }, { "type": "doc", - "id": "version-24.04/installation/installation-of-centreon-ha/integrating-pollers" + "id": "version-24.04/administration/centreon-ha/monitoring-guide" } ] }, @@ -1497,10 +1504,6 @@ "type": "doc", "id": "version-24.04/administration/centreon-ha/acceptance-guide" }, - { - "type": "doc", - "id": "version-24.04/administration/centreon-ha/monitoring-guide" - }, { "type": "doc", "id": "version-24.04/administration/centreon-ha/operating-guide" From 3dbc0502fedac5b06773423542130cac669ac90c Mon Sep 17 00:00:00 2001 From: cgenier Date: Fri, 19 Apr 2024 11:11:55 +0200 Subject: [PATCH 02/41] Workaround for bugged link --- .../installation/installation-of-centreon-ha/installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index 850c6339f95b..7e43da9c9b6e 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -60,13 +60,13 @@ Make sure to give your servers clear, relevant hostnames so that you know which #### Install and set up replication for the databases 1. If you have a Centreon with already existing data, make a dump of the database first. -2. Install 2 blank Centreon databases [using our installation procedure for remote databases](../installation-of-a-central-server/using-packages.md#step-2-installation). +2. Install 2 blank Centreon databases [using our installation procedure for remote databases](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages/#step-2-installation). 3. Set up replication for the databases using the official replication tools for MariaDB or MySQL. 4. Configure the databases so that they can communicate with their dedicated VIP. #### Install the central servers -[Install the two central nodes using packages](../installation-of-a-central-server/using-packages.md) with the exact same version of Centreon on them ([update](../../update/update-centreon-platform.md) your version if needed). Use the procedure for an installation with remote databases, but skip all steps concerning the databases themselves as you already installed them. At [step 6 of the web installation procedure](../web-and-post-installation.md#step-6-database-information), make sure you enter the address of the VIP dedicated to your databases in the **Database Host Address** field. +[Install the two central nodes using packages](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages) with the exact same version of Centreon on them ([update](../../update/update-centreon-platform.md) your version if needed). Use the procedure for an installation with remote databases, but skip all steps concerning the databases themselves as you already installed them. At [step 6 of the web installation procedure](../web-and-post-installation.md#step-6-database-information), make sure you enter the address of the VIP dedicated to your databases in the **Database Host Address** field. * Node 1 can be an existing Centreon that already monitors resources; however, node 2 should be a freshly installed Centreon. * Both central servers should have an **admin** account with the same password. From 91935cdd8553c47fa75b1f757bf5b73de270a0f1 Mon Sep 17 00:00:00 2001 From: cgenier Date: Fri, 19 Apr 2024 11:57:39 +0200 Subject: [PATCH 03/41] Workaround for link bug --- .../installation/installation-of-centreon-ha/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index 7e43da9c9b6e..f4184dfd4e0d 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -66,7 +66,7 @@ Make sure to give your servers clear, relevant hostnames so that you know which #### Install the central servers -[Install the two central nodes using packages](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages) with the exact same version of Centreon on them ([update](../../update/update-centreon-platform.md) your version if needed). Use the procedure for an installation with remote databases, but skip all steps concerning the databases themselves as you already installed them. At [step 6 of the web installation procedure](../web-and-post-installation.md#step-6-database-information), make sure you enter the address of the VIP dedicated to your databases in the **Database Host Address** field. +[Install the two central nodes using packages](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages) with the exact same version of Centreon on them ([update](https://docs.centreon.com/docs/update/update-centreon-platform) your version if needed). Use the procedure for an installation with remote databases, but skip all steps concerning the databases themselves as you already installed them. At [step 6 of the web installation procedure](../web-and-post-installation.md#step-6-database-information), make sure you enter the address of the VIP dedicated to your databases in the **Database Host Address** field. * Node 1 can be an existing Centreon that already monitors resources; however, node 2 should be a freshly installed Centreon. * Both central servers should have an **admin** account with the same password. From 285d900a8176ffd88a050e22e3ba24176a9c6506 Mon Sep 17 00:00:00 2001 From: cgenier Date: Fri, 19 Apr 2024 14:26:31 +0200 Subject: [PATCH 04/41] Workaround for link bug --- .../installation/installation-of-centreon-ha/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index f4184dfd4e0d..f6adafc60faf 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -66,7 +66,7 @@ Make sure to give your servers clear, relevant hostnames so that you know which #### Install the central servers -[Install the two central nodes using packages](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages) with the exact same version of Centreon on them ([update](https://docs.centreon.com/docs/update/update-centreon-platform) your version if needed). Use the procedure for an installation with remote databases, but skip all steps concerning the databases themselves as you already installed them. At [step 6 of the web installation procedure](../web-and-post-installation.md#step-6-database-information), make sure you enter the address of the VIP dedicated to your databases in the **Database Host Address** field. +[Install the two central nodes using packages](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages) with the exact same version of Centreon on them ([update](https://docs.centreon.com/docs/update/update-centreon-platform) your version if needed). Use the procedure for an installation with remote databases, but skip all steps concerning the databases themselves as you already installed them. At [step 6 of the web installation procedure](https://docs.centreon.com/docs/installation/web-and-post-installation/#step-6-database-information), make sure you enter the address of the VIP dedicated to your databases in the **Database Host Address** field. * Node 1 can be an existing Centreon that already monitors resources; however, node 2 should be a freshly installed Centreon. * Both central servers should have an **admin** account with the same password. From d4e0addba9a189cb564763099181b325369bee1a Mon Sep 17 00:00:00 2001 From: cgenier Date: Fri, 19 Apr 2024 16:22:55 +0200 Subject: [PATCH 05/41] Workaround for link bug --- .../installation/installation-of-centreon-ha/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index f6adafc60faf..55428d3ce20e 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -74,7 +74,7 @@ Make sure to give your servers clear, relevant hostnames so that you know which #### Install the pollers -Install the host machines and [install the pollers from packages](../installation-of-a-poller/using-packages.md) or [using the unattended script](../installation-of-a-poller/unattended.md). Do not register the poller to a central server yet. +Install the host machines and [install the pollers from packages](https://docs.centreon.com/docs/installation/installation-of-a-poller/using-packages) or [using the unattended script](https://docs.centreon.com/docs/installation/installation-of-a-poller/unattended-install-poller/). Do not register the poller to a central server yet. #### Choose a quorum device From 15aa2277f7e371375ac2ea809f0d9006085ea74a Mon Sep 17 00:00:00 2001 From: cgenier Date: Fri, 19 Apr 2024 18:16:20 +0200 Subject: [PATCH 06/41] Fix broken link --- .../installation/installation-of-centreon-ha/installation.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index 55428d3ce20e..1d4588c64c5d 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -9,6 +9,8 @@ import TabItem from '@theme/TabItem'; ## Before you start +This procedure only applies if you are able to set up a database cluster with a dedicated VIP. The Centreon cluster and the database cluster will be independent. + ### Disclaimer It is strongly recommended that your HA is installed by Centreon Professional Services. You may implement HA yourself **only** if: @@ -318,7 +320,7 @@ Exit the SSH session (`Ctrl D`), then exit the `centreon` session by typing `exi ### Open network flows -In addition to the necessary flows described in the [official documentation](../architectures.md#Tables_of_network_flows), +In addition to the necessary flows described in the [official documentation](../technical/#tables-of-network-flows), you will need to open the following flows: | From | Destination | Protocol | Port | Application | From 6c79e2da6be3ef08e56924ebb7ed954250d34f4b Mon Sep 17 00:00:00 2001 From: cgenier Date: Fri, 19 Apr 2024 18:19:26 +0200 Subject: [PATCH 07/41] Fix fix --- .../installation/installation-of-centreon-ha/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index 1d4588c64c5d..a181b050cce9 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -320,7 +320,7 @@ Exit the SSH session (`Ctrl D`), then exit the `centreon` session by typing `exi ### Open network flows -In addition to the necessary flows described in the [official documentation](../technical/#tables-of-network-flows), +In addition to the necessary flows described in the [official documentation](../technical.md#tables-of-network-flows), you will need to open the following flows: | From | Destination | Protocol | Port | Application | From 8f0ec7180284c9614564253c211a893d8146d4e6 Mon Sep 17 00:00:00 2001 From: cgenier Date: Mon, 22 Apr 2024 09:59:50 +0200 Subject: [PATCH 08/41] Workaround for link bug --- .../installation-of-centreon-ha/installation.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index a181b050cce9..bb6b59a3868c 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -320,7 +320,7 @@ Exit the SSH session (`Ctrl D`), then exit the `centreon` session by typing `exi ### Open network flows -In addition to the necessary flows described in the [official documentation](../technical.md#tables-of-network-flows), +In addition to the necessary flows described in the [official documentation](https://docs.centreon.com/docs/installation/technical/#tables-of-network-flows), you will need to open the following flows: | From | Destination | Protocol | Port | Application | @@ -1085,11 +1085,11 @@ pcs resource enable ms_mysql ## Step 3: Integrate your pollers 1. If you haven't already done so, apply the necessary [kernel network tuning](#kernel-network-tuning) to the host machines for your pollers. -2. [Install your pollers](../installation-of-a-poller/using-packages.md) and register them using the VIP as the address of the central server. The password is that of the admin account for node 1? - Then run the wizard to [attach the poller](../../monitoring/monitoring-servers/add-a-poller-to-configuration.md) to the VIP. -3. [Add your pollers](./integrating-pollers.md) to the platform's HA architecture. +2. [Install your pollers](https://docs.centreon.com/docs/installation/installation-of-a-poller/using-packages) and register them using the VIP as the address of the central server. The password is that of the admin account for node 1? - Then run the wizard to [attach the poller](https://docs.centreon.com/docs/monitoring/monitoring-servers/add-a-poller-to-configuration) to the VIP. +3. [Add your pollers](https://docs.centreon.com/docs/installation/installation-of-centreon-ha/integrating-pollers) to the platform's HA architecture. You can now start your monitoring. ## Step 4: Monitor your cluster -See [Monitoring Centreon HA](../../administration/centreon-ha/monitoring-guide.md). +See [Monitoring Centreon HA](https://docs.centreon.com/docs/administration/centreon-ha/monitoring-guide). From 6dc1c3817944519f54c9507f20ac102d6285726e Mon Sep 17 00:00:00 2001 From: cgenier Date: Mon, 22 Apr 2024 10:18:02 +0200 Subject: [PATCH 09/41] Workaround for link bug --- .../installation/installation-of-centreon-ha/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index bb6b59a3868c..33aea88ed764 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -855,7 +855,7 @@ pcs resource create "cbd_rrd" \ ### Create the centreon resource group -The **centreon** [resource group](overview.md#what-processes-are-synchronized-by-centreon-ha) is the list of processes that Pacemaker will have to manage. These processes will not be managed by the central nodes themselves (most of them have been [disabled](#stop-and-disable-services) on the central servers). +The **centreon** [resource group](https://docs.centreon.com/docs/installation/installation-of-centreon-ha/overview/#what-processes-are-synchronized-by-centreon-ha) is the list of processes that Pacemaker will have to manage. These processes will not be managed by the central nodes themselves (most of them have been [disabled](#stop-and-disable-services) on the central servers). #### Define the VIP address From 11e9ea86844cdbdde17aaf8dd283030b6b3679f2 Mon Sep 17 00:00:00 2001 From: cgenier Date: Mon, 6 May 2024 11:39:45 +0200 Subject: [PATCH 10/41] Update --- .../integrations/centreon-ha/centreon-ha.png | Bin 0 -> 110466 bytes .../centreon-ha/acceptance-guide.md | 19 +- .../centreon-ha/operating-guide.md | 64 ++---- .../integrations/centreon-ha/centreon-ha.png | Bin 0 -> 107712 bytes .../installation-of-centreon-ha/faq.md | 13 +- .../installation-of-centreon-ha/overview.md | 6 +- .../update/update-centreon-ha.md | 189 ++++++++++++++++++ 7 files changed, 221 insertions(+), 70 deletions(-) create mode 100644 i18n/fr/docusaurus-plugin-content-docs/version-24.04/assets/integrations/centreon-ha/centreon-ha.png create mode 100644 versioned_docs/version-24.04/assets/integrations/centreon-ha/centreon-ha.png create mode 100644 versioned_docs/version-24.04/update/update-centreon-ha.md diff --git a/i18n/fr/docusaurus-plugin-content-docs/version-24.04/assets/integrations/centreon-ha/centreon-ha.png b/i18n/fr/docusaurus-plugin-content-docs/version-24.04/assets/integrations/centreon-ha/centreon-ha.png new file mode 100644 index 0000000000000000000000000000000000000000..ca56ca6cf025e9c54f05f7743d6fdb0bdf212113 GIT binary patch literal 110466 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 Unless otherwise stated, all commands in this document must be passed as `root`. > In this page, we will refer to characteristics that are bound to change from one platform to another (such as IP addresses and host names) by the [macros defined here](../../installation/installation-of-centreon-ha/installation.md#convention-for-names-and-ip-addresses). -### In Resource Status, how do I know the state of the cluster? - -On both central nodes, the **PCS-Status** service gives you the detailed state of the cluster. The output of the service in the details panel is the output of the `pcs status` command. - -### In Resource status, how do I know which central is the active node? - -You can know which central is the active node by looking at which node is carrying the cluster resources in the output of the **PCS-Status** service on each central. - -### What happens when the cluster fails over? +## What happens when the cluster fails over? When the cluster fails over (e.g. when the active node is affected by a network outage, if its Broker partitions are full...): @@ -26,6 +16,14 @@ When the cluster fails over (e.g. when the active node is affected by a network * You may receive notifications if you have configured them. * You may have to log on to the interface again. +## In Resource Status, how do I know the state of the cluster? + +On both central nodes, the **PCS-Status** service gives you the detailed state of the cluster. The output of the service in the details panel is the output of the `pcs status` command. + +## In Resource status, how do I know which central is the active node? + +You can know which central is the active node by looking at which node is carrying the cluster resources in the output of the **PCS-Status** service on each central. + ## Cluster Management The following set of commands can be run from any member of the cluster (central nodes, quorum device). @@ -71,43 +69,9 @@ Active Resources: These commands should return no errors. If there are "Failed actions" on any resource, troubleshoot them using the [troubleshooting guide](troubleshooting-guide.md). -### View the status of a resource - -If you suspect that a specific process is causing problems, find out the status of the corresponding resource by running this command: - -```bash -pcs resource show -``` - -For example, to find out the status of the **centengine** resource, run this command: - -```bash -pcs resource show centengine -``` - -OUTPUT: - -``` -Warning: This command is deprecated and will be removed. Please use 'pcs resource config' instead. -Resource: centengine (class=systemd type=centengine) - Meta Attributes: centengine-meta_attributes - multiple-active=stop_start - target-role=started - Operations: - monitor: centengine-monitor-interval-5s - interval=5s - timeout=30s - start: centengine-start-interval-0s - interval=0s - timeout=90s - stop: centengine-stop-interval-0s - interval=0s - timeout=90s -``` - ### View the cluster's configuration -To display a very detailed description the cluster's configuration (including xxxxxxx), run this command: +To display a very detailed description the cluster's configuration (including network information), run this command: ```bash pcs config show @@ -115,14 +79,12 @@ pcs config show ### Test the configuration -To test the cluster's configuration, run this command: +To test the cluster's configuration (e.g. to check the name of the resources for any typos, or to check network information), run this command: ```bash crm_verify -L -V ``` -NO OUTPUT (-> because no problem?) - ## Switching resources/resource groups from one node to another To toggle the `centreon` resource group: @@ -165,7 +127,7 @@ The cluster logs are located in `/var/log/cluster/corosync.log`: tail -f /var/log/cluster/corosync.log ``` -Useful logs can also be found in `/var/log/messages`. +Useful logs can also be found in `/var/log/pacemaker/pacemaker.log`. ### Change the cluster log verbosity level @@ -216,7 +178,7 @@ pcs config restore export.tar.bz2 ### Delete a Pacemaker resource group -> **Warning:** These commands will prevent your Centreon cluster from working. Only do this if you know what you are doing. +> **Warning:** These commands will destroy your Centreon cluster. Do this only if you know what you are doing. Connect to a cluster node and run the following commands: diff --git a/versioned_docs/version-24.04/assets/integrations/centreon-ha/centreon-ha.png b/versioned_docs/version-24.04/assets/integrations/centreon-ha/centreon-ha.png new file mode 100644 index 0000000000000000000000000000000000000000..fd66c881b5c39f4a2810d0f6918675fce706b601 GIT binary patch literal 107712 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 z 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%0DL2Czji#chyJ~(V*obo7HGDy zBV=p@6;!kq#oxtLtdVLORyVv4aG&uw3EF@g^s>j;*ho8xl>6Gv=ynlxO)qO>(&p3o zU{eLaQ}urFj5-`%us4%Ar&Ovdv${iY9`baoZtdVIYXE6)EH~9U`qmtA^9S}-BsrK0zv|A319h3$JcKZ7(GG7gOs!>3FLc^qPk@b^5 z)LVyPIFjn_htX2}fN)-i=hmr~@16u!Gii&-gpIFX>1znu$S9`LLETmf5OSX#E^}}& z0$kKli#}<>~d-ophP8hNmv>vs9^gl1jyXAAcHri(^P8 zu5yl&C2kiq9BzI{0WTD4*knEw&_rs2lKwXz(8i^=`iTOdtA+X8dBW0#05pECbK8&&a;Y-<>i|}6SBfY%YWKYSKALg3R6>W+`IP#S^4C4 zKC9WK0%}dEmQ$w8_}TS#(W$F*R0V%rHb8W>N7LL}U^9NQfgQwMG0LaNswV>f6FK*%SF9`bMBj-%dq`n8Zp;(#^7X5BEs*sYJ1U~1s# zmSGj6EvcU?kKo}gd*GN^_`=qxm|Rxn7K5#KQ`2zx438JfulvUzth*Exu=)F2)XljY zU&q*sMkuY8^Hzu0kcgS=L#y4y00|!4bj?f<588WAu-2k>G}Yh7@_U^ARV3Oe08w$pZ}&iwC2 z+L$S9&c3mXjHkm|!=uEBv!cg7stfY_f9j)KFBC;JJA@t#yf#HYm?q)KAkoYb1)S=7nk1x%?=n!k3CTL!eP{amQ8eo6OvN(%0q7M*qaP#dmg5#0h|$hf4Vd_cA>s+`coHKx{tGo-gvz;`1&z~e z+}ve}i5!B0%Nsd|VFHQdX5yAR4z=YACd>ybA)(FqD^yG^^y#bM_ou$Jus642_6GY7 z)R6LIzm2=*u=eO+n;IxjX!OfJkFLtSd4~X1eR%t(G5K7_geuuVzyA>xL#W&pCB0?d zOUlSdOG$wszXEXhD>LIoOAEXE9tf(nyWqmlY{u3p#g!WcK(^}ZE}WW%`Z>VJD4U&- zptUpD=Xt#?0bE9I-p>^M{#xwsmi+PRW1!_9G&7rla}{b(UKE$!ivRn%Ir6sdILib6 zexne$LTqDkq2tY)#sdmVVD6h~-QCv@GnF>4j(&eXQTLw{1dDU&hnzeGaVCp);1JINXzU&|=DVq7< z{!&lQL5YAo`9VCAnPFPNtBbBrg?fb|pnBktgtBrYML(bb#eg%Jg0-qXR8!+iO{Mjk zlijTwxIiAq92`nffD?s@fnr=aS>QlMem*x(L7<->uwx^Gz=xO^ZB6YVW%a(SHfQpY zo43qUkI6lp{g%c{yg6>IcSKkG#P;VDs0mY`+vj0M!C_}7>CGD=I8jnqH~|VOVjOr- z*T55EeiWGlG3suTGca({)T|JyxW}2@3eKh+Y|sm%N_)pi9NC|(JyPfWM|{GOIWHp%nb3`(~dvf(}yowdhJGd?F=h;!TLSD z$iiXF{&wR%00HfB9;*XSnD+xHnDmN7# g|8U32h|$Bt **WARNING:** Anyone following the installation procedure does so at their own risk. Under no circumstances shall Centreon be liable for any breakdown or loss of data. +Your HA must be installed by Centreon Professional Services. ## Do I need a licence for Centreon HA? -Extensions need specific license files to work on both nodes smoothly. If you have an IT or Business subscription, please get in touch with your Centreon sales representative or Technical Account Manager before implementing high availability. +Extensions need specific license files to work on both nodes smoothly. If you have an IT or Business subscription, please get in touch with your Centreon sales representative or Technical Account Manager. ## What is supported, and what isn't? With Centreon 24.04, HA clusters are supported on Alma/RHEL/Oracle Linux 8 and 9 and Debian 11, and the only supported DBMS is MariaDB 10.11. Debian 12 and MySQL8 are not supported yet: if you need to use them, please contact your Centreon sales representative. -Support for HA setups is not included in the Centreon standard support. If you want support for your HA system, your HA setup must be installed by Centreon Professional Services, and you need to purchase a specific HA support pack. Moreover, Centreon can only support Centreon software and does not offer support on your database redundancy setup. - -From version 24.04 on, you need a remote database in all cases. The redundancy of the database is the responsibility of the customer. MariaDB and MySQL have their own redundancy system: set up a database redundancy system using the tools provided by MariaDB or MySQL. +Support for HA setups is not included in the Centreon standard support. If you want support for your HA system, your HA setup must be installed by Centreon Professional Services, and you need to purchase a specific HA support pack. ## What modules can I set up HA on? diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md index 87f9de18fd86..b3b4ad6025b3 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md @@ -25,9 +25,9 @@ Centreon HA consists of a set of clustering tools on top of twin Centreon centra * A VIP, to which the pollers send the data, so that the VIP can forward the data to the current active node. -* Remote databases. Setting up redundancy for the database is [the responsibility of the customer](faq.md#what-is-supported-and-what-isnt). The [installation procedure](installation.md) describes the case where you already have a database cluster set up. The Centreon cluster and the database cluster are independent. The Centreon cluster communicates with the database cluster through a dedicated VIP. +* Remote, replicated databases. -![image](../../assets/integrations/centreon-ha/centreon-ha-2-nodes-arch.png) +![image](../../assets/integrations/centreon-ha/centreon-ha.png) ## How does the HA cluster work? @@ -42,7 +42,7 @@ In an HA cluster, all processes ("resources") are managed by the clustering tool ## How do I know the state of the cluster? -The installation procedure includes a step where you set up the monitoring of the members of the cluster by a poller. This way, you can be notified if a member of the cluster goes down. +The installation process includes the monitoring of the members of the cluster by a poller. This way, you can be notified if a member of the cluster goes down. You access the interface of the active node via the IP address of the VIP. This means that you always use the same URL to access the interface, whether the interface is that of node 1 or of node 2. diff --git a/versioned_docs/version-24.04/update/update-centreon-ha.md b/versioned_docs/version-24.04/update/update-centreon-ha.md new file mode 100644 index 000000000000..f89fe544e3bd --- /dev/null +++ b/versioned_docs/version-24.04/update/update-centreon-ha.md @@ -0,0 +1,189 @@ +--- +id: update-centreon-ha +title: Updating a Centreon-HA platform +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +This procedure is intended to be used to perform minor updates of Centreon when Engine/Broker compatibility between the old version and the new version is assured. No service downtime is necessary in this case; only a short outage of the Web UI login screen. + +## Suspend cluster resource management + +In order to avoid a failover of the cluster during the update, it is necessary to unmanage all Centreon resources, as well as MariaDB. + +```bash +pcs property set maintenance-mode=true +``` + +## Update process from the WUI + +> Make sure all users are logged out of the Centreon web interface +> before starting the upgrade procedure. + +### Centreon-Web update + +Update your cluster by running the following command on each central node: + + + + +Clean the cache : + +```shell +dnf clean all --enablerepo=* +``` + +Update all components: + +```shell +dnf update centreon\* +``` + + + + +Clean the cache : + +```shell +dnf clean all --enablerepo=* +``` + +Update all components: + +```shell +dnf update centreon\* +``` + + + + +Clean the cache : + +```shell +apt clean all +apt update +``` + +Update all components: + +```shell +apt install --only-upgrade centreon\* +``` + + + + +Once the package updates have been completed on both central servers, all that remains is to apply the update via the web interface **only on the active node** by closing the current session or refreshing the login page or by API [as shown here](https://docs.centreon.com/docs/update/update-centreon-platform/#update-the-centreon-central-server). + +On the **passive central node**, you must move the **"install" directory** and regenerate the Symfony cache to avoid displaying the update interface again following a switchover. + + + + +```bash +mv /usr/share/centreon/www/install /var/lib/centreon/installs/install-update-`date +%Y%m%d` +sudo -u apache /usr/share/centreon/bin/console cache:clear +``` + + + +```bash +mv /usr/share/centreon/www/install /var/lib/centreon/installs/install-update-`date +%Y%m%d` +sudo -u apache /usr/share/centreon/bin/console cache:clear +``` + + + +```bash +mv /usr/share/centreon/www/install /var/lib/centreon/installs/install-update-`date +%Y%m%d` +sudo -u www-data /usr/share/centreon/bin/console cache:clear +``` + + + +### Removing cron jobs + +The RPM upgrade restores the unnecessary cron jobs that were deleted during the installation procedure. Remove them on the two central nodes to avoid concurrent executions: + + + + +```bash +rm -f /etc/cron.d/centreon +rm -f /etc/cron.d/centstorage +rm -f /etc/cron.d/centreon-auto-disco +systemctl restart crond +``` + + + + +```bash +rm -f /etc/cron.d/centreon +rm -f /etc/cron.d/centstorage +rm -f /etc/cron.d/centreon-auto-disco +systemctl restart crond +``` + + + +```bash +rm -f /etc/cron.d/centreon +rm -f /etc/cron.d/centstorage +rm -f /etc/cron.d/centreon-auto-disco +systemctl restart cron +``` + + + +### Updating Centreon extensions + +The Centreon extensions are also updated *via* the WUI, from the "Administration > Extensions > Manager" menu, by clicking the "Update all" button. + +### Updating the Monitoring Connectors + +In order to maintain compatibility between the [Monitoring Connectors](../monitoring/pluginpacks.md) and the installed plugins (that have just been updated on the central server), the Monitoring Connectors must also be updated in the WUI from the **Configuration > Monitoring Connector Manager** menu. + +### Exporting Engine/Broker configuration + +Generate and export new Engine/Broker configuration files for all pollers (central included) in **Configuration > Pollers** with these options checked: + +* Generate Configuration Files +* Run monitoring engine debug (-v) +* Move Export Files + +Then restart them **one at a time** from the same menu and make sure to select the **"Restart" method, not "Reload"**, if the `centreon-engine` and/or `centreon-broker` packages have been updated. + +In addition, the `cbd-sql` service must be restarted **on the central master server**: + +```bash +service cbd-sql restart +``` + +The `cbd` service must also be restarted on [Centreon Remote Servers](../installation/architectures.md#description): + +```bash +service cbd restart +``` + +## Resuming cluster resource management + +Now that the update is finished, the resources can be managed again: + +```bash +pcs property set maintenance-mode=false +pcs resource cleanup ms_mysql +``` + +## Verifying platform stability + +You should now check that everything works fine: + +* Access to the web UI menus. +* Poller configuration generation + reload and restart method. +* Schedule an immediate check (Central + Pollers) and acknowledge, downtime etc. +* Move resources or reboot the master server and check again that everything is fine. + +## Updating the pollers + +Pollers can then be updated by following the [procedure indicated here](../update/update-centreon-platform.md#update-the-pollers). From ed6240792820d55634d95fe7028a1f55d423a3b6 Mon Sep 17 00:00:00 2001 From: cgenier Date: Mon, 6 May 2024 11:52:02 +0200 Subject: [PATCH 11/41] Fix links --- .../administration/centreon-ha/acceptance-guide.md | 2 +- .../version-24.04/administration/centreon-ha/operating-guide.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md index 07bda3932f37..cf1d55da5dfd 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md @@ -583,7 +583,7 @@ Migration Summary: Ub)7ZiuBZm+C#!}27g8tA&(CQsb8NaW-W!A~I7 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 z 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%0DL2Czji#chyJ~(V*obo7HGDy zBV=p@6;!kq#oxtLtdVLORyVv4aG&uw3EF@g^s>j;*ho8xl>6Gv=ynlxO)qO>(&p3o zU{eLaQ}urFj5-`%us4%Ar&Ovdv${iY9`baoZtdVIYXE6)EH~9U`qmtA^9S}-BsrK0zv|A319h3$JcKZ7(GG7gOs!>3FLc^qPk@b^5 z)LVyPIFjn_htX2}fN)-i=hmr~@16u!Gii&-gpIFX>1znu$S9`LLETmf5OSX#E^}}& z0$kKli#}<>~d-ophP8hNmv>vs9^gl1jyXAAcHri(^P8 zu5yl&C2kiq9BzI{0WTD4*knEw&_rs2lKwXz(8i^=`iTOdtA+X8dBW0#05pECbK8&&a;Y-<>i|}6SBfY%YWKYSKALg3R6>W+`IP#S^4C4 zKC9WK0%}dEmQ$w8_}TS#(W$F*R0V%rHb8W>N7LL}U^9NQfgQwMG0LaNswV>f6FK*%SF9`bMBj-%dq`n8Zp;(#^7X5BEs*sYJ1U~1s# zmSGj6EvcU?kKo}gd*GN^_`=qxm|Rxn7K5#KQ`2zx438JfulvUzth*Exu=)F2)XljY zU&q*sMkuY8^Hzu0kcgS=L#y4y00|!4bj?f<588WAu-2k>G}Yh7@_U^ARV3Oe08w$pZ}&iwC2 z+L$S9&c3mXjHkm|!=uEBv!cg7stfY_f9j)KFBC;JJA@t#yf#HYm?q)KAkoYb1)S=7nk1x%?=n!k3CTL!eP{amQ8eo6OvN(%0q7M*qaP#dmg5#0h|$hf4Vd_cA>s+`coHKx{tGo-gvz;`1&z~e z+}ve}i5!B0%Nsd|VFHQdX5yAR4z=YACd>ybA)(FqD^yG^^y#bM_ou$Jus642_6GY7 z)R6LIzm2=*u=eO+n;IxjX!OfJkFLtSd4~X1eR%t(G5K7_geuuVzyA>xL#W&pCB0?d zOUlSdOG$wszXEXhD>LIoOAEXE9tf(nyWqmlY{u3p#g!WcK(^}ZE}WW%`Z>VJD4U&- zptUpD=Xt#?0bE9I-p>^M{#xwsmi+PRW1!_9G&7rla}{b(UKE$!ivRn%Ir6sdILib6 zexne$LTqDkq2tY)#sdmVVD6h~-QCv@GnF>4j(&eXQTLw{1dDU&hnzeGaVCp);1JINXzU&|=DVq7< z{!&lQL5YAo`9VCAnPFPNtBbBrg?fb|pnBktgtBrYML(bb#eg%Jg0-qXR8!+iO{Mjk zlijTwxIiAq92`nffD?s@fnr=aS>QlMem*x(L7<->uwx^Gz=xO^ZB6YVW%a(SHfQpY zo43qUkI6lp{g%c{yg6>IcSKkG#P;VDs0mY`+vj0M!C_}7>CGD=I8jnqH~|VOVjOr- z*T55EeiWGlG3suTGca({)T|JyxW}2@3eKh+Y|sm%N_)pi9NC|(JyPfWM|{GOIWHp%nb3`(~dvf(}yowdhJGd?F=h;!TLSD z$iiXF{&wR%00HfB9;*XSnD+xHnDmN7# g|8U32h|$Bt Date: Tue, 14 May 2024 16:55:51 +0200 Subject: [PATCH 18/41] Update, WIP --- .../installation.md | 866 +++++++++++++++++- .../installation-of-centreon-ha/overview.md | 47 +- 2 files changed, 858 insertions(+), 55 deletions(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index a9c0981593ed..67503d37845e 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -12,7 +12,7 @@ import TabItem from '@theme/TabItem'; ### Disclaimer Your HA must be installed by Centreon. -This procedure is geared towards experts users who have a strong knowledge of the Pacemaker-Corosync clustering tools, of networks, of Linux OS and of Centreon. +This procedure is geared towards expers users who have a strong knowledge of the Pacemaker-Corosync clustering tools, of networks, of Linux OS and of Centreon. > **WARNING:** Anyone following this procedure does so at their own risk. Under no circumstances shall Centreon be liable for any breakdown or data loss. @@ -28,13 +28,25 @@ In this procedure, we will refer to characteristics that are bound to change fro * `@CENTRAL_PASSIVE_NAME@`: passive central server's name (must be identical to `hostname -s`) * `@QDEVICE_IPADDR@`: quorum device's IP address * `@QDEVICE_NAME@`: quorum device's name (must be identical to `hostname -s`) -* `@VIP_IPADDR@`: virtual IP address of the cluster -* `@VIP_IFNAME@`: network device carrying the cluster's VIP (name of the interface the VIP must send the flows to. The interface must have the same name on both central nodes). +* `@VIP_IPADDR@`: virtual IP address of the central servers cluster +* `@VIP_IFNAME@`: network device carrying the central servers cluster's VIP (name of the interface the VIP must send the flows to. The interface must have the same name on both central nodes). * `@VIP_CIDR_NETMASK@`: subnet mask length in bits (e.g. 24) -* `@VIP_BROADCAST_IPADDR@`: cluster's VIP broadcast address +* `@VIP_BROADCAST_IPADDR@`: central servers cluster's VIP broadcast address * `@CENTREON_CLUSTER_PASSWD@`: `hacluster` user's password - -During the installation procedure, node 1 will be the active node and node 2 will be the passive node. Of course, the roles will be able to be switched later. +* `@DATABASE_ACTIVE_IPADDR@`: active database server's IP address +* `@DATABASE_ACTIVE_NAME@`: active database server's FQDN (must be identical to: `hostname -s`) +* `@DATABASE_PASSIVE_IPADDR@`: passive database server's IP address +* `@DATABASE_PASSIVE_NAME@`: passive database server's FQDN (must be identical to: `hostname -s`) +* `@DB_REPL_USER@`: DB replication login (default: `centreon-repl`) +* `@DB_REPL_PASSWD@`: DB replication password +* `@DB_CENTREON_USER@`: DB Centreon login (default: `centreon`) +* `@DB_CENTREON_PASSWD@`: DB Centreon +* `@VIP_SQL_IPADDR@`: virtual IP address of the SQL cluster +* `@VIP_SQL_IFNAME@`: network device carrying the SQL cluster's VIP (name of the interface the VIP must send the flows to. The interface must have the same name on both database nodes). +* `@VIP_SQL_CIDR_NETMASK@`: SQL Cluster subnet mask length in bits (e.g. 24) +* `@VIP_SQL_BROADCAST_IPADDR@`: cluster's VIP SQL broadcast address + +During the installation procedure, central node 1 will be the active node and central node 2 will be the passive node. Of course, the roles will be able to be switched later. ### How should I organize my Centreon HA? @@ -53,31 +65,27 @@ Make sure to give your servers clear, relevant hostnames so that you know which #### Set up VIPs for the central servers and for the databases * Reserve an IP address in your network to act as a VIP so that pollers can always send data to the active central node. -* Reserve another VIP through which the central servers will access the replicated databases. - -#### Install and set up replication for the databases - -1. If you have a Centreon with already existing data, make a dump of the database first. -2. Install 2 blank Centreon databases [using our installation procedure for remote databases](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages/#step-2-installation). -3. Set up replication for the databases using the official replication tools for MariaDB or MySQL. -4. Configure the databases so that they can communicate with their dedicated VIP. +* Reserve another VIP through which the active central server will access the active database server. #### Install the central servers -[Install the two central nodes using packages](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages) with the exact same version of Centreon on them ([update](https://docs.centreon.com/docs/update/update-centreon-platform) your version if needed). Use the procedure for an installation with remote databases, but skip all steps concerning the databases themselves as you already installed them. At [step 6 of the web installation procedure](https://docs.centreon.com/docs/installation/web-and-post-installation/#step-6-database-information), make sure you enter the address of the VIP dedicated to your databases in the **Database Host Address** field. +Node 1 can be an existing Centreon that already monitors resources; however, node 2 should be a freshly installed Centreon. + +Using the procedure for an installation with remote databases, [install your second central node from packages](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages) with the exact same version of Centreon on it as node 1 ([update](https://docs.centreon.com/docs/update/update-centreon-platform) your version if needed). At [step 6 of the web installation procedure](https://docs.centreon.com/docs/installation/web-and-post-installation/#step-6-database-information), make sure you enter the address of the VIP dedicated to your databases in the **Database Host Address** field. -* Node 1 can be an existing Centreon that already monitors resources; however, node 2 should be a freshly installed Centreon. * Both central servers should have an **admin** account with the same password. * If you have an IT or Business edition, remember that license files for HA are specific. Please contact your Centreon sales representative to obtain your license files. #### Install the pollers -Install the host machines and [install the pollers from packages](https://docs.centreon.com/docs/installation/installation-of-a-poller/using-packages) or [using the unattended script](https://docs.centreon.com/docs/installation/installation-of-a-poller/unattended-install-poller/). Do not register the poller to a central server yet. +Install the host machines and [install the pollers from packages](https://docs.centreon.com/docs/installation/installation-of-a-poller/using-packages) or [using the unattended script](https://docs.centreon.com/docs/installation/installation-of-a-poller/unattended-install-poller/). Do not register the pollers to a central server yet, this will be done later. #### Choose a quorum device Choose which server in your infrastructure should act as a quorum device. This can be a poller. (The actual configuration will be done later: see [Preparing the server that will function as the quorum device](#preparing-the-server-that-will-function-as-the-quorum-device) and [Defining the quorum device](#defining-the-quorum-device).) +In order to adhere to best practices and be as resilient as possible, the quorum server should be at a different site than the two primary nodes, with independent network connections. + ### Configure centreon-broker on the central servers #### Change the link to the cbd service @@ -119,7 +127,7 @@ In the event of a cluster switch, you will expect the newly elected active centr Once the above actions have been done ([Change the link to the cbd service](#change-the-link-to-the-cbd-service) and [Double the output stream toward RRD](#double-the-output-stream-toward-rrd)), export the configuration of the central server to apply these changes. The **Move Export Files** option must be checked. -All the above actions should be applied either to both nodes or to `@CENTRAL_ACTIVE_NAME@` only, and the exported files should be copied to `@CENTRAL_PASSIVE_NAME@`: +All the above actions should be applied either to both nodes, or to central node 1 only and then the exported files should be copied to central node 2: ```bash rsync -a /etc/centreon-broker/*json @CENTRAL_PASSIVE_IPADDR@:/etc/centreon-broker/ @@ -192,13 +200,15 @@ reboot So that the Centreon HA cluster can stay in operation in the event of a DNS service breakdown, all members of the cluster must know each other by name, using `/etc/hosts`. -Run the following command on the two central nodes and on the quorum device: +Run the following command on the two central nodes, on the quorum device, and on both database servers: ```bash cat >/etc/hosts <<"EOF" 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 @CENTRAL_ACTIVE_IPADDR@ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_IPADDR@ @CENTRAL_PASSIVE_NAME@ +@DATABASE_ACTIVE_IPADDR@ @DATABASE_ACTIVE_NAME@ +@DATABASE_PASSIVE_IPADDR@ @DATABASE_PASSIVE_NAME@ @QDEVICE_IPADDR@ @QDEVICE_NAME@ EOF ``` @@ -271,9 +281,76 @@ apt update && apt install centreon-ha-web pcs pacemaker corosync corosync-qdevic +### Install HA tools on the database servers + +Install the following packages on both database nodes. + + + + +```bash +dnf config-manager --enable ha +dnf install centreon-ha-common pcs pacemaker corosync corosync-qdevice +``` + + + + +```bash +dnf -y install dnf-plugins-core https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm +subscription-manager repos --enable rhel-8-for-x86_64-highavailability-rpms +dnf install centreon-ha-common pcs pacemaker corosync corosync-qdevice +``` + + + + +```bash +dnf config-manager --enable ol8_addons +dnf install centreon-ha-common pcs pacemaker corosync corosync-qdevice +``` + + + + +```bash +dnf config-manager --enable highavailability +dnf install centreon-ha-common pcs pacemaker corosync corosync-qdevice +``` + + + + +```bash +dnf -y install dnf-plugins-core https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm +subscription-manager repos --enable rhel-9-for-x86_64-highavailability-rpms +dnf install centreon-ha-common pcs pacemaker corosync corosync-qdevice +``` + + + + +```bash +dnf config-manager --enable ol9_addons +dnf install centreon-ha-common pcs pacemaker corosync corosync-qdevice +``` + + + + +```bash +apt update && apt install centreon-ha-common pcs pacemaker corosync corosync-qdevice +``` + + + + ### Configure SSH keys exchange -SSH key-based authentication must be set up so that files and commands can be sent from one node to another by the **centreon** Unix account. +SSH key-based authentication must be set up so that files and commands can be sent: + +* from one central node to another by the **centreon** Unix account. +* from one database node to another by the **mysql** Unix account. There are two ways of exchanging such keys: @@ -282,13 +359,15 @@ There are two ways of exchanging such keys: The second method will be documented below. -Switch to `centreon`'s bash environment on both nodes: +#### **centreon** account + +Switch to `centreon`'s bash environment on both central nodes: ```bash su - centreon ``` -Then run this command on both nodes: +Then run this command on both central nodes: ```bash ssh-keygen -t ed25519 -a 100 @@ -314,6 +393,41 @@ ssh Exit the SSH session (`Ctrl D`), then exit the `centreon` session by typing `exit` or `Ctrl D`. +#### **mysql** account + +For the `mysql` account, the procedure is slightly different because this user normally has neither a home directory nor the ability to open a Shell session. Run the following commands on both database nodes: + +```bash +systemctl stop mysql +mkdir /home/mysql +chown mysql: /home/mysql +usermod -d /home/mysql mysql +usermod -s /bin/bash mysql +systemctl start mysql +su - mysql +``` + +Once in `mysql`'s `bash` environment, run these commands on both database nodes: + +```bash +ssh-keygen -t ed25519 -a 100 +cat ~/.ssh/id_ed25519.pub +``` + +Once done, copy the content of the public key file displayed by `cat` and paste it to `~/.ssh/authorized_keys` (must be created) on the other database node, and then apply the correct file permissions (still as user`mysql`): + +```bash +chmod 600 ~/.ssh/authorized_keys +``` + +The key exchange must be validated by an initial connection from each database node to the other in order to accept and register the peer node's SSH fingerprint (still as user `mysql`): + +```bash +ssh +``` + +Exit the SSH session (`Ctrl D`), then exit the `mysql` session by typing `exit` or `Ctrl D`. + ### Open network flows In addition to the necessary flows described in the [official documentation](https://docs.centreon.com/docs/installation/technical/#tables-of-network-flows), @@ -321,16 +435,455 @@ you will need to open the following flows: | From | Destination | Protocol | Port | Application | | :----------------------------- | :----------------------------- | :------- | :------- | :----------------------------------------------------------------------------------------- | -| Active Central Server | Passive Central Server | SSH | TCP 22 | Synchronization of configuration files (Must also be open from passive to active node) | -| Active Central Server | Passive Central Server | BDDO | TCP 5670 | RRDs synchronization (Must also be open from passive to active node) | -| Active Database Server | Passive Database Server | MySQL | TCP 3306 | MySQL synchronization (Must also be open from passive to active node) | -| Active Database Server | Passive Database Server | SSH | TCP 22 | MySQL synchronization (Must also be open from passive to active node) | +| Active Central Server | Passive Central Server | SSH | TCP 22 | Synchronization of configuration files (must also be open from passive to active node) | +| Active Central Server | Passive Central Server | BDDO | TCP 5670 | RRDs synchronization (must also be open from passive to active node) | +| Active Database Server | Passive Database Server | MySQL | TCP 3306 | MySQL synchronization (must also be open from passive to active node) | +| Active Database Server | Passive Database Server | SSH | TCP 22 | MySQL synchronization (must also be open from passive to active node) | | Central Servers + DB + QDevice | Central Servers + DB + QDevice | Corosync | UDP 5404 | Communication inside the cluster (Multicast) | | Central Servers + DB + QDevice | Central Servers + DB + QDevice | Corosync | UDP 5405 | Communication inside the cluster (Unicast) | | Central Servers + DB + QDevice | Central Servers + DB + QDevice | PCS | TCP 2224 | Communication inside the cluster | | Central Servers + DB + QDevice | Central Servers + DB + QDevice | Corosync | TCP 5403 | Communication with the QDevice | -## Step 2: Set up the Centreon cluster +## Step 2: Set up the database replication + +An active-passive MariaDB cluster will be set up so that your data is synchronized in real time. + +**Note**: unless otherwise stated, each of the following steps must be run on both database nodes. + +### Configuring MariaDB + + + + +For both optimization and cluster reliability purposes, you need to add these tuning options to the MariaDB configuration in the `/etc/my.cnf.d/server.cnf` file. By default, the `[server]` section of this file is empty. Paste the following lines (some need to be modified) into this section: + +```ini +[server] +server-id=1 # SET TO 1 FOR MASTER AND 2 FOR SLAVE +#read_only +log-bin=mysql-bin +binlog-do-db=centreon +binlog-do-db=centreon_storage +innodb_flush_log_at_trx_commit=1 +sync_binlog=1 +binlog_format=MIXED +slave_compressed_protocol=1 +slave_parallel_mode=conservative +datadir=/var/lib/mysql +pid-file=/var/lib/mysql/mysql.pid +skip-slave-start +log-slave-updates +gtid_strict_mode=ON +expire_logs_days=7 +ignore-db-dir=lost+found + +# Tuning standard Centreon +innodb_file_per_table=1 +open_files_limit=32000 +key_buffer_size=256M +sort_buffer_size=32M +join_buffer_size=4M +thread_cache_size=64 +read_buffer_size=512K +read_rnd_buffer_size=256K +max_allowed_packet=64M +# Uncomment for 4 Go Ram +#innodb_buffer_pool_size=512M +# Uncomment for 8 Go Ram +#innodb_buffer_pool_size=1G +``` + + + + +For both optimization and cluster reliability purposes, you need to add these tuning options to the MariaDB configuration in the `/etc/my.cnf.d/server.cnf` file. By default, the `[server]` section of this file is empty. Paste the following lines (some need to be modified) into this section: + +```ini +[server] +server-id=1 # SET TO 1 FOR MASTER AND 2 FOR SLAVE +#read_only +log-bin=mysql-bin +binlog-do-db=centreon +binlog-do-db=centreon_storage +innodb_flush_log_at_trx_commit=1 +sync_binlog=1 +binlog_format=MIXED +slave_compressed_protocol=1 +slave_parallel_mode=conservative +datadir=/var/lib/mysql +pid-file=/var/lib/mysql/mysql.pid +skip-slave-start +log-slave-updates +gtid_strict_mode=ON +expire_logs_days=7 +ignore-db-dir=lost+found + +# Tuning standard Centreon +innodb_file_per_table=1 +open_files_limit=32000 +key_buffer_size=256M +sort_buffer_size=32M +join_buffer_size=4M +thread_cache_size=64 +read_buffer_size=512K +read_rnd_buffer_size=256K +max_allowed_packet=128M +# Uncomment for 4 Go Ram +#innodb_buffer_pool_size=512M +# Uncomment for 8 Go Ram +#innodb_buffer_pool_size=1G +``` + +In addition, replace the [mysqld] section with : + +``` +[mysqld] +datadir=/var/lib/mysql +socket=/var/lib/mysql/mysql.sock +log-error=/var/log/mariadb/mariadb.log +pid-file=/var/lib/mysql/mysql.pid +``` + +then create the directory and corresponding log file: + +```shell +mkdir /var/log/mariadb +touch /var/log/mariadb/mariadb.log +chown -R mysql: /var/log/mariadb +``` + + + + +For both optimization and cluster reliability purposes, you need to add these tuning options to the MariaDB configuration in the `/etc/mysql/mariadb.conf.d/50-server.cnf` file. By default, the `[server]` section of this file is empty. Paste the following lines (some need to be modified) into this section: + +```ini +[server] +server-id=1 # SET TO 1 FOR MASTER AND 2 FOR SLAVE +#read_only +log-bin=mysql-bin +binlog-do-db=centreon +binlog-do-db=centreon_storage +innodb_flush_log_at_trx_commit=1 +sync_binlog=1 +binlog_format=MIXED +slave_compressed_protocol=1 +slave_parallel_mode=conservative +datadir=/var/lib/mysql +pid-file=/run/mysqld/mysql.pid +skip-slave-start +log-slave-updates +gtid_strict_mode=ON +expire_logs_days=7 +ignore-db-dir=lost+found + +# Tuning standard Centreon +innodb_file_per_table=1 +open_files_limit=32000 +key_buffer_size=256M +sort_buffer_size=32M +join_buffer_size=4M +thread_cache_size=64 +read_buffer_size=512K +read_rnd_buffer_size=256K +max_allowed_packet=64M +# Uncomment for 4 Go Ram +#innodb_buffer_pool_size=512M +# Uncomment for 8 Go Ram +#innodb_buffer_pool_size=1G +``` + + + + +> **Important:** the value of the `server-id` option must be different from one server to the other. The values suggested in the comments, 1 for the master and 2 for the slave, are not mandatory, but recommended. + +**Reminder:** remember to uncomment the right value for `innodb_buffer_pool_size` according to your own servers' memory size. + +To apply the new configuration, restart the database server: + +```bash +systemctl restart mysql +``` + +Make sure the restart went well: + +```bash +systemctl status mysql +``` + +> **Warning:** other files in `/etc/my.cnf.d/`, such as `centreon.cnf`, will be ignored from now on. Any customization will have to be added to `server.cnf`. + +> **Warning:** remember to change the parameter `Mysql configuration file path` in **Administration > Parameters > Backup**. + +### Creating the `centreon` MariaDB account + +First log in as `root` on both database servers (using the newly-defined password): + +```bash +mysql -p +``` + +Then, on both sides, paste the following SQL commands to the MariaDB prompt to create the application user (default: `centreon`). Replace the macros first: + +```sql +CREATE USER '@MARIADB_CENTREON_USER@'@'@DATABASE_SLAVE_IPADDR@' IDENTIFIED BY '@MARIADB_CENTREON_PASSWD@'; +GRANT ALL PRIVILEGES ON centreon.* TO '@MARIADB_CENTREON_USER@'@'@DATABASE_SLAVE_IPADDR@'; +GRANT ALL PRIVILEGES ON centreon_storage.* TO '@MARIADB_CENTREON_USER@'@'@DATABASE_SLAVE_IPADDR@'; + +CREATE USER '@MARIADB_CENTREON_USER@'@'@DATABASE_MASTER_IPADDR@' IDENTIFIED BY '@MARIADB_CENTREON_PASSWD@'; +GRANT ALL PRIVILEGES ON centreon.* TO '@MARIADB_CENTREON_USER@'@'@DATABASE_MASTER_IPADDR@'; +GRANT ALL PRIVILEGES ON centreon_storage.* TO '@MARIADB_CENTREON_USER@'@'@DATABASE_MASTER_IPADDR@'; +``` + +Optionally, you can allow these privileges to be used from the Central Cluster. This will make some administration scripts runnable from every node. + +```sql +CREATE USER '@MARIADB_CENTREON_USER@'@'@CENTRAL_SLAVE_IPADDR@' IDENTIFIED BY '@MARIADB_CENTREON_PASSWD@'; +GRANT ALL PRIVILEGES ON centreon.* TO '@MARIADB_CENTREON_USER@'@'@CENTRAL_SLAVE_IPADDR@'; +GRANT ALL PRIVILEGES ON centreon_storage.* TO '@MARIADB_CENTREON_USER@'@'@CENTRAL_SLAVE_IPADDR@'; + +CREATE USER '@MARIADB_CENTREON_USER@'@'@CENTRAL_MASTER_IPADDR@' IDENTIFIED BY '@MARIADB_CENTREON_PASSWD@'; +GRANT ALL PRIVILEGES ON centreon.* TO '@MARIADB_CENTREON_USER@'@'@CENTRAL_MASTER_IPADDR@'; +GRANT ALL PRIVILEGES ON centreon_storage.* TO '@MARIADB_CENTREON_USER@'@'@CENTRAL_MASTER_IPADDR@'; +``` + +When upgrading to centreon-ha from an existing Centreon platform or an OVA/OVF VM deployment, update the `'@MARIADB_CENTREON_USER@'@'localhost'` password: + +```sql +ALTER USER '@MARIADB_CENTREON_USER@'@'localhost' IDENTIFIED BY '@MARIADB_CENTREON_PASSWD@'; +``` + +### Creating the MariaDB replication account + +Still in the same prompt, create the replication user (default: `centreon-repl`): + +```sql +GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* +TO '@MARIADB_REPL_USER@'@'localhost' IDENTIFIED BY '@MARIADB_REPL_PASSWD@'; + +GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* +TO '@MARIADB_REPL_USER@'@'@DATABASE_SLAVE_IPADDR@' IDENTIFIED BY '@MARIADB_REPL_PASSWD@'; + +GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* +TO '@MARIADB_REPL_USER@'@'@DATABASE_MASTER_IPADDR@' IDENTIFIED BY '@MARIADB_REPL_PASSWD@'; +``` + +Optionally, you can allow these privileges to be used from the Central Cluster. This will make some administration scripts runnable from every node. + +```sql +GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* +TO '@MARIADB_REPL_USER@'@'@CENTRAL_SLAVE_IPADDR@' IDENTIFIED BY '@MARIADB_REPL_PASSWD@'; + +GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* +TO '@MARIADB_REPL_USER@'@'@CENTRAL_MASTER_IPADDR@' IDENTIFIED BY '@MARIADB_REPL_PASSWD@'; +``` + +### Configuring the MariaDB scripts environment variables + +The `/etc/centreon-ha/mysql-resources.sh` file declares environment variables that must be configured so that the *Centreon HA* scripts dedicated to MariaDB can work properly. These variables must be assigned the chosen values for the macros. + +```bash +#!/bin/bash + +############################### +# Database access credentials # +############################### + +DBHOSTNAMEMASTER='@DATABASE_MASTER_NAME@' +DBHOSTNAMESLAVE='@DATABASE_SLAVE_NAME@' +DBREPLUSER='@MARIADB_REPL_USER@' +DBREPLPASSWORD='@MARIADB_REPL_PASSWD@' +DBROOTUSER='@MARIADB_REPL_USER@' +DBROOTPASSWORD='@MARIADB_REPL_PASSWD@' +CENTREON_DB='centreon' +CENTREON_STORAGE_DB='centreon_storage' + +############################### +``` + +To make sure that all the previous steps have been successful, and that the correct names, logins and passwords have been entered in the configuration bash file, run this command on both database nodes: + +```bash +/usr/share/centreon-ha/bin/mysql-check-status.sh +``` + +The expected output is: + +```text +Connection MASTER Status '@DATABASE_MASTER_NAME@' [OK] +Connection SLAVE Status '@DATABASE_SLAVE_NAME@' [OK] +Slave Thread Status [KO] +Error reports: + No slave (maybe because we cannot check a server). +Position Status [SKIP] +!Error reports: + Skip because we can't identify a unique slave. +``` + +What matters here is that the first two connection tests are `OK`. + +### Switching to read-only mode + + + + +Now that everything is configured correctly, enable the `read_only` on both database servers by uncommenting the following instruction in the `/etc/my.cnf.d/server.cnf` file (i.e., by removing the `#` at the beginning of the line): + +* Primary node: + +```ini +[server] +server-id=1 +read_only +log-bin=mysql-bin +``` + +* Secondary node: + +```ini +[server] +server-id=2 +read_only +log-bin=mysql-bin +``` + +Then apply this change by restarting MariaDB on both nodes: + +```bash +systemctl restart mysql +``` + + + + +Now that everything is configured correctly, enable the `read_only` on both database servers by uncommenting the following instruction in the `/etc/my.cnf.d/server.cnf` file (i.e., by removing the `#` at the beginning of the line): + +* Primary node: + +```ini +[server] +server-id=1 +read_only +log-bin=mysql-bin +``` + +* Secondary node: + +```ini +[server] +server-id=2 +read_only +log-bin=mysql-bin +``` + +Then apply this change by restarting MariaDB on both nodes: + +```bash +systemctl restart mysql +``` + + + + +Now that everything is configured correctly, enable the `read_only` on both database servers by uncommenting the following instruction in the `/etc/mysql/mariadb.conf.d/50-server.cnf` file (i.e., by removing the `#` at the beginning of the line): + +* Primary node + +```ini +[server] +server-id=1 +read_only +log-bin=mysql-bin +``` + +* Secondary node + +```ini +[server] +server-id=2 +read_only +log-bin=mysql-bin +``` + +Next, apply this change by restarting MariaDB on both nodes: + +```bash +systemctl restart mariadb +``` + + + + +### Synchronizing the databases and enabling MariaDB replication + +In the process of synchronizing the databases, you will first stop the secondary database process so that its data can be overwritten by the primary node's data. + +Run this command **on the secondary node**: + +```bash +systemctl stop mysql +``` + +It is important to make sure that MariaDB is completely shut down. Run this command and check that it returns no output: + +```bash +ps -ef | grep mariadb[d] +``` + +In case one or more processes are still alive, run the following command (it will prompt for the MariaDB root password): + +```bash +mysqladmin -p shutdown +``` + +Once the service is stopped **on the secondary node**, run the synchronization script **from the primary database node**: + +```bash +/usr/share/centreon-ha/bin/mysql-sync-bigdb.sh +``` + +This script will perform the following actions: + +* Check that MariaDB is stopped on the secondary node. +* Stop MariaDB on the primary node. +* Mount an LVM snapshot on the same volume group that holds `/var/lib/mysql` (or whatever mount point holds the MariaDB data files). +* Start MariaDB again on the primary node. +* Record the current position in the binary log. +* Disable the `read_only` mode on the primary node (this node will now be able to write to its database). +* Synchronize/overwrite all the data files (except for the `mysql` system database). +* Unmount the LVM snapshot. +* Create the replication thread that will keep both databases synchronized. + +This script's output is very verbose and you can't expect to understand everything, so to make sure it went well, focus on the last lines of its output, checking that it looks like this: + +```text +Umount and Delete LVM snapshot + Logical volume "dbbackupdatadir" successfully removed +Start MySQL Slave +Start Replication +Id User Host db Command Time State Info Progress +[variable number of lines] +``` + +The important thing to check is that `Start MySQL Slave` and `Start Replication` are present and are not followed by any errors. + +In addition, the output of this command must display only `OK` results: + +```bash +/usr/share/centreon-ha/bin/mysql-check-status.sh +``` + +The expected output is: + +```text +Connection MASTER Status '@DATABASE_MASTER_NAME@' [OK] +Connection SLAVE Status '@DATABASE_SLAVE_NAME@' [OK] +Slave Thread Status [OK] +Position Status [OK] +``` + +## Step 3: Set up the Centreon cluster **Note**: unless otherwise stated, each of the following steps must be run **on both central nodes**. @@ -417,7 +970,9 @@ chmod 775 /tmp/centreon-autodisco/ ### Stop and disable services -The central nodes must no longer launch services at boot time: this will be done by the clustering tools, and only them. Stop and disable the following services on each central node: +The central nodes and the database nodes must no longer launch some services at boot time: this will be done by the clustering tools, and only them. + +#### On each central node @@ -448,9 +1003,46 @@ systemctl disable centengine snmptrapd centreontrapd gorgoned cbd apache2 php8.1 At this point, you no longer have access to the central servers' interfaces (as you have stopped the corresponding service). The interfaces will be up again at the end of the installation procedure. +#### On each database node + +```bash +systemctl stop mysql +systemctl disable mysql +``` + + + + +By default, the `mysql` service is enabled in both systemd and system V perspectives, so you should make sure it is disabled: + +```bash +chkconfig mysql off +``` + + + + +By default, the `mysql` service is enabled in both systemd and system V perspectives, so you should make sure it is disabled: + +```bash +chkconfig mysql off +``` + + + + +By default, the `mysql` service is enabled in both systemd and system V perspectives, so you should make sure it is disabled: + +```bash +update-rc.d -f mariadb remove +``` + + + + ### Activate the clustering services -Start `pcsd` on both central nodes: +Start `pcsd` on all nodes (central nodes, database nodes and quorum device): ```bash systemctl start pcsd @@ -552,10 +1144,10 @@ pcs qdevice status net --full -RETOUR de qdevice status +Output of the `qdevice status` command: ```shell -[root@ip-172-16-5-171 ~]# pcs qdevice status net --full +[root@@QDEVICE_NAME@ ~]# pcs qdevice status net --full QNetd address: *:5403 TLS: Supported (client certificate required) Connected clients: 0 @@ -563,7 +1155,6 @@ Connected clusters: 0 Maximum send/receive size: 32768/32768 bytes ``` - @@ -595,14 +1186,14 @@ COROSYNC_QNETD_OPTIONS="-4" ### Authenticate the hacluster user to the cluster's members -A user called **hacluster** has been automatically created when you installed Pacemaker and Corosync. This user will run the Corosync and Pacemaker processes on all 3 members of the cluster. -For the sake of simplicity, the **hacluster** user will be assigned the same password on both central nodes and on the quorum device. Run the following command on each machine and set the password you want. +A user called **hacluster** has been automatically created when you installed Pacemaker and Corosync. This user will run the Corosync and Pacemaker processes on all 5 members of the cluster. +For the sake of simplicity, the **hacluster** user will be assigned the same password on both central nodes, on both database servers and on the quorum device. Run the following command on each machine and set the password you want. ```bash passwd hacluster ``` -Now that all members of the cluster (both central nodes and the quorum device server) share the same password, run this command **only on one of the central nodes** in order to authenticate the **hacluster** user to all members of the cluster. +Now that all members of the cluster (both central nodes, both database nodes and the quorum device server) share the same password, run this command **only on one of the central nodes** in order to authenticate the **hacluster** user to all members of the cluster. @@ -671,6 +1262,8 @@ pcs cluster setup \ centreon_cluster \ "@CENTRAL_ACTIVE_NAME@" \ "@CENTRAL_PASSIVE_NAME@" \ + "@DATABASE_ACTIVE_NAME@" \ + "@DATABASE_PASSIVE_NAME@" \ --force ``` @@ -682,6 +1275,8 @@ pcs cluster setup \ centreon_cluster \ "@CENTRAL_ACTIVE_NAME@" \ "@CENTRAL_PASSIVE_NAME@" \ + "@DATABASE_ACTIVE_NAME@" \ + "@DATABASE_PASSIVE_NAME@" \ --force ``` @@ -693,6 +1288,8 @@ pcs cluster setup \ centreon_cluster \ "@CENTRAL_ACTIVE_NAME@" \ "@CENTRAL_PASSIVE_NAME@" \ + "@DATABASE_ACTIVE_NAME@" \ + "@DATABASE_PASSIVE_NAME@" \ --force ``` @@ -722,7 +1319,7 @@ Sending 'corosync.conf' to '@CENTRAL_ACTIVE_IPADDR@', '@CENTRAL_PASSIVE_IPADDR@' Cluster has been successfully set up. ``` -Then start the `pacemaker` service **on both central nodes**: +Then start the `pacemaker` service **on both central and database nodes**: ```bash systemctl enable pacemaker pcsd corosync @@ -739,7 +1336,7 @@ pcs resource defaults update resource-stickiness="100" You can now monitor the state of the cluster with the `crm_mon -f` command: it will display [the new cluster resources as you create them](#create-the-centreon-resource-group). -At this stage, no resources have been added to the cluster, so the resultst of the command run from node 1 should look like this: +At this stage, no resources have been added to the cluster, so the results of the command run from node 1 should look like this: ```shell Cluster Summary: @@ -788,6 +1385,129 @@ Starting corosync-qdevice... @CENTRAL_PASSIVE_IPADDR@: corosync-qdevice started ``` +### Create the database cluster resources + +All commands within this section should be executed on **only one Cluster node**. The configuration will be spread automatically. + +#### Primary & Secondary MySQL processes + + + + +```bash +pcs resource create "ms_mysql" \ + ocf:heartbeat:mariadb-centreon \ + config="/etc/my.cnf.d/server.cnf" \ + pid="/var/lib/mysql/mysql.pid" \ + datadir="/var/lib/mysql" \ + socket="/var/lib/mysql/mysql.sock" \ + binary="/usr/bin/mysqld_safe" \ + node_list="@DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@" \ + replication_user="@MARIADB_REPL_USER@" \ + replication_passwd='@MARIADB_REPL_PASSWD@' \ + test_user="@MARIADB_REPL_USER@" \ + test_passwd='@MARIADB_REPL_PASSWD@' \ + test_table='centreon.host' +``` + + + + +```bash +pcs resource create "ms_mysql" \ + ocf:heartbeat:mariadb-centreon \ + config="/etc/my.cnf.d/server.cnf" \ + pid="/var/lib/mysql/mysql.pid" \ + datadir="/var/lib/mysql" \ + socket="/var/lib/mysql/mysql.sock" \ + binary="/usr/bin/mysqld_safe" \ + node_list="@DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@" \ + replication_user="@MARIADB_REPL_USER@" \ + replication_passwd='@MARIADB_REPL_PASSWD@' \ + test_user="@MARIADB_REPL_USER@" \ + test_passwd='@MARIADB_REPL_PASSWD@' \ + test_table='centreon.host' +``` + + + + +```bash +pcs resource create "ms_mysql" \ + ocf:heartbeat:mariadb-centreon \ + config="/etc/mysql/mariadb.conf.d/50-server.cnf" \ + pid="/run/mysqld/mysqld.pid" \ + datadir="/var/lib/mysql" \ + socket="/run/mysqld/mysqld.sock" \ + binary="/usr/bin/mysqld_safe" \ + node_list="@DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@" \ + replication_user="@MARIADB_REPL_USER@" \ + replication_passwd='@MARIADB_REPL_PASSWD@' \ + test_user="@MARIADB_REPL_USER@" \ + test_passwd='@MARIADB_REPL_PASSWD@' \ + test_table='centreon.host' +``` + + + + +> **WARNING:** the syntax of the following command depends on the Linux Distribution you are using. + + + + +```bash +pcs resource promotable ms_mysql \ + master-node-max="1" \ + clone_max="2" \ + globally-unique="false" \ + clone-node-max="1" \ + notify="true" +``` + + + + +```bash +pcs resource promotable ms_mysql \ + master-node-max="1" \ + clone_max="2" \ + globally-unique="false" \ + clone-node-max="1" \ + notify="true" +``` + + + + +```bash +pcs resource promotable ms_mysql \ + master-node-max="1" \ + clone_max="2" \ + globally-unique="false" \ + clone-node-max="1" \ + notify="true" +``` + + + + +#### MariaDB Virtual IP Address + +```bash +pcs resource create vip_mysql \ + ocf:heartbeat:IPaddr2 \ + ip="@VIP_SQL_IPADDR@" \ + nic="@VIP_SQL_IFNAME@" \ + cidr_netmask="@VIP_SQL_CIDR_NETMASK@" \ + broadcast="@VIP_SQL_BROADCAST_IPADDR@" \ + flush_routes="true" \ + meta target-role="stopped" \ + op start interval="0s" timeout="20s" \ + stop interval="0s" timeout="20s" \ + monitor interval="10s" timeout="20s" +``` + ### Define the clone resources RRD broker and PHP8 will run on both central nodes at the same time. For this to work properly, they must be declared as clone resources. @@ -997,6 +1717,74 @@ pcs resource create snmptrapd \ --group centreon ``` +### Define resource constraints + +When using the four-node architecture, you must define some specific constraints to specify where resources could run. + +In order to colocate the active database role with the VIP, define a mutual constraint: + + + + +```bash +pcs constraint colocation add "vip_mysql" with master "ms_mysql-clone" +pcs constraint colocation add master "ms_mysql-clone" with "vip_mysql" +``` + + + + +```bash +pcs constraint colocation add "vip_mysql" with Promoted "ms_mysql-clone" +pcs constraint colocation add Promoted "ms_mysql-clone" with "vip_mysql" +``` + + + + +```bash +pcs constraint colocation add "vip_mysql" with master "ms_mysql-clone" +pcs constraint colocation add master "ms_mysql-clone" with "vip_mysql" +``` + + + + +Create the constraint that prevents Centreon processes from running on database nodes and vice-versa: + + + + +```bash +pcs constraint location centreon avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY +pcs constraint location ms_mysql-clone avoids @CENTRAL_MASTER_NAME@=INFINITY @CENTRAL_SLAVE_NAME@=INFINITY +pcs constraint location cbd_rrd-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY +pcs constraint location php-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY +``` + + + + +```bash +pcs constraint location centreon avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY +pcs constraint location ms_mysql-clone avoids @CENTRAL_MASTER_NAME@=INFINITY @CENTRAL_SLAVE_NAME@=INFINITY +pcs constraint location cbd_rrd-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY +pcs constraint location php-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY +``` + + + + +```bash +pcs constraint location centreon avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY +pcs constraint location ms_mysql-clone avoids @CENTRAL_MASTER_NAME@=INFINITY @CENTRAL_SLAVE_NAME@=INFINITY +pcs constraint location cbd_rrd-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY +pcs constraint location php-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY +``` + + + + ### Activate the resources ```bash @@ -1079,7 +1867,7 @@ In our case: pcs resource enable ms_mysql ``` -## Step 3: Integrate your pollers +## Step 4: Integrate your pollers 1. If you haven't already done so, apply the necessary [kernel network tuning](#kernel-network-tuning) to the host machines for your pollers. 2. [Install your pollers](https://docs.centreon.com/docs/installation/installation-of-a-poller/using-packages) and register them using the VIP as the address of the central server. The password is that of the admin account for node 1? - Then run the wizard to [attach the poller](https://docs.centreon.com/docs/monitoring/monitoring-servers/add-a-poller-to-configuration) to the VIP. @@ -1087,6 +1875,6 @@ pcs resource enable ms_mysql You can now start your monitoring. -## Step 4: Monitor your cluster +## Step 5: Monitor your cluster See [Monitoring Centreon HA](https://docs.centreon.com/docs/administration/centreon-ha/monitoring-guide). diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md index 279858b3e896..b73953027662 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md @@ -7,39 +7,43 @@ import TabItem from '@theme/TabItem'; ## What are the elements of Centreon HA? -Centreon HA consists of a set of clustering tools on top of twin Centreon central servers that manage pollers (in a [distributed architecture](../../installation/architectures.md#distributed-architecture)), with remote databases. +Centreon HA consists of a set of clustering tools on top of twin Centreon central servers that manage pollers (in a [distributed architecture](../../installation/architectures.md#distributed-architecture)), with remote twin databases. * There are 5 members in a Centreon HA cluster: - * 2 Centreon central servers: one active node, one passive node. Thanks to synchronization scripts, the same data will exist on both servers so that if the active node goes down, the passive node will take its place. The central servers do not monitor your resources (the pollers do). In this documentation, we will call the central servers "node 1" and "node 2" to differentiate them: bear in mind that both of them can have the role of active or passive node. - * 1 server called "quorum device", whose sole purpose is to decide which central server is the active node and which is the passive node. This is mandatory to avoid split-brain issues. You can define one of your pollers as the quorum device. - * 2 database nodes. They are remote, replicated databases. There is one active database node and one passive database node. + * 2 Centreon central servers: one active node, one passive node. Thanks to synchronization scripts, the same data will exist on both servers so that if the active node goes down, the passive node will take its place. The central servers do not monitor your resources (the pollers do). In this documentation, we will call the central servers "central node 1" and "central node 2" to differentiate them: bear in mind that both of them can have the role of active or passive node. + * 2 database nodes. They are remote, replicated databases. There is one active database node and one passive database node, and all data is synchronized from one node to another. >>> Active/Passive binlog replication (storage) + * 1 server called "quorum device", whose sole purpose is to decide which central server/database is the active node and which is the passive node. This is mandatory to avoid split-brain issues. You can define one of your pollers as the quorum device. + + > Although the Centreon HA cluster is technically one cluster with 5 members, it actually works as two independent 2-node clusters (plus a server that acts as a quorum device for both clusters). Location constraints define that only Centreon processes run on the central nodes, and only database processes run on the database nodes. The central server cluster and the database cluster are independent: the database cluster fails over only when the active database node goes down, not when the active central node fails over. * Clustering tools: - - Centreon high availability scripts, contained in the **centreon-ha-web** package. They include the **centreon_central_sync** service, that synchronizes all the necessary processes ("resources"). Also, in the **centreon-ha-common** package, scripts that manage the replication of the database and the automation of the failover process. - - Corosync: allows the members of the cluster to communicate in real time, to check if the active node is up, and take the decision to failover if needed. + - Centreon high availability scripts, contained in the **centreon-ha-web** package. They include the **centreon_central_sync** service, that synchronizes all the necessary Centreon processes ("resources"). Also, in the **centreon-ha-common** package, scripts manage the replication of the database and the automation of its failover process. + - Corosync: allows the members of the cluster to communicate in real time, to check if the active nodes are up, and take the decision to failover if needed (for the central servers or for the databases). - Pacemaker: starts, stops and controls the state of Centreon processes. You need to tell Pacemaker which processes should be checked: these processes are called "resources". - crm_mon: a command-line tool that allows you to know the state of the cluster in real time. - pcs: a command-line tool that allows you to configure Corosync and Pacemaker. * Pollers, which do the actual monitoring. -* A VIP to which the pollers send the data, so that the VIP can forward the data to the current active central node. +* A "central VIP" to which the pollers send the collected data, so that the VIP can forward the data to the current active central node. -* A VIP to which the active central node sends the data, so that the VIP can forward the data to the current active database node. +* A "database VIP" to which the active central node sends the data, so that the VIP can forward the data to the current active database node. ![image](../../assets/integrations/centreon-ha/centreon-ha.png) ## How does the HA cluster work? -In a Centreon HA cluster, all processes ("resources") are managed by the clustering tools (Pacemaker and Corosync). +In the central cluster, all Centreon processes ("resources") are managed by the clustering tools (Pacemaker and Corosync). + +1. Everything is OK : central node 1 (the current active node) receives data from the pollers, and all relevant files are synchronized by a dedicated script (**centreon_central_sync**) onto central node 2 (the current passive node) so that the passive node is ready to become the active node at all times. +2. An incident occurs and central node 1 (the active node) goes down. + - Corosync detects that it is down: after consulting with the quorum device, it tells central node 2 to become the active node. + - An operator is notified that central node 1 is down, thanks to the Centreon monitoring that has been set up on the poller. +3. Central node 2 is now the active node. It receives data from the pollers. During this time, the operator tries to understand why central node 1 is down. They must fix the problem using the cluster management tool **pcs**, not by manipulating central node 1 directly. +4. Central node 1 is fixed and comes back online. The **centreon_central_sync** script synchronizes all relevant files from central node 2 to central node 1, so that central node 1 can catch up on what has happened during its down time. Central node 1 is ready to become the active node if central node 2 goes down. -1. Everything is OK : Node 1 (the current active node) receives data from the pollers, and all relevant files are synchronized by a dedicated script (**centreon_central_sync**) onto node 2 (the current passive node) so that the passive node is ready to become the active node at all times. -2. An incident occurs and node 1 (the active node) goes down. - - Corosync detects that it is down: after consulting with the quorum device, it tells node 2 to become the active node. - - An operator is notified that node 1 is down, thanks to the Centreon monitoring that has been set up on the poller. -3. Node 2 is now the active node. It receives data from the pollers. During this time, the operator tries to understand why node 1 is down. They must fix the problem using the cluster management tool pcs, not by manipulating node 1 directly. -4. Node 1 is fixed and comes back online. The **centreon_central_sync** script synchronizes all relevant files from node 2 to node 1, so that node 1 can catch up on what has happened during its down time. Node 1 is ready to become the active node if node 2 goes down. +The process is the same for the database cluster. ## How do I know the state of the cluster? @@ -51,7 +55,7 @@ You can also [know the state of the cluster at all times](../../administration/c ## What processes are synchronized by Centreon HA? -Here is the list of processes (resources) that will be managed by the HA tools: +Here is the list of processes (resources) that will be managed by the HA tools in the central cluster: * Central server applicative daemons * centreon-engine (scheduler) @@ -70,6 +74,8 @@ All these resources are described in the table below. | Name | Type | Description | | ----------------------- | -------------------- | ---------------------------------------------------- | +| `ms_mysql` | multi-state resource | Handles the `mysql` process and data replication | +| `ms_mysql-master` | location | Set MariaDB Master server rule preference | | `php8` | clone service | FastCGI Process Manager service (`php-fpm`) | | `cbd_rrd` | clone service | Broker RRD service (`cbd`) | | `centreon` | group | Centreon "primitive services" group | @@ -84,6 +90,15 @@ All these resources are described in the table below. **Note:** The resources of the `centreon` group are started one after the other in the list order. +| Name | Type | Description | +| ----------------------- | -------------------- | ---------------------------------------------------- | +| `ms_mysql` | multi-state resource | Handles the `mysql` process and data replication | +| `ms_mysql-master` | location | Set MariaDB Master server rule preference | + +>>> mysql sur central? + +>>> 2 tableaux, ce qui tourne sur le cluster central et ce qui tourne sur le cluster db. + ## Active/passive nodes or master/slave nodes? In this chapter, we will refer to active/passive nodes. You may notice that the output of some commands use the terms master and slave: these are Pacemaker and Corosync terms. Master means the active node and slave the passive node. From 2e4bdbb33e17f233dc8fc41c3ef679e005eda48f Mon Sep 17 00:00:00 2001 From: cgenier Date: Wed, 3 Jul 2024 15:07:49 +0200 Subject: [PATCH 19/41] Update --- .../centreon-ha/acceptance-guide.md | 1135 +++++------------ .../centreon-ha/operating-guide.md | 711 ++++++++++- .../centreon-ha/troubleshooting-guide.md | 2 +- .../installation-of-centreon-ha/faq.md | 2 +- .../installation.md | 551 +++++--- .../installation-of-centreon-ha/overview.md | 92 +- 6 files changed, 1361 insertions(+), 1132 deletions(-) diff --git a/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md index cf1d55da5dfd..bff704125c7e 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md @@ -9,11 +9,11 @@ This page provides you with a procedure to validate that your cluster is working > Please note that all commands presented in this document should be run as `root` unless otherwise stated. -On this page, we will use the macros @NODE1_NAME@ and @NODE2_NAME@ to represent the hostnames of node 1 and 2. Bear in mind that depending on the situation, either node 1 or node 2 can be the active or the passive node (if node 1 is the active node, node 2 is the passive node, and vice versa). +On this page, we will use the macros @CENTRAL_NODE1_NAME@ and @CENTRAL_NODE2_NAME@ to represent the hostnames of central nodes 1 and 2. Bear in mind that depending on the situation, either node 1 or node 2 can be the active or the passive node (if node 1 is the active node, node 2 is the passive node, and vice versa). It is the same with the database nodes. ## Check the state of the cluster -After completing the installation procedure and before starting any tests, the active node should be node 1 and the passive node should be node 2. +After completing the installation procedure and before starting any tests, the active central node should be central node 1 and the passive central node should be central node 2. To check the general state of the cluster, run the following command: @@ -24,36 +24,51 @@ pcs status The command should return the following information: ```text -Cluster Summary: - * Stack: corosync - * Current DC: @NODE1_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum - * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @NODE1_NAME@ - * 2 nodes configured - * 12 resource instances configured +Cluster name: centreon_cluster +Stack: corosync +Current DC: @CENTRAL_NODE1_NAME@ (version 1.1.23-1.el8_9.1-9acf116022) - partition with quorum +Last updated: Wed May 4 15:36:20 2022 +Last change: Mon May 2 18:20:27 2022 by root via crm_attribute on @CENTRAL_NODE1_NAME@ + + * 4 nodes configured + * 21 resource instances configured + Node List: - * Online: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Online: [ central1 central2 db1 db2 ] + Full List of Resources: + * Clone Set: ms_mysql-clone [ms_mysql] (promotable): + * Masters: [ db1 ] + * Slaves: [ db2 ] + * Stopped: [ central1 central2 ] * Clone Set: php-clone [php]: - * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Started: [ central1 central2 ] + * Stopped: [ db1 db2 ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Started: [ central1 central2 ] + * Stopped: [ db1 db2 ] + * vip_mysql (ocf::heartbeat:IPaddr2): Started db1 * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @NODE1_NAME@ - * http (systemd:httpd): Started @NODE1_NAME@ - * gorgone (systemd:gorgoned): Started @NODE1_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @NODE1_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @NODE1_NAME@ - * centengine (systemd:centengine): Started @NODE1_NAME@ - * centreontrapd (systemd:centreontrapd): Started @NODE1_NAME@ - * snmptrapd (systemd:snmptrapd): Started @NODE1_NAME@ + * vip (ocf::heartbeat:IPaddr2): Started central1 + * http (systemd:httpd): Started central1 + * gorgone (systemd:gorgoned): Started central1 + * centreon_central_sync (systemd:centreon-central-sync): Started central1 + * cbd_central_broker (systemd:cbd-sql): Started central1 + * centengine (systemd:centengine): Started central1 + * centreontrapd (systemd:centreontrapd): Started central1 + * snmptrapd (systemd:snmptrapd): Started central1 + +Daemon Status: + corosync: active/enabled + pacemaker: active/enabled + pcsd: active/enabled ``` > This command should return no errors. If there are "Failed actions" on any resource, troubleshoot them using the [troubleshooting guide](troubleshooting-guide.md). ### Check the constraints -If a failover has occurred at some point, there may be some leftover location constraints. Run the following command: +If a failover has occurred at some point, there may be some leftover location constraints. Run the following command to display the current constraints: ```bash pcs constraint @@ -63,24 +78,66 @@ The command should return this: ```text Location Constraints: + Resource: cbd_rrd-clone + Disabled on: + Node: @DATABASE_NODE1_NAME@ (score:-INFINITY) + Node: @DATABASE_NODE2_NAME@ (score:-INFINITY) + Resource: centreon + Disabled on: + Node: @DATABASE_NODE1_NAME@ (score:-INFINITY) + Node: @DATABASE_NODE2_NAME@ (score:-INFINITY) + Resource: ms_mysql-clone + Disabled on: + Node: @CENTRAL_NODE1_NAME@ (score:-INFINITY) + Node: @CENTRAL_NODE2_NAME@ (score:-INFINITY) + Resource: php-clone + Disabled on: + Node: @DATABASE_NODE1_NAME@ (score:-INFINITY) + Node: @DATABASE_NODE2_NAME@ (score:-INFINITY) Ordering Constraints: Colocation Constraints: + vip_mysql with ms_mysql-clone (score:INFINITY) (rsc-role:Started) (with-rsc-role:Master) + ms_mysql-clone with vip_mysql (score:INFINITY) (rsc-role:Master) (with-rsc-role:Started) Ticket Constraints: + ``` +The output shows the constraints you have defined during the installation procedure: the **ms_mysql-clone** resource only runs on the database nodes, the **cbd_rrd-clone**, **centreon** and **php-clone** resources only run on the central nodes. + To remove unwanted constraints, run the following command: ```bash pcs resource clear centreon ``` +### Check the status of the database synchronization + +To check that the database synchronization is working, run the following command: + +```bash +/usr/share/centreon-ha/bin/mysql-check-status.sh +``` + +The command should return the following information: + +```bash +Connection MASTER Status '@DATABASE_NODE1_NAME@' [OK] +Connection SLAVE Status '@DATABASE_NODE2_NAME@' [OK] +Slave Thread Status [OK] +Position Status [OK] +``` + +> If the synchronization shows `KO`, you must fix it with the help of the [operating guide](operating-guide.md). + ## Test 1: Centreon resource failover ### Perform a failover -We're assuming that node 1 is the active node and node 2 is the passive node ([check the state of the cluster](#check-the-state-of-the-cluster) if you need to). +We're assuming that central node 1 is the active central node and central node 2 is the passive central node ([check the state of the cluster](#check-the-state-of-the-cluster) if you need to). + +When you move the **centreon** resource group from central node 1 to central node 2, central node 2 will become the active node and central node 1 will become the passive node. -When you move all resources from node 1 to node 2 (i.e., the **centreon** resource group), node 2 will become the active node and node 1 will become the passive node. Run the following command: +1. Run the following command to perform the failover: ```bash pcs resource move centreon @@ -90,7 +147,7 @@ In another terminal, you can also use the `crm_mon -fr` command to watch the fai > Warning: The `pcs resource move centreon` command sets an `-INFINITY` constraint on node 1. This means that the resource is no longer allowed to be running on that node. -The resources move to node 2. To check that the resources have indeed moved, run the following command: +2. The resources move to node 2. To check that the resources have indeed moved, run the following command: ```bash pcs status @@ -99,35 +156,52 @@ pcs status The expected output is: ```text +Cluster name: centreon_cluster + +WARNINGS: +Following resources have been moved and their move constraints are still in plac e: 'centreon' +Run 'pcs constraint location' or 'pcs resource clear ' to view or r emove the constraints, respectively + Cluster Summary: - * Stack: corosync - * Current DC: @NODE1_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum - * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @NODE1_NAME@ - * 2 nodes configured - * 12 resource instances configured + * Stack: corosync (Pacemaker is running) + * Current DC: central2 (version 2.1.6-9.1.el8_9-6fdc9deea29) - MIXED-VERSION p artition with quorum + * Last updated: Tue Jun 4 05:41:08 2024 on central2 + * Last change: Tue Jun 4 05:36:52 2024 by root via crm_resource on central1 + * 4 nodes configured + * 21 resource instances configured + Node List: - * Online: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Online: [ central1 central2 db1 db2 ] + Full List of Resources: * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @NODE1_NAME@ ] - * Slaves: [ @NODE2_NAME@ ] + * Masters: [ db1 ] + * Slaves: [ db2 ] + * Stopped: [ central1 central2 ] * Clone Set: php-clone [php]: - * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Started: [ central1 central2 ] + * Stopped: [ db1 db2 ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Started: [ central1 central2 ] + * Stopped: [ db1 db2 ] + * vip_mysql (ocf::heartbeat:IPaddr2): Started db1 * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started Started @NODE2_NAME@ - * http (systemd:httpd): Started Started @NODE2_NAME@ - * gorgone (systemd:gorgoned): Started Started @NODE2_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @NODE2_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @NODE2_NAME@ - * centengine (systemd:centengine): Started @NODE2_NAME@ - * centreontrapd (systemd:centreontrapd): Started @NODE2_NAME@ - * snmptrapd (systemd:snmptrapd): Started @NODE2_NAME@ + * vip (ocf::heartbeat:IPaddr2): Started central2 + * http (systemd:httpd): Started central2 + * gorgone (systemd:gorgoned): Started central2 + * centreon_central_sync (systemd:centreon-central-sync): Started central2 + * cbd_central_broker (systemd:cbd-sql): Started central2 + * centengine (systemd:centengine): Started central2 + * centreontrapd (systemd:centreontrapd): Started central2 + * snmptrapd (systemd:snmptrapd): Started central2 + +Daemon Status: + corosync: active/enabled + pacemaker: active/enabled + pcsd: active/enabled ``` -Once the failover is completed, execute the following command to ensure the resources can be moved back to their original node in the future. +3. Once the failover is completed, execute the following command to ensure the resources can be moved back to their original node in the future (EL8 or Debian). ```bash pcs resource clear centreon @@ -137,15 +211,15 @@ This will remove the constraints established during the failover. ### Go back to the nominal situation -If you want to return to the nominal situation, you must perform a second resource failover. +If you want to return to the nominal situation (i.e. central node 1 is the active central node and central node 2 is the passive central node), you must perform a second resource failover. -1. If you have `Location Constraints`, run the constraint cleanup command: +1. If you haven't already done so, run the constraint cleanup command to remove the constraint created by the failover (EL8 or Debian): ```bash pcs resource clear centreon ``` -2. Then, execute the failover command: +2. Then, execute the failover command: ```bash pcs resource move centreon @@ -153,55 +227,78 @@ If you want to return to the nominal situation, you must perform a second resour As before, you can follow the failover with the `crm_mon -fr` command. -3. Finally, remove the constraints with the command: +3. Finally, remove the constraints with the following command (EL8 or Debian): ```bash pcs resource clear centreon ``` -## Test 2: Simulate the loss of the passive node +## Test 2: Simulate the loss of the passive central node -If the passive node goes down, the cluster should carry on working as before, as the resources are managed by the active node. You will see your passive node as down in Resources Status. +If the passive central node goes down, the cluster should carry on working as before, as the resources are managed by the active central node. You will see your passive central node as down in Resources Status. -To simulate a network failure that would isolate the passive node, you can use `iptables` to drop traffic from and to the passive node. The passive node will be completely excluded from the cluster. The active node keeps the majority with the quorum device. +To simulate a network failure that would isolate the passive central node, you can use `iptables` to drop traffic from and to the passive central node. The passive central node will be completely excluded from the cluster. The active central node keeps the majority with the quorum device. ### Perform the test We're assuming that node 1 is the active node and node 2 is the passive node ([check the state of the cluster](#check-the-state-of-the-cluster) if you need to). -To perform this test, launch the `iptables` commands on the active node: +To perform this test, run the `iptables` commands on the **active central node**: ```bash -iptables -A INPUT -s @IP_PASSIVE_NODE@ -j DROP -iptables -A OUTPUT -d @IP_PASSIVE_NODE@ -j DROP +iptables -A INPUT -s @CENTRAL_NODE1_IPADDR@ -j DROP +iptables -A OUTPUT -d @CENTRAL_NODE1_IPADDR@ -j DROP +iptables -A INPUT -s @DATABASE_NODE1_IPADDR@ -j DROP +iptables -A OUTPUT -d @DATABASE_NODE1_IPADDR@ -j DROP +iptables -A INPUT -s @DATABASE_NODE2_IPADDR@ -j DROP +iptables -A OUTPUT -d @DATABASE_NODE2_IPADDR@ -j DROP +iptables -A INPUT -s @QDEVICE_IPADDR@ -j DROP +iptables -A OUTPUT -d @QDEVICE_IPADDR@ -j DROP ``` -The passive node is now excluded from the cluster. +The passive central node is now excluded from the cluster. -If you run `pcs status` on the active node: +If you run `pcs status` on the active central node: * The resources and the cluster are still working. -* The passive node is seen `offline` on the active node: +* The passive central node is seen `offline` on the active node: ```text Cluster name: centreon_cluster -Cluster Summary: - * Stack: corosync - * Current DC: @NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum - * Last updated: Tue Nov 8 15:19:52 2022 - * Last change: Tue Nov 8 14:25:58 2022 by root via crm_resource on @NODE1_NAME@ - * 2 nodes configured - * 12 resource instances configured -Node List: - * Online: [ @NODE1_NAME@ ] - * OFFLINE: [ @NODE2_NAME@ ] -Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @NODE1_NAME@ ] - @@ -545,40 +609,51 @@ Full List of Resources: - * centengine (systemd:centengine): Started @NODE1_NAME@ - * centreontrapd (systemd:centreontrapd): Started @NODE1_NAME@ - * snmptrapd (systemd:snmptrapd): Started @NODE1_NAME@ +Stack: corosync +Current DC: @CENTRAL_MASTER_NAME@ (version 1.1.23-1.el8_9.1-9acf116022) - partition with quorum +Last updated: Thu May 5 10:34:05 2022 +Last change: Thu May 5 09:09:50 2022 by root via crm_resource on @CENTRAL_MASTER_NAME@ + +4 nodes configured +21 resource instances configured + +Online: [ @DATABASE_MASTER_NAME@ @CENTRAL_MASTER_NAME@ @DATABASE_SLAVE_NAME@ ] +OFFLINE: [ @CENTRAL_SLAVE_NAME@ ] + +Full list of resources: + + Master/Slave Set: ms_mysql-clone [ms_mysql] + Masters: [ @DATABASE_MASTER_NAME@ ] + Slaves: [ @DATABASE_SLAVE_NAME@ ] + Stopped: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + vip_mysql (ocf::heartbeat:IPaddr2): Started @DATABASE_MASTER_NAME@ + Clone Set: php-clone [php] + Started: [ @CENTRAL_MASTER_NAME@ ] + Stopped: [ @DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@ @CENTRAL_SLAVE_NAME@ ] + Clone Set: cbd_rrd-clone [cbd_rrd] + Started: [ @CENTRAL_MASTER_NAME@ ] + Stopped: [ @DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@ @CENTRAL_SLAVE_NAME@ ] + Resource Group: centreon + vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_MASTER_NAME@ + http (systemd:httpd24-httpd): Started @CENTRAL_MASTER_NAME@ + gorgone (systemd:gorgoned): Started @CENTRAL_MASTER_NAME@ + centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_MASTER_NAME@ + cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_MASTER_NAME@ + centengine (systemd:centengine): Started @CENTRAL_MASTER_NAME@ + centreontrapd (systemd:centreontrapd): Started @CENTRAL_MASTER_NAME@ + snmptrapd (systemd:snmptrapd): Started @CENTRAL_MASTER_NAME@ + Daemon Status: corosync: active/enabled pacemaker: active/enabled @@ -217,19 +314,19 @@ If you run `pcs status` on the passive node: Cluster name: centreon_cluster Cluster Summary: * Stack: corosync - * Current DC: @NODE2_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition WITHOUT quorum + * Current DC: @CENTRAL_NODE2_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition WITHOUT quorum * Last updated: Tue Nov 8 14:33:00 2022 - * Last change: Tue Nov 8 14:25:58 2022 by root via crm_resource on @NODE1_NAME@ + * Last change: Tue Nov 8 14:25:58 2022 by root via crm_resource on @CENTRAL_NODE1_NAME@ * 2 nodes configured * 12 resource instances configured Node List: - * Online: [ @NODE2_NAME@ ] - * OFFLINE: [ @NODE1_NAME@ ] + * Online: [ @CENTRAL_NODE2_NAME@ ] + * OFFLINE: [ @CENTRAL_NODE1_NAME@ ] Full List of Resources: * Clone Set: php-clone [php]: - * Stopped: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Stopped: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Stopped: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Stopped: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] * Resource Group: centreon: * vip (ocf::heartbeat:IPaddr2): Stopped * http (systemd:httpd): Stopped @@ -260,14 +357,14 @@ The command should return the following information: ```text Chain INPUT (policy ACCEPT) target prot opt source destination -DROP all -- @NODE2_NAME@ anywhere +DROP all -- @CENTRAL_NODE2_NAME@ anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination -DROP all -- anywhere @NODE2_NAME@ +DROP all -- anywhere @CENTRAL_NODE2_NAME@ ``` If you do not have any other iptables rules configured, you can execute the following command to remove the rules related to the test: @@ -294,27 +391,42 @@ If you run `pcs status` on the active node, the passive node is seen as `online` ```text Cluster Summary: * Stack: corosync - * Current DC: @NODE1_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum + * Current DC: @CENTRAL_NODE1_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @NODE1_NAME@ + * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @CENTRAL_NODE1_NAME@ * 2 nodes configured * 12 resource instances configured Node List: - * Online: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Online: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] Full List of Resources: * Clone Set: php-clone [php]: - * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Started: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Started: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @NODE1_NAME@ - * http (systemd:httpd): Started @NODE1_NAME@ - * gorgone (systemd:gorgoned): Started @NODE1_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @NODE1_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @NODE1_NAME@ - * centengine (systemd:centengine): Started @NODE1_NAME@ - * centreontrapd (systemd:centreontrapd): Started @NODE1_NAME@ - * snmptrapd (systemd:snmptrapd): Started @NODE1_NAME@ + * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE1_NAME@ + * http (systemd:httpd): Started @CENTRAL_NODE1_NAME@ + * gorgone (systemd:gorgoned): Started @CENTRAL_NODE1_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE1_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE1_NAME@ + * centengine (systemd:centengine): Started @CENTRAL_NODE1_NAME@ + * centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE1_NAME@ + * snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE1_NAME@ +``` + +Also check that the database replication is still operational using the following command: + +```bash +/usr/share/centreon-ha/bin/mysql-check-status.sh +``` + +The expected output is: + +```text +Connection MASTER Status '@DATABASE_NODE1_NAME@' [OK] +Connection SLAVE Status '@DATABASE_NODE2_NAME@' [OK] +Slave Thread Status [OK] +Position Status [OK] ``` ## Test 3: Simulate the loss of the active node @@ -323,47 +435,62 @@ This test checks that the resources are switched to the passive node if the acti ### Perform the test -We're assuming that node 1 is the active node and node 2 is the passive node ([check the state of the cluster](#check-the-state-of-the-cluster) if you need to). +We're assuming that central node 1 is the active central node and central node 2 is the passive central node ([check the state of the cluster](#check-the-state-of-the-cluster) if you need to). -To perform this test, run the commands on the active node: +To perform this test, run the commands on the active central node: ```bash -iptables -A INPUT -s @IP_PASSIVE_NODE@ -j DROP -iptables -A OUTPUT -d @IP_PASSIVE_NODE@ -j DROP -iptables -A INPUT -s @QDEVICE_IP@ -j DROP -iptables -A OUTPUT -d @QDEVICE_IP@ -j DROP +iptables -A INPUT -s @CENTRAL_NODE2_IPADDR@ -j DROP +iptables -A OUTPUT -d @CENTRAL_NODE2_IPADDR@ -j DROP +iptables -A INPUT -s @DATABASE_NODE1_IPADDR@ -j DROP +iptables -A OUTPUT -d @DATABASE_NODE1_IPADDR@ -j DROP +iptables -A INPUT -s @DATABASE_NODE2_IPADDR@ -j DROP +iptables -A OUTPUT -d @DATABASE_NODE2_IPADDR@ -j DROP +iptables -A INPUT -s @QDEVICE_IPADDR@ -j DROP +iptables -A OUTPUT -d @QDEVICE_IPADDR@ -j DROP ``` -Resources on the active node (node 1) should stop. Node 2 becomes the active node and all the resources switch to it. You can use the `crm_mon -fr` command on node 2 to watch the startup of resources: +Resources on the active central node (central node 1) should stop. Central node 2 becomes the active node and all the resources switch to it. You can use the `crm_mon -fr` command on central node 2 to watch the startup of resources: ```text -Cluster Summary: - * Stack: corosync - * Current DC: @NODE2_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum - * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @NODE2_NAME@ - * 2 nodes configured - * 12 resource instances configured -Node List: - * Online: [ @NODE2_NAME@ ] - * OFFLINE [ @NODE1_NAME@ ] -Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @NODE1_NAME@ ] - * Slaves: [ @NODE2_NAME@ ] - * Clone Set: php-clone [php]: - * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] - * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] - * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @NODE2_NAME@ - * http (systemd:httpd): Started @NODE2_NAME@ - * gorgone (systemd:gorgoned): Started @NODE2_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @NODE2_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @NODE2_NAME@ - * centengine (systemd:centengine): Started @NODE2_NAME@ - * centreontrapd (systemd:centreontrapd): Started @NODE2_NAME@ - * snmptrapd (systemd:snmptrapd): Started @NODE2_NAME@ +Stack: corosync +Current DC: @CENTRAL_NODE1_NAME@ (version 1.1.23-1.el8_9.1-9acf116022) - partition with quorum +Last updated: Thu May 5 11:06:38 2022 +Last change: Thu May 5 09:09:50 2022 by root via crm_resource on @CENTRAL_NODE1_NAME@ + +4 nodes configured +21 resource instances configured + +Online: [ @DATABASE_NODE1_NAME@ @DATABASE_NODE2_NAME@ @CENTRAL_NODE2_NAME@ ] +OFFLINE: [ @CENTRAL_NODE1_NAME@ ] + +Full list of resources: + + Master/Slave Set: ms_mysql-clone [ms_mysql] + Masters: [ @DATABASE_NODE1_NAME@ ] + Slaves: [ @DATABASE_NODE2_NAME@ ] + Stopped: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] +vip_mysql (ocf::heartbeat:IPaddr2): Started @DATABASE_NODE1_NAME@ + Clone Set: php-clone [php] + Started: [ @CENTRAL_NODE2_NAME@ ] + Stopped: [ @DATABASE_NODE1_NAME@ @CENTRAL_NODE1_NAME@ @DATABASE_NODE2_NAME@ ] + Clone Set: cbd_rrd-clone [cbd_rrd] + Started: [ @CENTRAL_NODE2_NAME@ ] + Stopped: [ @DATABASE_NODE1_NAME@ @CENTRAL_NODE1_NAME@ @DATABASE_NODE2_NAME@ ] + Resource Group: centreon + vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE2_NAME@ + http (systemd:httpd24-httpd): Started @CENTRAL_NODE2_NAME@ + gorgone (systemd:gorgoned): Started @CENTRAL_NODE2_NAME@ + centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE2_NAME@ + cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE2_NAME@ + centengine (systemd:centengine): Started @CENTRAL_NODE2_NAME@ + centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE2_NAME@ + snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE2_NAME@ + +Migration Summary: +* Node @DATABASE_NODE1_NAME@: +* Node @CENTRAL_NODE2_NAME@: +* Node @DATABASE_NODE2_NAME@: ``` ### Go back to the nominal situation @@ -379,15 +506,19 @@ The command should return the following information: ```text Chain INPUT (policy ACCEPT) target prot opt source destination -DROP all -- @NODE2_NAME@ anywhere -DROP all -- @QDEVICE_NAME@ anywhere +DROP all -- @CENTRAL_NODE2_NAME@ anywhere +DROP all -- @DATABASE_NODE1_NAME@ anywhere +DROP all -- @DATABASE_NODE2_NAME@ anywhere +DROP all -- @QDEVICE_NAME@ anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination -DROP all -- anywhere @NODE2_NAME@ +DROP all -- anywhere @CENTRAL_NODE2_NAME@ +DROP all -- anywhere @DATABASE_NODE1_NAME@ +DROP all -- anywhere @DATABASE_NODE2_NAME@ DROP all -- anywhere @QDEVICE_NAME@ ``` @@ -415,37 +546,37 @@ If you run the `crm_mon` command on node 2, you can see that node 1 is still the ```text Cluster Summary: * Stack: corosync - * Current DC: @NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum + * Current DC: @CENTRAL_NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum * Last updated: Tue Nov 8 17:27:28 2022 - * Last change: Tue Nov 8 17:23:19 2022 by root via crm_attribute on @NODE2_NAME@ + * Last change: Tue Nov 8 17:23:19 2022 by root via crm_attribute on @CENTRAL_NODE2_NAME@ * 2 nodes configured * 12 resource instances configured Node List: - * Online: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Online: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] Full List of Resources: * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * ms_mysql (ocf::heartbeat:mariadb-centreon): Stopped @NODE1_NAME@ (Monitoring) - * Masters: [ @NODE2_NAME@ ] - * Stopped: [ @NODE1_NAME@ ] + * ms_mysql (ocf::heartbeat:mariadb-centreon): Stopped @CENTRAL_NODE1_NAME@ (Monitoring) + * Masters: [ @CENTRAL_NODE2_NAME@ ] + * Stopped: [ @CENTRAL_NODE1_NAME@ ] * Clone Set: php-clone [php]: - * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Started: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @NODE1_NAME@ @NODE2_NAME@ ] + * Started: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @NODE2_NAME@ - * http (systemd:httpd): Started @NODE2_NAME@ - * gorgone (systemd:gorgoned): Started @NODE2_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @NODE2_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @NODE2_NAME@ - * centengine (systemd:centengine): Started @NODE2_NAME@ - * centreontrapd (systemd:centreontrapd): Started @NODE2_NAME@ - * snmptrapd (systemd:snmptrapd): Started @NODE2_NAME@ + * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE2_NAME@ + * http (systemd:httpd): Started @CENTRAL_NODE2_NAME@ + * gorgone (systemd:gorgoned): Started @CENTRAL_NODE2_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE2_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE2_NAME@ + * centengine (systemd:centengine): Started @CENTRAL_NODE2_NAME@ + * centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE2_NAME@ + * snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE2_NAME@ Migration Summary: - * Node: @NODE1_NAME@: + * Node: @CENTRAL_NODE1_NAME@: * ms_mysql: migration-threshold=1000000 fail-count=1000000 last-failure='Tue Nov 8 17:27:25 2 022' Failed Resource Actions: - * ms_mysql_start_0 on @NODE1_NAME@ 'error' (1): call=440, status='complete', exitreason='M + * ms_mysql_start_0 on @CENTRAL_NODE1_NAME@ 'error' (1): call=440, status='complete', exitreason='M ariaDB slave io has failed (1236): Got fatal error 1236 from master when reading data from binary log: 'Error: connecting slave', last-rc-change='Tue Nov 8 17:27:21 2022', queued=0ms, exec=4060ms ``` @@ -480,21 +611,21 @@ At this time, the cluster is in degraded mode with two passive nodes. In this particular case, it returns the following information because the ms_mysql resource is stopped on node 1: ```text -Connection SLAVE Status '@NODE1_NAME@' [KO] +Connection SLAVE Status '@CENTRAL_NODE1_NAME@' [KO] Error reports: - ERROR 2002 (HY000): Can't connect to MySQL server on '@NODE1_NAME@' (115) -Impossible de se connecter au serveur '@NODE1_NAME@'. -Connection SLAVE Status '@NODE2_NAME@' [OK] + ERROR 2002 (HY000): Can't connect to MySQL server on '@CENTRAL_NODE1_NAME@' (115) +Impossible de se connecter au serveur '@CENTRAL_NODE1_NAME@'. +Connection SLAVE Status '@CENTRAL_NODE2_NAME@' [OK] Slave Thread Status [KO] Error reports: - Skip check on '@NODE1_NAME@'. + Skip check on '@CENTRAL_NODE1_NAME@'. No slave (maybe because we cannot check a server). Position Status [SKIP] Error reports: Skip because we can't identify a unique slave. ``` -You must do a database synchronization from @NODE2_NAME@ to @NODE1_NAME@ by launching the "sync-bigdb" script on the **Slave node**. +You must do a database synchronization from @CENTRAL_NODE2_NAME@ to @CENTRAL_NODE1_NAME@ by launching the "sync-bigdb" script on the **Slave node**. ```shell /usr/share/centreon-ha/bin/mysql-sync-bigdb.sh @@ -509,7 +640,7 @@ Start MySQL Slave OK Start Replication Id User Host db Command Time State Info Progress -5 centreon-repl @NODE2_NAME@:51850 NULL Query 0 starting show processlist 0.000 +5 centreon-repl @CENTRAL_NODE2_NAME@:51850 NULL Query 0 starting show processlist 0.000 6 centreon localhost centreon_storage Sleep 0 NULL 0.000 7 system user NULL Connect 0 Connecting to master NULL 0.000 8 system user NULL Slave_SQL 0 Slave has read all relay log; waiting for more updates NULL 0.000 @@ -524,8 +655,8 @@ Database replication should now be OK. Check this. The result should be: ```text -Connection MASTER Status '@NODE2_NAME@' [OK] -Connection SLAVE Status '@NODE1_NAME@' [OK] +Connection MASTER Status '@CENTRAL_NODE2_NAME@' [OK] +Connection SLAVE Status '@CENTRAL_NODE1_NAME@' [OK] Slave Thread Status [OK] Position Status [OK] ``` @@ -536,7 +667,7 @@ Now, you can perform a failover to return to the initial situation. pcs resource clear centreon ``` -Do a cleanup to clear errors and restart the ms_mysql resource on @NODE1_NAME@. +Do a cleanup to clear errors and restart the ms_mysql resource on @CENTRAL_NODE1_NAME@. ```shell pcs resource cleanup @@ -553,685 +684,29 @@ The **centreon** resource is now relocated and the cluster is OK. Check this wit ```text Cluster Summary: * Stack: corosync - * Current DC: @NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum + * Current DC: @CENTRAL_NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum * Last updated: Wed Nov 9 10:23:54 2022 - * Last change: Wed Nov 9 10:23:26 2022 by root via crm_attribute on @NODE1_NAME@ + * Last change: Wed Nov 9 10:23:26 2022 by root via crm_attribute on @CENTRAL_NODE1_NAME@ * 2 nodes configured * 12 resource instances configured Node List: - * Online: [ @NODE1_NAME@ centreon-rhel8-sec ] + * Online: [ @CENTRAL_NODE1_NAME@ centreon-rhel8-sec ] Full List of Resources: * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @NODE1_NAME@ ] + * Masters: [ @CENTRAL_NODE1_NAME@ ] * Slaves: [ centreon-rhel8-sec ] * Clone Set: php-clone [php]: - * Started: [ @NODE1_NAME@ centreon-rhel8-sec ] + * Started: [ @CENTRAL_NODE1_NAME@ centreon-rhel8-sec ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @NODE1_NAME@ centreon-rhel8-sec ] + * Started: [ @CENTRAL_NODE1_NAME@ centreon-rhel8-sec ] * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @NODE1_NAME@ - * http (systemd:httpd): Started @NODE1_NAME@ - * gorgone (systemd:gorgoned): Started @NODE1_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @NODE1_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @NODE1_NAME@ - * centengine (systemd:centengine): Started @NODE1_NAME@ - * centreontrapd (systemd:centreontrapd): Started @NODE1_NAME@ - * snmptrapd (systemd:snmptrapd): Started @NODE1_NAME@ + * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE1_NAME@ + * http (systemd:httpd): Started @CENTRAL_NODE1_NAME@ + * gorgone (systemd:gorgoned): Started @CENTRAL_NODE1_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE1_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE1_NAME@ + * centengine (systemd:centengine): Started @CENTRAL_NODE1_NAME@ + * centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE1_NAME@ + * snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE1_NAME@ Migration Summary: ``` - - diff --git a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md index a2c8006ff3a3..df45ec94ea0a 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md @@ -3,111 +3,712 @@ id: operating-guide title: Operating guide --- -> Unless otherwise stated, all commands in this document must be passed as `root`. +> Unless otherwise stated, all commands in this page must be passed as `root`. -> In this page, we will refer to characteristics that are bound to change from one platform to another (such as IP addresses and host names) by the [macros defined here](../../installation/installation-of-centreon-ha/installation.md#convention-for-names-and-ip-addresses). +## Logging in to Centreon on the active node -## What happens when the cluster fails over? +You access the interface of the active node via the IP address of the central VIP. This means that you always use the same URL to access the interface, whether the interface is that of central node 1 or of central node 2. -When the cluster fails over (e.g. when the active node is affected by a network outage, if its Broker partitions are full...): +> In this page, we will refer to characteristics that are bound to change from one platform to another (such as IP addresses and host names) by the [macros defined here](../../installation/installation-of-centreon-ha/installation.md#convention-for-names-and-ip-addresses).--> -* The host for the VIP should be OK (it may temporarily go down in a SOFT state if the corresponding monitoring check is performed at the exact same time the cluster fails over.) -* The host for the central node that failed will show up as DOWN and/or with CRITICAL services. -* You may receive notifications if you have configured them. -* You may have to log on to the interface again. +## How do I know the state of the cluster? -## In Resource Status, how do I know the state of the cluster? +### Using crm_mon and pcs status -On both central nodes, the **PCS-Status** service gives you the detailed state of the cluster. The output of the service in the details panel is the output of the `pcs status` command. +You can know the state of the cluster at all times by using the `crm_mon` command, or the `pcs status`command, on any member of the cluster (central nodes, quorum device, database nodes). -## In Resource status, how do I know which central is the active node? +* `pcs status` has a static output: it displays the state of the cluster as it is at the time you run the command. -You can know which central is the active node by looking at which node is carrying the cluster resources in the output of the **PCS-Status** service on each central. +* `crm_mon` has a dynamic output: the state of the cluster is displayed in real time. You can watch the resources being stopped and transferred to the other node. Use `crm_mon -fr` to keep displaying stopped resources. -## Cluster Management +Example of output when the cluster is working properly: + +```text +Cluster Summary: + * Stack: corosync (Pacemaker is running) + * Current DC: central2 (version 2.1.6-9.1.el8_9-6fdc9deea29) - MIXED-VERSION partition with quorum + * Last updated: Tue Jun 4 07:49:50 2024 on central1 + * Last change: Tue Jun 4 05:44:11 2024 by root via crm_resource on central2 + * 4 nodes configured + * 21 resource instances configured + +Node List: + * Online: [ central1 central2 db1 db2 ] -The following set of commands can be run from any member of the cluster (central nodes, quorum device). +Full List of Resources: + * Clone Set: ms_mysql-clone [ms_mysql] (promotable): + * Masters: [ db1 ] + * Slaves: [ db2 ] + * Stopped: [ central1 central2 ] + * Clone Set: php-clone [php]: + * Started: [ central1 central2 ] + * Stopped: [ db1 db2 ] + * Clone Set: cbd_rrd-clone [cbd_rrd]: + * Started: [ central1 central2 ] + * Stopped: [ db1 db2 ] + * vip_mysql (ocf::heartbeat:IPaddr2): Started db1 + * Resource Group: centreon: + * vip (ocf::heartbeat:IPaddr2): Started central1 + * http (systemd:httpd): Started central1 + * gorgone (systemd:gorgoned): Started central1 + * centreon_central_sync (systemd:centreon-central-sync): Started central1 + * cbd_central_broker (systemd:cbd-sql): Started central1 + * centengine (systemd:centengine): Started central1 + * centreontrapd (systemd:centreontrapd): Started central1 + * snmptrapd (systemd:snmptrapd): Started central1 + +Migration Summary: +``` -### Display the status of the cluster +> These commands should return no errors. If there are "Failed actions" on any resource, troubleshoot them using the [troubleshooting guide](troubleshooting-guide.md). -To view the general state of the cluster, you can run the following commands: +### Using the Centreon interface -* `pcs status`, which has a static output: it displays the state of the cluster as it is at the time you run the command. +The installation process includes the monitoring of the members of the cluster by a poller. This way, you can be notified if a member of the cluster goes down. -* `crm_mon`, which has a dynamic output: the state of the cluster is displayed in real time. You can watch the resources being stopped and transferred to the other node. Use `crm_mon -fr` to keep displaying stopped resources. +The Resource Status page gives you the following information: -Example of output when the cluster is working properly: +* On both central nodes, the **PCS-Status** service gives you the detailed state of the cluster. The output of the service in the details panel is the output of the `pcs status` command. +* You can know which central node is the active node by looking at which node is carrying the cluster resources in the output of the **PCS-Status** service on each central. + +## Check the constraints + +If a failover has occurred at some point, there may be some leftover location constraints. Run the following command to display the current constraints: + +```bash +pcs constraint +``` + +The command should return this: + +```text +Location Constraints: + Resource: cbd_rrd-clone + Disabled on: + Node: @DATABASE_NODE1_NAME@ (score:-INFINITY) + Node: @DATABASE_NODE2_NAME@ (score:-INFINITY) + Resource: centreon + Disabled on: + Node: @DATABASE_NODE1_NAME@ (score:-INFINITY) + Node: @DATABASE_NODE2_NAME@ (score:-INFINITY) + Resource: ms_mysql-clone + Disabled on: + Node: @CENTRAL_NODE1_NAME@ (score:-INFINITY) + Node: @CENTRAL_NODE2_NAME@ (score:-INFINITY) + Resource: php-clone + Disabled on: + Node: @DATABASE_NODE1_NAME@ (score:-INFINITY) + Node: @DATABASE_NODE2_NAME@ (score:-INFINITY) +Ordering Constraints: +Colocation Constraints: + vip_mysql with ms_mysql-clone (score:INFINITY) (rsc-role:Started) (with-rsc-role:Master) + ms_mysql-clone with vip_mysql (score:INFINITY) (rsc-role:Master) (with-rsc-role:Started) +Ticket Constraints: + +``` + +The output shows the constraints you have defined during the installation procedure: the **ms_mysql-clone** resource only runs on the database nodes, the **cbd_rrd-clone**, **centreon** and **php-clone** resources only run on the central nodes. + +To remove unwanted constraints, run the following command: + +```bash +pcs resource clear centreon +``` +## Check the status of the database synchronization + +To check that the database synchronization is working, run the following command: + +```bash +/usr/share/centreon-ha/bin/mysql-check-status.sh +``` + +The command should return the following information: + +```bash +Connection MASTER Status '@DATABASE_NODE1_NAME@' [OK] +Connection SLAVE Status '@DATABASE_NODE2_NAME@' [OK] +Slave Thread Status [OK] +Position Status [OK] +``` + +> If the synchronization shows `KO`, you must fix it with the help of the [operating guide](operating-guide.md). + +## View the cluster's configuration + +To display a very detailed description the cluster's configuration (e.g. to check the name of the resources for any typos, or to check network information), run this command: + +```bash +pcs config show +``` + +## Testing the cluster + +This section provides you with examples of tests to validate that your cluster is working properly: perform a failover, simulate a network failure, and check that the cluster behaves as expected. + +### How to perform a manual failover + +We're assuming that central node 1 is the active central node and central node 2 is the passive central node ([check the state of the cluster](#how-do-i-know-the-state-of-the-cluster) if you need to). + +When you move the **centreon** resource group from central node 1 to central node 2, central node 2 will become the active node and central node 1 will become the passive node. + +1. Run the following command to perform the failover: + +```bash +pcs resource move centreon ``` + +In another terminal, you can also use the `crm_mon -fr` command to watch the failover as it happens. It will be necessary to use Ctrl+c to exit the command. + +> Warning: The `pcs resource move centreon` command sets an `-INFINITY` constraint on node 1. This means that the resource is no longer allowed to be running on that node. + +2. The resources move to node 2. To check that the resources have indeed moved, run the following command: + +```bash +pcs status +``` + +The expected output is: + +```text +Cluster name: centreon_cluster + +WARNINGS: +Following resources have been moved and their move constraints are still in place: 'centreon' +Run 'pcs constraint location' or 'pcs resource clear ' to view or remove the constraints, respectively + Cluster Summary: * Stack: corosync (Pacemaker is running) - * Current DC: @CENTRAL_PASSIVE_NAME@ (version 2.1.6-9.1.el8_9-6fdc9deea29) - partition with quorum - * Last updated: Wed Apr 17 10:24:25 2024 on @CENTRAL_ACTIVE_NAME@ - * Last change: Tue Apr 16 05:47:37 2024 by hacluster via crmd on @CENTRAL_PASSIVE_NAME@ + * Current DC: central2 (version 2.1.6-9.1.el8_9-6fdc9deea29) - MIXED-VERSION partition with quorum + * Last updated: Tue Jun 4 05:41:08 2024 on central2 + * Last change: Tue Jun 4 05:36:52 2024 by root via crm_resource on central1 + * 4 nodes configured + * 21 resource instances configured + +Node List: + * Online: [ central1 central2 db1 db2 ] + +Full List of Resources: + * Clone Set: ms_mysql-clone [ms_mysql] (promotable): + * Masters: [ db1 ] + * Slaves: [ db2 ] + * Stopped: [ central1 central2 ] + * Clone Set: php-clone [php]: + * Started: [ central1 central2 ] + * Stopped: [ db1 db2 ] + * Clone Set: cbd_rrd-clone [cbd_rrd]: + * Started: [ central1 central2 ] + * Stopped: [ db1 db2 ] + * vip_mysql (ocf::heartbeat:IPaddr2): Started db1 + * Resource Group: centreon: + * vip (ocf::heartbeat:IPaddr2): Started central2 + * http (systemd:httpd): Started central2 + * gorgone (systemd:gorgoned): Started central2 + * centreon_central_sync (systemd:centreon-central-sync): Started central2 + * cbd_central_broker (systemd:cbd-sql): Started central2 + * centengine (systemd:centengine): Started central2 + * centreontrapd (systemd:centreontrapd): Started central2 + * snmptrapd (systemd:snmptrapd): Started central2 + +Daemon Status: + corosync: active/enabled + pacemaker: active/enabled + pcsd: active/enabled +``` + +3. Once the failover is completed, execute the following command to ensure the resources can be moved back to their original node in the future (EL8 or Debian). + +```bash +pcs resource clear centreon +``` + +This will remove the constraints established during the failover. + +> If you move a single resource from the centreon resource group from one node to the other, all the other resources in the group will switch too. + +If you want to return to the nominal situation (i.e. central node 1 is the active central node and central node 2 is the passive central node), you must perform a second resource failover. + +### How to simulate the loss of the passive central node + +If the passive central node goes down, the cluster should carry on working as before, as the resources are managed by the active central node. You will see your passive central node as down in Resources Status. + +To simulate a network failure that would isolate the passive central node, you can use `iptables` to drop traffic from and to the passive central node. The passive central node will be completely excluded from the cluster. The active central node keeps the majority with the quorum device. + +#### Perform the test + +We're assuming that node 1 is the active node and node 2 is the passive node ([check the state of the cluster](#how-do-i-know-the-state-of-the-cluster) if you need to). + +To perform this test, run the `iptables` commands on the **active central node**: + +```bash +iptables -A INPUT -s @CENTRAL_NODE1_IPADDR@ -j DROP +iptables -A OUTPUT -d @CENTRAL_NODE1_IPADDR@ -j DROP +iptables -A INPUT -s @DATABASE_NODE1_IPADDR@ -j DROP +iptables -A OUTPUT -d @DATABASE_NODE1_IPADDR@ -j DROP +iptables -A INPUT -s @DATABASE_NODE2_IPADDR@ -j DROP +iptables -A OUTPUT -d @DATABASE_NODE2_IPADDR@ -j DROP +iptables -A INPUT -s @QDEVICE_IPADDR@ -j DROP +iptables -A OUTPUT -d @QDEVICE_IPADDR@ -j DROP +``` + +The passive central node is now excluded from the cluster. + +If you run `pcs status` on the active central node: + +* The resources and the cluster are still working. +* The passive central node is seen `offline` on the active node: + +```text +Cluster name: centreon_cluster +Stack: corosync +Current DC: @CENTRAL_MASTER_NAME@ (version 1.1.23-1.el8_9.1-9acf116022) - partition with quorum +Last updated: Thu May 5 10:34:05 2022 +Last change: Thu May 5 09:09:50 2022 by root via crm_resource on @CENTRAL_MASTER_NAME@ + +4 nodes configured +21 resource instances configured + +Online: [ @DATABASE_MASTER_NAME@ @CENTRAL_MASTER_NAME@ @DATABASE_SLAVE_NAME@ ] +OFFLINE: [ @CENTRAL_SLAVE_NAME@ ] + +Full list of resources: + + Master/Slave Set: ms_mysql-clone [ms_mysql] + Masters: [ @DATABASE_MASTER_NAME@ ] + Slaves: [ @DATABASE_SLAVE_NAME@ ] + Stopped: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] + vip_mysql (ocf::heartbeat:IPaddr2): Started @DATABASE_MASTER_NAME@ + Clone Set: php-clone [php] + Started: [ @CENTRAL_MASTER_NAME@ ] + Stopped: [ @DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@ @CENTRAL_SLAVE_NAME@ ] + Clone Set: cbd_rrd-clone [cbd_rrd] + Started: [ @CENTRAL_MASTER_NAME@ ] + Stopped: [ @DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@ @CENTRAL_SLAVE_NAME@ ] + Resource Group: centreon + vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_MASTER_NAME@ + http (systemd:httpd24-httpd): Started @CENTRAL_MASTER_NAME@ + gorgone (systemd:gorgoned): Started @CENTRAL_MASTER_NAME@ + centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_MASTER_NAME@ + cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_MASTER_NAME@ + centengine (systemd:centengine): Started @CENTRAL_MASTER_NAME@ + centreontrapd (systemd:centreontrapd): Started @CENTRAL_MASTER_NAME@ + snmptrapd (systemd:snmptrapd): Started @CENTRAL_MASTER_NAME@ + +Daemon Status: + corosync: active/enabled + pacemaker: active/enabled + pcsd: active/enabled +``` + +If you run `pcs status` on the passive node: + +* All resources appear stopped on the passive node +* The active node is seen as `offline` (as the passive node is cut off from the rest of the cluster): + +```text +Cluster name: centreon_cluster +Cluster Summary: + * Stack: corosync + * Current DC: @CENTRAL_NODE2_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition WITHOUT quorum + * Last updated: Tue Nov 8 14:33:00 2022 + * Last change: Tue Nov 8 14:25:58 2022 by root via crm_resource on @CENTRAL_NODE1_NAME@ * 2 nodes configured * 12 resource instances configured - Node List: - * Online: [ @CENTRAL_PASSIVE_NAME@ @CENTRAL_ACTIVE_NAME@ ] + * Online: [ @CENTRAL_NODE2_NAME@ ] + * OFFLINE: [ @CENTRAL_NODE1_NAME@ ] +Full List of Resources: + * Clone Set: php-clone [php]: + * Stopped: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] + * Clone Set: cbd_rrd-clone [cbd_rrd]: + * Stopped: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] + * Resource Group: centreon: + * vip (ocf::heartbeat:IPaddr2): Stopped + * http (systemd:httpd): Stopped + * gorgone (systemd:gorgoned): Stopped + * centreon_central_sync (systemd:centreon-central-sync): Stopped + * cbd_central_broker (systemd:cbd-sql): Stopped + * centengine (systemd:centengine): Stopped + * centreontrapd (systemd:centreontrapd): Stopped + * snmptrapd (systemd:snmptrapd): Stopped +Daemon Status: + corosync: active/enabled + pacemaker: active/enabled + pcsd: active/enabled +``` + +#### Go back to the nominal situation + +If you want to go back to the nominal situation, remove the iptables rules. + +To view the various iptables rules configured on the active node, run the following command: + +```bash +iptables -L +``` + +The command should return the following information: + +```text +Chain INPUT (policy ACCEPT) +target prot opt source destination +DROP all -- @CENTRAL_NODE2_NAME@ anywhere + +Chain FORWARD (policy ACCEPT) +target prot opt source destination + +Chain OUTPUT (policy ACCEPT) +target prot opt source destination +DROP all -- anywhere @CENTRAL_NODE2_NAME@ +``` + +If you do not have any other iptables rules configured, you can execute the following command to remove the rules related to the test: + +```bash +iptables -F +``` + +Otherwise, you will have to list the rule numbers with the following command: -Active Resources: +```bash +iptables -L --line-numbers +``` + +And delete them with the following command: + +```bash +iptables -D INPUT @RULE_NUMBER@ +iptables -D OUTPUT @RULE_NUMBER@ +``` + +If you run `pcs status` on the active node, the passive node is seen as `online` again: + +```text +Cluster Summary: + * Stack: corosync + * Current DC: @CENTRAL_NODE1_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum + * Last updated: Wed Sep 15 16:35:47 2021 + * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @CENTRAL_NODE1_NAME@ + * 2 nodes configured + * 12 resource instances configured +Node List: + * Online: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] +Full List of Resources: * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_PASSIVE_NAME@ @CENTRAL_ACTIVE_NAME@ ] + * Started: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_PASSIVE_NAME@ @CENTRAL_ACTIVE_NAME@ ] + * Started: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_ACTIVE_NAME@ - * http (systemd:httpd): Started @CENTRAL_ACTIVE_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_ACTIVE_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_ACTIVE_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_ACTIVE_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_ACTIVE_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_ACTIVE_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_ACTIVE_NAME@ + * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE1_NAME@ + * http (systemd:httpd): Started @CENTRAL_NODE1_NAME@ + * gorgone (systemd:gorgoned): Started @CENTRAL_NODE1_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE1_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE1_NAME@ + * centengine (systemd:centengine): Started @CENTRAL_NODE1_NAME@ + * centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE1_NAME@ + * snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE1_NAME@ +``` + +Also check that the database replication is still operational using the following command: + +```bash +/usr/share/centreon-ha/bin/mysql-check-status.sh +``` + +The expected output is: +```text +Connection MASTER Status '@DATABASE_NODE1_NAME@' [OK] +Connection SLAVE Status '@DATABASE_NODE2_NAME@' [OK] +Slave Thread Status [OK] +Position Status [OK] ``` -These commands should return no errors. If there are "Failed actions" on any resource, troubleshoot them using the [troubleshooting guide](troubleshooting-guide.md). +### How to simulate the loss of the active node -### View the cluster's configuration +This test checks that the resources are switched to the passive node if the active node is unavailable, allowing for continuity of service. -To display a very detailed description the cluster's configuration (including network information), run this command: +#### Perform the test + +We're assuming that central node 1 is the active central node and central node 2 is the passive central node ([check the state of the cluster](#how-do-i-know-the-state-of-the-cluster) if you need to). + +To perform this test, run the commands on the active central node: ```bash -pcs config show +iptables -A INPUT -s @CENTRAL_NODE2_IPADDR@ -j DROP +iptables -A OUTPUT -d @CENTRAL_NODE2_IPADDR@ -j DROP +iptables -A INPUT -s @DATABASE_NODE1_IPADDR@ -j DROP +iptables -A OUTPUT -d @DATABASE_NODE1_IPADDR@ -j DROP +iptables -A INPUT -s @DATABASE_NODE2_IPADDR@ -j DROP +iptables -A OUTPUT -d @DATABASE_NODE2_IPADDR@ -j DROP +iptables -A INPUT -s @QDEVICE_IPADDR@ -j DROP +iptables -A OUTPUT -d @QDEVICE_IPADDR@ -j DROP ``` -### Test the configuration +Resources on the active central node (central node 1) should stop. Central node 2 becomes the active node and all the resources switch to it. You can use the `crm_mon -fr` command on central node 2 to watch the startup of resources: + +```text +Stack: corosync +Current DC: @CENTRAL_NODE1_NAME@ (version 1.1.23-1.el8_9.1-9acf116022) - partition with quorum +Last updated: Thu May 5 11:06:38 2022 +Last change: Thu May 5 09:09:50 2022 by root via crm_resource on @CENTRAL_NODE1_NAME@ + +4 nodes configured +21 resource instances configured + +Online: [ @DATABASE_NODE1_NAME@ @DATABASE_NODE2_NAME@ @CENTRAL_NODE2_NAME@ ] +OFFLINE: [ @CENTRAL_NODE1_NAME@ ] + +Full list of resources: + + Master/Slave Set: ms_mysql-clone [ms_mysql] + Masters: [ @DATABASE_NODE1_NAME@ ] + Slaves: [ @DATABASE_NODE2_NAME@ ] + Stopped: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] +vip_mysql (ocf::heartbeat:IPaddr2): Started @DATABASE_NODE1_NAME@ + Clone Set: php-clone [php] + Started: [ @CENTRAL_NODE2_NAME@ ] + Stopped: [ @DATABASE_NODE1_NAME@ @CENTRAL_NODE1_NAME@ @DATABASE_NODE2_NAME@ ] + Clone Set: cbd_rrd-clone [cbd_rrd] + Started: [ @CENTRAL_NODE2_NAME@ ] + Stopped: [ @DATABASE_NODE1_NAME@ @CENTRAL_NODE1_NAME@ @DATABASE_NODE2_NAME@ ] + Resource Group: centreon + vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE2_NAME@ + http (systemd:httpd24-httpd): Started @CENTRAL_NODE2_NAME@ + gorgone (systemd:gorgoned): Started @CENTRAL_NODE2_NAME@ + centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE2_NAME@ + cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE2_NAME@ + centengine (systemd:centengine): Started @CENTRAL_NODE2_NAME@ + centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE2_NAME@ + snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE2_NAME@ + +Migration Summary: +* Node @DATABASE_NODE1_NAME@: +* Node @CENTRAL_NODE2_NAME@: +* Node @DATABASE_NODE2_NAME@: +``` + +#### Go back to the nominal situation -To test the cluster's configuration (e.g. to check the name of the resources for any typos, or to check network information), run this command: +To check the various iptables rules configured on the active node, run the following command: ```bash -crm_verify -L -V +iptables -L +``` + +The command should return the following information: + +```text +Chain INPUT (policy ACCEPT) +target prot opt source destination +DROP all -- @CENTRAL_NODE2_NAME@ anywhere +DROP all -- @DATABASE_NODE1_NAME@ anywhere +DROP all -- @DATABASE_NODE2_NAME@ anywhere +DROP all -- @QDEVICE_NAME@ anywhere + +Chain FORWARD (policy ACCEPT) +target prot opt source destination + +Chain OUTPUT (policy ACCEPT) +target prot opt source destination +DROP all -- anywhere @CENTRAL_NODE2_NAME@ +DROP all -- anywhere @DATABASE_NODE1_NAME@ +DROP all -- anywhere @DATABASE_NODE2_NAME@ +DROP all -- anywhere @QDEVICE_NAME@ ``` -## Switching resources/resource groups from one node to another +If you do not have any other iptables rules configured, you can execute the following command to remove the rules related to the test: -To toggle the `centreon` resource group: +```bash +iptables -F +``` -1. Move the resource group to the other node: +Otherwise, it will be necessary to list the rule numbers with the specific command: - ```bash - pcs resource move centreon - ``` +```bash +iptables -L --line-numbers +``` - This command sets an "-Inf" constraint on the node hosting the resource. As a result, the resource group switches to another node. +And delete them with the following command: -2. Clear the constraint: +```bash +iptables -D INPUT @RULE_NUMBER@; +iptables -D OUTPUT @RULE_NUMBER@ +``` - ```bash - pcs resource clear centreon - ``` +If you run the `crm_mon` command on node 2, you can see that node 1 is still the passive node: -If you move a single resource from the centreon resource group from one node to the other, all the other resources in the group will switch too. +```text +Cluster Summary: + * Stack: corosync + * Current DC: @CENTRAL_NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum + * Last updated: Tue Nov 8 17:27:28 2022 + * Last change: Tue Nov 8 17:23:19 2022 by root via crm_attribute on @CENTRAL_NODE2_NAME@ + * 2 nodes configured + * 12 resource instances configured +Node List: + * Online: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] +Full List of Resources: + * Clone Set: ms_mysql-clone [ms_mysql] (promotable): + * ms_mysql (ocf::heartbeat:mariadb-centreon): Stopped @CENTRAL_NODE1_NAME@ (Monitoring) + * Masters: [ @CENTRAL_NODE2_NAME@ ] + * Stopped: [ @CENTRAL_NODE1_NAME@ ] + * Clone Set: php-clone [php]: + * Started: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] + * Clone Set: cbd_rrd-clone [cbd_rrd]: + * Started: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] + * Resource Group: centreon: + * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE2_NAME@ + * http (systemd:httpd): Started @CENTRAL_NODE2_NAME@ + * gorgone (systemd:gorgoned): Started @CENTRAL_NODE2_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE2_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE2_NAME@ + * centengine (systemd:centengine): Started @CENTRAL_NODE2_NAME@ + * centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE2_NAME@ + * snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE2_NAME@ +Migration Summary: + * Node: @CENTRAL_NODE1_NAME@: + * ms_mysql: migration-threshold=1000000 fail-count=1000000 last-failure='Tue Nov 8 17:27:25 2 +022' +Failed Resource Actions: + * ms_mysql_start_0 on @CENTRAL_NODE1_NAME@ 'error' (1): call=440, status='complete', exitreason='M +ariaDB slave io has failed (1236): Got fatal error 1236 from master when reading data from binary +log: 'Error: connecting slave', last-rc-change='Tue Nov 8 17:27:21 2022', queued=0ms, exec=4060ms +``` + +If you want to switch to the active node, you must do a failover. +So, **before you do this, you must check the cluster and database replication status**. + +First, check the constraints: + +```shell +pcs constraint +``` + +The command should return this: + +```text +Location Constraints: +Ordering Constraints: +Colocation Constraints: + centreon with ms_mysql-clone (score:INFINITY) (rsc-role:Started) (with-rsc-role:Master) + ms_mysql-clone with centreon (score:INFINITY) (rsc-role:Master) (with-rsc-role:Started) +Ticket Constraints: +``` + +then check the database replication + +```bash +/usr/share/centreon-ha/bin/mysql-check-status.sh +``` + +At this time, the cluster is in degraded mode with two passive nodes. +In this particular case, it returns the following information because the ms_mysql resource is stopped on node 1: + +```text +Connection SLAVE Status '@CENTRAL_NODE1_NAME@' [KO] +Error reports: + ERROR 2002 (HY000): Can't connect to MySQL server on '@CENTRAL_NODE1_NAME@' (115) +Impossible de se connecter au serveur '@CENTRAL_NODE1_NAME@'. +Connection SLAVE Status '@CENTRAL_NODE2_NAME@' [OK] +Slave Thread Status [KO] +Error reports: + Skip check on '@CENTRAL_NODE1_NAME@'. + No slave (maybe because we cannot check a server). +Position Status [SKIP] +Error reports: + Skip because we can't identify a unique slave. +``` + +You must do a database synchronization from @CENTRAL_NODE2_NAME@ to @CENTRAL_NODE1_NAME@ by launching the "sync-bigdb" script on the **Slave node**. + +```shell +/usr/share/centreon-ha/bin/mysql-sync-bigdb.sh +``` + +As for the previous execution of this script, check whether the LVM Snapshot is correctly deleted and the MySQL Slave restarted: + +```text +Umount and Delete LVM snapshot + Logical volume "dbbackupdatadir" successfully removed. +Start MySQL Slave +OK +Start Replication +Id User Host db Command Time State Info Progress +5 centreon-repl @CENTRAL_NODE2_NAME@:51850 NULL Query 0 starting show processlist 0.000 +6 centreon localhost centreon_storage Sleep 0 NULL 0.000 +7 system user NULL Connect 0 Connecting to master NULL 0.000 +8 system user NULL Slave_SQL 0 Slave has read all relay log; waiting for more updates NULL 0.000 +``` + +Database replication should now be OK. Check this. + +```shell +/usr/share/centreon-ha/bin/mysql-check-status.sh +``` + +The result should be: + +```text +Connection MASTER Status '@CENTRAL_NODE2_NAME@' [OK] +Connection SLAVE Status '@CENTRAL_NODE1_NAME@' [OK] +Slave Thread Status [OK] +Position Status [OK] +``` + +Now, you can perform a failover to return to the initial situation. + +```shell +pcs resource clear centreon +``` + +Do a cleanup to clear errors and restart the ms_mysql resource on @CENTRAL_NODE1_NAME@. + +```shell +pcs resource cleanup +``` + +The situation has stabilized, and you can perform a failover by moving the **centreon** resource. + +```shell +pcs resource move centreon +``` + +The **centreon** resource is now relocated and the cluster is OK. Check this with `crm_mon -fr` on any node. + +```text +Cluster Summary: + * Stack: corosync + * Current DC: @CENTRAL_NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum + * Last updated: Wed Nov 9 10:23:54 2022 + * Last change: Wed Nov 9 10:23:26 2022 by root via crm_attribute on @CENTRAL_NODE1_NAME@ + * 2 nodes configured + * 12 resource instances configured +Node List: + * Online: [ @CENTRAL_NODE1_NAME@ centreon-rhel8-sec ] +Full List of Resources: + * Clone Set: ms_mysql-clone [ms_mysql] (promotable): + * Masters: [ @CENTRAL_NODE1_NAME@ ] + * Slaves: [ centreon-rhel8-sec ] + * Clone Set: php-clone [php]: + * Started: [ @CENTRAL_NODE1_NAME@ centreon-rhel8-sec ] + * Clone Set: cbd_rrd-clone [cbd_rrd]: + * Started: [ @CENTRAL_NODE1_NAME@ centreon-rhel8-sec ] + * Resource Group: centreon: + * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE1_NAME@ + * http (systemd:httpd): Started @CENTRAL_NODE1_NAME@ + * gorgone (systemd:gorgoned): Started @CENTRAL_NODE1_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE1_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE1_NAME@ + * centengine (systemd:centengine): Started @CENTRAL_NODE1_NAME@ + * centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE1_NAME@ + * snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE1_NAME@ +Migration Summary: +``` ## Remove an error displayed in the cluster status -Once the cause of the error has been identified and fixed ([troubleshooting guide](troubleshooting-guide.md)), you must manually delete the error message: +Once the cause of the error has been identified and fixed (see the [troubleshooting guide](troubleshooting-guide.md)), you must manually delete the error message: ```bash pcs resource cleanup diff --git a/versioned_docs/version-24.04/administration/centreon-ha/troubleshooting-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/troubleshooting-guide.md index b095aef761d5..ad19ff1486b9 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/troubleshooting-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/troubleshooting-guide.md @@ -127,7 +127,7 @@ Ticket Constraints: We notice that the centreon group is not authorized to start on any node. -To free the resource group from its constraints, run the following command: +To free the resource group from its constraints, run the following command (EL8 and Debian): ```bash pcs resource clear centreon diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/faq.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/faq.md index 461f74839e3b..3bb0ed37e3d5 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/faq.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/faq.md @@ -17,7 +17,7 @@ Your HA must be installed by Centreon Professional Services. ## Do I need a licence for Centreon HA? -Extensions need specific license files to work on both nodes smoothly. If you have an IT or Business subscription, please get in touch with your Centreon sales representative or Technical Account Manager. +Extensions need specific license files to work on both central nodes smoothly. If you have an IT or Business subscription, please get in touch with your Centreon sales representative or Technical Account Manager. ## What is supported, and what isn't? diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index 67503d37845e..591c48178b71 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -37,12 +37,12 @@ In this procedure, we will refer to characteristics that are bound to change fro * `@DATABASE_ACTIVE_NAME@`: active database server's FQDN (must be identical to: `hostname -s`) * `@DATABASE_PASSIVE_IPADDR@`: passive database server's IP address * `@DATABASE_PASSIVE_NAME@`: passive database server's FQDN (must be identical to: `hostname -s`) -* `@DB_REPL_USER@`: DB replication login (default: `centreon-repl`) -* `@DB_REPL_PASSWD@`: DB replication password -* `@DB_CENTREON_USER@`: DB Centreon login (default: `centreon`) -* `@DB_CENTREON_PASSWD@`: DB Centreon +* `@DB_REPL_USER@`: account that will perform the database replication (default: `centreon-repl`) +* `@DB_REPL_PASSWD@`: password for this account +* `@DB_CENTREON_USER@`: Account that the central servers will use to log in to the databases (to display the interface, to insert data into the databases, etc). The default value is `centreon`. +* `@DB_CENTREON_PASSWD@`: Password for this account * `@VIP_SQL_IPADDR@`: virtual IP address of the SQL cluster -* `@VIP_SQL_IFNAME@`: network device carrying the SQL cluster's VIP (name of the interface the VIP must send the flows to. The interface must have the same name on both database nodes). +* `@VIP_SQL_IFNAME@`: network device carrying the SQL cluster's VIP (name of the interface the central server must send the flows to. The interface must have the same name on both database nodes). * `@VIP_SQL_CIDR_NETMASK@`: SQL Cluster subnet mask length in bits (e.g. 24) * `@VIP_SQL_BROADCAST_IPADDR@`: cluster's VIP SQL broadcast address @@ -69,22 +69,39 @@ Make sure to give your servers clear, relevant hostnames so that you know which #### Install the central servers -Node 1 can be an existing Centreon that already monitors resources; however, node 2 should be a freshly installed Centreon. +* Node 1 can either be a freshly installed Centreon or an existing Centreon with a remote database that already monitors resources (in that case, it should be running smoothly and without errors). If your existing Centreon has a local database, you need to transform it into a remote database first. +* Node 2 must be a freshly installed Centreon. -Using the procedure for an installation with remote databases, [install your second central node from packages](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages) with the exact same version of Centreon on it as node 1 ([update](https://docs.centreon.com/docs/update/update-centreon-platform) your version if needed). At [step 6 of the web installation procedure](https://docs.centreon.com/docs/installation/web-and-post-installation/#step-6-database-information), make sure you enter the address of the VIP dedicated to your databases in the **Database Host Address** field. +Using the procedure for an installation with remote databases, [install the central server(s) from packages](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages). Both central servers must have the exact same version of Centreon ([update](https://docs.centreon.com/docs/update/update-centreon-platform) your platform if needed). In all cases, at this stage, make central node 1 point to database node 1 and central node 2 point to database node 2. [Both central nodes will be made to point to the database VIP](#step-4-modifying-the-centreon-configuration-files) once database replication is set up and and the resources in the **centreon** group only run on the active node. * Both central servers should have an **admin** account with the same password. * If you have an IT or Business edition, remember that license files for HA are specific. Please contact your Centreon sales representative to obtain your license files. +#### Check the databases + +On the database servers, it is mandatory that **about 5 GB free space has been spared on the LVM volume group** that carries the MariaDB data directory (`/var/lib/mysql` mount point by default). + +The output of the `vgs` command must look like this (notice the value under `VFree`): + +```text + VG #PV #LV #SN Attr VSize VFree + centos_centreon-c1 1 5 0 wz--n- <31,00g <5,00g +``` + +* MariaDB files `ibdata*` and `ib_logfile*` must be in the "datadir" directory or in a subdirectory (scripts `centreondb-smooth-backup.sh` and `mysql-sync-bigdb.sh` are not compatible with this operation); +* MariaDB files `log-bin*` and `relay-log*` can be located in a directory (or a subdirectory) different from "datadir". They can also be on a different logical volume (`lvm`) than "datadir". However, the logical volume must be located in the volume group where "datadir" is stored. + +> **WARNING:** If these particular prerequisites are not effective, the database synchronization method described below will not work. + #### Install the pollers -Install the host machines and [install the pollers from packages](https://docs.centreon.com/docs/installation/installation-of-a-poller/using-packages) or [using the unattended script](https://docs.centreon.com/docs/installation/installation-of-a-poller/unattended-install-poller/). Do not register the pollers to a central server yet, this will be done later. +Install your host machines and [install the pollers from packages](https://docs.centreon.com/docs/installation/installation-of-a-poller/using-packages) or [using the unattended script](https://docs.centreon.com/docs/installation/installation-of-a-poller/unattended-install-poller/). Do not register the pollers to a central server yet, this will be done later. #### Choose a quorum device -Choose which server in your infrastructure should act as a quorum device. This can be a poller. (The actual configuration will be done later: see [Preparing the server that will function as the quorum device](#preparing-the-server-that-will-function-as-the-quorum-device) and [Defining the quorum device](#defining-the-quorum-device).) +Choose which server in your infrastructure should act as a quorum device. This can be a poller. (The actual configuration will be done later: see [Prepare the server that will function as the quorum device](#prepare-the-server-that-will-function-as-the-quorum-device) and [Define the quorum device](#define-the-quorum-device).) -In order to adhere to best practices and be as resilient as possible, the quorum server should be at a different site than the two primary nodes, with independent network connections. +In order to adhere to best practices and be as resilient as possible, the quorum server should be at a different site than the other nodes, with independent network connections. ### Configure centreon-broker on the central servers @@ -105,7 +122,7 @@ On both central servers: 1. Go to **Configuration > Pollers > Broker configuration**, then select **central-broker-master**. 2. On the **General** tab, in the **Main options** section, set **Link to cbd service** to **No**. -This will result in the **Last Update** column of the **Configuration > Pollers > Pollers** page to become yellow, as Broker is temporarily stopped. An error will also appear in the **Pollers** section of the header bar: this is normal. Things will come back to normal at the end of the installation procedure (after you have defined all the resource groups, including sql_broker). +This will result in the **Last Update** column of the **Configuration > Pollers > Pollers** page to become yellow, as Broker is temporarily stopped. An error will also appear in the **Pollers** section of the header bar: this is normal. Things will come back to normal at the end of the installation procedure (after you have defined all the resource groups, including **sql_broker**). #### Double the output stream toward RRD @@ -140,7 +157,7 @@ Check that the files have been properly copied to node 2. If you just copied the In Centreon, the central broker daemon is reloaded every time you export your configuration. In the context of a HA setup, the central broker service is managed by the cluster and is called `cbd-sql`, [as described earlier](#change-the-link-to-the-cbd-service). This means that the service that needs to be reloaded when you export the configuration is `cbd-sql`, and no longer `cbd`: you need to configure this on central node 1. 1. Go to **Configuration > Pollers > Pollers**, then click on the central server. -2. In section **Centreon Broker**, set the **Centreon Broker reload command** parameter to `service cbd-sql reload`. +2. In the **Centreon Broker** section, set the **Centreon Broker reload command** parameter to `service cbd-sql reload`. ### Tune kernel network settings @@ -215,7 +232,7 @@ EOF ### Install HA tools on the central servers -Install the following packages on both central nodes. They provide all the files and dependencies required by a Centreon cluster. +Install the following packages on both central nodes. They provide all the files and dependencies required by a Centreon central cluster. @@ -357,7 +374,7 @@ There are two ways of exchanging such keys: * By using the `ssh-copy-id` command: needs to be able to log in to remote host using a password. It is however unsafe for such system accounts to have a password authentication available. If you choose this method, we advise you to revoke the password afterward with these commands: `passwd -d centreon` and `passwd -d mysql`. * By manually copying the public key in `~/.ssh/authorized_keys`. This method is safer. -The second method will be documented below. +The second method is documented below. #### **centreon** account @@ -446,7 +463,10 @@ you will need to open the following flows: ## Step 2: Set up the database replication -An active-passive MariaDB cluster will be set up so that your data is synchronized in real time. +An active-passive database cluster will be set up so that your data is synchronized in real time. + +* If one of your databases contains data, it must become the active database node. +* If both your databases are blank, either can be the active node. **Note**: unless otherwise stated, each of the following steps must be run on both database nodes. @@ -459,7 +479,7 @@ For both optimization and cluster reliability purposes, you need to add these tu ```ini [server] -server-id=1 # SET TO 1 FOR MASTER AND 2 FOR SLAVE +server-id=1 # SET TO 1 FOR DATABASE NODE 1 AND 2 FOR DATABASE NODE 2 #read_only log-bin=mysql-bin binlog-do-db=centreon @@ -500,7 +520,7 @@ For both optimization and cluster reliability purposes, you need to add these tu ```ini [server] -server-id=1 # SET TO 1 FOR MASTER AND 2 FOR SLAVE +server-id=1 # SET TO 1 FOR DATABASE NODE 1 AND 2 FOR DATABASE NODE 2 #read_only log-bin=mysql-bin binlog-do-db=centreon @@ -559,7 +579,7 @@ For both optimization and cluster reliability purposes, you need to add these tu ```ini [server] -server-id=1 # SET TO 1 FOR MASTER AND 2 FOR SLAVE +server-id=1 # SET TO 1 FOR DATABASE NODE 1 AND 2 FOR DATABASE NODE 2 #read_only log-bin=mysql-bin binlog-do-db=centreon @@ -596,9 +616,9 @@ max_allowed_packet=64M -> **Important:** the value of the `server-id` option must be different from one server to the other. The values suggested in the comments, 1 for the master and 2 for the slave, are not mandatory, but recommended. +> **Important**: The value of the `server-id` option must be different from one server to the other. -**Reminder:** remember to uncomment the right value for `innodb_buffer_pool_size` according to your own servers' memory size. +**Reminder**: Remember to uncomment the right value for `innodb_buffer_pool_size` according to your own servers' memory size. To apply the new configuration, restart the database server: @@ -614,74 +634,84 @@ systemctl status mysql > **Warning:** other files in `/etc/my.cnf.d/`, such as `centreon.cnf`, will be ignored from now on. Any customization will have to be added to `server.cnf`. -> **Warning:** remember to change the parameter `Mysql configuration file path` in **Administration > Parameters > Backup**. + + + +> **Warning:** remember to change the parameter `Mysql configuration file path` to `/etc/my.cnf.d/server.cnf` in **Administration > Parameters > Backup** on central node 1. + + + + +> **Warning:** remember to change the parameter `Mysql configuration file path` to `/etc/my.cnf.d/server.cnf` in **Administration > Parameters > Backup** on central node 1. + + + + +> **Warning:** remember to change the parameter `Mysql configuration file path` to `/etc/mysql/mariadb.conf.d/50-server.cnf` in **Administration > Parameters > Backup** on central node 1. + + + ### Creating the `centreon` MariaDB account -First log in as `root` on both database servers (using the newly-defined password): +First log in to MariaDB as `root` on both database servers (using the password you have defined during installation, when executing the **mysql_secure_installation** script): ```bash mysql -p ``` -Then, on both sides, paste the following SQL commands to the MariaDB prompt to create the application user (default: `centreon`). Replace the macros first: +Then, on both database servers, paste the following SQL commands to the MariaDB prompt to create and/or configure the account that the central servers will use to connect to the databases (to display the interface, to insert data into the databases, etc). You may have created this account at [step 6 of the web installation](../web-and-post-installation.md#step-6-database-information). The default name for this account is `centreon`. Replace the macros first: ```sql -CREATE USER '@MARIADB_CENTREON_USER@'@'@DATABASE_SLAVE_IPADDR@' IDENTIFIED BY '@MARIADB_CENTREON_PASSWD@'; -GRANT ALL PRIVILEGES ON centreon.* TO '@MARIADB_CENTREON_USER@'@'@DATABASE_SLAVE_IPADDR@'; -GRANT ALL PRIVILEGES ON centreon_storage.* TO '@MARIADB_CENTREON_USER@'@'@DATABASE_SLAVE_IPADDR@'; +CREATE USER '@DB_CENTREON_USER@'@'@DATABASE_PASSIVE_IPADDR@' IDENTIFIED BY '@DB_CENTREON_PASSWD@'; +GRANT ALL PRIVILEGES ON centreon.* TO '@DB_CENTREON_USER@'@'@DATABASE_PASSIVE_IPADDR@'; +GRANT ALL PRIVILEGES ON centreon_storage.* TO '@DB_CENTREON_USER@'@'@DATABASE_PASSIVE_IPADDR@'; -CREATE USER '@MARIADB_CENTREON_USER@'@'@DATABASE_MASTER_IPADDR@' IDENTIFIED BY '@MARIADB_CENTREON_PASSWD@'; -GRANT ALL PRIVILEGES ON centreon.* TO '@MARIADB_CENTREON_USER@'@'@DATABASE_MASTER_IPADDR@'; -GRANT ALL PRIVILEGES ON centreon_storage.* TO '@MARIADB_CENTREON_USER@'@'@DATABASE_MASTER_IPADDR@'; +CREATE USER '@DB_CENTREON_USER@'@'@DATABASE_ACTIVE_IPADDR@' IDENTIFIED BY '@DB_CENTREON_PASSWD@'; +GRANT ALL PRIVILEGES ON centreon.* TO '@DB_CENTREON_USER@'@'@DATABASE_ACTIVE_IPADDR@'; +GRANT ALL PRIVILEGES ON centreon_storage.* TO '@DB_CENTREON_USER@'@'@DATABASE_ACTIVE_IPADDR@'; ``` -Optionally, you can allow these privileges to be used from the Central Cluster. This will make some administration scripts runnable from every node. +Add the following privileges so that the status of this account can be seen from the central cluster too. ```sql -CREATE USER '@MARIADB_CENTREON_USER@'@'@CENTRAL_SLAVE_IPADDR@' IDENTIFIED BY '@MARIADB_CENTREON_PASSWD@'; -GRANT ALL PRIVILEGES ON centreon.* TO '@MARIADB_CENTREON_USER@'@'@CENTRAL_SLAVE_IPADDR@'; -GRANT ALL PRIVILEGES ON centreon_storage.* TO '@MARIADB_CENTREON_USER@'@'@CENTRAL_SLAVE_IPADDR@'; - -CREATE USER '@MARIADB_CENTREON_USER@'@'@CENTRAL_MASTER_IPADDR@' IDENTIFIED BY '@MARIADB_CENTREON_PASSWD@'; -GRANT ALL PRIVILEGES ON centreon.* TO '@MARIADB_CENTREON_USER@'@'@CENTRAL_MASTER_IPADDR@'; -GRANT ALL PRIVILEGES ON centreon_storage.* TO '@MARIADB_CENTREON_USER@'@'@CENTRAL_MASTER_IPADDR@'; -``` - -When upgrading to centreon-ha from an existing Centreon platform or an OVA/OVF VM deployment, update the `'@MARIADB_CENTREON_USER@'@'localhost'` password: +CREATE USER '@DB_CENTREON_USER@'@'@CENTRAL_PASSIVE_IPADDR@' IDENTIFIED BY '@DB_CENTREON_PASSWD@'; +GRANT ALL PRIVILEGES ON centreon.* TO '@DB_CENTREON_USER@'@'@CENTRAL_PASSIVE_IPADDR@'; +GRANT ALL PRIVILEGES ON centreon_storage.* TO '@DB_CENTREON_USER@'@'@CENTRAL_PASSIVE_IPADDR@'; -```sql -ALTER USER '@MARIADB_CENTREON_USER@'@'localhost' IDENTIFIED BY '@MARIADB_CENTREON_PASSWD@'; +CREATE USER '@DB_CENTREON_USER@'@'@CENTRAL_ACTIVE_IPADDR@' IDENTIFIED BY '@DB_CENTREON_PASSWD@'; +GRANT ALL PRIVILEGES ON centreon.* TO '@DB_CENTREON_USER@'@'@CENTRAL_ACTIVE_IPADDR@'; +GRANT ALL PRIVILEGES ON centreon_storage.* TO '@DB_CENTREON_USER@'@'@CENTRAL_ACTIVE_IPADDR@'; ``` ### Creating the MariaDB replication account -Still in the same prompt, create the replication user (default: `centreon-repl`): +Still in the same prompt, create the account that will perform the database replication (its default name is `centreon-repl`): ```sql GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* -TO '@MARIADB_REPL_USER@'@'localhost' IDENTIFIED BY '@MARIADB_REPL_PASSWD@'; +TO '@DB_REPL_USER@'@'localhost' IDENTIFIED BY '@DB_REPL_PASSWD@'; GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* -TO '@MARIADB_REPL_USER@'@'@DATABASE_SLAVE_IPADDR@' IDENTIFIED BY '@MARIADB_REPL_PASSWD@'; +TO '@DB_REPL_USER@'@'@DATABASE_PASSIVE_IPADDR@' IDENTIFIED BY '@DB_REPL_PASSWD@'; GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* -TO '@MARIADB_REPL_USER@'@'@DATABASE_MASTER_IPADDR@' IDENTIFIED BY '@MARIADB_REPL_PASSWD@'; +TO '@DB_REPL_USER@'@'@DATABASE_ACTIVE_IPADDR@' IDENTIFIED BY '@DB_REPL_PASSWD@'; ``` -Optionally, you can allow these privileges to be used from the Central Cluster. This will make some administration scripts runnable from every node. +Add the following privileges so that the status of this account can be seen from the central cluster too. ```sql GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* -TO '@MARIADB_REPL_USER@'@'@CENTRAL_SLAVE_IPADDR@' IDENTIFIED BY '@MARIADB_REPL_PASSWD@'; +TO '@DB_REPL_USER@'@'@CENTRAL_PASSIVE_IPADDR@' IDENTIFIED BY '@DB_REPL_PASSWD@'; GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* -TO '@MARIADB_REPL_USER@'@'@CENTRAL_MASTER_IPADDR@' IDENTIFIED BY '@MARIADB_REPL_PASSWD@'; +TO '@DB_REPL_USER@'@'@CENTRAL_ACTIVE_IPADDR@' IDENTIFIED BY '@DB_REPL_PASSWD@'; ``` -### Configuring the MariaDB scripts environment variables +### Configuring environment variables for the MariaDB scripts -The `/etc/centreon-ha/mysql-resources.sh` file declares environment variables that must be configured so that the *Centreon HA* scripts dedicated to MariaDB can work properly. These variables must be assigned the chosen values for the macros. +In the `/etc/centreon-ha/mysql-resources.sh` file, configure environment variables so that the Centreon HA scripts dedicated to MariaDB can work on every node. This must be done on both central nodes and on both database nodes. These variables must be assigned the chosen values for the macros. ```bash #!/bin/bash @@ -690,12 +720,12 @@ The `/etc/centreon-ha/mysql-resources.sh` file declares environment variables th # Database access credentials # ############################### -DBHOSTNAMEMASTER='@DATABASE_MASTER_NAME@' -DBHOSTNAMESLAVE='@DATABASE_SLAVE_NAME@' -DBREPLUSER='@MARIADB_REPL_USER@' -DBREPLPASSWORD='@MARIADB_REPL_PASSWD@' -DBROOTUSER='@MARIADB_REPL_USER@' -DBROOTPASSWORD='@MARIADB_REPL_PASSWD@' +DBHOSTNAMEMASTER='@DATABASE_ACTIVE_NAME@' +DBHOSTNAMESLAVE='@DATABASE_PASSIVE_NAME@' +DBREPLUSER='@DB_REPL_USER@' +DBREPLPASSWORD='@DB_REPL_PASSWD@' +DBROOTUSER='@DB_REPL_USER@' +DBROOTPASSWORD='@DB_REPL_PASSWD@' CENTREON_DB='centreon' CENTREON_STORAGE_DB='centreon_storage' @@ -711,8 +741,8 @@ To make sure that all the previous steps have been successful, and that the corr The expected output is: ```text -Connection MASTER Status '@DATABASE_MASTER_NAME@' [OK] -Connection SLAVE Status '@DATABASE_SLAVE_NAME@' [OK] +Connection SLAVE Status '@DATABASE_ACTIVE_NAME@' [OK] +Connection SLAVE Status '@DATABASE_PASSIVE_NAME@' [OK] Slave Thread Status [KO] Error reports: No slave (maybe because we cannot check a server). @@ -728,9 +758,9 @@ What matters here is that the first two connection tests are `OK`. -Now that everything is configured correctly, enable the `read_only` on both database servers by uncommenting the following instruction in the `/etc/my.cnf.d/server.cnf` file (i.e., by removing the `#` at the beginning of the line): +Now that everything is configured correctly, enable the `read_only` on both database servers by uncommenting the **read_only** instruction in the `/etc/my.cnf.d/server.cnf` file (i.e., by removing the `#` at the beginning of the line). The beggining of the `[server]` section should now look like this: -* Primary node: +* Active database node: ```ini [server] @@ -739,7 +769,7 @@ read_only log-bin=mysql-bin ``` -* Secondary node: +* Passive database node: ```ini [server] @@ -757,9 +787,9 @@ systemctl restart mysql -Now that everything is configured correctly, enable the `read_only` on both database servers by uncommenting the following instruction in the `/etc/my.cnf.d/server.cnf` file (i.e., by removing the `#` at the beginning of the line): +Now that everything is configured correctly, enable the `read_only` on both database servers by uncommenting the **read_only** instruction in the `/etc/my.cnf.d/server.cnf` file (i.e., by removing the `#` at the beginning of the line). The beggining of the `[server]` section should now look like this: -* Primary node: +* Active database node: ```ini [server] @@ -768,7 +798,7 @@ read_only log-bin=mysql-bin ``` -* Secondary node: +* Passive database node: ```ini [server] @@ -786,9 +816,9 @@ systemctl restart mysql -Now that everything is configured correctly, enable the `read_only` on both database servers by uncommenting the following instruction in the `/etc/mysql/mariadb.conf.d/50-server.cnf` file (i.e., by removing the `#` at the beginning of the line): +Now that everything is configured correctly, enable the `read_only` on both database servers by uncommenting the **read_only** instruction in the `/etc/mysql/mariadb.conf.d/50-server.cnf` file (i.e., by removing the `#` at the beginning of the line). The beggining of the `[server]` section should now look like this: -* Primary node +* Active database node ```ini [server] @@ -797,7 +827,7 @@ read_only log-bin=mysql-bin ``` -* Secondary node +* Passive database node ```ini [server] @@ -817,15 +847,17 @@ systemctl restart mariadb ### Synchronizing the databases and enabling MariaDB replication -In the process of synchronizing the databases, you will first stop the secondary database process so that its data can be overwritten by the primary node's data. +In the process of synchronizing the databases, you will first stop the passive database process so that its data can be overwritten by the active database node's data. -Run this command **on the secondary node**: +> Important: If you have existing data, make sure you synchronize the database with the data onto the blank database (i.e. the database that contains data must be the active node), and not the other way round. + +Run this command **on the passive node**: ```bash systemctl stop mysql ``` -It is important to make sure that MariaDB is completely shut down. Run this command and check that it returns no output: +It is important to make sure that MariaDB is completely shut down. Run this command on the passive node and check that it returns no output: ```bash ps -ef | grep mariadb[d] @@ -837,7 +869,7 @@ In case one or more processes are still alive, run the following command (it wil mysqladmin -p shutdown ``` -Once the service is stopped **on the secondary node**, run the synchronization script **from the primary database node**: +Once the database service is stopped **on the passive database node**, run the synchronization script **from the active database node**: ```bash /usr/share/centreon-ha/bin/mysql-sync-bigdb.sh @@ -850,7 +882,7 @@ This script will perform the following actions: * Mount an LVM snapshot on the same volume group that holds `/var/lib/mysql` (or whatever mount point holds the MariaDB data files). * Start MariaDB again on the primary node. * Record the current position in the binary log. -* Disable the `read_only` mode on the primary node (this node will now be able to write to its database). +* Disable the `read_only` mode on the active database node (this node will now be able to write to its database). The passive database node stays in `read_only` mode: only the replication process can insert data there. * Synchronize/overwrite all the data files (except for the `mysql` system database). * Unmount the LVM snapshot. * Create the replication thread that will keep both databases synchronized. @@ -877,21 +909,21 @@ In addition, the output of this command must display only `OK` results: The expected output is: ```text -Connection MASTER Status '@DATABASE_MASTER_NAME@' [OK] -Connection SLAVE Status '@DATABASE_SLAVE_NAME@' [OK] +Connection MASTER Status '@DATABASE_ACTIVE_NAME@' [OK] +Connection SLAVE Status '@DATABASE_PASSIVE_NAME@' [OK] Slave Thread Status [OK] Position Status [OK] ``` ## Step 3: Set up the Centreon cluster -**Note**: unless otherwise stated, each of the following steps must be run **on both central nodes**. +**Note**: Unless otherwise stated, each of the following steps must be run **on both central nodes**. ### Configure the file synchronization service Each central node must know the IP address of the other central node so that data can be synced between them. To be more specific, the `centreon-central-sync` file synchronization service needs the IP address of the peer node to be entered in its configuration file (`/etc/centreon-ha/centreon_central_sync.pm`). -So, on the `@CENTRAL_ACTIVE_NAME@` server, the configuration file should look like this: +So, on the active central server, the configuration file should look like this: ```perl our %centreon_central_sync_config = ( @@ -900,7 +932,7 @@ our %centreon_central_sync_config = ( 1; ``` -And on `@CENTRAL_PASSIVE_NAME@`: +And on the passive central server: ```perl our %centreon_central_sync_config = ( @@ -970,7 +1002,7 @@ chmod 775 /tmp/centreon-autodisco/ ### Stop and disable services -The central nodes and the database nodes must no longer launch some services at boot time: this will be done by the clustering tools, and only them. +The central nodes and the database nodes must no longer launch some services at boot time: this will be done by the clustering tools, and only them. #### On each central node @@ -978,24 +1010,24 @@ The central nodes and the database nodes must no longer launch some services at ```bash -systemctl stop centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon mysql -systemctl disable centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon mysql +systemctl stop centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon +systemctl disable centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon ``` ```bash -systemctl stop centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon mariadb -systemctl disable centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon mariadb +systemctl stop centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon +systemctl disable centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon ``` ```bash -systemctl stop centengine snmptrapd centreontrapd gorgoned cbd apache2 php8.1-fpm centreon mariadb -systemctl disable centengine snmptrapd centreontrapd gorgoned cbd apache2 php8.1-fpm centreon mariadb +systemctl stop centengine snmptrapd centreontrapd gorgoned cbd apache2 php8.1-fpm centreon +systemctl disable centengine snmptrapd centreontrapd gorgoned cbd apache2 php8.1-fpm centreon ``` @@ -1042,7 +1074,7 @@ update-rc.d -f mariadb remove ### Activate the clustering services -Start `pcsd` on all nodes (central nodes, database nodes and quorum device): +Start `pcsd` on the central and database nodes: ```bash systemctl start pcsd @@ -1144,7 +1176,7 @@ pcs qdevice status net --full -Output of the `qdevice status` command: +Here is the expected output of the `qdevice status` command: ```shell [root@@QDEVICE_NAME@ ~]# pcs qdevice status net --full @@ -1202,6 +1234,8 @@ Now that all members of the cluster (both central nodes, both database nodes and pcs host auth \ "@CENTRAL_ACTIVE_NAME@" \ "@CENTRAL_PASSIVE_NAME@" \ + "@DATABASE_ACTIVE_NAME@" \ + "@DATABASE_PASSIVE_NAME@" \ "@QDEVICE_NAME@" \ -u "hacluster" \ -p '@CENTREON_CLUSTER_PASSWD@' @@ -1214,6 +1248,8 @@ pcs host auth \ pcs host auth \ "@CENTRAL_ACTIVE_NAME@" \ "@CENTRAL_PASSIVE_NAME@" \ + "@DATABASE_ACTIVE_NAME@" \ + "@DATABASE_PASSIVE_NAME@" \ "@QDEVICE_NAME@" \ -u "hacluster" \ -p '@CENTREON_CLUSTER_PASSWD@' @@ -1234,6 +1270,8 @@ Then you can start the authentication of the cluster: pcs host auth \ "@CENTRAL_ACTIVE_NAME@" \ "@CENTRAL_PASSIVE_NAME@" \ + "@DATABASE_ACTIVE_NAME@" \ + "@DATABASE_PASSIVE_NAME@" \ "@QDEVICE_NAME@" \ -u "hacluster" \ -p '@CENTREON_CLUSTER_PASSWD@' @@ -1247,6 +1285,8 @@ If the authentication has succeeded on all nodes, you will get a message similar ```shell @CENTRAL_PASSIVE_NAME@: Authorized @CENTRAL_PASSIVE_NAME@: Authorized +@DATABASE_ACTIVE_NAME@: Authorized +@DATABASE_PASSIVE_NAME@: Authorized @QDEVICE_NAME@: Authorized ``` @@ -1299,7 +1339,7 @@ pcs cluster setup \ You should get the following message: ```shell -[root@ip-@CENTRAL_ACTIVE_IPADDR@ ~]# pcs cluster setup centreon_cluster "@CENTRAL_ACTIVE_IPADDR@" "@CENTRAL_PASSIVE_IPADDR@" --force +[root@@CENTRAL_ACTIVE_IPNAME@ ~]# pcs cluster setup centreon_cluster "@CENTRAL_ACTIVE_IPADDR@" "@CENTRAL_PASSIVE_IPADDR@" --force No addresses specified for host '@CENTRAL_ACTIVE_IPADDR@', using '@CENTRAL_ACTIVE_IPADDR@' No addresses specified for host '@CENTRAL_PASSIVE_IPADDR@', using '@CENTRAL_PASSIVE_IPADDR@' Destroying cluster on hosts: '@CENTRAL_ACTIVE_IPADDR@', '@CENTRAL_PASSIVE_IPADDR@'... @@ -1341,15 +1381,14 @@ At this stage, no resources have been added to the cluster, so the results of th ```shell Cluster Summary: * Stack: corosync (Pacemaker is running) - * Current DC: @CENTRAL_ACTIVE_IPADDR@ (version 2.1.6-9.1.el8 -_9-6fdc9deea29) - partition with quorum - * Last updated: Fri Mar 29 10:47:22 2024 on @CENTRAL_ACTIVE_IPADDR@ - * Last change: Thu Mar 28 16:38:56 2024 by root via cibadmin on @CENTRAL_ACTIVE_IPADDR@ - * 2 nodes configured + * Current DC: @CENTRAL_ACTIVE_NAME@ (version 2.1.6-9.1.el8_9-6fdc9deea29) - partition with quorum + * Last updated: Fri Mar 29 10:47:22 2024 on @CENTRAL_ACTIVE_NAME@ + * Last change: Thu Mar 28 16:38:56 2024 by root via cibadmin on @CENTRAL_ACTIVE_NAME@ + * 4 nodes configured * 0 resource instances configured Node List: - * Online: [ @CENTRAL_ACTIVE_IPADDR@ @CENTRAL_PASSIVE_IPADDR@ ] + * Online: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ @DATABASE_ACTIVE_NAME@ @DATABASE_PASSIVE_NAME@ ] Active Resources: * No active resources @@ -1371,25 +1410,34 @@ The results should look like this: ```shell Setting up qdevice certificates on nodes... -@CENTRAL_ACTIVE_IPADDR@: Succeeded -@CENTRAL_PASSIVE_IPADDR@: Succeeded +@CENTRAL_ACTIVE_NAME@: Succeeded +@CENTRAL_PASSIVE_NAME@: Succeeded +@DATABASE_PASSIVE_NAME@: Succeeded +@DATABASE_ACTIVE_NAME@: Succeeded Enabling corosync-qdevice... -@CENTRAL_ACTIVE_IPADDR@: corosync-qdevice enabled -@CENTRAL_PASSIVE_IPADDR@: corosync-qdevice enabled +@CENTRAL_PASSIVE_NAME@: corosync-qdevice enabled +@DATABASE_PASSIVE_NAME@: corosync-qdevice enabled +@DATABASE_ACTIVE_NAME@: corosync-qdevice enabled +@CENTRAL_ACTIVE_NAME@: corosync-qdevice enabled Sending updated corosync.conf to nodes... -@CENTRAL_PASSIVE_IPADDR@: Succeeded -@CENTRAL_ACTIVE_IPADDR@: Succeeded -@CENTRAL_ACTIVE_IPADDR@: Corosync configuration reloaded +@CENTRAL_ACTIVE_NAME@: Succeeded +@DATABASE_ACTIVE_NAME@: Succeeded +@CENTRAL_PASSIVE_NAME@: Succeeded +@DATABASE_PASSIVE_NAME@: Succeeded +@CENTRAL_ACTIVE_NAME@: Corosync configuration reloaded Starting corosync-qdevice... -@CENTRAL_ACTIVE_IPADDR@: corosync-qdevice started -@CENTRAL_PASSIVE_IPADDR@: corosync-qdevice started +@CENTRAL_ACTIVE_NAME@: corosync-qdevice started +@CENTRAL_PASSIVE_NAME@: corosync-qdevice started +@DATABASE_PASSIVE_NAME@: corosync-qdevice started +@DATABASE_ACTIVE_NAME@: corosync-qdevice started + ``` ### Create the database cluster resources -All commands within this section should be executed on **only one Cluster node**. The configuration will be spread automatically. +All commands within this section should be executed on **only one database node**. The configuration will be spread automatically. -#### Primary & Secondary MySQL processes +#### Active and passive MySQL processes @@ -1402,11 +1450,11 @@ pcs resource create "ms_mysql" \ datadir="/var/lib/mysql" \ socket="/var/lib/mysql/mysql.sock" \ binary="/usr/bin/mysqld_safe" \ - node_list="@DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@" \ - replication_user="@MARIADB_REPL_USER@" \ - replication_passwd='@MARIADB_REPL_PASSWD@' \ - test_user="@MARIADB_REPL_USER@" \ - test_passwd='@MARIADB_REPL_PASSWD@' \ + node_list="@DATABASE_ACTIVE_NAME@ @DATABASE_PASSIVE_NAME@" \ + replication_user="@DB_REPL_USER@" \ + replication_passwd='@DB_REPL_PASSWD@' \ + test_user="@DB_REPL_USER@" \ + test_passwd='@DB_REPL_PASSWD@' \ test_table='centreon.host' ``` @@ -1421,11 +1469,11 @@ pcs resource create "ms_mysql" \ datadir="/var/lib/mysql" \ socket="/var/lib/mysql/mysql.sock" \ binary="/usr/bin/mysqld_safe" \ - node_list="@DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@" \ - replication_user="@MARIADB_REPL_USER@" \ - replication_passwd='@MARIADB_REPL_PASSWD@' \ - test_user="@MARIADB_REPL_USER@" \ - test_passwd='@MARIADB_REPL_PASSWD@' \ + node_list="@DATABASE_ACTIVE_NAME@ @DATABASE_PASSIVE_NAME@" \ + replication_user="@DB_REPL_USER@" \ + replication_passwd='@DB_REPL_PASSWD@' \ + test_user="@DB_REPL_USER@" \ + test_passwd='@DB_REPL_PASSWD@' \ test_table='centreon.host' ``` @@ -1440,18 +1488,18 @@ pcs resource create "ms_mysql" \ datadir="/var/lib/mysql" \ socket="/run/mysqld/mysqld.sock" \ binary="/usr/bin/mysqld_safe" \ - node_list="@DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@" \ - replication_user="@MARIADB_REPL_USER@" \ - replication_passwd='@MARIADB_REPL_PASSWD@' \ - test_user="@MARIADB_REPL_USER@" \ - test_passwd='@MARIADB_REPL_PASSWD@' \ + node_list="@DATABASE_ACTIVE_NAME@ @DATABASE_PASSIVE_NAME@" \ + replication_user="@DB_REPL_USER@" \ + replication_passwd='@DB_REPL_PASSWD@' \ + test_user="@DB_REPL_USER@" \ + test_passwd='@DB_REPL_PASSWD@' \ test_table='centreon.host' ``` -> **WARNING:** the syntax of the following command depends on the Linux Distribution you are using. +This command has no output. @@ -1492,7 +1540,11 @@ pcs resource promotable ms_mysql \ -#### MariaDB Virtual IP Address +This command has no output. + +#### Define the database VIP + +Run the following command on the active database node to let it know the address of the database VIP. ```bash pcs resource create vip_mysql \ @@ -1574,9 +1626,9 @@ pcs resource create "cbd_rrd" \ The **centreon** [resource group](https://docs.centreon.com/docs/installation/installation-of-centreon-ha/overview/#what-processes-are-synchronized-by-centreon-ha) is the list of processes that Pacemaker will have to manage. These processes will not be managed by the central nodes themselves (most of them have been [disabled](#stop-and-disable-services) on the central servers). -#### Define the VIP address +#### Define the central VIP -Run the following command on the active node to let it know the address of the VIP. +Run the following command on the active central node to let it know the address of the VIP. ```bash pcs resource create vip \ @@ -1593,7 +1645,7 @@ pcs resource create vip \ --group centreon ``` -From now on, when you connect using SSH to the active node, your terminal will show the IP address of the VIP. +From now on, when you connect using SSH to the active node, your terminal may show the IP address of the VIP. #### httpd service @@ -1719,9 +1771,9 @@ pcs resource create snmptrapd \ ### Define resource constraints -When using the four-node architecture, you must define some specific constraints to specify where resources could run. +When using this architecture, you must define some specific constraints to specify on which nodes resources are allowed to run. -In order to colocate the active database role with the VIP, define a mutual constraint: +In order to colocate the active database role with the database VIP, define a mutual constraint: @@ -1756,30 +1808,30 @@ Create the constraint that prevents Centreon processes from running on database ```bash -pcs constraint location centreon avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY -pcs constraint location ms_mysql-clone avoids @CENTRAL_MASTER_NAME@=INFINITY @CENTRAL_SLAVE_NAME@=INFINITY -pcs constraint location cbd_rrd-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY -pcs constraint location php-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY +pcs constraint location centreon avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY +pcs constraint location ms_mysql-clone avoids @CENTRAL_ACTIVE_NAME@=INFINITY @CENTRAL_PASSIVE_NAME@=INFINITY +pcs constraint location cbd_rrd-clone avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY +pcs constraint location php-clone avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY ``` ```bash -pcs constraint location centreon avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY -pcs constraint location ms_mysql-clone avoids @CENTRAL_MASTER_NAME@=INFINITY @CENTRAL_SLAVE_NAME@=INFINITY -pcs constraint location cbd_rrd-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY -pcs constraint location php-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY +pcs constraint location centreon avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY +pcs constraint location ms_mysql-clone avoids @CENTRAL_ACTIVE_NAME@=INFINITY @CENTRAL_PASSIVE_NAME@=INFINITY +pcs constraint location cbd_rrd-clone avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY +pcs constraint location php-clone avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY ``` ```bash -pcs constraint location centreon avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY -pcs constraint location ms_mysql-clone avoids @CENTRAL_MASTER_NAME@=INFINITY @CENTRAL_SLAVE_NAME@=INFINITY -pcs constraint location cbd_rrd-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY -pcs constraint location php-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABASE_SLAVE_NAME@=INFINITY +pcs constraint location centreon avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY +pcs constraint location ms_mysql-clone avoids @CENTRAL_ACTIVE_NAME@=INFINITY @CENTRAL_PASSIVE_NAME@=INFINITY +pcs constraint location cbd_rrd-clone avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY +pcs constraint location php-clone avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY ``` @@ -1791,6 +1843,7 @@ pcs constraint location php-clone avoids @DATABASE_MASTER_NAME@=INFINITY @DATABA pcs resource enable php-clone pcs resource enable cbd_rrd-clone pcs resource meta vip target-role="started" +pcs resource meta vip_mysql target-role="started" pcs resource meta centreontrapd target-role="started" pcs resource meta snmptrapd target-role="started" pcs resource meta centengine target-role="started" @@ -1809,37 +1862,49 @@ qu'est-ce qui me dit dans la ui où est la base? In Configuration > Pollers > Br #### Check the state of the resources -You can monitor the cluster's resources in real time using the `crm_mon -f` command. Here is an exmaple of output: +Use the `crm_mon -f` command to check that all your resources have been created and are started. Here is an example of output: ```bash Cluster Summary: - * Stack: corosync - * Current DC: @CENTRAL_ACTIVE_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum - * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @CENTRAL_ACTIVE_NAME@ - * 2 nodes configured - * 12 resource instances configured + * Stack: corosync (Pacemaker is running) + * Current DC: @CENTRAL_ACTIVE_NODE@ (version 2.1.6-9.1.el8_9-6fdc9deea29) - MIXED-VERSION partition with quorum + * Last updated: Tue Jun 4 07:57:43 2024 on @CENTRAL_ACTIVE_NODE@ + * Last change: Tue Jun 4 05:44:11 2024 by root via crm_resource on @CENTRAL_PASSIVE_NODE@ + * 4 nodes configured + * 21 resource instances configured + Node List: - * Online: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] + * Online: [ @CENTRAL_ACTIVE_NODE@ @CENTRAL_PASSIVE_NODE@ @DATABASE_ACTIVE_NODE@ @DATABASE_PASSIVE_NODE@ ] + Full List of Resources: + * Clone Set: ms_mysql-clone [ms_mysql] (promotable): + * Masters: [ @DATABASE_ACTIVE_NODE@ ] + * Slaves: [ @DATABASE_PASSIVE_NODE@ ] + * Stopped: [ @CENTRAL_ACTIVE_NODE@ @CENTRAL_PASSIVE_NODE@ ] * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] + * Started: [ @CENTRAL_ACTIVE_NODE@ @CENTRAL_PASSIVE_NODE@ ] + * Stopped: [ @DATABASE_ACTIVE_NODE@ @DATABASE_PASSIVE_NODE@ ] * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] + * Started: [ @CENTRAL_ACTIVE_NODE@ @CENTRAL_PASSIVE_NODE@ ] + * Stopped: [ @DATABASE_ACTIVE_NODE@ @DATABASE_PASSIVE_NODE@ ] + * vip_mysql (ocf::heartbeat:IPaddr2): Started @DATABASE_ACTIVE_NODE@ * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_ACTIVE_NAME@ - * http (systemd:httpd): Started @CENTRAL_ACTIVE_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_ACTIVE_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_ACTIVE_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_ACTIVE_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_ACTIVE_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_ACTIVE_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_ACTIVE_NAME@ + * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_ACTIVE_NODE@ + * http (systemd:httpd): Started @CENTRAL_ACTIVE_NODE@ + * gorgone (systemd:gorgoned): Started @CENTRAL_ACTIVE_NODE@ + * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_ACTIVE_NODE@ + * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_ACTIVE_NODE@ + * centengine (systemd:centengine): Started @CENTRAL_ACTIVE_NODE@ + * centreontrapd (systemd:centreontrapd): Started @CENTRAL_ACTIVE_NODE@ + * snmptrapd (systemd:snmptrapd): Started @CENTRAL_ACTIVE_NODE@ + +Migration Summary: + ``` If **centreon_central_sync** won't start, check if the folder `/usr/share/centreon-broker/lua` exists. -If not, you can create it with this command: `mkdir -p /usr/share/centreon-broker/lua`. And launch a cleanup with this command: `pcs resource cleanup`. +If not, you can create it with this command: `mkdir -p /usr/share/centreon-broker/lua`. Then launch a cleanup with this command: `pcs resource cleanup`. #### Disabled resources @@ -1848,8 +1913,8 @@ When you do a `crm_mon -fr` and you have a resource that is disabled: ```text ... Master/Slave Set: ms_mysql-master [ms_mysql] - Masters: [ @DATABASE_MASTER_NAME@ ] - Slaves: [ @DATABASE_SLAVE_NAME@ ] + Masters: [ @DATABASE_ACTIVE_NAME@ ] + Slaves: [ @DATABASE_PASSIVE_NAME@ ] Stopped: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] ms_mysql (ocf::heartbeat:IPaddr2): Stopped (disabled) ... @@ -1861,20 +1926,178 @@ You must enable the resource with the following command: pcs resource enable @RESSOURCE_NAME@ ``` -In our case: +In the case of the above example: ```bash pcs resource enable ms_mysql ``` -## Step 4: Integrate your pollers +## Step 4: Modifying the Centreon configuration files + +We have [defined a VIP for the databases](#define-the-database-vip) earlier: the data will be sent from the active central node to the current active database via the database VIP. This means that we must give the central nodes the address of the VIP so that they can send the data to it. It is necessary to modify the output of Centreon Broker and three configuration files on the central servers so that they point to the database VIP. + +### Modifying central-broker-master outputs + +1. Go to **Configuration > Pollers > Broker Configuration**. +2. Click **central-broker-master**. +3. On the **Output** tab, edit the **Unified SQL** output and replace "@DATABASE_ACTIVE_IPADDR@" with @VIP_SQL_IPADDR@: + +| Broker Output | Parameter | Value | +| ------------------------------------- | ---------- | ---------------- | +| Unified SQL | DB host | @VIP_SQL_IPADDR@ | + +### Deploying the configuration + +Once the actions in the previous paragraph have been completed, the configuration of the **active central node** must be deployed for them to take effect (check the first three boxes under **Actions**). + +Then copy the broker configuration files to the **passive central node**: + +```bash +rsync -a /etc/centreon-broker/*json @CENTRAL_PASSIVE_IPADDR@:/etc/centreon-broker/ +``` + +### Modification of the three configuration files + +After modifying the output of the broker, we must modify the Centreon configuration files. **You need to do this on both central nodes.** +To do this, first, edit the `/etc/centreon/conf.pm` file and replace @DATABASE_ACTIVE_IPADDR@ with the address of the database VIP. Here is the expected result: + +```bash +############################################# +# File Added by Centreon +# +$centreon_config = { + VarLib => "/var/lib/centreon", + CentreonDir => "/usr/share/centreon/", + CacheDir => "/var/cache/centreon/", + "centreon_db" => "centreon", + "centstorage_db" => "centreon_storage", + "db_host" => "@VIP_SQL_IPADDR@:3306", + "db_user" => "@DB_CENTREON_USER@", + "db_passwd" => '@DB_CENTREON_PASSWD@' +}; +# Central or Poller? +$instance_mode = "central"; +# Centreon Centcore Command File +$cmdFile = "/var/lib/centreon/centcore.cmd"; +# Deprecated format of Config file. +$mysql_user = "@DB_CENTREON_USER@"; +$mysql_passwd = '@DB_CENTREON_PASSWD@'; +$mysql_host = "@VIP_SQL_IPADDR@:3306"; +$mysql_database_oreon = "centreon"; +$mysql_database_ods = "centreon_storage"; +1; +``` + +Then perform the same operation in the `/etc/centreon/centreon.conf.php` file. Here is the expected result: + +```bash + +``` + +And finish with the last file: `/etc/centreon/config.d/10-database.yaml`. Here is the expected result: + +```bash +database: + db_configuration: + dsn: "mysql:host=@VIP_SQL_IPADDR@:3306;dbname=centreon" + username: "@DB_CENTREON_USER@" + password: "@DB_CENTREON_PASSWD@" + db_realtime: + dsn: "mysql:host=@VIP_SQL_IPADDR@:3306;dbname=centreon_storage" + username: "@DB_CENTREON_USER@" + password: "@DB_CENTREON_PASSWD@" +``` + +You then need to restart the **gorgone** and **cbd_central_broker** resources for changes to take effect. Use the following command: + +```bash +pcs resource restart centreon +``` + +After resources are restarted, check if all is OK using the `crm_mon -fr` command. The result should look like this: + +```text +Cluster Summary: + * Stack: corosync + * Current DC: @CENTRAL_ACTIVE_NAME@ (version 2.1.4-5.el8_7.2-dc6eb4362e) - partition with quoru +m + * Last updated: Wed Nov 23 10:27:48 2022 + * Last change: Wed Nov 23 10:27:43 2022 by hacluster via crmd on @CENTRAL_ACTIVE_NAME@ + * 4 nodes configured + * 21 resource instances configured + +Node List: + * Online: [ @CENTRAL_ACTIVE_NAME@ @DATABASE_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ @DATABASE_PASSIVE_NAME@ +] + +Full List of Resources: + * Clone Set: ms_mysql-clone [ms_mysql] (promotable): + * Masters: [ @DATABASE_ACTIVE_NAME@ ] + * Slaves: [ @DATABASE_PASSIVE_NAME@ ] + * Stopped: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] + * vip_mysql (ocf::heartbeat:IPaddr2): Started @DATABASE_ACTIVE_NAME@ + * Clone Set: php-clone [php]: + * Started: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] + * Stopped: [ @DATABASE_ACTIVE_NAME@ @DATABASE_PASSIVE_NAME@ ] + * Clone Set: cbd_rrd-clone [cbd_rrd]: + * Started: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] + * Stopped: [ @DATABASE_ACTIVE_NAME@ @DATABASE_PASSIVE_NAME@ ] + * Resource Group: centreon: + * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_ACTIVE_NAME@ + * http (systemd:httpd): Started @CENTRAL_ACTIVE_NAME@ + * gorgone (systemd:gorgoned): Started @CENTRAL_ACTIVE_NAME@ + * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_ACTIVE_NAME@ + * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_ACTIVE_NAME@ + * centengine (systemd:centengine): Started @CENTRAL_ACTIVE_NAME@ + * centreontrapd (systemd:centreontrapd): Started@CENTRAL_ACTIVE_NAME@ + * snmptrapd (systemd:snmptrapd): Started @CENTRAL_ACTIVE_NAME@ + +Migration Summary: +``` + +If an error is found while your resources are running, use the following command: + +```bash +pcs resource cleanup +``` + +## Step 5: Integrate your pollers 1. If you haven't already done so, apply the necessary [kernel network tuning](#kernel-network-tuning) to the host machines for your pollers. -2. [Install your pollers](https://docs.centreon.com/docs/installation/installation-of-a-poller/using-packages) and register them using the VIP as the address of the central server. The password is that of the admin account for node 1? - Then run the wizard to [attach the poller](https://docs.centreon.com/docs/monitoring/monitoring-servers/add-a-poller-to-configuration) to the VIP. +2. [Install your pollers](https://docs.centreon.com/docs/installation/installation-of-a-poller/using-packages) and register them using the central VIP as the address of the central server. Then run the wizard to [attach the poller](https://docs.centreon.com/docs/monitoring/monitoring-servers/add-a-poller-to-configuration) to the VIP. 3. [Add your pollers](https://docs.centreon.com/docs/installation/installation-of-centreon-ha/integrating-pollers) to the platform's HA architecture. You can now start your monitoring. -## Step 5: Monitor your cluster +## Step 6: Monitor your cluster See [Monitoring Centreon HA](https://docs.centreon.com/docs/administration/centreon-ha/monitoring-guide). diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md index b73953027662..e30487284a38 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md @@ -5,34 +5,7 @@ title: How Centreon HA works import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -## What are the elements of Centreon HA? - -Centreon HA consists of a set of clustering tools on top of twin Centreon central servers that manage pollers (in a [distributed architecture](../../installation/architectures.md#distributed-architecture)), with remote twin databases. - -* There are 5 members in a Centreon HA cluster: - - * 2 Centreon central servers: one active node, one passive node. Thanks to synchronization scripts, the same data will exist on both servers so that if the active node goes down, the passive node will take its place. The central servers do not monitor your resources (the pollers do). In this documentation, we will call the central servers "central node 1" and "central node 2" to differentiate them: bear in mind that both of them can have the role of active or passive node. - * 2 database nodes. They are remote, replicated databases. There is one active database node and one passive database node, and all data is synchronized from one node to another. >>> Active/Passive binlog replication (storage) - * 1 server called "quorum device", whose sole purpose is to decide which central server/database is the active node and which is the passive node. This is mandatory to avoid split-brain issues. You can define one of your pollers as the quorum device. - - > Although the Centreon HA cluster is technically one cluster with 5 members, it actually works as two independent 2-node clusters (plus a server that acts as a quorum device for both clusters). Location constraints define that only Centreon processes run on the central nodes, and only database processes run on the database nodes. The central server cluster and the database cluster are independent: the database cluster fails over only when the active database node goes down, not when the active central node fails over. - -* Clustering tools: - - Centreon high availability scripts, contained in the **centreon-ha-web** package. They include the **centreon_central_sync** service, that synchronizes all the necessary Centreon processes ("resources"). Also, in the **centreon-ha-common** package, scripts manage the replication of the database and the automation of its failover process. - - Corosync: allows the members of the cluster to communicate in real time, to check if the active nodes are up, and take the decision to failover if needed (for the central servers or for the databases). - - Pacemaker: starts, stops and controls the state of Centreon processes. You need to tell Pacemaker which processes should be checked: these processes are called "resources". - - crm_mon: a command-line tool that allows you to know the state of the cluster in real time. - - pcs: a command-line tool that allows you to configure Corosync and Pacemaker. - -* Pollers, which do the actual monitoring. - -* A "central VIP" to which the pollers send the collected data, so that the VIP can forward the data to the current active central node. - -* A "database VIP" to which the active central node sends the data, so that the VIP can forward the data to the current active database node. - -![image](../../assets/integrations/centreon-ha/centreon-ha.png) - -## How does the HA cluster work? +## How does a Centreon HA cluster work? In the central cluster, all Centreon processes ("resources") are managed by the clustering tools (Pacemaker and Corosync). @@ -45,60 +18,17 @@ In the central cluster, all Centreon processes ("resources") are managed by the The process is the same for the database cluster. -## How do I know the state of the cluster? - -The installation process includes the monitoring of the members of the cluster by a poller. This way, you can be notified if a member of the cluster goes down. - -You access the interface of the active node via the IP address of the VIP. This means that you always use the same URL to access the interface, whether the interface is that of node 1 or of node 2. - -You can also [know the state of the cluster at all times](../../administration/centreon-ha/operating-guide.md#display-the-status-of-the-cluster) by using the `crm_mon` command, or the `pcs status`command. - -## What processes are synchronized by Centreon HA? - -Here is the list of processes (resources) that will be managed by the HA tools in the central cluster: - -* Central server applicative daemons - * centreon-engine (scheduler) - * centreon-broker (multiplexer) - * centreon-gorgone (task manager) - * all configuration files (replicated using the centreon-central-sync process) - * snmptrapd and centreontrapd (system and applicative trap management processes) -* Central Server third-party daemons - * php-fpm - * Apache server (webserver) - -All these resources are described in the table below. - -* Clone resources run on both active and passive nodes. -* Unique resources (primitive services), part of the `centreon` functional group, run on only one node. - -| Name | Type | Description | -| ----------------------- | -------------------- | ---------------------------------------------------- | -| `ms_mysql` | multi-state resource | Handles the `mysql` process and data replication | -| `ms_mysql-master` | location | Set MariaDB Master server rule preference | -| `php8` | clone service | FastCGI Process Manager service (`php-fpm`) | -| `cbd_rrd` | clone service | Broker RRD service (`cbd`) | -| `centreon` | group | Centreon "primitive services" group | -| `vip` | primitive service | VIP address for centreon | -| `http` | primitive service | Apache service (`httpd24-httpd`) | -| `gorgone` | primitive service | Gorgone service (`gorgoned`) | -| `centreon_central_sync` | primitive service | File synchronization service | -| `cbd_central_broker` | primitive service | Central Broker service (`cbd-sql`) | -| `centengine` | primitive service | Centreon-Engine service (`centengine`) | -| `centreontrapd` | primitive service | SNMP Traps management service (`centreontrapd`) | -| `snmptrapd` | primitive service | SNMP Traps listening service (`snmptrapd`) | - -**Note:** The resources of the `centreon` group are started one after the other in the list order. - -| Name | Type | Description | -| ----------------------- | -------------------- | ---------------------------------------------------- | -| `ms_mysql` | multi-state resource | Handles the `mysql` process and data replication | -| `ms_mysql-master` | location | Set MariaDB Master server rule preference | +## What happens when the cluster fails over? ->>> mysql sur central? +[If you have monitored your cluster as described here](../../administration/centreon-ha/monitoring-guide.md), when the cluster fails over (e.g. when the active node is affected by a network outage, if its Broker partitions are full...): ->>> 2 tableaux, ce qui tourne sur le cluster central et ce qui tourne sur le cluster db. +* The host for the VIP should be OK in the **Resource status** page (it may temporarily go down in a SOFT state if the corresponding monitoring check is performed at the exact same time the cluster fails over.) +* The host for the central node that failed will show up as DOWN and/or with CRITICAL services. +* You may receive notifications if you have configured them. +* You may have to log on to the interface again. -## Active/passive nodes or master/slave nodes? +You need to take action and fix the problem so that the central node that failed (let's say, central node 1) comes back online. Once central node 1 comes back online: -In this chapter, we will refer to active/passive nodes. You may notice that the output of some commands use the terms master and slave: these are Pacemaker and Corosync terms. Master means the active node and slave the passive node. +* Central node 1 is still the passive node: the cluster does **not** switch back automatically. +* If you are using EL8 or Debian, you need to clear manually the constraint created by the failover (using `pcs resource clear centreon`). +* In a production context, you do not **have** to go back to central node 1 being the active node - but you can do it if you want to (e.g. if central node 2 has limited performance), by [performing a failover](../../administration/centreon-ha/acceptance-guide.md#perform-a-failover) on central node 2. From 65c2ae63f04173854752738706b47490f4e4bc9e Mon Sep 17 00:00:00 2001 From: cgenier Date: Wed, 3 Jul 2024 15:31:00 +0200 Subject: [PATCH 20/41] Add file --- .../cluster-elements.md | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md new file mode 100644 index 000000000000..6c53fcf54541 --- /dev/null +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md @@ -0,0 +1,84 @@ +--- +id: cluster-elements +title: Elements of a Centreon HA cluster +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +## Schema of a Centreon HA cluster + +![image](../../assets/integrations/centreon-ha/centreon-ha.png) + +## What are the elements of Centreon HA? + +Centreon HA consists of a set of clustering tools on top of twin Centreon central servers that manage pollers (in a [distributed architecture](../../installation/architectures.md#distributed-architecture)), with remote twin databases. The HA tools manage the processes that would normally be managed by the central servers or the databases themselves. In this HA context, these processes are called "resources". + +* There are 5 members in a Centreon HA cluster: + + * 2 Centreon central servers: one active node, one passive node. Thanks to synchronization scripts, the same data will exist on both servers so that if the active node goes down, the passive node will take its place. The central servers do not monitor your resources (the pollers do). In this documentation, we will call the central servers "central node 1" and "central node 2" to differentiate them: bear in mind that both of them can have the role of active or passive node. + * 2 database nodes. They are remote, replicated databases. There is one active database node and one passive database node, and all of the data is synchronized from one node to another. + * 1 server called "quorum device", whose sole purpose is to decide which central server/database is the active node and which is the passive node. This is mandatory to avoid split-brain issues. You can define one of your pollers as the quorum device. + + > Although the Centreon HA cluster is technically one cluster with 5 members, it actually works as two independent 2-node clusters: a central cluster and a database cluster (plus a server that acts as a quorum device for both clusters). Location constraints define that only Centreon processes run on the central nodes, and only database processes run on the database nodes. The central server cluster and the database cluster are independent: the database cluster fails over only when the active database node goes down, not when the active central node fails over. + +* Clustering tools: + - Centreon high availability scripts, contained in the **centreon-ha-web** package. They include the **centreon_central_sync** service, that synchronizes all the necessary Centreon processes ("resources"). Also, in the **centreon-ha-common** package, scripts manage the replication of the database and the automation of its failover process. + - Corosync: allows the members of the cluster to communicate in real time, to check if the active nodes are up, and take the decision to failover if needed (for the central servers or for the databases). + - Pacemaker: starts, stops and controls the state of Centreon processes. You need to tell Pacemaker which processes should be checked: these processes are called "resources". + - crm_mon: a command-line tool that allows you to know the state of the cluster in real time. + - pcs: a command-line tool that allows you to configure Corosync and Pacemaker. + +* Pollers, which do the actual monitoring. + +* A "central VIP" to which the pollers send the collected data, so that the VIP can forward the data to the current active central node. + +* A "database VIP" to which the active central node sends the data, so that the VIP can forward the data to the current active database node. + +## What processes are managed by Centreon HA? + +Here is the list of processes (resources) that will be managed by the HA tools in the central cluster: + +* Central server applicative daemons + * centreon-engine (scheduler) + * centreon-broker (multiplexer) + * centreon-gorgone (task manager) + * all configuration files (replicated using the centreon-central-sync process) + * snmptrapd and centreontrapd (system and applicative trap management processes) +* Central Server third-party daemons + * php-fpm + * Apache server (webserver) + +All these resources are described in the table below. + +* Clone resources run on both active and passive nodes. +* Unique resources (primitive services), part of the `centreon` functional group, run on only one node. + +### Central cluster + +| Name | Type | Description | +| ----------------------- | -------------------- | ---------------------------------------------------- | +| `php` | clone service | FastCGI Process Manager service (`php-fpm`) | +| `cbd_rrd` | clone service | Broker RRD service (`cbd`) | +| `centreon` | group | Centreon "primitive services" group | +| `vip` | primitive service | VIP address for the central cluster | +| `http` | primitive service | Apache service (`httpd24-httpd`) | +| `gorgone` | primitive service | Gorgone service (`gorgoned`) | +| `centreon_central_sync` | primitive service | File synchronization service | +| `cbd_central_broker` | primitive service | Central Broker service (`cbd-sql`) | +| `centengine` | primitive service | Centreon-Engine service (`centengine`) | +| `centreontrapd` | primitive service | SNMP Traps management service (`centreontrapd`) | +| `snmptrapd` | primitive service | SNMP Traps listening service (`snmptrapd`) | + +**Note:** The resources of the `centreon` group are started one after the other in the list order. + +### Database cluster + +| Name | Type | Description | +| ----------------------- | -------------------- | ---------------------------------------------------- | +| `ms_mysql` | multi-state resource | Handles the `mysql` process and performs data replication between the two databases | +| `ms_mysql-master` | location | Defines which database is the active node | +| `vip_mysql` | primitive service | VIP address for the database cluster | + +## Active/passive nodes or master/slave nodes? + +In this chapter, we will refer to active/passive nodes. You may notice that the output of some commands use the terms master and slave: these are Pacemaker and Corosync terms. Master means the active node and slave the passive node. \ No newline at end of file From fc0ad29c4998bb9d75ae3fcb08257840b51d81aa Mon Sep 17 00:00:00 2001 From: cgenier Date: Wed, 3 Jul 2024 15:32:30 +0200 Subject: [PATCH 21/41] Typo --- .../installation/installation-of-centreon-ha/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index 591c48178b71..5a2fe653aa06 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -72,7 +72,7 @@ Make sure to give your servers clear, relevant hostnames so that you know which * Node 1 can either be a freshly installed Centreon or an existing Centreon with a remote database that already monitors resources (in that case, it should be running smoothly and without errors). If your existing Centreon has a local database, you need to transform it into a remote database first. * Node 2 must be a freshly installed Centreon. -Using the procedure for an installation with remote databases, [install the central server(s) from packages](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages). Both central servers must have the exact same version of Centreon ([update](https://docs.centreon.com/docs/update/update-centreon-platform) your platform if needed). In all cases, at this stage, make central node 1 point to database node 1 and central node 2 point to database node 2. [Both central nodes will be made to point to the database VIP](#step-4-modifying-the-centreon-configuration-files) once database replication is set up and and the resources in the **centreon** group only run on the active node. +Using the procedure for an installation with remote databases, [install the central server(s) from packages](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages). Both central servers must have the exact same version of Centreon ([update](https://docs.centreon.com/docs/update/update-centreon-platform) your platform if needed). In all cases, at this stage, make central node 1 point to database node 1 and central node 2 point to database node 2. [Both central nodes will be made to point to the database VIP](#step-4-modifying-the-centreon-configuration-files) once database replication is set up and the resources in the **centreon** group only run on the active node. * Both central servers should have an **admin** account with the same password. * If you have an IT or Business edition, remember that license files for HA are specific. Please contact your Centreon sales representative to obtain your license files. From 5bde029ef03af559cb9ef32c6681ff2dfb0fe624 Mon Sep 17 00:00:00 2001 From: cgenier Date: Wed, 3 Jul 2024 16:32:49 +0200 Subject: [PATCH 22/41] Update --- .../installation/installation-of-centreon-ha/installation.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index 5a2fe653aa06..6a890cb24b12 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -1853,10 +1853,9 @@ pcs resource meta centreon_central_sync target-role="started" pcs resource meta http target-role="started" ``` -At this stage, you can connect to the interface of the active node using the VIP's address. [avec la base déportée j'ai plus rien parce que mon utilisateur autorisé pointait vers l'adresse directe de la base et pas vers une vip] +At this stage, you can connect to the interface of the active node using the VIP's address. -étape proxy de l'interface -qu'est-ce qui me dit dans la ui où est la base? In Configuration > Pollers > Broker configuration, Open “central-broker-master” and in the “Output” tab, you have to change the “DB host” -> ça m'avait mis la base 2 au lieu de la base 1 +If the **Resource Status** page is empty, check that the central points to the database VIP and not to one database in particular. In **Configuration > Pollers > Broker configuration**, open **central-broker-master** and in the **Output** tab, update the **DB host**. ### Check the state of the cluster From d85759700bd29b9aaf3769e0ee84f87be3ef0ed4 Mon Sep 17 00:00:00 2001 From: cgenier Date: Thu, 4 Jul 2024 10:24:41 +0200 Subject: [PATCH 23/41] Fix build (link bug workaround) --- .../installation-of-centreon-ha/cluster-elements.md | 2 +- .../installation/installation-of-centreon-ha/installation.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md index 6c53fcf54541..6bcc5ee444bb 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md @@ -11,7 +11,7 @@ import TabItem from '@theme/TabItem'; ## What are the elements of Centreon HA? -Centreon HA consists of a set of clustering tools on top of twin Centreon central servers that manage pollers (in a [distributed architecture](../../installation/architectures.md#distributed-architecture)), with remote twin databases. The HA tools manage the processes that would normally be managed by the central servers or the databases themselves. In this HA context, these processes are called "resources". +Centreon HA consists of a set of clustering tools on top of twin Centreon central servers that manage pollers (in a [distributed architecture](https://docs.centreon.com/docs/installation/architectures/#distributed-architecture)), with remote twin databases. The HA tools manage the processes that would normally be managed by the central servers or the databases themselves. In this HA context, these processes are called "resources". * There are 5 members in a Centreon HA cluster: diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index 6a890cb24b12..da54b15a3df1 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -660,7 +660,7 @@ First log in to MariaDB as `root` on both database servers (using the password y mysql -p ``` -Then, on both database servers, paste the following SQL commands to the MariaDB prompt to create and/or configure the account that the central servers will use to connect to the databases (to display the interface, to insert data into the databases, etc). You may have created this account at [step 6 of the web installation](../web-and-post-installation.md#step-6-database-information). The default name for this account is `centreon`. Replace the macros first: +Then, on both database servers, paste the following SQL commands to the MariaDB prompt to create and/or configure the account that the central servers will use to connect to the databases (to display the interface, to insert data into the databases, etc). You may have created this account at [step 6 of the web installation](https://docs.centreon.com/docs/installation/web-and-post-installation/#step-6-database-information). The default name for this account is `centreon`. Replace the macros first: ```sql CREATE USER '@DB_CENTREON_USER@'@'@DATABASE_PASSIVE_IPADDR@' IDENTIFIED BY '@DB_CENTREON_PASSWD@'; From 104e5d54cf1fbac35bcadb67b422ed9a8f789ec0 Mon Sep 17 00:00:00 2001 From: cgenier Date: Tue, 9 Jul 2024 16:33:33 +0200 Subject: [PATCH 24/41] Update --- .../installation-of-centreon-ha/installation.md | 10 +++++----- versioned_sidebars/version-24.04-sidebars.json | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md index da54b15a3df1..09c029311fb5 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md @@ -689,23 +689,23 @@ GRANT ALL PRIVILEGES ON centreon_storage.* TO '@DB_CENTREON_USER@'@'@CENTRAL_ACT Still in the same prompt, create the account that will perform the database replication (its default name is `centreon-repl`): ```sql -GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* +GRANT GRANT READ_ONLY ADMIN, SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO '@DB_REPL_USER@'@'localhost' IDENTIFIED BY '@DB_REPL_PASSWD@'; -GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* +GRANT GRANT READ_ONLY ADMIN, SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO '@DB_REPL_USER@'@'@DATABASE_PASSIVE_IPADDR@' IDENTIFIED BY '@DB_REPL_PASSWD@'; -GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* +GRANT GRANT READ_ONLY ADMIN, SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO '@DB_REPL_USER@'@'@DATABASE_ACTIVE_IPADDR@' IDENTIFIED BY '@DB_REPL_PASSWD@'; ``` Add the following privileges so that the status of this account can be seen from the central cluster too. ```sql -GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* +GRANT GRANT READ_ONLY ADMIN, SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO '@DB_REPL_USER@'@'@CENTRAL_PASSIVE_IPADDR@' IDENTIFIED BY '@DB_REPL_PASSWD@'; -GRANT SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* +GRANT GRANT READ_ONLY ADMIN, SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO '@DB_REPL_USER@'@'@CENTRAL_ACTIVE_IPADDR@' IDENTIFIED BY '@DB_REPL_PASSWD@'; ``` diff --git a/versioned_sidebars/version-24.04-sidebars.json b/versioned_sidebars/version-24.04-sidebars.json index bd64e06aeec8..f7cae082e0d5 100644 --- a/versioned_sidebars/version-24.04-sidebars.json +++ b/versioned_sidebars/version-24.04-sidebars.json @@ -1476,6 +1476,10 @@ "type": "doc", "id": "version-24.04/installation/installation-of-centreon-ha/ha-faq" }, + { + "type": "doc", + "id": "version-24.04/installation/installation-of-centreon-ha/cluster-elements" + }, { "type": "doc", "id": "version-24.04/installation/installation-of-centreon-ha/overview" @@ -1508,10 +1512,6 @@ "type": "generated-index" }, "items": [ - { - "type": "doc", - "id": "version-24.04/administration/centreon-ha/acceptance-guide" - }, { "type": "doc", "id": "version-24.04/administration/centreon-ha/operating-guide" From 03436a6751dac38c2371909f673ae3ebd1e030f4 Mon Sep 17 00:00:00 2001 From: cgenier Date: Wed, 10 Jul 2024 18:30:27 +0200 Subject: [PATCH 25/41] Remove installation file + typos --- .../installation.md | 2102 ----------------- .../integrating-pollers.md | 2 +- .../version-24.04-sidebars.json | 9 +- 3 files changed, 4 insertions(+), 2109 deletions(-) delete mode 100644 versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md deleted file mode 100644 index 09c029311fb5..000000000000 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/installation.md +++ /dev/null @@ -1,2102 +0,0 @@ ---- -id: installation -title: Installing Centreon HA ---- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -> Debian 12 and MySQL 8 are not supported yet for HA installations using Centreon version 24.04. If you wish to install an HA platform with this configuration, please contact your Centreon sales representative. - -## Before you start - -### Disclaimer - -Your HA must be installed by Centreon. -This procedure is geared towards expers users who have a strong knowledge of the Pacemaker-Corosync clustering tools, of networks, of Linux OS and of Centreon. - -> **WARNING:** Anyone following this procedure does so at their own risk. Under no circumstances shall Centreon be liable for any breakdown or data loss. - -See also "[What is supported, and what isn't?](faq.md#what-is-supported-and-what-isnt)". - -### Convention for names and IP addresses - -In this procedure, we will refer to characteristics that are bound to change from one platform to another (such as IP addresses) by the following macros: - -* `@CENTRAL_ACTIVE_IPADDR@`: active central server's IP address -* `@CENTRAL_ACTIVE_NAME@`: active central server's name (must be identical to `hostname -s`) -* `@CENTRAL_PASSIVE_IPADDR@`: passive central server's IP address -* `@CENTRAL_PASSIVE_NAME@`: passive central server's name (must be identical to `hostname -s`) -* `@QDEVICE_IPADDR@`: quorum device's IP address -* `@QDEVICE_NAME@`: quorum device's name (must be identical to `hostname -s`) -* `@VIP_IPADDR@`: virtual IP address of the central servers cluster -* `@VIP_IFNAME@`: network device carrying the central servers cluster's VIP (name of the interface the VIP must send the flows to. The interface must have the same name on both central nodes). -* `@VIP_CIDR_NETMASK@`: subnet mask length in bits (e.g. 24) -* `@VIP_BROADCAST_IPADDR@`: central servers cluster's VIP broadcast address -* `@CENTREON_CLUSTER_PASSWD@`: `hacluster` user's password -* `@DATABASE_ACTIVE_IPADDR@`: active database server's IP address -* `@DATABASE_ACTIVE_NAME@`: active database server's FQDN (must be identical to: `hostname -s`) -* `@DATABASE_PASSIVE_IPADDR@`: passive database server's IP address -* `@DATABASE_PASSIVE_NAME@`: passive database server's FQDN (must be identical to: `hostname -s`) -* `@DB_REPL_USER@`: account that will perform the database replication (default: `centreon-repl`) -* `@DB_REPL_PASSWD@`: password for this account -* `@DB_CENTREON_USER@`: Account that the central servers will use to log in to the databases (to display the interface, to insert data into the databases, etc). The default value is `centreon`. -* `@DB_CENTREON_PASSWD@`: Password for this account -* `@VIP_SQL_IPADDR@`: virtual IP address of the SQL cluster -* `@VIP_SQL_IFNAME@`: network device carrying the SQL cluster's VIP (name of the interface the central server must send the flows to. The interface must have the same name on both database nodes). -* `@VIP_SQL_CIDR_NETMASK@`: SQL Cluster subnet mask length in bits (e.g. 24) -* `@VIP_SQL_BROADCAST_IPADDR@`: cluster's VIP SQL broadcast address - -During the installation procedure, central node 1 will be the active node and central node 2 will be the passive node. Of course, the roles will be able to be switched later. - -### How should I organize my Centreon HA? - -Ideally, the two central nodes should be running on different geographical sites. The quorum device should communicate with both sites independently. All members of the cluster (active and passive nodes, quorum device) need to communicate with each other. - -To reduce the probability of an interruption of service occurring, it is not recommended to set up a Centreon HA cluster where all your servers are running in the same datacenter or (even more so) within the same rack. - -In the case of a highly available architecture the Centreon central servers must not monitor resources. If this recommendation is not followed, the centengine service will take too long to restart and it may cause the functional Centreon group to failover. - -Make sure to give your servers clear, relevant hostnames so that you know which is which. - -## Step 1: Prepare the elements of the cluster - -### Installation checklist - -#### Set up VIPs for the central servers and for the databases - -* Reserve an IP address in your network to act as a VIP so that pollers can always send data to the active central node. -* Reserve another VIP through which the active central server will access the active database server. - -#### Install the central servers - -* Node 1 can either be a freshly installed Centreon or an existing Centreon with a remote database that already monitors resources (in that case, it should be running smoothly and without errors). If your existing Centreon has a local database, you need to transform it into a remote database first. -* Node 2 must be a freshly installed Centreon. - -Using the procedure for an installation with remote databases, [install the central server(s) from packages](https://docs.centreon.com/docs/installation/installation-of-a-central-server/using-packages). Both central servers must have the exact same version of Centreon ([update](https://docs.centreon.com/docs/update/update-centreon-platform) your platform if needed). In all cases, at this stage, make central node 1 point to database node 1 and central node 2 point to database node 2. [Both central nodes will be made to point to the database VIP](#step-4-modifying-the-centreon-configuration-files) once database replication is set up and the resources in the **centreon** group only run on the active node. - -* Both central servers should have an **admin** account with the same password. -* If you have an IT or Business edition, remember that license files for HA are specific. Please contact your Centreon sales representative to obtain your license files. - -#### Check the databases - -On the database servers, it is mandatory that **about 5 GB free space has been spared on the LVM volume group** that carries the MariaDB data directory (`/var/lib/mysql` mount point by default). - -The output of the `vgs` command must look like this (notice the value under `VFree`): - -```text - VG #PV #LV #SN Attr VSize VFree - centos_centreon-c1 1 5 0 wz--n- <31,00g <5,00g -``` - -* MariaDB files `ibdata*` and `ib_logfile*` must be in the "datadir" directory or in a subdirectory (scripts `centreondb-smooth-backup.sh` and `mysql-sync-bigdb.sh` are not compatible with this operation); -* MariaDB files `log-bin*` and `relay-log*` can be located in a directory (or a subdirectory) different from "datadir". They can also be on a different logical volume (`lvm`) than "datadir". However, the logical volume must be located in the volume group where "datadir" is stored. - -> **WARNING:** If these particular prerequisites are not effective, the database synchronization method described below will not work. - -#### Install the pollers - -Install your host machines and [install the pollers from packages](https://docs.centreon.com/docs/installation/installation-of-a-poller/using-packages) or [using the unattended script](https://docs.centreon.com/docs/installation/installation-of-a-poller/unattended-install-poller/). Do not register the pollers to a central server yet, this will be done later. - -#### Choose a quorum device - -Choose which server in your infrastructure should act as a quorum device. This can be a poller. (The actual configuration will be done later: see [Prepare the server that will function as the quorum device](#prepare-the-server-that-will-function-as-the-quorum-device) and [Define the quorum device](#define-the-quorum-device).) - -In order to adhere to best practices and be as resilient as possible, the quorum server should be at a different site than the other nodes, with independent network connections. - -### Configure centreon-broker on the central servers - -#### Change the link to the cbd service - -On a standard Centreon platform, there are two `cbd` services: - -* `central-broker-master`: also called "central broker" or "SQL broker", redirects input-output from pollers to the database, to RRD broker, and so on. -* `central-rrd-master`: also called "RRD broker", receives the stream from the central broker and updates the RRD binary data files (used to display graphs). - -In the context of a Centreon HA cluster, both broker processes will be handled by a separate service, managed by the cluster. - -* `central-broker-master` is replaced by `cbd_central_broker` (linked to *systemd* service `cbd-sql`) -* `central-rrd-master` is replaced by `cbd_rrd` (linked to *systemd* `cbd` service), the standard broker service for Centreon. - -On both central servers: - -1. Go to **Configuration > Pollers > Broker configuration**, then select **central-broker-master**. -2. On the **General** tab, in the **Main options** section, set **Link to cbd service** to **No**. - -This will result in the **Last Update** column of the **Configuration > Pollers > Pollers** page to become yellow, as Broker is temporarily stopped. An error will also appear in the **Pollers** section of the header bar: this is normal. Things will come back to normal at the end of the installation procedure (after you have defined all the resource groups, including **sql_broker**). - -#### Double the output stream toward RRD - -In the event of a cluster switch, you will expect the newly elected active central server to be able to display the metrics graphs, which requires all RRD data files to be up to date on both nodes. In order to fulfill this condition, you will double the central broker output stream and send it to both RRD broker processes. - -1. Go to **Configuration > Pollers > Broker configuration**, then select **central-broker-master**. -2. On the **Output** tab, select **Output 2 - IPv4**. The name of this output is **centreon-broker-master-rrd**. -3. In the **Host to connect to** field, replace **localhost** with the IP address of the active node (`@CENTRAL_ACTIVE_IPADDR@`). -4. Select **TCP - IPv4** from the dropdown list at the top of the page, then click **Add**. -5. Fill in the following details for this new output: - -| Output IPv4 | | -| ------------------ | ------------------------- | -| Name | centreon-broker-slave-rrd | -| Connection port | 5670 | -| Host to connect to | `@CENTRAL_PASSIVE_IPADDR@` | - -#### Export the configuration - -Once the above actions have been done ([Change the link to the cbd service](#change-the-link-to-the-cbd-service) and [Double the output stream toward RRD](#double-the-output-stream-toward-rrd)), export the configuration of the central server to apply these changes. The **Move Export Files** option must be checked. - -All the above actions should be applied either to both nodes, or to central node 1 only and then the exported files should be copied to central node 2: - -```bash -rsync -a /etc/centreon-broker/*json @CENTRAL_PASSIVE_IPADDR@:/etc/centreon-broker/ -``` - -Check that the files have been properly copied to node 2. If you just copied the json files from node 1 to node 2, for the moment, the changes do not appear in node 2's interface. - -### Customize the poller reload command - -In Centreon, the central broker daemon is reloaded every time you export your configuration. In the context of a HA setup, the central broker service is managed by the cluster and is called `cbd-sql`, [as described earlier](#change-the-link-to-the-cbd-service). This means that the service that needs to be reloaded when you export the configuration is `cbd-sql`, and no longer `cbd`: you need to configure this on central node 1. - -1. Go to **Configuration > Pollers > Pollers**, then click on the central server. -2. In the **Centreon Broker** section, set the **Centreon Broker reload command** parameter to `service cbd-sql reload`. - -### Tune kernel network settings - -In order to improve the reliability of the cluster, and since Centreon HA only supports IPv4, we recommend applying the following kernel settings to all your Centreon servers (including pollers): - - - - -```bash -cat >> /etc/sysctl.conf < - - - -```bash -cat >> /etc/sysctl.conf < - - - -```bash -cat >> /etc/sysctl.conf < - - -### Allow for server name resolution - -So that the Centreon HA cluster can stay in operation in the event of a DNS service breakdown, all members of the cluster must know each other by name, using `/etc/hosts`. - -Run the following command on the two central nodes, on the quorum device, and on both database servers: - -```bash -cat >/etc/hosts <<"EOF" -127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 -@CENTRAL_ACTIVE_IPADDR@ @CENTRAL_ACTIVE_NAME@ -@CENTRAL_PASSIVE_IPADDR@ @CENTRAL_PASSIVE_NAME@ -@DATABASE_ACTIVE_IPADDR@ @DATABASE_ACTIVE_NAME@ -@DATABASE_PASSIVE_IPADDR@ @DATABASE_PASSIVE_NAME@ -@QDEVICE_IPADDR@ @QDEVICE_NAME@ -EOF -``` - -### Install HA tools on the central servers - -Install the following packages on both central nodes. They provide all the files and dependencies required by a Centreon central cluster. - - - - -```bash -dnf config-manager --enable ha -dnf install centreon-ha-web pcs pacemaker corosync corosync-qdevice -``` - - - - -> To install Pacemaker and Corosync packages on RedHat systems, servers must have access to the **Red Hat Enterprise Linux High Availability** licensed repository. - -```bash -dnf -y install dnf-plugins-core https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -subscription-manager repos --enable rhel-8-for-x86_64-highavailability-rpms -dnf install centreon-ha-web pcs pacemaker corosync corosync-qdevice -``` - - - - -```bash -dnf config-manager --enable ol8_addons -dnf install centreon-ha-web pcs pacemaker corosync corosync-qdevice -``` - - - - -```bash -dnf config-manager --enable highavailability -dnf install centreon-ha-web pcs pacemaker corosync corosync-qdevice -``` - - - - -> To install Pacemaker and Corosync packages on RedHat systems, servers must have access to the **Red Hat Enterprise Linux High Availability** licensed repository. - -```bash -dnf -y install dnf-plugins-core https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm -subscription-manager repos --enable rhel-9-for-x86_64-highavailability-rpms -dnf install centreon-ha-web pcs pacemaker corosync corosync-qdevice -``` - - - - -```bash -dnf config-manager --enable ol9_addons -dnf install centreon-ha-web pcs pacemaker corosync corosync-qdevice -``` - - - - -```bash -apt update && apt install centreon-ha-web pcs pacemaker corosync corosync-qdevice -``` - - - - -### Install HA tools on the database servers - -Install the following packages on both database nodes. - - - - -```bash -dnf config-manager --enable ha -dnf install centreon-ha-common pcs pacemaker corosync corosync-qdevice -``` - - - - -```bash -dnf -y install dnf-plugins-core https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -subscription-manager repos --enable rhel-8-for-x86_64-highavailability-rpms -dnf install centreon-ha-common pcs pacemaker corosync corosync-qdevice -``` - - - - -```bash -dnf config-manager --enable ol8_addons -dnf install centreon-ha-common pcs pacemaker corosync corosync-qdevice -``` - - - - -```bash -dnf config-manager --enable highavailability -dnf install centreon-ha-common pcs pacemaker corosync corosync-qdevice -``` - - - - -```bash -dnf -y install dnf-plugins-core https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm -subscription-manager repos --enable rhel-9-for-x86_64-highavailability-rpms -dnf install centreon-ha-common pcs pacemaker corosync corosync-qdevice -``` - - - - -```bash -dnf config-manager --enable ol9_addons -dnf install centreon-ha-common pcs pacemaker corosync corosync-qdevice -``` - - - - -```bash -apt update && apt install centreon-ha-common pcs pacemaker corosync corosync-qdevice -``` - - - - -### Configure SSH keys exchange - -SSH key-based authentication must be set up so that files and commands can be sent: - -* from one central node to another by the **centreon** Unix account. -* from one database node to another by the **mysql** Unix account. - -There are two ways of exchanging such keys: - -* By using the `ssh-copy-id` command: needs to be able to log in to remote host using a password. It is however unsafe for such system accounts to have a password authentication available. If you choose this method, we advise you to revoke the password afterward with these commands: `passwd -d centreon` and `passwd -d mysql`. -* By manually copying the public key in `~/.ssh/authorized_keys`. This method is safer. - -The second method is documented below. - -#### **centreon** account - -Switch to `centreon`'s bash environment on both central nodes: - -```bash -su - centreon -``` - -Then run this command on both central nodes: - -```bash -ssh-keygen -t ed25519 -a 100 -``` - -Display the contents of the key file in your terminal using this command: - -```bash -cat ~/.ssh/id_ed25519.pub -``` - -Once done, copy the content of the public key file displayed by `cat` and paste it to the `~/.ssh/authorized_keys` file (must be created) on the other node, and then apply the correct file permissions (still as user `centreon`): - -```bash -chmod 600 ~/.ssh/authorized_keys -``` - -The key exchange must be validated by an initial connection from each node to the other in order to accept and register the peer node's SSH fingerprint (still as user `centreon`): - -```bash -ssh -``` - -Exit the SSH session (`Ctrl D`), then exit the `centreon` session by typing `exit` or `Ctrl D`. - -#### **mysql** account - -For the `mysql` account, the procedure is slightly different because this user normally has neither a home directory nor the ability to open a Shell session. Run the following commands on both database nodes: - -```bash -systemctl stop mysql -mkdir /home/mysql -chown mysql: /home/mysql -usermod -d /home/mysql mysql -usermod -s /bin/bash mysql -systemctl start mysql -su - mysql -``` - -Once in `mysql`'s `bash` environment, run these commands on both database nodes: - -```bash -ssh-keygen -t ed25519 -a 100 -cat ~/.ssh/id_ed25519.pub -``` - -Once done, copy the content of the public key file displayed by `cat` and paste it to `~/.ssh/authorized_keys` (must be created) on the other database node, and then apply the correct file permissions (still as user`mysql`): - -```bash -chmod 600 ~/.ssh/authorized_keys -``` - -The key exchange must be validated by an initial connection from each database node to the other in order to accept and register the peer node's SSH fingerprint (still as user `mysql`): - -```bash -ssh -``` - -Exit the SSH session (`Ctrl D`), then exit the `mysql` session by typing `exit` or `Ctrl D`. - -### Open network flows - -In addition to the necessary flows described in the [official documentation](https://docs.centreon.com/docs/installation/technical/#tables-of-network-flows), -you will need to open the following flows: - -| From | Destination | Protocol | Port | Application | -| :----------------------------- | :----------------------------- | :------- | :------- | :----------------------------------------------------------------------------------------- | -| Active Central Server | Passive Central Server | SSH | TCP 22 | Synchronization of configuration files (must also be open from passive to active node) | -| Active Central Server | Passive Central Server | BDDO | TCP 5670 | RRDs synchronization (must also be open from passive to active node) | -| Active Database Server | Passive Database Server | MySQL | TCP 3306 | MySQL synchronization (must also be open from passive to active node) | -| Active Database Server | Passive Database Server | SSH | TCP 22 | MySQL synchronization (must also be open from passive to active node) | -| Central Servers + DB + QDevice | Central Servers + DB + QDevice | Corosync | UDP 5404 | Communication inside the cluster (Multicast) | -| Central Servers + DB + QDevice | Central Servers + DB + QDevice | Corosync | UDP 5405 | Communication inside the cluster (Unicast) | -| Central Servers + DB + QDevice | Central Servers + DB + QDevice | PCS | TCP 2224 | Communication inside the cluster | -| Central Servers + DB + QDevice | Central Servers + DB + QDevice | Corosync | TCP 5403 | Communication with the QDevice | - -## Step 2: Set up the database replication - -An active-passive database cluster will be set up so that your data is synchronized in real time. - -* If one of your databases contains data, it must become the active database node. -* If both your databases are blank, either can be the active node. - -**Note**: unless otherwise stated, each of the following steps must be run on both database nodes. - -### Configuring MariaDB - - - - -For both optimization and cluster reliability purposes, you need to add these tuning options to the MariaDB configuration in the `/etc/my.cnf.d/server.cnf` file. By default, the `[server]` section of this file is empty. Paste the following lines (some need to be modified) into this section: - -```ini -[server] -server-id=1 # SET TO 1 FOR DATABASE NODE 1 AND 2 FOR DATABASE NODE 2 -#read_only -log-bin=mysql-bin -binlog-do-db=centreon -binlog-do-db=centreon_storage -innodb_flush_log_at_trx_commit=1 -sync_binlog=1 -binlog_format=MIXED -slave_compressed_protocol=1 -slave_parallel_mode=conservative -datadir=/var/lib/mysql -pid-file=/var/lib/mysql/mysql.pid -skip-slave-start -log-slave-updates -gtid_strict_mode=ON -expire_logs_days=7 -ignore-db-dir=lost+found - -# Tuning standard Centreon -innodb_file_per_table=1 -open_files_limit=32000 -key_buffer_size=256M -sort_buffer_size=32M -join_buffer_size=4M -thread_cache_size=64 -read_buffer_size=512K -read_rnd_buffer_size=256K -max_allowed_packet=64M -# Uncomment for 4 Go Ram -#innodb_buffer_pool_size=512M -# Uncomment for 8 Go Ram -#innodb_buffer_pool_size=1G -``` - - - - -For both optimization and cluster reliability purposes, you need to add these tuning options to the MariaDB configuration in the `/etc/my.cnf.d/server.cnf` file. By default, the `[server]` section of this file is empty. Paste the following lines (some need to be modified) into this section: - -```ini -[server] -server-id=1 # SET TO 1 FOR DATABASE NODE 1 AND 2 FOR DATABASE NODE 2 -#read_only -log-bin=mysql-bin -binlog-do-db=centreon -binlog-do-db=centreon_storage -innodb_flush_log_at_trx_commit=1 -sync_binlog=1 -binlog_format=MIXED -slave_compressed_protocol=1 -slave_parallel_mode=conservative -datadir=/var/lib/mysql -pid-file=/var/lib/mysql/mysql.pid -skip-slave-start -log-slave-updates -gtid_strict_mode=ON -expire_logs_days=7 -ignore-db-dir=lost+found - -# Tuning standard Centreon -innodb_file_per_table=1 -open_files_limit=32000 -key_buffer_size=256M -sort_buffer_size=32M -join_buffer_size=4M -thread_cache_size=64 -read_buffer_size=512K -read_rnd_buffer_size=256K -max_allowed_packet=128M -# Uncomment for 4 Go Ram -#innodb_buffer_pool_size=512M -# Uncomment for 8 Go Ram -#innodb_buffer_pool_size=1G -``` - -In addition, replace the [mysqld] section with : - -``` -[mysqld] -datadir=/var/lib/mysql -socket=/var/lib/mysql/mysql.sock -log-error=/var/log/mariadb/mariadb.log -pid-file=/var/lib/mysql/mysql.pid -``` - -then create the directory and corresponding log file: - -```shell -mkdir /var/log/mariadb -touch /var/log/mariadb/mariadb.log -chown -R mysql: /var/log/mariadb -``` - - - - -For both optimization and cluster reliability purposes, you need to add these tuning options to the MariaDB configuration in the `/etc/mysql/mariadb.conf.d/50-server.cnf` file. By default, the `[server]` section of this file is empty. Paste the following lines (some need to be modified) into this section: - -```ini -[server] -server-id=1 # SET TO 1 FOR DATABASE NODE 1 AND 2 FOR DATABASE NODE 2 -#read_only -log-bin=mysql-bin -binlog-do-db=centreon -binlog-do-db=centreon_storage -innodb_flush_log_at_trx_commit=1 -sync_binlog=1 -binlog_format=MIXED -slave_compressed_protocol=1 -slave_parallel_mode=conservative -datadir=/var/lib/mysql -pid-file=/run/mysqld/mysql.pid -skip-slave-start -log-slave-updates -gtid_strict_mode=ON -expire_logs_days=7 -ignore-db-dir=lost+found - -# Tuning standard Centreon -innodb_file_per_table=1 -open_files_limit=32000 -key_buffer_size=256M -sort_buffer_size=32M -join_buffer_size=4M -thread_cache_size=64 -read_buffer_size=512K -read_rnd_buffer_size=256K -max_allowed_packet=64M -# Uncomment for 4 Go Ram -#innodb_buffer_pool_size=512M -# Uncomment for 8 Go Ram -#innodb_buffer_pool_size=1G -``` - - - - -> **Important**: The value of the `server-id` option must be different from one server to the other. - -**Reminder**: Remember to uncomment the right value for `innodb_buffer_pool_size` according to your own servers' memory size. - -To apply the new configuration, restart the database server: - -```bash -systemctl restart mysql -``` - -Make sure the restart went well: - -```bash -systemctl status mysql -``` - -> **Warning:** other files in `/etc/my.cnf.d/`, such as `centreon.cnf`, will be ignored from now on. Any customization will have to be added to `server.cnf`. - - - - -> **Warning:** remember to change the parameter `Mysql configuration file path` to `/etc/my.cnf.d/server.cnf` in **Administration > Parameters > Backup** on central node 1. - - - - -> **Warning:** remember to change the parameter `Mysql configuration file path` to `/etc/my.cnf.d/server.cnf` in **Administration > Parameters > Backup** on central node 1. - - - - -> **Warning:** remember to change the parameter `Mysql configuration file path` to `/etc/mysql/mariadb.conf.d/50-server.cnf` in **Administration > Parameters > Backup** on central node 1. - - - - -### Creating the `centreon` MariaDB account - -First log in to MariaDB as `root` on both database servers (using the password you have defined during installation, when executing the **mysql_secure_installation** script): - -```bash -mysql -p -``` - -Then, on both database servers, paste the following SQL commands to the MariaDB prompt to create and/or configure the account that the central servers will use to connect to the databases (to display the interface, to insert data into the databases, etc). You may have created this account at [step 6 of the web installation](https://docs.centreon.com/docs/installation/web-and-post-installation/#step-6-database-information). The default name for this account is `centreon`. Replace the macros first: - -```sql -CREATE USER '@DB_CENTREON_USER@'@'@DATABASE_PASSIVE_IPADDR@' IDENTIFIED BY '@DB_CENTREON_PASSWD@'; -GRANT ALL PRIVILEGES ON centreon.* TO '@DB_CENTREON_USER@'@'@DATABASE_PASSIVE_IPADDR@'; -GRANT ALL PRIVILEGES ON centreon_storage.* TO '@DB_CENTREON_USER@'@'@DATABASE_PASSIVE_IPADDR@'; - -CREATE USER '@DB_CENTREON_USER@'@'@DATABASE_ACTIVE_IPADDR@' IDENTIFIED BY '@DB_CENTREON_PASSWD@'; -GRANT ALL PRIVILEGES ON centreon.* TO '@DB_CENTREON_USER@'@'@DATABASE_ACTIVE_IPADDR@'; -GRANT ALL PRIVILEGES ON centreon_storage.* TO '@DB_CENTREON_USER@'@'@DATABASE_ACTIVE_IPADDR@'; -``` - -Add the following privileges so that the status of this account can be seen from the central cluster too. - -```sql -CREATE USER '@DB_CENTREON_USER@'@'@CENTRAL_PASSIVE_IPADDR@' IDENTIFIED BY '@DB_CENTREON_PASSWD@'; -GRANT ALL PRIVILEGES ON centreon.* TO '@DB_CENTREON_USER@'@'@CENTRAL_PASSIVE_IPADDR@'; -GRANT ALL PRIVILEGES ON centreon_storage.* TO '@DB_CENTREON_USER@'@'@CENTRAL_PASSIVE_IPADDR@'; - -CREATE USER '@DB_CENTREON_USER@'@'@CENTRAL_ACTIVE_IPADDR@' IDENTIFIED BY '@DB_CENTREON_PASSWD@'; -GRANT ALL PRIVILEGES ON centreon.* TO '@DB_CENTREON_USER@'@'@CENTRAL_ACTIVE_IPADDR@'; -GRANT ALL PRIVILEGES ON centreon_storage.* TO '@DB_CENTREON_USER@'@'@CENTRAL_ACTIVE_IPADDR@'; -``` - -### Creating the MariaDB replication account - -Still in the same prompt, create the account that will perform the database replication (its default name is `centreon-repl`): - -```sql -GRANT GRANT READ_ONLY ADMIN, SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* -TO '@DB_REPL_USER@'@'localhost' IDENTIFIED BY '@DB_REPL_PASSWD@'; - -GRANT GRANT READ_ONLY ADMIN, SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* -TO '@DB_REPL_USER@'@'@DATABASE_PASSIVE_IPADDR@' IDENTIFIED BY '@DB_REPL_PASSWD@'; - -GRANT GRANT READ_ONLY ADMIN, SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* -TO '@DB_REPL_USER@'@'@DATABASE_ACTIVE_IPADDR@' IDENTIFIED BY '@DB_REPL_PASSWD@'; -``` - -Add the following privileges so that the status of this account can be seen from the central cluster too. - -```sql -GRANT GRANT READ_ONLY ADMIN, SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* -TO '@DB_REPL_USER@'@'@CENTRAL_PASSIVE_IPADDR@' IDENTIFIED BY '@DB_REPL_PASSWD@'; - -GRANT GRANT READ_ONLY ADMIN, SHUTDOWN, PROCESS, RELOAD, SUPER, SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* -TO '@DB_REPL_USER@'@'@CENTRAL_ACTIVE_IPADDR@' IDENTIFIED BY '@DB_REPL_PASSWD@'; -``` - -### Configuring environment variables for the MariaDB scripts - -In the `/etc/centreon-ha/mysql-resources.sh` file, configure environment variables so that the Centreon HA scripts dedicated to MariaDB can work on every node. This must be done on both central nodes and on both database nodes. These variables must be assigned the chosen values for the macros. - -```bash -#!/bin/bash - -############################### -# Database access credentials # -############################### - -DBHOSTNAMEMASTER='@DATABASE_ACTIVE_NAME@' -DBHOSTNAMESLAVE='@DATABASE_PASSIVE_NAME@' -DBREPLUSER='@DB_REPL_USER@' -DBREPLPASSWORD='@DB_REPL_PASSWD@' -DBROOTUSER='@DB_REPL_USER@' -DBROOTPASSWORD='@DB_REPL_PASSWD@' -CENTREON_DB='centreon' -CENTREON_STORAGE_DB='centreon_storage' - -############################### -``` - -To make sure that all the previous steps have been successful, and that the correct names, logins and passwords have been entered in the configuration bash file, run this command on both database nodes: - -```bash -/usr/share/centreon-ha/bin/mysql-check-status.sh -``` - -The expected output is: - -```text -Connection SLAVE Status '@DATABASE_ACTIVE_NAME@' [OK] -Connection SLAVE Status '@DATABASE_PASSIVE_NAME@' [OK] -Slave Thread Status [KO] -Error reports: - No slave (maybe because we cannot check a server). -Position Status [SKIP] -!Error reports: - Skip because we can't identify a unique slave. -``` - -What matters here is that the first two connection tests are `OK`. - -### Switching to read-only mode - - - - -Now that everything is configured correctly, enable the `read_only` on both database servers by uncommenting the **read_only** instruction in the `/etc/my.cnf.d/server.cnf` file (i.e., by removing the `#` at the beginning of the line). The beggining of the `[server]` section should now look like this: - -* Active database node: - -```ini -[server] -server-id=1 -read_only -log-bin=mysql-bin -``` - -* Passive database node: - -```ini -[server] -server-id=2 -read_only -log-bin=mysql-bin -``` - -Then apply this change by restarting MariaDB on both nodes: - -```bash -systemctl restart mysql -``` - - - - -Now that everything is configured correctly, enable the `read_only` on both database servers by uncommenting the **read_only** instruction in the `/etc/my.cnf.d/server.cnf` file (i.e., by removing the `#` at the beginning of the line). The beggining of the `[server]` section should now look like this: - -* Active database node: - -```ini -[server] -server-id=1 -read_only -log-bin=mysql-bin -``` - -* Passive database node: - -```ini -[server] -server-id=2 -read_only -log-bin=mysql-bin -``` - -Then apply this change by restarting MariaDB on both nodes: - -```bash -systemctl restart mysql -``` - - - - -Now that everything is configured correctly, enable the `read_only` on both database servers by uncommenting the **read_only** instruction in the `/etc/mysql/mariadb.conf.d/50-server.cnf` file (i.e., by removing the `#` at the beginning of the line). The beggining of the `[server]` section should now look like this: - -* Active database node - -```ini -[server] -server-id=1 -read_only -log-bin=mysql-bin -``` - -* Passive database node - -```ini -[server] -server-id=2 -read_only -log-bin=mysql-bin -``` - -Next, apply this change by restarting MariaDB on both nodes: - -```bash -systemctl restart mariadb -``` - - - - -### Synchronizing the databases and enabling MariaDB replication - -In the process of synchronizing the databases, you will first stop the passive database process so that its data can be overwritten by the active database node's data. - -> Important: If you have existing data, make sure you synchronize the database with the data onto the blank database (i.e. the database that contains data must be the active node), and not the other way round. - -Run this command **on the passive node**: - -```bash -systemctl stop mysql -``` - -It is important to make sure that MariaDB is completely shut down. Run this command on the passive node and check that it returns no output: - -```bash -ps -ef | grep mariadb[d] -``` - -In case one or more processes are still alive, run the following command (it will prompt for the MariaDB root password): - -```bash -mysqladmin -p shutdown -``` - -Once the database service is stopped **on the passive database node**, run the synchronization script **from the active database node**: - -```bash -/usr/share/centreon-ha/bin/mysql-sync-bigdb.sh -``` - -This script will perform the following actions: - -* Check that MariaDB is stopped on the secondary node. -* Stop MariaDB on the primary node. -* Mount an LVM snapshot on the same volume group that holds `/var/lib/mysql` (or whatever mount point holds the MariaDB data files). -* Start MariaDB again on the primary node. -* Record the current position in the binary log. -* Disable the `read_only` mode on the active database node (this node will now be able to write to its database). The passive database node stays in `read_only` mode: only the replication process can insert data there. -* Synchronize/overwrite all the data files (except for the `mysql` system database). -* Unmount the LVM snapshot. -* Create the replication thread that will keep both databases synchronized. - -This script's output is very verbose and you can't expect to understand everything, so to make sure it went well, focus on the last lines of its output, checking that it looks like this: - -```text -Umount and Delete LVM snapshot - Logical volume "dbbackupdatadir" successfully removed -Start MySQL Slave -Start Replication -Id User Host db Command Time State Info Progress -[variable number of lines] -``` - -The important thing to check is that `Start MySQL Slave` and `Start Replication` are present and are not followed by any errors. - -In addition, the output of this command must display only `OK` results: - -```bash -/usr/share/centreon-ha/bin/mysql-check-status.sh -``` - -The expected output is: - -```text -Connection MASTER Status '@DATABASE_ACTIVE_NAME@' [OK] -Connection SLAVE Status '@DATABASE_PASSIVE_NAME@' [OK] -Slave Thread Status [OK] -Position Status [OK] -``` - -## Step 3: Set up the Centreon cluster - -**Note**: Unless otherwise stated, each of the following steps must be run **on both central nodes**. - -### Configure the file synchronization service - -Each central node must know the IP address of the other central node so that data can be synced between them. To be more specific, the `centreon-central-sync` file synchronization service needs the IP address of the peer node to be entered in its configuration file (`/etc/centreon-ha/centreon_central_sync.pm`). - -So, on the active central server, the configuration file should look like this: - -```perl -our %centreon_central_sync_config = ( - peer_addr => "@CENTRAL_PASSIVE_IPADDR@" -); -1; -``` - -And on the passive central server: - -```perl -our %centreon_central_sync_config = ( - peer_addr => "@CENTRAL_ACTIVE_IPADDR@" -); -1; -``` - -### Remove legacy Centreon cron jobs - -In a high-availability setup, all cron-based scheduled tasks are managed by the gorgone daemon. This means that all Centreon-related crons on both central nodes are unnecessary and must be removed from the **/etc/cron.d/** directory, otherwise the metrics will be incorrect. Run the following commands: - -```bash -rm -f /etc/cron.d/centreon -rm -f /etc/cron.d/centstorage -rm -f /etc/cron.d/centreon-auto-disco -rm -f /etc/cron.d/centreon-ha-mysql -``` - -### Modify permissions on directories - -Modifications must be made to the permissions for the `/var/log/centreon-engine` and `/tmp/centreon-autodisco` directories. This is mandatory so that file sync and discovery scheduled tasks are fully functional. - -* Files synchronization - -```bash -chmod 775 /var/log/centreon-engine/ -mkdir /var/log/centreon-engine/archives -chown centreon-engine: /var/log/centreon-engine/archives -chmod 775 /var/log/centreon-engine/archives/ -find /var/log/centreon-engine/ -type f -exec chmod 664 {} \; -find /usr/share/centreon/www/img/media -type d -exec chmod 775 {} \; -find /usr/share/centreon/www/img/media -type f \( ! -iname ".keep" ! -iname ".htaccess" \) -exec chmod 664 {} \; -``` - -* Services discovery - - - - -```bash -mkdir /tmp/centreon-autodisco/ -chown apache: /tmp/centreon-autodisco/ -chmod 775 /tmp/centreon-autodisco/ -``` - - - - -```bash -mkdir /tmp/centreon-autodisco/ -chown apache: /tmp/centreon-autodisco/ -chmod 775 /tmp/centreon-autodisco/ -``` - - - - -```bash -mkdir /tmp/centreon-autodisco/ -chown www-data: /tmp/centreon-autodisco/ -chmod 775 /tmp/centreon-autodisco/ -``` - - - - -### Stop and disable services - -The central nodes and the database nodes must no longer launch some services at boot time: this will be done by the clustering tools, and only them. - -#### On each central node - - - - -```bash -systemctl stop centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon -systemctl disable centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon -``` - - - - -```bash -systemctl stop centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon -systemctl disable centengine snmptrapd centreontrapd gorgoned cbd httpd php-fpm centreon -``` - - - - -```bash -systemctl stop centengine snmptrapd centreontrapd gorgoned cbd apache2 php8.1-fpm centreon -systemctl disable centengine snmptrapd centreontrapd gorgoned cbd apache2 php8.1-fpm centreon -``` - - - - -At this point, you no longer have access to the central servers' interfaces (as you have stopped the corresponding service). The interfaces will be up again at the end of the installation procedure. - -#### On each database node - -```bash -systemctl stop mysql -systemctl disable mysql -``` - - - - -By default, the `mysql` service is enabled in both systemd and system V perspectives, so you should make sure it is disabled: - -```bash -chkconfig mysql off -``` - - - - -By default, the `mysql` service is enabled in both systemd and system V perspectives, so you should make sure it is disabled: - -```bash -chkconfig mysql off -``` - - - - -By default, the `mysql` service is enabled in both systemd and system V perspectives, so you should make sure it is disabled: - -```bash -update-rc.d -f mariadb remove -``` - - - - -### Activate the clustering services - -Start `pcsd` on the central and database nodes: - -```bash -systemctl start pcsd -``` - -### Prepare the server that will function as the quorum device - -You can use one of your pollers to play the role of quorum device. - -> **WARNING:** Make sure Selinux and Firewalld are disabled on this machine. - -Run the following commands to install all required packages on the quorum device: - - - - -```bash -dnf config-manager --enable ha -dnf install pcs corosync-qnetd -systemctl start pcsd.service -systemctl enable pcsd.service -pcs qdevice setup model net --enable --start -pcs qdevice status net --full -``` - - - - -```bash -dnf -y install dnf-plugins-core https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -subscription-manager repos --enable rhel-8-for-x86_64-highavailability-rpms -dnf install pcs corosync-qnetd -systemctl start pcsd.service -systemctl enable pcsd.service -pcs qdevice setup model net --enable --start -pcs qdevice status net --full -``` - - - - -```bash -dnf config-manager --enable ol8_addons -dnf install pcs corosync-qnetd -systemctl start pcsd.service -systemctl enable pcsd.service -pcs qdevice setup model net --enable --start -pcs qdevice status net --full -``` - - - - -```bash -dnf config-manager --enable ha -dnf install pcs corosync-qnetd -systemctl start pcsd.service -systemctl enable pcsd.service -pcs qdevice setup model net --enable --start -pcs qdevice status net --full -``` - - - - -```bash -dnf -y install dnf-plugins-core https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm -subscription-manager repos --enable rhel-9-for-x86_64-highavailability-rpms -dnf install pcs corosync-qnetd -systemctl start pcsd.service -systemctl enable pcsd.service -pcs qdevice setup model net --enable --start -pcs qdevice status net --full -``` - - - - -```bash -dnf config-manager --enable ol9_addons -dnf install pcs corosync-qnetd -systemctl start pcsd.service -systemctl enable pcsd.service -pcs qdevice setup model net --enable --start -pcs qdevice status net --full -``` - - - - -```bash -apt install pcs corosync-qnetd -systemctl start pcsd.service -systemctl enable pcsd.service -pcs qdevice setup model net --enable --start -pcs qdevice status net --full -``` - - - - -Here is the expected output of the `qdevice status` command: - -```shell -[root@@QDEVICE_NAME@ ~]# pcs qdevice status net --full -QNetd address: *:5403 -TLS: Supported (client certificate required) -Connected clients: 0 -Connected clusters: 0 -Maximum send/receive size: 32768/32768 bytes -``` - - - - -Modify the parameter `COROSYNC_QNETD_OPTIONS` in the file `/etc/sysconfig/corosync-qnetd` to make sure the service will be listening to the connections on Ipv4 only. - -```bash -COROSYNC_QNETD_OPTIONS="-4" -``` - - - - - -```bash -COROSYNC_QNETD_OPTIONS="-4" -``` - - - - -Modify the parameter `COROSYNC_QNETD_OPTIONS` in the file `/etc/default/corosync-qnetd` to make sure the service will be listening to the connections on Ipv4 only. - -```bash -COROSYNC_QNETD_OPTIONS="-4" -``` - - - - -### Authenticate the hacluster user to the cluster's members - -A user called **hacluster** has been automatically created when you installed Pacemaker and Corosync. This user will run the Corosync and Pacemaker processes on all 5 members of the cluster. -For the sake of simplicity, the **hacluster** user will be assigned the same password on both central nodes, on both database servers and on the quorum device. Run the following command on each machine and set the password you want. - -```bash -passwd hacluster -``` - -Now that all members of the cluster (both central nodes, both database nodes and the quorum device server) share the same password, run this command **only on one of the central nodes** in order to authenticate the **hacluster** user to all members of the cluster. - - - - -```bash -pcs host auth \ - "@CENTRAL_ACTIVE_NAME@" \ - "@CENTRAL_PASSIVE_NAME@" \ - "@DATABASE_ACTIVE_NAME@" \ - "@DATABASE_PASSIVE_NAME@" \ - "@QDEVICE_NAME@" \ - -u "hacluster" \ - -p '@CENTREON_CLUSTER_PASSWD@' -``` - - - - -```bash -pcs host auth \ - "@CENTRAL_ACTIVE_NAME@" \ - "@CENTRAL_PASSIVE_NAME@" \ - "@DATABASE_ACTIVE_NAME@" \ - "@DATABASE_PASSIVE_NAME@" \ - "@QDEVICE_NAME@" \ - -u "hacluster" \ - -p '@CENTREON_CLUSTER_PASSWD@' -``` - - - - -On Debian, the cluster is autoconfigured with default values. In order to install our cluster, we need to remove the default values using the following command: - -```bash -pcs cluster destroy -``` - -Then you can start the authentication of the cluster: - -```bash -pcs host auth \ - "@CENTRAL_ACTIVE_NAME@" \ - "@CENTRAL_PASSIVE_NAME@" \ - "@DATABASE_ACTIVE_NAME@" \ - "@DATABASE_PASSIVE_NAME@" \ - "@QDEVICE_NAME@" \ - -u "hacluster" \ - -p '@CENTREON_CLUSTER_PASSWD@' -``` - - - - -If the authentication has succeeded on all nodes, you will get a message similar to this: - -```shell -@CENTRAL_PASSIVE_NAME@: Authorized -@CENTRAL_PASSIVE_NAME@: Authorized -@DATABASE_ACTIVE_NAME@: Authorized -@DATABASE_PASSIVE_NAME@: Authorized -@QDEVICE_NAME@: Authorized -``` - -### Create the cluster - -The following command creates the cluster. Run it **only on one of the central nodes**. - - - - -```bash -pcs cluster setup \ - centreon_cluster \ - "@CENTRAL_ACTIVE_NAME@" \ - "@CENTRAL_PASSIVE_NAME@" \ - "@DATABASE_ACTIVE_NAME@" \ - "@DATABASE_PASSIVE_NAME@" \ - --force -``` - - - - -```bash -pcs cluster setup \ - centreon_cluster \ - "@CENTRAL_ACTIVE_NAME@" \ - "@CENTRAL_PASSIVE_NAME@" \ - "@DATABASE_ACTIVE_NAME@" \ - "@DATABASE_PASSIVE_NAME@" \ - --force -``` - - - - -```bash -pcs cluster setup \ - centreon_cluster \ - "@CENTRAL_ACTIVE_NAME@" \ - "@CENTRAL_PASSIVE_NAME@" \ - "@DATABASE_ACTIVE_NAME@" \ - "@DATABASE_PASSIVE_NAME@" \ - --force -``` - - - - -You should get the following message: - -```shell -[root@@CENTRAL_ACTIVE_IPNAME@ ~]# pcs cluster setup centreon_cluster "@CENTRAL_ACTIVE_IPADDR@" "@CENTRAL_PASSIVE_IPADDR@" --force -No addresses specified for host '@CENTRAL_ACTIVE_IPADDR@', using '@CENTRAL_ACTIVE_IPADDR@' -No addresses specified for host '@CENTRAL_PASSIVE_IPADDR@', using '@CENTRAL_PASSIVE_IPADDR@' -Destroying cluster on hosts: '@CENTRAL_ACTIVE_IPADDR@', '@CENTRAL_PASSIVE_IPADDR@'... -@CENTRAL_ACTIVE_IPADDR@: Successfully destroyed cluster -@CENTRAL_PASSIVE_IPADDR@: Successfully destroyed cluster -Requesting remove 'pcsd settings' from '@CENTRAL_ACTIVE_IPADDR@', '@CENTRAL_PASSIVE_IPADDR@' -@CENTRAL_ACTIVE_IPADDR@: successful removal of the file 'pcsd settings' -@CENTRAL_PASSIVE_IPADDR@: successful removal of the file 'pcsd settings' -Sending 'corosync authkey', 'pacemaker authkey' to '@CENTRAL_ACTIVE_IPADDR@', '@CENTRAL_PASSIVE_IPADDR@' -@CENTRAL_ACTIVE_IPADDR@: successful distribution of the file 'corosync authkey' -@CENTRAL_ACTIVE_IPADDR@: successful distribution of the file 'pacemaker authkey' -@CENTRAL_PASSIVE_IPADDR@: successful distribution of the file 'corosync authkey' -@CENTRAL_PASSIVE_IPADDR@: successful distribution of the file 'pacemaker authkey' -Sending 'corosync.conf' to '@CENTRAL_ACTIVE_IPADDR@', '@CENTRAL_PASSIVE_IPADDR@' -@CENTRAL_ACTIVE_IPADDR@: successful distribution of the file 'corosync.conf' -@CENTRAL_PASSIVE_IPADDR@: successful distribution of the file 'corosync.conf' -Cluster has been successfully set up. -``` - -Then start the `pacemaker` service **on both central and database nodes**: - -```bash -systemctl enable pacemaker pcsd corosync -systemctl start pacemaker -``` - -And afterward define these properties **only on one node**: - -```bash -pcs property set symmetric-cluster="true" -pcs property set stonith-enabled="false" -pcs resource defaults update resource-stickiness="100" -``` - -You can now monitor the state of the cluster with the `crm_mon -f` command: it will display [the new cluster resources as you create them](#create-the-centreon-resource-group). - -At this stage, no resources have been added to the cluster, so the results of the command run from node 1 should look like this: - -```shell -Cluster Summary: - * Stack: corosync (Pacemaker is running) - * Current DC: @CENTRAL_ACTIVE_NAME@ (version 2.1.6-9.1.el8_9-6fdc9deea29) - partition with quorum - * Last updated: Fri Mar 29 10:47:22 2024 on @CENTRAL_ACTIVE_NAME@ - * Last change: Thu Mar 28 16:38:56 2024 by root via cibadmin on @CENTRAL_ACTIVE_NAME@ - * 4 nodes configured - * 0 resource instances configured - -Node List: - * Online: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ @DATABASE_ACTIVE_NAME@ @DATABASE_PASSIVE_NAME@ ] - -Active Resources: - * No active resources - -Migration Summary: -``` - -### Define the quorum device - -To let the central nodes know which server is the quorum device, run this command on one of the central nodes: - -```bash -pcs quorum device add model net \ - host="@QDEVICE_NAME@" \ - algorithm="ffsplit" -``` - -The results should look like this: - -```shell -Setting up qdevice certificates on nodes... -@CENTRAL_ACTIVE_NAME@: Succeeded -@CENTRAL_PASSIVE_NAME@: Succeeded -@DATABASE_PASSIVE_NAME@: Succeeded -@DATABASE_ACTIVE_NAME@: Succeeded -Enabling corosync-qdevice... -@CENTRAL_PASSIVE_NAME@: corosync-qdevice enabled -@DATABASE_PASSIVE_NAME@: corosync-qdevice enabled -@DATABASE_ACTIVE_NAME@: corosync-qdevice enabled -@CENTRAL_ACTIVE_NAME@: corosync-qdevice enabled -Sending updated corosync.conf to nodes... -@CENTRAL_ACTIVE_NAME@: Succeeded -@DATABASE_ACTIVE_NAME@: Succeeded -@CENTRAL_PASSIVE_NAME@: Succeeded -@DATABASE_PASSIVE_NAME@: Succeeded -@CENTRAL_ACTIVE_NAME@: Corosync configuration reloaded -Starting corosync-qdevice... -@CENTRAL_ACTIVE_NAME@: corosync-qdevice started -@CENTRAL_PASSIVE_NAME@: corosync-qdevice started -@DATABASE_PASSIVE_NAME@: corosync-qdevice started -@DATABASE_ACTIVE_NAME@: corosync-qdevice started - -``` - -### Create the database cluster resources - -All commands within this section should be executed on **only one database node**. The configuration will be spread automatically. - -#### Active and passive MySQL processes - - - - -```bash -pcs resource create "ms_mysql" \ - ocf:heartbeat:mariadb-centreon \ - config="/etc/my.cnf.d/server.cnf" \ - pid="/var/lib/mysql/mysql.pid" \ - datadir="/var/lib/mysql" \ - socket="/var/lib/mysql/mysql.sock" \ - binary="/usr/bin/mysqld_safe" \ - node_list="@DATABASE_ACTIVE_NAME@ @DATABASE_PASSIVE_NAME@" \ - replication_user="@DB_REPL_USER@" \ - replication_passwd='@DB_REPL_PASSWD@' \ - test_user="@DB_REPL_USER@" \ - test_passwd='@DB_REPL_PASSWD@' \ - test_table='centreon.host' -``` - - - - -```bash -pcs resource create "ms_mysql" \ - ocf:heartbeat:mariadb-centreon \ - config="/etc/my.cnf.d/server.cnf" \ - pid="/var/lib/mysql/mysql.pid" \ - datadir="/var/lib/mysql" \ - socket="/var/lib/mysql/mysql.sock" \ - binary="/usr/bin/mysqld_safe" \ - node_list="@DATABASE_ACTIVE_NAME@ @DATABASE_PASSIVE_NAME@" \ - replication_user="@DB_REPL_USER@" \ - replication_passwd='@DB_REPL_PASSWD@' \ - test_user="@DB_REPL_USER@" \ - test_passwd='@DB_REPL_PASSWD@' \ - test_table='centreon.host' -``` - - - - -```bash -pcs resource create "ms_mysql" \ - ocf:heartbeat:mariadb-centreon \ - config="/etc/mysql/mariadb.conf.d/50-server.cnf" \ - pid="/run/mysqld/mysqld.pid" \ - datadir="/var/lib/mysql" \ - socket="/run/mysqld/mysqld.sock" \ - binary="/usr/bin/mysqld_safe" \ - node_list="@DATABASE_ACTIVE_NAME@ @DATABASE_PASSIVE_NAME@" \ - replication_user="@DB_REPL_USER@" \ - replication_passwd='@DB_REPL_PASSWD@' \ - test_user="@DB_REPL_USER@" \ - test_passwd='@DB_REPL_PASSWD@' \ - test_table='centreon.host' -``` - - - - -This command has no output. - - - - -```bash -pcs resource promotable ms_mysql \ - master-node-max="1" \ - clone_max="2" \ - globally-unique="false" \ - clone-node-max="1" \ - notify="true" -``` - - - - -```bash -pcs resource promotable ms_mysql \ - master-node-max="1" \ - clone_max="2" \ - globally-unique="false" \ - clone-node-max="1" \ - notify="true" -``` - - - - -```bash -pcs resource promotable ms_mysql \ - master-node-max="1" \ - clone_max="2" \ - globally-unique="false" \ - clone-node-max="1" \ - notify="true" -``` - - - - -This command has no output. - -#### Define the database VIP - -Run the following command on the active database node to let it know the address of the database VIP. - -```bash -pcs resource create vip_mysql \ - ocf:heartbeat:IPaddr2 \ - ip="@VIP_SQL_IPADDR@" \ - nic="@VIP_SQL_IFNAME@" \ - cidr_netmask="@VIP_SQL_CIDR_NETMASK@" \ - broadcast="@VIP_SQL_BROADCAST_IPADDR@" \ - flush_routes="true" \ - meta target-role="stopped" \ - op start interval="0s" timeout="20s" \ - stop interval="0s" timeout="20s" \ - monitor interval="10s" timeout="20s" -``` - -### Define the clone resources - -RRD broker and PHP8 will run on both central nodes at the same time. For this to work properly, they must be declared as clone resources. - -> **Warning:** All the commands in this section should be run only once on the central node of your choice. - -##### PHP8 resource - - - - -```bash -pcs resource create "php" \ - systemd:php-fpm \ - meta target-role="started" \ - op start interval="0s" timeout="30s" \ - stop interval="0s" timeout="30s" \ - monitor interval="5s" timeout="30s" \ - clone -``` - - - - -```bash -pcs resource create "php" \ - systemd:php-fpm \ - meta target-role="started" \ - op start interval="0s" timeout="30s" \ - stop interval="0s" timeout="30s" \ - monitor interval="5s" timeout="30s" \ - clone -``` - - - - -```bash -pcs resource create "php" \ - systemd:php8.1-fpm \ - meta target-role="started" \ - op start interval="0s" timeout="30s" \ - stop interval="0s" timeout="30s" \ - monitor interval="5s" timeout="30s" \ - clone -``` - - - - -##### RRD broker resource - -```bash -pcs resource create "cbd_rrd" \ - systemd:cbd \ - meta target-role="started" \ - op start interval="0s" timeout="90s" \ - stop interval="0s" timeout="90s" \ - monitor interval="20s" timeout="30s" \ - clone -``` - -### Create the centreon resource group - -The **centreon** [resource group](https://docs.centreon.com/docs/installation/installation-of-centreon-ha/overview/#what-processes-are-synchronized-by-centreon-ha) is the list of processes that Pacemaker will have to manage. These processes will not be managed by the central nodes themselves (most of them have been [disabled](#stop-and-disable-services) on the central servers). - -#### Define the central VIP - -Run the following command on the active central node to let it know the address of the VIP. - -```bash -pcs resource create vip \ - ocf:heartbeat:IPaddr2 \ - ip="@VIP_IPADDR@" \ - nic="@VIP_IFNAME@" \ - cidr_netmask="@VIP_CIDR_NETMASK@" \ - broadcast="@VIP_BROADCAST_IPADDR@" \ - flush_routes="true" \ - meta target-role="started" \ - op start interval="0s" timeout="20s" \ - stop interval="0s" timeout="20s" \ - monitor interval="10s" timeout="20s" \ - --group centreon -``` - -From now on, when you connect using SSH to the active node, your terminal may show the IP address of the VIP. - -#### httpd service - -This will enable the web server. - - - - -```bash -pcs resource create http \ - systemd:httpd \ - meta target-role="started" \ - op start interval="0s" timeout="40s" \ - stop interval="0s" timeout="40s" \ - monitor interval="5s" timeout="20s" \ - --group centreon \ - --force -``` - - - - -```bash -pcs resource create http \ - systemd:httpd \ - meta target-role="started" \ - op start interval="0s" timeout="40s" \ - stop interval="0s" timeout="40s" \ - monitor interval="5s" timeout="20s" \ - --group centreon \ - --force -``` - - - - -```bash -pcs resource create http \ - systemd:apache2 \ - meta target-role="started" \ - op start interval="0s" timeout="40s" \ - stop interval="0s" timeout="40s" \ - monitor interval="5s" timeout="20s" \ - --group centreon \ - --force -``` - - - - -#### Gorgone service - -```bash -pcs resource create gorgone \ - systemd:gorgoned \ - meta target-role="started" \ - op start interval="0s" timeout="90s" \ - stop interval="0s" timeout="90s" \ - monitor interval="5s" timeout="20s" \ - --group centreon -``` - -#### centreon-central-sync service - -This service only exists in the context of Centreon HA. It provides real-time synchronization for configuration files, images, etc. - -```bash -pcs resource create centreon_central_sync \ - systemd:centreon-central-sync \ - meta target-role="started" \ - op start interval="0s" timeout="90s" \ - stop interval="0s" timeout="90s" \ - monitor interval="5s" timeout="20s" \ - --group centreon -``` - -#### SQL Broker - -```bash -pcs resource create cbd_central_broker \ - systemd:cbd-sql \ - meta target-role="started" \ - op start interval="0s" timeout="90s" \ - stop interval="0s" timeout="90s" \ - monitor interval="5s" timeout="30s" \ - --group centreon -``` - -#### Centengine service - -```bash -pcs resource create centengine \ - systemd:centengine \ - meta multiple-active="stop_start" target-role="started" \ - op start interval="0s" timeout="90s" stop interval="0s" timeout="90s" \ - monitor interval="5s" timeout="30s" \ - --group centreon -``` - -#### Centreontrapd service - -```bash -pcs resource create centreontrapd \ - systemd:centreontrapd \ - meta target-role="started" \ - op start interval="0s" timeout="30s" \ - stop interval="0s" timeout="30s" \ - monitor interval="5s" timeout="20s" \ - --group centreon -``` - -#### Snmptrapd service - -```bash -pcs resource create snmptrapd \ - systemd:snmptrapd \ - meta target-role="started" \ - op start interval="0s" timeout="30s" \ - stop interval="0s" timeout="30s" \ - monitor interval="5s" timeout="20s" \ - --group centreon -``` - -### Define resource constraints - -When using this architecture, you must define some specific constraints to specify on which nodes resources are allowed to run. - -In order to colocate the active database role with the database VIP, define a mutual constraint: - - - - -```bash -pcs constraint colocation add "vip_mysql" with master "ms_mysql-clone" -pcs constraint colocation add master "ms_mysql-clone" with "vip_mysql" -``` - - - - -```bash -pcs constraint colocation add "vip_mysql" with Promoted "ms_mysql-clone" -pcs constraint colocation add Promoted "ms_mysql-clone" with "vip_mysql" -``` - - - - -```bash -pcs constraint colocation add "vip_mysql" with master "ms_mysql-clone" -pcs constraint colocation add master "ms_mysql-clone" with "vip_mysql" -``` - - - - -Create the constraint that prevents Centreon processes from running on database nodes and vice-versa: - - - - -```bash -pcs constraint location centreon avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY -pcs constraint location ms_mysql-clone avoids @CENTRAL_ACTIVE_NAME@=INFINITY @CENTRAL_PASSIVE_NAME@=INFINITY -pcs constraint location cbd_rrd-clone avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY -pcs constraint location php-clone avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY -``` - - - - -```bash -pcs constraint location centreon avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY -pcs constraint location ms_mysql-clone avoids @CENTRAL_ACTIVE_NAME@=INFINITY @CENTRAL_PASSIVE_NAME@=INFINITY -pcs constraint location cbd_rrd-clone avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY -pcs constraint location php-clone avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY -``` - - - - -```bash -pcs constraint location centreon avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY -pcs constraint location ms_mysql-clone avoids @CENTRAL_ACTIVE_NAME@=INFINITY @CENTRAL_PASSIVE_NAME@=INFINITY -pcs constraint location cbd_rrd-clone avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY -pcs constraint location php-clone avoids @DATABASE_ACTIVE_NAME@=INFINITY @DATABASE_PASSIVE_NAME@=INFINITY -``` - - - - -### Activate the resources - -```bash -pcs resource enable php-clone -pcs resource enable cbd_rrd-clone -pcs resource meta vip target-role="started" -pcs resource meta vip_mysql target-role="started" -pcs resource meta centreontrapd target-role="started" -pcs resource meta snmptrapd target-role="started" -pcs resource meta centengine target-role="started" -pcs resource meta cbd_central_broker target-role="started" -pcs resource meta gorgone target-role="started" -pcs resource meta centreon_central_sync target-role="started" -pcs resource meta http target-role="started" -``` - -At this stage, you can connect to the interface of the active node using the VIP's address. - -If the **Resource Status** page is empty, check that the central points to the database VIP and not to one database in particular. In **Configuration > Pollers > Broker configuration**, open **central-broker-master** and in the **Output** tab, update the **DB host**. - -### Check the state of the cluster - -#### Check the state of the resources - -Use the `crm_mon -f` command to check that all your resources have been created and are started. Here is an example of output: - -```bash -Cluster Summary: - * Stack: corosync (Pacemaker is running) - * Current DC: @CENTRAL_ACTIVE_NODE@ (version 2.1.6-9.1.el8_9-6fdc9deea29) - MIXED-VERSION partition with quorum - * Last updated: Tue Jun 4 07:57:43 2024 on @CENTRAL_ACTIVE_NODE@ - * Last change: Tue Jun 4 05:44:11 2024 by root via crm_resource on @CENTRAL_PASSIVE_NODE@ - * 4 nodes configured - * 21 resource instances configured - -Node List: - * Online: [ @CENTRAL_ACTIVE_NODE@ @CENTRAL_PASSIVE_NODE@ @DATABASE_ACTIVE_NODE@ @DATABASE_PASSIVE_NODE@ ] - -Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @DATABASE_ACTIVE_NODE@ ] - * Slaves: [ @DATABASE_PASSIVE_NODE@ ] - * Stopped: [ @CENTRAL_ACTIVE_NODE@ @CENTRAL_PASSIVE_NODE@ ] - * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_ACTIVE_NODE@ @CENTRAL_PASSIVE_NODE@ ] - * Stopped: [ @DATABASE_ACTIVE_NODE@ @DATABASE_PASSIVE_NODE@ ] - * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_ACTIVE_NODE@ @CENTRAL_PASSIVE_NODE@ ] - * Stopped: [ @DATABASE_ACTIVE_NODE@ @DATABASE_PASSIVE_NODE@ ] - * vip_mysql (ocf::heartbeat:IPaddr2): Started @DATABASE_ACTIVE_NODE@ - * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_ACTIVE_NODE@ - * http (systemd:httpd): Started @CENTRAL_ACTIVE_NODE@ - * gorgone (systemd:gorgoned): Started @CENTRAL_ACTIVE_NODE@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_ACTIVE_NODE@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_ACTIVE_NODE@ - * centengine (systemd:centengine): Started @CENTRAL_ACTIVE_NODE@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_ACTIVE_NODE@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_ACTIVE_NODE@ - -Migration Summary: - -``` - -If **centreon_central_sync** won't start, check if the folder `/usr/share/centreon-broker/lua` exists. - -If not, you can create it with this command: `mkdir -p /usr/share/centreon-broker/lua`. Then launch a cleanup with this command: `pcs resource cleanup`. - -#### Disabled resources - -When you do a `crm_mon -fr` and you have a resource that is disabled: - -```text -... - Master/Slave Set: ms_mysql-master [ms_mysql] - Masters: [ @DATABASE_ACTIVE_NAME@ ] - Slaves: [ @DATABASE_PASSIVE_NAME@ ] - Stopped: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] -ms_mysql (ocf::heartbeat:IPaddr2): Stopped (disabled) -... -``` - -You must enable the resource with the following command: - -```bash -pcs resource enable @RESSOURCE_NAME@ -``` - -In the case of the above example: - -```bash -pcs resource enable ms_mysql -``` - -## Step 4: Modifying the Centreon configuration files - -We have [defined a VIP for the databases](#define-the-database-vip) earlier: the data will be sent from the active central node to the current active database via the database VIP. This means that we must give the central nodes the address of the VIP so that they can send the data to it. It is necessary to modify the output of Centreon Broker and three configuration files on the central servers so that they point to the database VIP. - -### Modifying central-broker-master outputs - -1. Go to **Configuration > Pollers > Broker Configuration**. -2. Click **central-broker-master**. -3. On the **Output** tab, edit the **Unified SQL** output and replace "@DATABASE_ACTIVE_IPADDR@" with @VIP_SQL_IPADDR@: - -| Broker Output | Parameter | Value | -| ------------------------------------- | ---------- | ---------------- | -| Unified SQL | DB host | @VIP_SQL_IPADDR@ | - -### Deploying the configuration - -Once the actions in the previous paragraph have been completed, the configuration of the **active central node** must be deployed for them to take effect (check the first three boxes under **Actions**). - -Then copy the broker configuration files to the **passive central node**: - -```bash -rsync -a /etc/centreon-broker/*json @CENTRAL_PASSIVE_IPADDR@:/etc/centreon-broker/ -``` - -### Modification of the three configuration files - -After modifying the output of the broker, we must modify the Centreon configuration files. **You need to do this on both central nodes.** -To do this, first, edit the `/etc/centreon/conf.pm` file and replace @DATABASE_ACTIVE_IPADDR@ with the address of the database VIP. Here is the expected result: - -```bash -############################################# -# File Added by Centreon -# -$centreon_config = { - VarLib => "/var/lib/centreon", - CentreonDir => "/usr/share/centreon/", - CacheDir => "/var/cache/centreon/", - "centreon_db" => "centreon", - "centstorage_db" => "centreon_storage", - "db_host" => "@VIP_SQL_IPADDR@:3306", - "db_user" => "@DB_CENTREON_USER@", - "db_passwd" => '@DB_CENTREON_PASSWD@' -}; -# Central or Poller? -$instance_mode = "central"; -# Centreon Centcore Command File -$cmdFile = "/var/lib/centreon/centcore.cmd"; -# Deprecated format of Config file. -$mysql_user = "@DB_CENTREON_USER@"; -$mysql_passwd = '@DB_CENTREON_PASSWD@'; -$mysql_host = "@VIP_SQL_IPADDR@:3306"; -$mysql_database_oreon = "centreon"; -$mysql_database_ods = "centreon_storage"; -1; -``` - -Then perform the same operation in the `/etc/centreon/centreon.conf.php` file. Here is the expected result: - -```bash - -``` - -And finish with the last file: `/etc/centreon/config.d/10-database.yaml`. Here is the expected result: - -```bash -database: - db_configuration: - dsn: "mysql:host=@VIP_SQL_IPADDR@:3306;dbname=centreon" - username: "@DB_CENTREON_USER@" - password: "@DB_CENTREON_PASSWD@" - db_realtime: - dsn: "mysql:host=@VIP_SQL_IPADDR@:3306;dbname=centreon_storage" - username: "@DB_CENTREON_USER@" - password: "@DB_CENTREON_PASSWD@" -``` - -You then need to restart the **gorgone** and **cbd_central_broker** resources for changes to take effect. Use the following command: - -```bash -pcs resource restart centreon -``` - -After resources are restarted, check if all is OK using the `crm_mon -fr` command. The result should look like this: - -```text -Cluster Summary: - * Stack: corosync - * Current DC: @CENTRAL_ACTIVE_NAME@ (version 2.1.4-5.el8_7.2-dc6eb4362e) - partition with quoru -m - * Last updated: Wed Nov 23 10:27:48 2022 - * Last change: Wed Nov 23 10:27:43 2022 by hacluster via crmd on @CENTRAL_ACTIVE_NAME@ - * 4 nodes configured - * 21 resource instances configured - -Node List: - * Online: [ @CENTRAL_ACTIVE_NAME@ @DATABASE_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ @DATABASE_PASSIVE_NAME@ -] - -Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @DATABASE_ACTIVE_NAME@ ] - * Slaves: [ @DATABASE_PASSIVE_NAME@ ] - * Stopped: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] - * vip_mysql (ocf::heartbeat:IPaddr2): Started @DATABASE_ACTIVE_NAME@ - * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] - * Stopped: [ @DATABASE_ACTIVE_NAME@ @DATABASE_PASSIVE_NAME@ ] - * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_ACTIVE_NAME@ @CENTRAL_PASSIVE_NAME@ ] - * Stopped: [ @DATABASE_ACTIVE_NAME@ @DATABASE_PASSIVE_NAME@ ] - * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_ACTIVE_NAME@ - * http (systemd:httpd): Started @CENTRAL_ACTIVE_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_ACTIVE_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_ACTIVE_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_ACTIVE_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_ACTIVE_NAME@ - * centreontrapd (systemd:centreontrapd): Started@CENTRAL_ACTIVE_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_ACTIVE_NAME@ - -Migration Summary: -``` - -If an error is found while your resources are running, use the following command: - -```bash -pcs resource cleanup -``` - -## Step 5: Integrate your pollers - -1. If you haven't already done so, apply the necessary [kernel network tuning](#kernel-network-tuning) to the host machines for your pollers. -2. [Install your pollers](https://docs.centreon.com/docs/installation/installation-of-a-poller/using-packages) and register them using the central VIP as the address of the central server. Then run the wizard to [attach the poller](https://docs.centreon.com/docs/monitoring/monitoring-servers/add-a-poller-to-configuration) to the VIP. -3. [Add your pollers](https://docs.centreon.com/docs/installation/installation-of-centreon-ha/integrating-pollers) to the platform's HA architecture. - -You can now start your monitoring. - -## Step 6: Monitor your cluster - -See [Monitoring Centreon HA](https://docs.centreon.com/docs/administration/centreon-ha/monitoring-guide). diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/integrating-pollers.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/integrating-pollers.md index 17add700242a..6b6ec5981e35 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/integrating-pollers.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/integrating-pollers.md @@ -1,6 +1,6 @@ --- id: integrating-pollers -title: Integrating new pollers in a Centreon-HA cluster +title: Integrating new pollers in a Centreon HA cluster --- ## Obtaining the central nodes' thumbprints diff --git a/versioned_sidebars/version-24.04-sidebars.json b/versioned_sidebars/version-24.04-sidebars.json index f7cae082e0d5..1c94dfdeb0cb 100644 --- a/versioned_sidebars/version-24.04-sidebars.json +++ b/versioned_sidebars/version-24.04-sidebars.json @@ -1486,15 +1486,12 @@ }, { "type": "category", - "label": "Installing Centreon HA", + "label": "Completing your Centreon HA setup", "link": { - "type": "generated-index" + "type": "generated-index", + "description": "Your HA platform has been installed by Centreon Professional Services. What can you do next?" }, "items": [ - { - "type": "doc", - "id": "version-24.04/installation/installation-of-centreon-ha/installation" - }, { "type": "doc", "id": "version-24.04/installation/installation-of-centreon-ha/integrating-pollers" From b65708088c7a30e1376f226262dd8a35703c29ed Mon Sep 17 00:00:00 2001 From: cgenier Date: Thu, 11 Jul 2024 14:31:20 +0200 Subject: [PATCH 26/41] Remove dead link --- .../version-24.04/administration/centreon-ha/operating-guide.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md index df45ec94ea0a..ed6886b973bb 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md @@ -800,5 +800,3 @@ If that does not work, it is probably due to a resource in a failed state. Run t crm_resource --resource [resource] -D -t primitive -C pcs resource cleanup centreon ``` - -To create the resources again, follow the installation procedure [from this point](../../installation/installation-of-centreon-ha/installation.md#creating-the-centreon-resource-group) From b6e3a5ff223baba69a5da7c56e5c27f82be1fb42 Mon Sep 17 00:00:00 2001 From: cgenier Date: Thu, 11 Jul 2024 14:40:40 +0200 Subject: [PATCH 27/41] Delete comment --- .../version-24.04/administration/centreon-ha/operating-guide.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md index ed6886b973bb..5be9e84f83c6 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md @@ -9,8 +9,6 @@ title: Operating guide You access the interface of the active node via the IP address of the central VIP. This means that you always use the same URL to access the interface, whether the interface is that of central node 1 or of central node 2. -> In this page, we will refer to characteristics that are bound to change from one platform to another (such as IP addresses and host names) by the [macros defined here](../../installation/installation-of-centreon-ha/installation.md#convention-for-names-and-ip-addresses).--> - ## How do I know the state of the cluster? ### Using crm_mon and pcs status From 04e51d12720bf55a04558307af2cdc9946d640dc Mon Sep 17 00:00:00 2001 From: cgenier Date: Tue, 16 Jul 2024 09:49:38 +0200 Subject: [PATCH 28/41] Remove old file --- .../centreon-ha/acceptance-guide.md | 712 ------------------ 1 file changed, 712 deletions(-) delete mode 100644 versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md diff --git a/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md deleted file mode 100644 index bff704125c7e..000000000000 --- a/versioned_docs/version-24.04/administration/centreon-ha/acceptance-guide.md +++ /dev/null @@ -1,712 +0,0 @@ ---- -id: acceptance-guide -title: Testing the cluster ---- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -This page provides you with a procedure to validate that your cluster is working properly: you will perform a failover, simulate a network failure, and check that the cluster behaves as expected. - -> Please note that all commands presented in this document should be run as `root` unless otherwise stated. - -On this page, we will use the macros @CENTRAL_NODE1_NAME@ and @CENTRAL_NODE2_NAME@ to represent the hostnames of central nodes 1 and 2. Bear in mind that depending on the situation, either node 1 or node 2 can be the active or the passive node (if node 1 is the active node, node 2 is the passive node, and vice versa). It is the same with the database nodes. - -## Check the state of the cluster - -After completing the installation procedure and before starting any tests, the active central node should be central node 1 and the passive central node should be central node 2. - -To check the general state of the cluster, run the following command: - -```bash -pcs status -``` - -The command should return the following information: - -```text -Cluster name: centreon_cluster -Stack: corosync -Current DC: @CENTRAL_NODE1_NAME@ (version 1.1.23-1.el8_9.1-9acf116022) - partition with quorum -Last updated: Wed May 4 15:36:20 2022 -Last change: Mon May 2 18:20:27 2022 by root via crm_attribute on @CENTRAL_NODE1_NAME@ - - * 4 nodes configured - * 21 resource instances configured - -Node List: - * Online: [ central1 central2 db1 db2 ] - -Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ db1 ] - * Slaves: [ db2 ] - * Stopped: [ central1 central2 ] - * Clone Set: php-clone [php]: - * Started: [ central1 central2 ] - * Stopped: [ db1 db2 ] - * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ central1 central2 ] - * Stopped: [ db1 db2 ] - * vip_mysql (ocf::heartbeat:IPaddr2): Started db1 - * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started central1 - * http (systemd:httpd): Started central1 - * gorgone (systemd:gorgoned): Started central1 - * centreon_central_sync (systemd:centreon-central-sync): Started central1 - * cbd_central_broker (systemd:cbd-sql): Started central1 - * centengine (systemd:centengine): Started central1 - * centreontrapd (systemd:centreontrapd): Started central1 - * snmptrapd (systemd:snmptrapd): Started central1 - -Daemon Status: - corosync: active/enabled - pacemaker: active/enabled - pcsd: active/enabled -``` - -> This command should return no errors. If there are "Failed actions" on any resource, troubleshoot them using the [troubleshooting guide](troubleshooting-guide.md). - -### Check the constraints - -If a failover has occurred at some point, there may be some leftover location constraints. Run the following command to display the current constraints: - -```bash -pcs constraint -``` - -The command should return this: - -```text -Location Constraints: - Resource: cbd_rrd-clone - Disabled on: - Node: @DATABASE_NODE1_NAME@ (score:-INFINITY) - Node: @DATABASE_NODE2_NAME@ (score:-INFINITY) - Resource: centreon - Disabled on: - Node: @DATABASE_NODE1_NAME@ (score:-INFINITY) - Node: @DATABASE_NODE2_NAME@ (score:-INFINITY) - Resource: ms_mysql-clone - Disabled on: - Node: @CENTRAL_NODE1_NAME@ (score:-INFINITY) - Node: @CENTRAL_NODE2_NAME@ (score:-INFINITY) - Resource: php-clone - Disabled on: - Node: @DATABASE_NODE1_NAME@ (score:-INFINITY) - Node: @DATABASE_NODE2_NAME@ (score:-INFINITY) -Ordering Constraints: -Colocation Constraints: - vip_mysql with ms_mysql-clone (score:INFINITY) (rsc-role:Started) (with-rsc-role:Master) - ms_mysql-clone with vip_mysql (score:INFINITY) (rsc-role:Master) (with-rsc-role:Started) -Ticket Constraints: - -``` - -The output shows the constraints you have defined during the installation procedure: the **ms_mysql-clone** resource only runs on the database nodes, the **cbd_rrd-clone**, **centreon** and **php-clone** resources only run on the central nodes. - -To remove unwanted constraints, run the following command: - -```bash -pcs resource clear centreon -``` - -### Check the status of the database synchronization - -To check that the database synchronization is working, run the following command: - -```bash -/usr/share/centreon-ha/bin/mysql-check-status.sh -``` - -The command should return the following information: - -```bash -Connection MASTER Status '@DATABASE_NODE1_NAME@' [OK] -Connection SLAVE Status '@DATABASE_NODE2_NAME@' [OK] -Slave Thread Status [OK] -Position Status [OK] -``` - -> If the synchronization shows `KO`, you must fix it with the help of the [operating guide](operating-guide.md). - -## Test 1: Centreon resource failover - -### Perform a failover - -We're assuming that central node 1 is the active central node and central node 2 is the passive central node ([check the state of the cluster](#check-the-state-of-the-cluster) if you need to). - -When you move the **centreon** resource group from central node 1 to central node 2, central node 2 will become the active node and central node 1 will become the passive node. - -1. Run the following command to perform the failover: - -```bash -pcs resource move centreon -``` - -In another terminal, you can also use the `crm_mon -fr` command to watch the failover as it happens. It will be necessary to use Ctrl+c to exit the command. - -> Warning: The `pcs resource move centreon` command sets an `-INFINITY` constraint on node 1. This means that the resource is no longer allowed to be running on that node. - -2. The resources move to node 2. To check that the resources have indeed moved, run the following command: - -```bash -pcs status -``` - -The expected output is: - -```text -Cluster name: centreon_cluster - -WARNINGS: -Following resources have been moved and their move constraints are still in plac e: 'centreon' -Run 'pcs constraint location' or 'pcs resource clear ' to view or r emove the constraints, respectively - -Cluster Summary: - * Stack: corosync (Pacemaker is running) - * Current DC: central2 (version 2.1.6-9.1.el8_9-6fdc9deea29) - MIXED-VERSION p artition with quorum - * Last updated: Tue Jun 4 05:41:08 2024 on central2 - * Last change: Tue Jun 4 05:36:52 2024 by root via crm_resource on central1 - * 4 nodes configured - * 21 resource instances configured - -Node List: - * Online: [ central1 central2 db1 db2 ] - -Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ db1 ] - * Slaves: [ db2 ] - * Stopped: [ central1 central2 ] - * Clone Set: php-clone [php]: - * Started: [ central1 central2 ] - * Stopped: [ db1 db2 ] - * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ central1 central2 ] - * Stopped: [ db1 db2 ] - * vip_mysql (ocf::heartbeat:IPaddr2): Started db1 - * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started central2 - * http (systemd:httpd): Started central2 - * gorgone (systemd:gorgoned): Started central2 - * centreon_central_sync (systemd:centreon-central-sync): Started central2 - * cbd_central_broker (systemd:cbd-sql): Started central2 - * centengine (systemd:centengine): Started central2 - * centreontrapd (systemd:centreontrapd): Started central2 - * snmptrapd (systemd:snmptrapd): Started central2 - -Daemon Status: - corosync: active/enabled - pacemaker: active/enabled - pcsd: active/enabled -``` - -3. Once the failover is completed, execute the following command to ensure the resources can be moved back to their original node in the future (EL8 or Debian). - -```bash -pcs resource clear centreon -``` - -This will remove the constraints established during the failover. - -### Go back to the nominal situation - -If you want to return to the nominal situation (i.e. central node 1 is the active central node and central node 2 is the passive central node), you must perform a second resource failover. - -1. If you haven't already done so, run the constraint cleanup command to remove the constraint created by the failover (EL8 or Debian): - - ```bash - pcs resource clear centreon - ``` - -2. Then, execute the failover command: - - ```bash - pcs resource move centreon - ``` - -As before, you can follow the failover with the `crm_mon -fr` command. - -3. Finally, remove the constraints with the following command (EL8 or Debian): - - ```bash - pcs resource clear centreon - ``` - -## Test 2: Simulate the loss of the passive central node - -If the passive central node goes down, the cluster should carry on working as before, as the resources are managed by the active central node. You will see your passive central node as down in Resources Status. - -To simulate a network failure that would isolate the passive central node, you can use `iptables` to drop traffic from and to the passive central node. The passive central node will be completely excluded from the cluster. The active central node keeps the majority with the quorum device. - -### Perform the test - -We're assuming that node 1 is the active node and node 2 is the passive node ([check the state of the cluster](#check-the-state-of-the-cluster) if you need to). - -To perform this test, run the `iptables` commands on the **active central node**: - -```bash -iptables -A INPUT -s @CENTRAL_NODE1_IPADDR@ -j DROP -iptables -A OUTPUT -d @CENTRAL_NODE1_IPADDR@ -j DROP -iptables -A INPUT -s @DATABASE_NODE1_IPADDR@ -j DROP -iptables -A OUTPUT -d @DATABASE_NODE1_IPADDR@ -j DROP -iptables -A INPUT -s @DATABASE_NODE2_IPADDR@ -j DROP -iptables -A OUTPUT -d @DATABASE_NODE2_IPADDR@ -j DROP -iptables -A INPUT -s @QDEVICE_IPADDR@ -j DROP -iptables -A OUTPUT -d @QDEVICE_IPADDR@ -j DROP -``` - -The passive central node is now excluded from the cluster. - -If you run `pcs status` on the active central node: - -* The resources and the cluster are still working. -* The passive central node is seen `offline` on the active node: - -```text -Cluster name: centreon_cluster -Stack: corosync -Current DC: @CENTRAL_MASTER_NAME@ (version 1.1.23-1.el8_9.1-9acf116022) - partition with quorum -Last updated: Thu May 5 10:34:05 2022 -Last change: Thu May 5 09:09:50 2022 by root via crm_resource on @CENTRAL_MASTER_NAME@ - -4 nodes configured -21 resource instances configured - -Online: [ @DATABASE_MASTER_NAME@ @CENTRAL_MASTER_NAME@ @DATABASE_SLAVE_NAME@ ] -OFFLINE: [ @CENTRAL_SLAVE_NAME@ ] - -Full list of resources: - - Master/Slave Set: ms_mysql-clone [ms_mysql] - Masters: [ @DATABASE_MASTER_NAME@ ] - Slaves: [ @DATABASE_SLAVE_NAME@ ] - Stopped: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] - vip_mysql (ocf::heartbeat:IPaddr2): Started @DATABASE_MASTER_NAME@ - Clone Set: php-clone [php] - Started: [ @CENTRAL_MASTER_NAME@ ] - Stopped: [ @DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@ @CENTRAL_SLAVE_NAME@ ] - Clone Set: cbd_rrd-clone [cbd_rrd] - Started: [ @CENTRAL_MASTER_NAME@ ] - Stopped: [ @DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@ @CENTRAL_SLAVE_NAME@ ] - Resource Group: centreon - vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_MASTER_NAME@ - http (systemd:httpd24-httpd): Started @CENTRAL_MASTER_NAME@ - gorgone (systemd:gorgoned): Started @CENTRAL_MASTER_NAME@ - centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_MASTER_NAME@ - cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_MASTER_NAME@ - centengine (systemd:centengine): Started @CENTRAL_MASTER_NAME@ - centreontrapd (systemd:centreontrapd): Started @CENTRAL_MASTER_NAME@ - snmptrapd (systemd:snmptrapd): Started @CENTRAL_MASTER_NAME@ - -Daemon Status: - corosync: active/enabled - pacemaker: active/enabled - pcsd: active/enabled -``` - -If you run `pcs status` on the passive node: - -* All resources appear stopped on the passive node -* The active node is seen as `offline` (as the passive node is cut off from the rest of the cluster): - -```text -Cluster name: centreon_cluster -Cluster Summary: - * Stack: corosync - * Current DC: @CENTRAL_NODE2_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition WITHOUT quorum - * Last updated: Tue Nov 8 14:33:00 2022 - * Last change: Tue Nov 8 14:25:58 2022 by root via crm_resource on @CENTRAL_NODE1_NAME@ - * 2 nodes configured - * 12 resource instances configured -Node List: - * Online: [ @CENTRAL_NODE2_NAME@ ] - * OFFLINE: [ @CENTRAL_NODE1_NAME@ ] -Full List of Resources: - * Clone Set: php-clone [php]: - * Stopped: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] - * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Stopped: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] - * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Stopped - * http (systemd:httpd): Stopped - * gorgone (systemd:gorgoned): Stopped - * centreon_central_sync (systemd:centreon-central-sync): Stopped - * cbd_central_broker (systemd:cbd-sql): Stopped - * centengine (systemd:centengine): Stopped - * centreontrapd (systemd:centreontrapd): Stopped - * snmptrapd (systemd:snmptrapd): Stopped -Daemon Status: - corosync: active/enabled - pacemaker: active/enabled - pcsd: active/enabled -``` - -### Go back to the nominal situation - -If you want to go back to the nominal situation, remove the iptables rules. - -To view the various iptables rules configured on the active node, run the following command: - -```bash -iptables -L -``` - -The command should return the following information: - -```text -Chain INPUT (policy ACCEPT) -target prot opt source destination -DROP all -- @CENTRAL_NODE2_NAME@ anywhere - -Chain FORWARD (policy ACCEPT) -target prot opt source destination - -Chain OUTPUT (policy ACCEPT) -target prot opt source destination -DROP all -- anywhere @CENTRAL_NODE2_NAME@ -``` - -If you do not have any other iptables rules configured, you can execute the following command to remove the rules related to the test: - -```bash -iptables -F -``` - -Otherwise, you will have to list the rule numbers with the following command: - -```bash -iptables -L --line-numbers -``` - -And delete them with the following command: - -```bash -iptables -D INPUT @RULE_NUMBER@ -iptables -D OUTPUT @RULE_NUMBER@ -``` - -If you run `pcs status` on the active node, the passive node is seen as `online` again: - -```text -Cluster Summary: - * Stack: corosync - * Current DC: @CENTRAL_NODE1_NAME@ (version 2.0.5-9.0.1.el8_4.1-ba59be7122) - partition with quorum - * Last updated: Wed Sep 15 16:35:47 2021 - * Last change: Wed Sep 15 10:41:50 2021 by root via crm_attribute on @CENTRAL_NODE1_NAME@ - * 2 nodes configured - * 12 resource instances configured -Node List: - * Online: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] -Full List of Resources: - * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] - * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] - * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE1_NAME@ - * http (systemd:httpd): Started @CENTRAL_NODE1_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_NODE1_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE1_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE1_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_NODE1_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE1_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE1_NAME@ -``` - -Also check that the database replication is still operational using the following command: - -```bash -/usr/share/centreon-ha/bin/mysql-check-status.sh -``` - -The expected output is: - -```text -Connection MASTER Status '@DATABASE_NODE1_NAME@' [OK] -Connection SLAVE Status '@DATABASE_NODE2_NAME@' [OK] -Slave Thread Status [OK] -Position Status [OK] -``` - -## Test 3: Simulate the loss of the active node - -This test checks that the resources are switched to the passive node if the active node is unavailable, allowing for continuity of service. - -### Perform the test - -We're assuming that central node 1 is the active central node and central node 2 is the passive central node ([check the state of the cluster](#check-the-state-of-the-cluster) if you need to). - -To perform this test, run the commands on the active central node: - -```bash -iptables -A INPUT -s @CENTRAL_NODE2_IPADDR@ -j DROP -iptables -A OUTPUT -d @CENTRAL_NODE2_IPADDR@ -j DROP -iptables -A INPUT -s @DATABASE_NODE1_IPADDR@ -j DROP -iptables -A OUTPUT -d @DATABASE_NODE1_IPADDR@ -j DROP -iptables -A INPUT -s @DATABASE_NODE2_IPADDR@ -j DROP -iptables -A OUTPUT -d @DATABASE_NODE2_IPADDR@ -j DROP -iptables -A INPUT -s @QDEVICE_IPADDR@ -j DROP -iptables -A OUTPUT -d @QDEVICE_IPADDR@ -j DROP -``` - -Resources on the active central node (central node 1) should stop. Central node 2 becomes the active node and all the resources switch to it. You can use the `crm_mon -fr` command on central node 2 to watch the startup of resources: - -```text -Stack: corosync -Current DC: @CENTRAL_NODE1_NAME@ (version 1.1.23-1.el8_9.1-9acf116022) - partition with quorum -Last updated: Thu May 5 11:06:38 2022 -Last change: Thu May 5 09:09:50 2022 by root via crm_resource on @CENTRAL_NODE1_NAME@ - -4 nodes configured -21 resource instances configured - -Online: [ @DATABASE_NODE1_NAME@ @DATABASE_NODE2_NAME@ @CENTRAL_NODE2_NAME@ ] -OFFLINE: [ @CENTRAL_NODE1_NAME@ ] - -Full list of resources: - - Master/Slave Set: ms_mysql-clone [ms_mysql] - Masters: [ @DATABASE_NODE1_NAME@ ] - Slaves: [ @DATABASE_NODE2_NAME@ ] - Stopped: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] -vip_mysql (ocf::heartbeat:IPaddr2): Started @DATABASE_NODE1_NAME@ - Clone Set: php-clone [php] - Started: [ @CENTRAL_NODE2_NAME@ ] - Stopped: [ @DATABASE_NODE1_NAME@ @CENTRAL_NODE1_NAME@ @DATABASE_NODE2_NAME@ ] - Clone Set: cbd_rrd-clone [cbd_rrd] - Started: [ @CENTRAL_NODE2_NAME@ ] - Stopped: [ @DATABASE_NODE1_NAME@ @CENTRAL_NODE1_NAME@ @DATABASE_NODE2_NAME@ ] - Resource Group: centreon - vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE2_NAME@ - http (systemd:httpd24-httpd): Started @CENTRAL_NODE2_NAME@ - gorgone (systemd:gorgoned): Started @CENTRAL_NODE2_NAME@ - centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE2_NAME@ - cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE2_NAME@ - centengine (systemd:centengine): Started @CENTRAL_NODE2_NAME@ - centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE2_NAME@ - snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE2_NAME@ - -Migration Summary: -* Node @DATABASE_NODE1_NAME@: -* Node @CENTRAL_NODE2_NAME@: -* Node @DATABASE_NODE2_NAME@: -``` - -### Go back to the nominal situation - -To check the various iptables rules configured on the active node, run the following command: - -```bash -iptables -L -``` - -The command should return the following information: - -```text -Chain INPUT (policy ACCEPT) -target prot opt source destination -DROP all -- @CENTRAL_NODE2_NAME@ anywhere -DROP all -- @DATABASE_NODE1_NAME@ anywhere -DROP all -- @DATABASE_NODE2_NAME@ anywhere -DROP all -- @QDEVICE_NAME@ anywhere - -Chain FORWARD (policy ACCEPT) -target prot opt source destination - -Chain OUTPUT (policy ACCEPT) -target prot opt source destination -DROP all -- anywhere @CENTRAL_NODE2_NAME@ -DROP all -- anywhere @DATABASE_NODE1_NAME@ -DROP all -- anywhere @DATABASE_NODE2_NAME@ -DROP all -- anywhere @QDEVICE_NAME@ -``` - -If you do not have any other iptables rules configured, you can execute the following command to remove the rules related to the test: - -```bash -iptables -F -``` - -Otherwise, it will be necessary to list the rule numbers with the specific command: - -```bash -iptables -L --line-numbers -``` - -And delete them with the following command: - -```bash -iptables -D INPUT @RULE_NUMBER@; -iptables -D OUTPUT @RULE_NUMBER@ -``` - -If you run the `crm_mon` command on node 2, you can see that node 1 is still the passive node: - -```text -Cluster Summary: - * Stack: corosync - * Current DC: @CENTRAL_NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum - * Last updated: Tue Nov 8 17:27:28 2022 - * Last change: Tue Nov 8 17:23:19 2022 by root via crm_attribute on @CENTRAL_NODE2_NAME@ - * 2 nodes configured - * 12 resource instances configured -Node List: - * Online: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] -Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * ms_mysql (ocf::heartbeat:mariadb-centreon): Stopped @CENTRAL_NODE1_NAME@ (Monitoring) - * Masters: [ @CENTRAL_NODE2_NAME@ ] - * Stopped: [ @CENTRAL_NODE1_NAME@ ] - * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] - * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] - * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE2_NAME@ - * http (systemd:httpd): Started @CENTRAL_NODE2_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_NODE2_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE2_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE2_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_NODE2_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE2_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE2_NAME@ -Migration Summary: - * Node: @CENTRAL_NODE1_NAME@: - * ms_mysql: migration-threshold=1000000 fail-count=1000000 last-failure='Tue Nov 8 17:27:25 2 -022' -Failed Resource Actions: - * ms_mysql_start_0 on @CENTRAL_NODE1_NAME@ 'error' (1): call=440, status='complete', exitreason='M -ariaDB slave io has failed (1236): Got fatal error 1236 from master when reading data from binary -log: 'Error: connecting slave', last-rc-change='Tue Nov 8 17:27:21 2022', queued=0ms, exec=4060ms -``` - -If you want to switch to the active node, you must do a failover. -So, **before you do this, you must check the cluster and database replication status**. - -First, check the constraints: - -```shell -pcs constraint -``` - -The command should return this: - -```text -Location Constraints: -Ordering Constraints: -Colocation Constraints: - centreon with ms_mysql-clone (score:INFINITY) (rsc-role:Started) (with-rsc-role:Master) - ms_mysql-clone with centreon (score:INFINITY) (rsc-role:Master) (with-rsc-role:Started) -Ticket Constraints: -``` - -then check the database replication - -```bash -/usr/share/centreon-ha/bin/mysql-check-status.sh -``` - -At this time, the cluster is in degraded mode with two passive nodes. -In this particular case, it returns the following information because the ms_mysql resource is stopped on node 1: - -```text -Connection SLAVE Status '@CENTRAL_NODE1_NAME@' [KO] -Error reports: - ERROR 2002 (HY000): Can't connect to MySQL server on '@CENTRAL_NODE1_NAME@' (115) -Impossible de se connecter au serveur '@CENTRAL_NODE1_NAME@'. -Connection SLAVE Status '@CENTRAL_NODE2_NAME@' [OK] -Slave Thread Status [KO] -Error reports: - Skip check on '@CENTRAL_NODE1_NAME@'. - No slave (maybe because we cannot check a server). -Position Status [SKIP] -Error reports: - Skip because we can't identify a unique slave. -``` - -You must do a database synchronization from @CENTRAL_NODE2_NAME@ to @CENTRAL_NODE1_NAME@ by launching the "sync-bigdb" script on the **Slave node**. - -```shell -/usr/share/centreon-ha/bin/mysql-sync-bigdb.sh -``` - -As for the previous execution of this script, check whether the LVM Snapshot is correctly deleted and the MySQL Slave restarted: - -```text -Umount and Delete LVM snapshot - Logical volume "dbbackupdatadir" successfully removed. -Start MySQL Slave -OK -Start Replication -Id User Host db Command Time State Info Progress -5 centreon-repl @CENTRAL_NODE2_NAME@:51850 NULL Query 0 starting show processlist 0.000 -6 centreon localhost centreon_storage Sleep 0 NULL 0.000 -7 system user NULL Connect 0 Connecting to master NULL 0.000 -8 system user NULL Slave_SQL 0 Slave has read all relay log; waiting for more updates NULL 0.000 -``` - -Database replication should now be OK. Check this. - -```shell -/usr/share/centreon-ha/bin/mysql-check-status.sh -``` - -The result should be: - -```text -Connection MASTER Status '@CENTRAL_NODE2_NAME@' [OK] -Connection SLAVE Status '@CENTRAL_NODE1_NAME@' [OK] -Slave Thread Status [OK] -Position Status [OK] -``` - -Now, you can perform a failover to return to the initial situation. - -```shell -pcs resource clear centreon -``` - -Do a cleanup to clear errors and restart the ms_mysql resource on @CENTRAL_NODE1_NAME@. - -```shell -pcs resource cleanup -``` - -The situation has stabilized, and you can perform a failover by moving the **centreon** resource. - -```shell -pcs resource move centreon -``` - -The **centreon** resource is now relocated and the cluster is OK. Check this with `crm_mon -fr` on any node. - -```text -Cluster Summary: - * Stack: corosync - * Current DC: @CENTRAL_NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum - * Last updated: Wed Nov 9 10:23:54 2022 - * Last change: Wed Nov 9 10:23:26 2022 by root via crm_attribute on @CENTRAL_NODE1_NAME@ - * 2 nodes configured - * 12 resource instances configured -Node List: - * Online: [ @CENTRAL_NODE1_NAME@ centreon-rhel8-sec ] -Full List of Resources: - * Clone Set: ms_mysql-clone [ms_mysql] (promotable): - * Masters: [ @CENTRAL_NODE1_NAME@ ] - * Slaves: [ centreon-rhel8-sec ] - * Clone Set: php-clone [php]: - * Started: [ @CENTRAL_NODE1_NAME@ centreon-rhel8-sec ] - * Clone Set: cbd_rrd-clone [cbd_rrd]: - * Started: [ @CENTRAL_NODE1_NAME@ centreon-rhel8-sec ] - * Resource Group: centreon: - * vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE1_NAME@ - * http (systemd:httpd): Started @CENTRAL_NODE1_NAME@ - * gorgone (systemd:gorgoned): Started @CENTRAL_NODE1_NAME@ - * centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE1_NAME@ - * cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE1_NAME@ - * centengine (systemd:centengine): Started @CENTRAL_NODE1_NAME@ - * centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE1_NAME@ - * snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE1_NAME@ -Migration Summary: -``` From 59ed2f72962a0a7670630b925ed5a146b1748c36 Mon Sep 17 00:00:00 2001 From: cgenier Date: Tue, 16 Jul 2024 11:10:19 +0200 Subject: [PATCH 29/41] Changes following review --- .../centreon-ha/operating-guide.md | 76 +++++-------------- .../cluster-elements.md | 2 +- .../installation-of-centreon-ha/overview.md | 2 +- .../version-24.04/resources/glossary.md | 4 + .../update/update-centreon-ha.md | 2 +- 5 files changed, 26 insertions(+), 60 deletions(-) diff --git a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md index 5be9e84f83c6..97b75ee2b27e 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md @@ -69,6 +69,20 @@ The Resource Status page gives you the following information: * On both central nodes, the **PCS-Status** service gives you the detailed state of the cluster. The output of the service in the details panel is the output of the `pcs status` command. * You can know which central node is the active node by looking at which node is carrying the cluster resources in the output of the **PCS-Status** service on each central. +## Remove an error displayed in the cluster status + +Once the cause of the error has been identified and fixed (see the [troubleshooting guide](troubleshooting-guide.md)), you must delete the error message manually: + +```bash +pcs resource cleanup +``` + +Or, if you want to remove only the errors linked to one resource: + +```bash +pcs resource cleanup +``` + ## Check the constraints If a failover has occurred at some point, there may be some leftover location constraints. Run the following command to display the current constraints: @@ -123,14 +137,14 @@ To check that the database synchronization is working, run the following command The command should return the following information: -```bash +```text Connection MASTER Status '@DATABASE_NODE1_NAME@' [OK] Connection SLAVE Status '@DATABASE_NODE2_NAME@' [OK] Slave Thread Status [OK] Position Status [OK] ``` -> If the synchronization shows `KO`, you must fix it with the help of the [operating guide](operating-guide.md). + ## View the cluster's configuration @@ -158,7 +172,7 @@ pcs resource move centreon In another terminal, you can also use the `crm_mon -fr` command to watch the failover as it happens. It will be necessary to use Ctrl+c to exit the command. -> Warning: The `pcs resource move centreon` command sets an `-INFINITY` constraint on node 1. This means that the resource is no longer allowed to be running on that node. +> Warning: The `pcs resource move centreon` command sets an `-INFINITY` constraint on node 1. This means that the resource is no longer allowed to be running on that node. (You will clear this constraint at step 3.) 2. The resources move to node 2. To check that the resources have indeed moved, run the following command: @@ -224,7 +238,7 @@ This will remove the constraints established during the failover. > If you move a single resource from the centreon resource group from one node to the other, all the other resources in the group will switch too. -If you want to return to the nominal situation (i.e. central node 1 is the active central node and central node 2 is the passive central node), you must perform a second resource failover. +If you want to return to the nominal situation (i.e. central node 1 is the active central node and central node 2 is the passive central node), you must perform a second resource failover (and clear the constraints afterwards). ### How to simulate the loss of the passive central node @@ -704,23 +718,9 @@ Full List of Resources: Migration Summary: ``` -## Remove an error displayed in the cluster status - -Once the cause of the error has been identified and fixed (see the [troubleshooting guide](troubleshooting-guide.md)), you must manually delete the error message: - -```bash -pcs resource cleanup -``` - -Or, if you want to remove only the errors linked to one resource: - -```bash -pcs resource cleanup -``` - ## View cluster logs -The cluster logs are located in `/var/log/cluster/corosync.log`: +The cluster logs are located in `/var/log/cluster/corosync.log`. To display them, use the following command: ```bash tail -f /var/log/cluster/corosync.log @@ -737,44 +737,6 @@ To change the verbosity level of the cluster logs, edit the following files: ## Advanced commands -### Save & import the configuration of the cluster - -#### Export/import in XML format - -To save the cluster configuration in XML format, run this command: - -```bash -cibadmin --query > /tmp/cluster_configuration.xml -``` - -> The following commands perform important modifications to the cluster's configuration and might break it. Use them wisely. - -After modifying the XML configuration file, reimport it: - -```bash -cibadmin --replace --xml-file /tmp/cluster_configuration.xml -``` - -To completely reset your cluster's configuration, run this command: - -```bash -cibadmin --force --erase -``` - -#### Export/import in binary format - -The cluster's configuration can be backed up to a binary file: - -```bash -pcs config backup export -``` - -This backup can then be re-imported: - -```bash -pcs config restore export.tar.bz2 -``` - ### Delete a Pacemaker resource group > **Warning:** These commands will destroy your Centreon cluster. Do this only if you know what you are doing. diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md index 6bcc5ee444bb..c9bacffef155 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md @@ -30,7 +30,7 @@ Centreon HA consists of a set of clustering tools on top of twin Centreon centra * Pollers, which do the actual monitoring. -* A "central VIP" to which the pollers send the collected data, so that the VIP can forward the data to the current active central node. +* A "central [VIP](../../resources/glossary.md#vip)" to which the pollers send the collected data, so that the VIP can forward the data to the current active central node. * A "database VIP" to which the active central node sends the data, so that the VIP can forward the data to the current active database node. diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md index e30487284a38..75d0ef4343c4 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md @@ -13,7 +13,7 @@ In the central cluster, all Centreon processes ("resources") are managed by the 2. An incident occurs and central node 1 (the active node) goes down. - Corosync detects that it is down: after consulting with the quorum device, it tells central node 2 to become the active node. - An operator is notified that central node 1 is down, thanks to the Centreon monitoring that has been set up on the poller. -3. Central node 2 is now the active node. It receives data from the pollers. During this time, the operator tries to understand why central node 1 is down. They must fix the problem using the cluster management tool **pcs**, not by manipulating central node 1 directly. +3. Central node 2 is now the active node. It receives data from the pollers. During this time, the operator tries to understand why central node 1 is down. They must fix the problem, then restat the processes using the cluster management tool **pcs**, not by manipulating central node 1 directly. 4. Central node 1 is fixed and comes back online. The **centreon_central_sync** script synchronizes all relevant files from central node 2 to central node 1, so that central node 1 can catch up on what has happened during its down time. Central node 1 is ready to become the active node if central node 2 goes down. The process is the same for the database cluster. diff --git a/versioned_docs/version-24.04/resources/glossary.md b/versioned_docs/version-24.04/resources/glossary.md index ae8f60102bcb..526efcee286b 100644 --- a/versioned_docs/version-24.04/resources/glossary.md +++ b/versioned_docs/version-24.04/resources/glossary.md @@ -279,6 +279,10 @@ Time periods define a time interval for each day of the week. They enable the fe **See also**: [Time periods](../monitoring/basic-objects/timeperiods.md). +## VIP + +A virtual IP address (VIP) is used in an HA cluster. A VIP is not linked to a physical interface, but can send data to several interfaces. In a cluster, if data is sent to a VIP, the VIP forwards it to whichever node is the current active node. + ## Widget Configurable visual element that allows you to display data in a custom view. diff --git a/versioned_docs/version-24.04/update/update-centreon-ha.md b/versioned_docs/version-24.04/update/update-centreon-ha.md index 16ece042a39a..fe2c44547692 100644 --- a/versioned_docs/version-24.04/update/update-centreon-ha.md +++ b/versioned_docs/version-24.04/update/update-centreon-ha.md @@ -9,7 +9,7 @@ This procedure is intended to be used to perform minor updates of Centreon when ## Suspend cluster resource management -In order to avoid a failover of the cluster during the update, it is necessary to unmanage all Centreon resources, as well as MariaDB. +In order to avoid a failover of the cluster during the update, it is necessary to unmanage all Centreon resources, as well as the database. ```bash pcs property set maintenance-mode=true From 347f97c52ceb7c03e018789c628b08b1517c9043 Mon Sep 17 00:00:00 2001 From: cgenier Date: Tue, 16 Jul 2024 13:37:36 +0200 Subject: [PATCH 30/41] Update --- .../centreon-ha/operating-guide.md | 48 +++++++++---------- .../installation-of-centreon-ha/overview.md | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md index 97b75ee2b27e..c647212b3b14 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md @@ -250,7 +250,7 @@ To simulate a network failure that would isolate the passive central node, you c We're assuming that node 1 is the active node and node 2 is the passive node ([check the state of the cluster](#how-do-i-know-the-state-of-the-cluster) if you need to). -To perform this test, run the `iptables` commands on the **active central node**: +To perform this test, run the `iptables` commands on the **passive central node**. Thanks to these rules, all traffic coming from the active central node and the quorum device will be ignored by the passive central node: ```bash iptables -A INPUT -s @CENTRAL_NODE1_IPADDR@ -j DROP @@ -267,44 +267,44 @@ The passive central node is now excluded from the cluster. If you run `pcs status` on the active central node: -* The resources and the cluster are still working. +* The resources and the cluster are still working (the output shows that the noe still sees the quorum device). * The passive central node is seen `offline` on the active node: ```text Cluster name: centreon_cluster Stack: corosync -Current DC: @CENTRAL_MASTER_NAME@ (version 1.1.23-1.el8_9.1-9acf116022) - partition with quorum +Current DC: @CENTRAL_NODE1_NAME@ (version 1.1.23-1.el8_9.1-9acf116022) - partition with quorum Last updated: Thu May 5 10:34:05 2022 -Last change: Thu May 5 09:09:50 2022 by root via crm_resource on @CENTRAL_MASTER_NAME@ +Last change: Thu May 5 09:09:50 2022 by root via crm_resource on @CENTRAL_NODE1_NAME@ 4 nodes configured 21 resource instances configured -Online: [ @DATABASE_MASTER_NAME@ @CENTRAL_MASTER_NAME@ @DATABASE_SLAVE_NAME@ ] -OFFLINE: [ @CENTRAL_SLAVE_NAME@ ] +Online: [ @DATABASE_NODE1_NAME@ @CENTRAL_NODE1_NAME@ @DATABASE_NODE2_NAME@ ] +OFFLINE: [ @CENTRAL_NODE2_NAME@ ] Full list of resources: Master/Slave Set: ms_mysql-clone [ms_mysql] - Masters: [ @DATABASE_MASTER_NAME@ ] - Slaves: [ @DATABASE_SLAVE_NAME@ ] - Stopped: [ @CENTRAL_MASTER_NAME@ @CENTRAL_SLAVE_NAME@ ] - vip_mysql (ocf::heartbeat:IPaddr2): Started @DATABASE_MASTER_NAME@ + Masters: [ @DATABASE_NODE1_NAME@ ] + Slaves: [ @DATABASE_NODE2_NAME@ ] + Stopped: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] + vip_mysql (ocf::heartbeat:IPaddr2): Started @DATABASE_NODE1_NAME@ Clone Set: php-clone [php] - Started: [ @CENTRAL_MASTER_NAME@ ] - Stopped: [ @DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@ @CENTRAL_SLAVE_NAME@ ] + Started: [ @CENTRAL_NODE1_NAME@ ] + Stopped: [ @DATABASE_NODE1_NAME@ @DATABASE_NODE2_NAME@ @CENTRAL_NODE2_NAME@ ] Clone Set: cbd_rrd-clone [cbd_rrd] - Started: [ @CENTRAL_MASTER_NAME@ ] - Stopped: [ @DATABASE_MASTER_NAME@ @DATABASE_SLAVE_NAME@ @CENTRAL_SLAVE_NAME@ ] + Started: [ @CENTRAL_NODE1_NAME@ ] + Stopped: [ @DATABASE_NODE1_NAME@ @DATABASE_NODE2_NAME@ @CENTRAL_NODE2_NAME@ ] Resource Group: centreon - vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_MASTER_NAME@ - http (systemd:httpd24-httpd): Started @CENTRAL_MASTER_NAME@ - gorgone (systemd:gorgoned): Started @CENTRAL_MASTER_NAME@ - centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_MASTER_NAME@ - cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_MASTER_NAME@ - centengine (systemd:centengine): Started @CENTRAL_MASTER_NAME@ - centreontrapd (systemd:centreontrapd): Started @CENTRAL_MASTER_NAME@ - snmptrapd (systemd:snmptrapd): Started @CENTRAL_MASTER_NAME@ + vip (ocf::heartbeat:IPaddr2): Started @CENTRAL_NODE1_NAME@ + http (systemd:httpd24-httpd): Started @CENTRAL_NODE1_NAME@ + gorgone (systemd:gorgoned): Started @CENTRAL_NODE1_NAME@ + centreon_central_sync (systemd:centreon-central-sync): Started @CENTRAL_NODE1_NAME@ + cbd_central_broker (systemd:cbd-sql): Started @CENTRAL_NODE1_NAME@ + centengine (systemd:centengine): Started @CENTRAL_NODE1_NAME@ + centreontrapd (systemd:centreontrapd): Started @CENTRAL_NODE1_NAME@ + snmptrapd (systemd:snmptrapd): Started @CENTRAL_NODE1_NAME@ Daemon Status: corosync: active/enabled @@ -314,7 +314,7 @@ Daemon Status: If you run `pcs status` on the passive node: -* All resources appear stopped on the passive node +* All resources appear stopped on the passive node (this is because the passive node does not see the quorum device anymore, as "partition WITHOUT quorum" indicates below. The resources are stopped.) * The active node is seen as `offline` (as the passive node is cut off from the rest of the cluster): ```text @@ -444,7 +444,7 @@ This test checks that the resources are switched to the passive node if the acti We're assuming that central node 1 is the active central node and central node 2 is the passive central node ([check the state of the cluster](#how-do-i-know-the-state-of-the-cluster) if you need to). -To perform this test, run the commands on the active central node: +To perform this test, run the commands on the **active central node**: ```bash iptables -A INPUT -s @CENTRAL_NODE2_IPADDR@ -j DROP diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md index 75d0ef4343c4..2b7c080e2855 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md @@ -31,4 +31,4 @@ You need to take action and fix the problem so that the central node that failed * Central node 1 is still the passive node: the cluster does **not** switch back automatically. * If you are using EL8 or Debian, you need to clear manually the constraint created by the failover (using `pcs resource clear centreon`). -* In a production context, you do not **have** to go back to central node 1 being the active node - but you can do it if you want to (e.g. if central node 2 has limited performance), by [performing a failover](../../administration/centreon-ha/acceptance-guide.md#perform-a-failover) on central node 2. +* In a production context, you do not **have** to go back to central node 1 being the active node - but you can do it if you want to (e.g. if central node 2 has limited performance), by [performing a failover](../../administration/centreon-ha/operating-guide.md#how-to-perform-a-manual-failover) on central node 2. From 8d0de8e7336f592ac81adc28f4d213ae038ec940 Mon Sep 17 00:00:00 2001 From: cgenier Date: Tue, 16 Jul 2024 15:48:49 +0200 Subject: [PATCH 31/41] Update --- .../centreon-ha/operating-guide.md | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md index c647212b3b14..e4a56d9219a3 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md @@ -250,7 +250,7 @@ To simulate a network failure that would isolate the passive central node, you c We're assuming that node 1 is the active node and node 2 is the passive node ([check the state of the cluster](#how-do-i-know-the-state-of-the-cluster) if you need to). -To perform this test, run the `iptables` commands on the **passive central node**. Thanks to these rules, all traffic coming from the active central node and the quorum device will be ignored by the passive central node: +To perform this test, run the `iptables` commands on the **passive central node**. Thanks to these rules, all traffic coming from the active central node, the databases and the quorum device will be ignored by the passive central node: ```bash iptables -A INPUT -s @CENTRAL_NODE1_IPADDR@ -j DROP @@ -436,7 +436,7 @@ Slave Thread Status [OK] Position Status [OK] ``` -### How to simulate the loss of the active node +### How to simulate the loss of the active central node This test checks that the resources are switched to the passive node if the active node is unavailable, allowing for continuity of service. @@ -444,7 +444,7 @@ This test checks that the resources are switched to the passive node if the acti We're assuming that central node 1 is the active central node and central node 2 is the passive central node ([check the state of the cluster](#how-do-i-know-the-state-of-the-cluster) if you need to). -To perform this test, run the commands on the **active central node**: +To perform this test, run the following commands on the **active central node**. Thanks to these rules, all traffic coming from the passive central node, the databases and the quorum device will be ignored by the active central node: ```bash iptables -A INPUT -s @CENTRAL_NODE2_IPADDR@ -j DROP @@ -548,7 +548,7 @@ iptables -D INPUT @RULE_NUMBER@; iptables -D OUTPUT @RULE_NUMBER@ ``` -If you run the `crm_mon` command on node 2, you can see that node 1 is still the passive node: +If you run the `crm_mon` command on central node 2, you can see that central node 1 is still the passive node: ```text Cluster Summary: @@ -556,8 +556,8 @@ Cluster Summary: * Current DC: @CENTRAL_NODE1_NAME@ (version 2.1.2-4.el8_6.3-ada5c3b36e2) - partition with quorum * Last updated: Tue Nov 8 17:27:28 2022 * Last change: Tue Nov 8 17:23:19 2022 by root via crm_attribute on @CENTRAL_NODE2_NAME@ - * 2 nodes configured - * 12 resource instances configured + * 4 nodes configured + * 21 resource instances configured Node List: * Online: [ @CENTRAL_NODE1_NAME@ @CENTRAL_NODE2_NAME@ ] Full List of Resources: @@ -588,7 +588,7 @@ ariaDB slave io has failed (1236): Got fatal error 1236 from master when reading log: 'Error: connecting slave', last-rc-change='Tue Nov 8 17:27:21 2022', queued=0ms, exec=4060ms ``` -If you want to switch to the active node, you must do a failover. +If you want central node 1 to be the active node again, you must do a failover. So, **before you do this, you must check the cluster and database replication status**. First, check the constraints: @@ -601,11 +601,29 @@ The command should return this: ```text Location Constraints: + Resource: cbd_rrd-clone + Disabled on: + Node: db1 (score:-INFINITY) + Node: db2 (score:-INFINITY) + Resource: centreon + Disabled on: + Node: db1 (score:-INFINITY) + Node: db2 (score:-INFINITY) + Node: central2 (score:-INFINITY) (role:Started) + Resource: ms_mysql-clone + Disabled on: + Node: central1 (score:-INFINITY) + Node: central2 (score:-INFINITY) + Resource: php-clone + Disabled on: + Node: db1 (score:-INFINITY) + Node: db2 (score:-INFINITY) Ordering Constraints: Colocation Constraints: - centreon with ms_mysql-clone (score:INFINITY) (rsc-role:Started) (with-rsc-role:Master) - ms_mysql-clone with centreon (score:INFINITY) (rsc-role:Master) (with-rsc-role:Started) + vip_mysql with ms_mysql-clone (score:INFINITY) (rsc-role:Started) (with-rsc-role:Master) + ms_mysql-clone with vip_mysql (score:INFINITY) (rsc-role:Master) (with-rsc-role:Started) Ticket Constraints: + ``` then check the database replication From 97b84e8fb1c96a6c2674aa9f5a2205215553eede Mon Sep 17 00:00:00 2001 From: cgenier Date: Tue, 16 Jul 2024 16:54:15 +0200 Subject: [PATCH 32/41] Update --- .../version-24.04/administration/centreon-ha/operating-guide.md | 2 +- .../installation-of-centreon-ha/cluster-elements.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md index e4a56d9219a3..0dd163c81d49 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md @@ -502,7 +502,7 @@ Migration Summary: #### Go back to the nominal situation -To check the various iptables rules configured on the active node, run the following command: +To check the various iptables rules configured on the central node 1, run the following command: ```bash iptables -L diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md index c9bacffef155..9274fcc2fd4d 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md @@ -30,7 +30,7 @@ Centreon HA consists of a set of clustering tools on top of twin Centreon centra * Pollers, which do the actual monitoring. -* A "central [VIP](../../resources/glossary.md#vip)" to which the pollers send the collected data, so that the VIP can forward the data to the current active central node. +* A "central [VIP](https://docs.centreon.com/docs/resources/glossary/#vip)" to which the pollers send the collected data, so that the VIP can forward the data to the current active central node. * A "database VIP" to which the active central node sends the data, so that the VIP can forward the data to the current active database node. From b9f97c4a8f8c209ac7635f0655611c22c2dc1df3 Mon Sep 17 00:00:00 2001 From: cg-tw <83637804+cg-tw@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:54:28 +0200 Subject: [PATCH 33/41] Update versioned_docs/version-24.04/update/update-centreon-ha.md --- versioned_docs/version-24.04/update/update-centreon-ha.md | 1 - 1 file changed, 1 deletion(-) diff --git a/versioned_docs/version-24.04/update/update-centreon-ha.md b/versioned_docs/version-24.04/update/update-centreon-ha.md index fe2c44547692..2bfcb8a653bc 100644 --- a/versioned_docs/version-24.04/update/update-centreon-ha.md +++ b/versioned_docs/version-24.04/update/update-centreon-ha.md @@ -172,7 +172,6 @@ Now that the update is finished, the resources can be managed again: ```bash pcs property set maintenance-mode=false -pcs resource cleanup ms_mysql ``` ## Verifying platform stability From 4fc384427a9b597db0ee60d4557c9df523741a1e Mon Sep 17 00:00:00 2001 From: cg-tw <83637804+cg-tw@users.noreply.github.com> Date: Mon, 26 Aug 2024 17:05:59 +0200 Subject: [PATCH 34/41] Typos --- .../version-24.04/administration/centreon-ha/operating-guide.md | 2 +- .../installation/installation-of-centreon-ha/overview.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md index 0dd163c81d49..9a1ccc2e907b 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md @@ -267,7 +267,7 @@ The passive central node is now excluded from the cluster. If you run `pcs status` on the active central node: -* The resources and the cluster are still working (the output shows that the noe still sees the quorum device). +* The resources and the cluster are still working (the output shows that the node still sees the quorum device). * The passive central node is seen `offline` on the active node: ```text diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md index 2b7c080e2855..5c4794785859 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/overview.md @@ -13,7 +13,7 @@ In the central cluster, all Centreon processes ("resources") are managed by the 2. An incident occurs and central node 1 (the active node) goes down. - Corosync detects that it is down: after consulting with the quorum device, it tells central node 2 to become the active node. - An operator is notified that central node 1 is down, thanks to the Centreon monitoring that has been set up on the poller. -3. Central node 2 is now the active node. It receives data from the pollers. During this time, the operator tries to understand why central node 1 is down. They must fix the problem, then restat the processes using the cluster management tool **pcs**, not by manipulating central node 1 directly. +3. Central node 2 is now the active node. It receives data from the pollers. During this time, the operator tries to understand why central node 1 is down. They must fix the problem, then restart the processes using the cluster management tool **pcs**, not by manipulating central node 1 directly. 4. Central node 1 is fixed and comes back online. The **centreon_central_sync** script synchronizes all relevant files from central node 2 to central node 1, so that central node 1 can catch up on what has happened during its down time. Central node 1 is ready to become the active node if central node 2 goes down. The process is the same for the database cluster. From 6438cc284552ffd8188e107425e3fb237389ab38 Mon Sep 17 00:00:00 2001 From: cg-tw <83637804+cg-tw@users.noreply.github.com> Date: Mon, 26 Aug 2024 17:09:48 +0200 Subject: [PATCH 35/41] How to repair DB replication --- .../centreon-ha/operating-guide.md | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md index 9a1ccc2e907b..1c666e1819bf 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/operating-guide.md @@ -144,7 +144,48 @@ Slave Thread Status [OK] Position Status [OK] ``` - +If the synchronization shows `KO`, you must fix it. The procedure below explains how to manually re-enable MariaDB replication. + +### Restore MariaDB master-slave replication + +> This procedure should be applied in the event of a breakdown in the MariaDB databases' replication thread or a server crash if it cannot be recovered by running `pcs resource cleanup ms_mysql` or `pcs resource restart ms_mysql`. + +Prevent the cluster from managing the MariaDB resource during the operation (to be run from any node): + +```bash +pcs resource unmanage ms_mysql +``` + +Connect to the MariaDB slave server and shut down the MariaDB service: + +```bash +mysqladmin -p shutdown +``` + +Connect to the MariaDB master server and run the following command to overwrite the slave's data with the master's: + +```bash +/usr/share/centreon-ha/bin/mysql-sync-bigdb.sh +``` + +Re-enable the cluster to manage the MariaDB resource: + +```bash +pcs resource manage ms_mysql +``` + +Run the following command on one of the database servers to make sure that the replication has been successfully restored: + +```bash +/usr/share/centreon-ha/bin/mysql-check-status.sh +``` + +```text +Connection Status '@CENTRAL_MASTER_NAME@' [OK] +Connection Status '@CENTRAL_SLAVE_NAME@' [OK] +Slave Thread Status [OK] +Position Status [OK] +``` ## View the cluster's configuration From 89163139b7cd004fe3ab0508ad56ef8d5f9f5e2e Mon Sep 17 00:00:00 2001 From: Cedric Meschin Date: Thu, 5 Sep 2024 10:31:40 +0200 Subject: [PATCH 36/41] [ENH] HA optimize resource order --- .../installation-of-centreon-ha/cluster-elements.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md index 9274fcc2fd4d..44b97e3cc49b 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md @@ -62,9 +62,9 @@ All these resources are described in the table below. | `centreon` | group | Centreon "primitive services" group | | `vip` | primitive service | VIP address for the central cluster | | `http` | primitive service | Apache service (`httpd24-httpd`) | +| `cbd_central_broker` | primitive service | Central Broker service (`cbd-sql`) | | `gorgone` | primitive service | Gorgone service (`gorgoned`) | | `centreon_central_sync` | primitive service | File synchronization service | -| `cbd_central_broker` | primitive service | Central Broker service (`cbd-sql`) | | `centengine` | primitive service | Centreon-Engine service (`centengine`) | | `centreontrapd` | primitive service | SNMP Traps management service (`centreontrapd`) | | `snmptrapd` | primitive service | SNMP Traps listening service (`snmptrapd`) | From 807fa3ce3533e4bd212e85cd3cffd49e9c205f94 Mon Sep 17 00:00:00 2001 From: cg-tw <83637804+cg-tw@users.noreply.github.com> Date: Wed, 2 Oct 2024 11:57:48 +0200 Subject: [PATCH 37/41] Add prerequisites topic --- .../cluster-elements.md | 2 +- .../prerequisites.md | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 versioned_docs/version-24.04/installation/installation-of-centreon-ha/prerequisites.md diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md index 44b97e3cc49b..31e23a379f1b 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/cluster-elements.md @@ -81,4 +81,4 @@ All these resources are described in the table below. ## Active/passive nodes or master/slave nodes? -In this chapter, we will refer to active/passive nodes. You may notice that the output of some commands use the terms master and slave: these are Pacemaker and Corosync terms. Master means the active node and slave the passive node. \ No newline at end of file +In this chapter, we will refer to active/passive nodes. You may notice that the output of some commands use the terms master and slave: these are Pacemaker and Corosync terms. Master means the active node and slave the passive node. diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/prerequisites.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/prerequisites.md new file mode 100644 index 000000000000..cbeb6ebde95e --- /dev/null +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/prerequisites.md @@ -0,0 +1,25 @@ +--- +id: ha-prerequisites +title: Prerequisites for an HA architecture +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +## Sizing + +See the [general sizing infomation](../prerequisites.md) for a standard Centreon platform. In addition, you **must** have at least 5 Go available on the VG that contains the **/var/lib/mysql** partition, otherwise you will not be able to set up the replication. + +## Table of HA network flows + +| Source | Destination | Port/Protocol | Comments | +|--------|-------------|----------------|----------| +| Active central node | Passive central node | TCP 22 | To synchronize configuration files (the flow must also be open in the passive --> active direction) | +| Active central node | Passive central node | TCP 5670 | To synchronize RRD files (the flow must also be open in the passive --> active direction) | +| Active DB node | Passive DB node | TCP 3306 | MySQL synchronization (the flow must also be open in the passive --> active direction) | +| Active DB node | Passive DB node | TCP 22 | MySQL Synchronization (the flow must also be open in the passive --> active direction) | +| Central servers + DB + QDevice | Central servers + DB + QDevice | UDP 5404 | Communication inside the cluster (Multicast) | +| Central servers + DB + QDevice | Central servers + DB + QDevice | UDP 5405 | Communication inside the cluster (Unicast)| +| Central servers + DB + QDevice | Central servers + DB + QDevice | TCP 2224 | Communication inside the cluster | +| Central servers + DB + QDevice | Central servers + DB + QDevice | TCP 5403 | Communication with the QDevice | + +See also the general [tables of network flows](../technical.md#tables-of-network-flows). From 0ee60c768681efcc62be3aa6e31e51f332eef4aa Mon Sep 17 00:00:00 2001 From: cg-tw <83637804+cg-tw@users.noreply.github.com> Date: Wed, 2 Oct 2024 13:13:29 +0200 Subject: [PATCH 38/41] Workaround for abnormally dead link --- .../installation/installation-of-centreon-ha/prerequisites.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/prerequisites.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/prerequisites.md index cbeb6ebde95e..abecbf4c4c44 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/prerequisites.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/prerequisites.md @@ -7,7 +7,7 @@ import TabItem from '@theme/TabItem'; ## Sizing -See the [general sizing infomation](../prerequisites.md) for a standard Centreon platform. In addition, you **must** have at least 5 Go available on the VG that contains the **/var/lib/mysql** partition, otherwise you will not be able to set up the replication. +See the [general sizing infomation](https://docs.centreon.com/docs/installation/prerequisites/) for a standard Centreon platform. In addition, you **must** have at least 5 Go available on the VG that contains the **/var/lib/mysql** partition, otherwise you will not be able to set up the replication. ## Table of HA network flows From 06629cd30a9b091f2582b950a865c622b54901d7 Mon Sep 17 00:00:00 2001 From: cg-tw <83637804+cg-tw@users.noreply.github.com> Date: Wed, 2 Oct 2024 13:32:15 +0200 Subject: [PATCH 39/41] Workaround for abnormally dead link --- .../installation/installation-of-centreon-ha/prerequisites.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/prerequisites.md b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/prerequisites.md index abecbf4c4c44..dfb924e8b46b 100644 --- a/versioned_docs/version-24.04/installation/installation-of-centreon-ha/prerequisites.md +++ b/versioned_docs/version-24.04/installation/installation-of-centreon-ha/prerequisites.md @@ -22,4 +22,4 @@ See the [general sizing infomation](https://docs.centreon.com/docs/installation/ | Central servers + DB + QDevice | Central servers + DB + QDevice | TCP 2224 | Communication inside the cluster | | Central servers + DB + QDevice | Central servers + DB + QDevice | TCP 5403 | Communication with the QDevice | -See also the general [tables of network flows](../technical.md#tables-of-network-flows). +See also the general [tables of network flows](https://docs.centreon.com/docs/installation/technical/#tables-of-network-flows). From 63ee689fc64ea994d9af11a0d762ac3105732b5e Mon Sep 17 00:00:00 2001 From: cg-tw <83637804+cg-tw@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:31:30 +0200 Subject: [PATCH 40/41] Add Prerequisites topic to ToC --- versioned_sidebars/version-24.04-sidebars.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/versioned_sidebars/version-24.04-sidebars.json b/versioned_sidebars/version-24.04-sidebars.json index 1c94dfdeb0cb..d231a065d10f 100644 --- a/versioned_sidebars/version-24.04-sidebars.json +++ b/versioned_sidebars/version-24.04-sidebars.json @@ -1484,6 +1484,10 @@ "type": "doc", "id": "version-24.04/installation/installation-of-centreon-ha/overview" }, + { + "type": "doc", + "id": "version-24.04/installation/installation-of-centreon-ha/ha-prerequisites" + }, { "type": "category", "label": "Completing your Centreon HA setup", From 154cc9ae5750483f2e12267156aa03087254e256 Mon Sep 17 00:00:00 2001 From: cg-tw <83637804+cg-tw@users.noreply.github.com> Date: Wed, 30 Oct 2024 16:15:32 +0100 Subject: [PATCH 41/41] Add troubleshooting case --- .../centreon-ha/troubleshooting-guide.md | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/versioned_docs/version-24.04/administration/centreon-ha/troubleshooting-guide.md b/versioned_docs/version-24.04/administration/centreon-ha/troubleshooting-guide.md index ad19ff1486b9..d103f7f54cd6 100644 --- a/versioned_docs/version-24.04/administration/centreon-ha/troubleshooting-guide.md +++ b/versioned_docs/version-24.04/administration/centreon-ha/troubleshooting-guide.md @@ -134,3 +134,49 @@ pcs resource clear centreon ``` Resources should be starting now. + +## No resource is starting + +If no resource is starting, one of the possible causes is that the quorum device is not started. + +### Solution + +To check how the quorum device is doing, run the following command on the central nodes or the database nodes: + +```shell +pcs quorum status +``` + +If everything is OK, the output looks like this: + +```text +Membership information +---------------------- + Nodeid Votes Qdevice Name + 1 1 A,V,NMW node1 (local) + 2 1 A,V,NMW node2 + 3 1 A,V,NMW node3 + 4 1 A,V,NMW node4 + 0 1 Qdevice +``` + +If you obtain something else, there is a problem. + +- Check that the **corosync-qnetd** service is running on your central and databases nodes. + +```shell +systemctl status corosync-qnetd +``` + +- Try running this command to know whether the quorum device is started or not: + +```shell +pcs qdevice status net --full +``` + +- If the quorum device is running, there may be a problem with the flows between the nodes and the quorum device. +- If the quorum device is not running, log in to your quorum device and start it using the following command: + +```shell +pcs qdevice start net +```