Browse Source

Add receipes for mariadb cluster deployment

After removal of the percona cluster receipes, add support for deploying
a galera-based mariadb cluster instead.

Change-Id: I7e4d0fc804be242302d2e7b7202159d4b7ba8c97
Jens Harbott 1 year ago
parent
commit
3731993f6a
4 changed files with 193 additions and 0 deletions
  1. 106
    0
      files/default/clustercheck
  2. 2
    0
      metadata.rb
  3. 19
    0
      recipes/mariadb-cluster-client.rb
  4. 66
    0
      recipes/mariadb-cluster-server.rb

+ 106
- 0
files/default/clustercheck View File

@@ -0,0 +1,106 @@
1
+#!/bin/bash
2
+#
3
+# Script to make a proxy (ie HAProxy) capable of monitoring MariaDB Cluster nodes properly
4
+#
5
+# Author: Olaf van Zandwijk <olaf.vanzandwijk@nedap.com>
6
+# Author: Raghavendra Prabhu <raghavendra.prabhu@percona.com>
7
+#
8
+# Documentation and download: https://github.com/olafz/percona-clustercheck
9
+#
10
+# Based on the original script from Unai Rodriguez
11
+#
12
+# Updated for MariaDB by: Jens Harbott <j.harbott@x-ion.de>
13
+#
14
+
15
+if [[ $1 == '-h' || $1 == '--help' ]];then
16
+    echo "Usage: $0 <user> <pass> <available_when_donor=0|1> <log_file> <available_when_readonly=0|1> <defaults_extra_file>"
17
+    exit
18
+fi
19
+
20
+# if the disabled file is present, return 503. This allows
21
+# admins to manually remove a node from a cluster easily.
22
+if [ -e "/var/tmp/clustercheck.disabled" ]; then
23
+    # Shell return-code is 1
24
+    echo -en "HTTP/1.1 503 Service Unavailable\r\n"
25
+    echo -en "Content-Type: text/plain\r\n"
26
+    echo -en "Connection: close\r\n"
27
+    echo -en "Content-Length: 51\r\n"
28
+    echo -en "\r\n"
29
+    echo -en "MariaDB Cluster Node is manually disabled.\r\n"
30
+    sleep 0.1
31
+    exit 1
32
+fi
33
+
34
+MYSQL_USERNAME="${1-clustercheckuser}"
35
+MYSQL_PASSWORD="${2-clustercheckpassword!}"
36
+AVAILABLE_WHEN_DONOR=${3:-0}
37
+ERR_FILE="${4:-/dev/null}"
38
+AVAILABLE_WHEN_READONLY=${5:-1}
39
+DEFAULTS_EXTRA_FILE=${6:-/etc/my.cnf}
40
+
41
+#Timeout exists for instances where mysqld may be hung
42
+TIMEOUT=10
43
+
44
+EXTRA_ARGS=""
45
+if [[ -n "$MYSQL_USERNAME" ]]; then
46
+    EXTRA_ARGS="$EXTRA_ARGS --user=${MYSQL_USERNAME}"
47
+fi
48
+if [[ -n "$MYSQL_PASSWORD" ]]; then
49
+    EXTRA_ARGS="$EXTRA_ARGS --password=${MYSQL_PASSWORD}"
50
+fi
51
+if [[ -r $DEFAULTS_EXTRA_FILE ]];then
52
+    MYSQL_CMDLINE="mysql --defaults-extra-file=$DEFAULTS_EXTRA_FILE -nNE --connect-timeout=$TIMEOUT \
53
+                    ${EXTRA_ARGS}"
54
+else
55
+    MYSQL_CMDLINE="mysql -nNE --connect-timeout=$TIMEOUT ${EXTRA_ARGS}"
56
+fi
57
+#
58
+# Perform the query to check the wsrep_local_state
59
+#
60
+WSREP_STATUS=$($MYSQL_CMDLINE -e "SHOW STATUS LIKE 'wsrep_local_state';" \
61
+    2>${ERR_FILE} | tail -1 2>>${ERR_FILE})
62
+
63
+if [[ "${WSREP_STATUS}" == "4" ]] || [[ "${WSREP_STATUS}" == "2" && ${AVAILABLE_WHEN_DONOR} == 1 ]]
64
+then
65
+    # Check only when set to 0 to avoid latency in response.
66
+    if [[ $AVAILABLE_WHEN_READONLY -eq 0 ]];then
67
+        READ_ONLY=$($MYSQL_CMDLINE -e "SHOW GLOBAL VARIABLES LIKE 'read_only';" \
68
+                    2>${ERR_FILE} | tail -1 2>>${ERR_FILE})
69
+
70
+        if [[ "${READ_ONLY}" == "ON" ]];then
71
+            # MariaDB Cluster node local state is 'Synced', but it is in
72
+            # read-only mode. The variable AVAILABLE_WHEN_READONLY is set to 0.
73
+            # => return HTTP 503
74
+            # Shell return-code is 1
75
+            echo -en "HTTP/1.1 503 Service Unavailable\r\n"
76
+            echo -en "Content-Type: text/plain\r\n"
77
+            echo -en "Connection: close\r\n"
78
+            echo -en "Content-Length: 43\r\n"
79
+            echo -en "\r\n"
80
+            echo -en "MariaDB Cluster Node is read-only.\r\n"
81
+            sleep 0.1
82
+            exit 1
83
+        fi
84
+    fi
85
+    # MariaDB Cluster node local state is 'Synced' => return HTTP 200
86
+    # Shell return-code is 0
87
+    echo -en "HTTP/1.1 200 OK\r\n"
88
+    echo -en "Content-Type: text/plain\r\n"
89
+    echo -en "Connection: close\r\n"
90
+    echo -en "Content-Length: 40\r\n"
91
+    echo -en "\r\n"
92
+    echo -en "MariaDB Cluster Node is synced.\r\n"
93
+    sleep 0.1
94
+    exit 0
95
+else
96
+    # MariaDB Cluster node local state is not 'Synced' => return HTTP 503
97
+    # Shell return-code is 1
98
+    echo -en "HTTP/1.1 503 Service Unavailable\r\n"
99
+    echo -en "Content-Type: text/plain\r\n"
100
+    echo -en "Connection: close\r\n"
101
+    echo -en "Content-Length: 44\r\n"
102
+    echo -en "\r\n"
103
+    echo -en "MariaDB Cluster Node is not synced.\r\n"
104
+    sleep 0.1
105
+    exit 1
106
+fi

+ 2
- 0
metadata.rb View File

@@ -11,6 +11,8 @@ recipe 'mysql-client', 'Installs MySQL client packages.'
11 11
 recipe 'mysql-server', 'Installs and configures MySQL server packages.'
12 12
 recipe 'mariadb-client', 'Installs MariaDB client packages.'
13 13
 recipe 'mariadb-server', 'Installs and configures MariaDB server packages.'
14
+recipe 'mariadb-cluster-client', 'Installs MariaDB Cluster client packages.'
15
+recipe 'mariadb-cluster-server', 'Installs and configures MariaDB Cluster server packages.'
14 16
 recipe 'openstack-db', 'Creates necessary tables, users, and grants for OpenStack.'
15 17
 
16 18
 %w(ubuntu redhat centos).each do |os|

+ 19
- 0
recipes/mariadb-cluster-client.rb View File

@@ -0,0 +1,19 @@
1
+# encoding: UTF-8
2
+#
3
+# Cookbook Name:: openstack-ops-database
4
+# Recipe:: mariadb-cluster-client
5
+#
6
+# Licensed under the Apache License, Version 2.0 (the "License");
7
+# you may not use this file except in compliance with the License.
8
+# You may obtain a copy of the License at
9
+#
10
+#     http://www.apache.org/licenses/LICENSE-2.0
11
+#
12
+# Unless required by applicable law or agreed to in writing, software
13
+# distributed under the License is distributed on an "AS IS" BASIS,
14
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+# See the License for the specific language governing permissions and
16
+# limitations under the License.
17
+#
18
+
19
+include_recipe 'openstack-ops-database::mariadb-client'

+ 66
- 0
recipes/mariadb-cluster-server.rb View File

@@ -0,0 +1,66 @@
1
+# encoding: UTF-8
2
+#
3
+# Cookbook Name:: openstack-ops-database
4
+# Recipe:: mariadb-cluster-server
5
+#
6
+# Licensed under the Apache License, Version 2.0 (the "License");
7
+# you may not use this file except in compliance with the License.
8
+# You may obtain a copy of the License at
9
+#
10
+#     http://www.apache.org/licenses/LICENSE-2.0
11
+#
12
+# Unless required by applicable law or agreed to in writing, software
13
+# distributed under the License is distributed on an "AS IS" BASIS,
14
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+# See the License for the specific language governing permissions and
16
+# limitations under the License.
17
+#
18
+
19
+class ::Chef::Recipe
20
+  include ::Openstack
21
+end
22
+
23
+## INFO: to use this recipe, set node['openstack']['db']['service_type'] = 'mariadb-cluster' in your environment
24
+
25
+bind_db = node['openstack']['bind_service']['db']
26
+if bind_db['interface']
27
+  listen_address = address_for bind_db['interface']
28
+  node.normal['mariadb']['galera']['options']['port'] = bind_db['port']
29
+else
30
+  listen_address = bind_db['host']
31
+  node.normal['mariadb']['galera']['options']['port'] = node['openstack']['endpoints']['db']['port']
32
+end
33
+node.normal['mariadb']['galera']['options']['bind-address'] = listen_address
34
+
35
+## CLUSTER SPECIFIC CONFIG
36
+node.normal['mariadb']['galera']['cluster_name'] = 'openstack'
37
+node.normal['mariadb']['galera']['wsrep_provider_options']['gmcast.listen_addr'] = "tcp://#{listen_address}:4567"
38
+### find all nodes in the mariadb cluster
39
+cluster_nodes = search(:node, 'recipes:"openstack-ops-database\:\:mariadb-cluster-server"').sort
40
+# if it's the first node make sure that wsrep_cluster_address is set to nothing to be able to bootstrap.
41
+is_first_node = cluster_nodes.empty? || (cluster_nodes.size == 1 && cluster_nodes.first['fqdn'] == node['fqdn'])
42
+if is_first_node
43
+  node.normal['mariadb']['galera']['gcomm_address'] = 'gcomm://'
44
+else
45
+  # otherwise set the correct cluster address with all cluster nodes
46
+  family = node['openstack']['endpoints']['family']
47
+  cluster_nodes_addresses = []
48
+  cluster_nodes.each do |cluster_node|
49
+    address = address_for bind_db['interface'], family, cluster_node
50
+    cluster_nodes_addresses << address
51
+  end
52
+  cluster_address = cluster_nodes_addresses.join(',')
53
+  node.normal['mariadb']['galera']['gcomm_address'] = "gcomm://#{cluster_address}"
54
+end
55
+
56
+include_recipe 'openstack-ops-database::mariadb-client'
57
+include_recipe 'mariadb::galera'
58
+
59
+# Install clustercheck tool
60
+cookbook_file '/usr/bin/clustercheck' do
61
+  source 'clustercheck'
62
+  owner 'root'
63
+  group 'root'
64
+  mode '0755'
65
+  action :create_if_missing
66
+end

Loading…
Cancel
Save