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: I7e4d0fc804be242302d2e7b7202159d4b7ba8c97changes/19/529819/5
parent
45a1623cb2
commit
3731993f6a
|
@ -0,0 +1,106 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Script to make a proxy (ie HAProxy) capable of monitoring MariaDB Cluster nodes properly
|
||||
#
|
||||
# Author: Olaf van Zandwijk <olaf.vanzandwijk@nedap.com>
|
||||
# Author: Raghavendra Prabhu <raghavendra.prabhu@percona.com>
|
||||
#
|
||||
# Documentation and download: https://github.com/olafz/percona-clustercheck
|
||||
#
|
||||
# Based on the original script from Unai Rodriguez
|
||||
#
|
||||
# Updated for MariaDB by: Jens Harbott <j.harbott@x-ion.de>
|
||||
#
|
||||
|
||||
if [[ $1 == '-h' || $1 == '--help' ]];then
|
||||
echo "Usage: $0 <user> <pass> <available_when_donor=0|1> <log_file> <available_when_readonly=0|1> <defaults_extra_file>"
|
||||
exit
|
||||
fi
|
||||
|
||||
# if the disabled file is present, return 503. This allows
|
||||
# admins to manually remove a node from a cluster easily.
|
||||
if [ -e "/var/tmp/clustercheck.disabled" ]; then
|
||||
# Shell return-code is 1
|
||||
echo -en "HTTP/1.1 503 Service Unavailable\r\n"
|
||||
echo -en "Content-Type: text/plain\r\n"
|
||||
echo -en "Connection: close\r\n"
|
||||
echo -en "Content-Length: 51\r\n"
|
||||
echo -en "\r\n"
|
||||
echo -en "MariaDB Cluster Node is manually disabled.\r\n"
|
||||
sleep 0.1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MYSQL_USERNAME="${1-clustercheckuser}"
|
||||
MYSQL_PASSWORD="${2-clustercheckpassword!}"
|
||||
AVAILABLE_WHEN_DONOR=${3:-0}
|
||||
ERR_FILE="${4:-/dev/null}"
|
||||
AVAILABLE_WHEN_READONLY=${5:-1}
|
||||
DEFAULTS_EXTRA_FILE=${6:-/etc/my.cnf}
|
||||
|
||||
#Timeout exists for instances where mysqld may be hung
|
||||
TIMEOUT=10
|
||||
|
||||
EXTRA_ARGS=""
|
||||
if [[ -n "$MYSQL_USERNAME" ]]; then
|
||||
EXTRA_ARGS="$EXTRA_ARGS --user=${MYSQL_USERNAME}"
|
||||
fi
|
||||
if [[ -n "$MYSQL_PASSWORD" ]]; then
|
||||
EXTRA_ARGS="$EXTRA_ARGS --password=${MYSQL_PASSWORD}"
|
||||
fi
|
||||
if [[ -r $DEFAULTS_EXTRA_FILE ]];then
|
||||
MYSQL_CMDLINE="mysql --defaults-extra-file=$DEFAULTS_EXTRA_FILE -nNE --connect-timeout=$TIMEOUT \
|
||||
${EXTRA_ARGS}"
|
||||
else
|
||||
MYSQL_CMDLINE="mysql -nNE --connect-timeout=$TIMEOUT ${EXTRA_ARGS}"
|
||||
fi
|
||||
#
|
||||
# Perform the query to check the wsrep_local_state
|
||||
#
|
||||
WSREP_STATUS=$($MYSQL_CMDLINE -e "SHOW STATUS LIKE 'wsrep_local_state';" \
|
||||
2>${ERR_FILE} | tail -1 2>>${ERR_FILE})
|
||||
|
||||
if [[ "${WSREP_STATUS}" == "4" ]] || [[ "${WSREP_STATUS}" == "2" && ${AVAILABLE_WHEN_DONOR} == 1 ]]
|
||||
then
|
||||
# Check only when set to 0 to avoid latency in response.
|
||||
if [[ $AVAILABLE_WHEN_READONLY -eq 0 ]];then
|
||||
READ_ONLY=$($MYSQL_CMDLINE -e "SHOW GLOBAL VARIABLES LIKE 'read_only';" \
|
||||
2>${ERR_FILE} | tail -1 2>>${ERR_FILE})
|
||||
|
||||
if [[ "${READ_ONLY}" == "ON" ]];then
|
||||
# MariaDB Cluster node local state is 'Synced', but it is in
|
||||
# read-only mode. The variable AVAILABLE_WHEN_READONLY is set to 0.
|
||||
# => return HTTP 503
|
||||
# Shell return-code is 1
|
||||
echo -en "HTTP/1.1 503 Service Unavailable\r\n"
|
||||
echo -en "Content-Type: text/plain\r\n"
|
||||
echo -en "Connection: close\r\n"
|
||||
echo -en "Content-Length: 43\r\n"
|
||||
echo -en "\r\n"
|
||||
echo -en "MariaDB Cluster Node is read-only.\r\n"
|
||||
sleep 0.1
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
# MariaDB Cluster node local state is 'Synced' => return HTTP 200
|
||||
# Shell return-code is 0
|
||||
echo -en "HTTP/1.1 200 OK\r\n"
|
||||
echo -en "Content-Type: text/plain\r\n"
|
||||
echo -en "Connection: close\r\n"
|
||||
echo -en "Content-Length: 40\r\n"
|
||||
echo -en "\r\n"
|
||||
echo -en "MariaDB Cluster Node is synced.\r\n"
|
||||
sleep 0.1
|
||||
exit 0
|
||||
else
|
||||
# MariaDB Cluster node local state is not 'Synced' => return HTTP 503
|
||||
# Shell return-code is 1
|
||||
echo -en "HTTP/1.1 503 Service Unavailable\r\n"
|
||||
echo -en "Content-Type: text/plain\r\n"
|
||||
echo -en "Connection: close\r\n"
|
||||
echo -en "Content-Length: 44\r\n"
|
||||
echo -en "\r\n"
|
||||
echo -en "MariaDB Cluster Node is not synced.\r\n"
|
||||
sleep 0.1
|
||||
exit 1
|
||||
fi
|
|
@ -11,6 +11,8 @@ recipe 'mysql-client', 'Installs MySQL client packages.'
|
|||
recipe 'mysql-server', 'Installs and configures MySQL server packages.'
|
||||
recipe 'mariadb-client', 'Installs MariaDB client packages.'
|
||||
recipe 'mariadb-server', 'Installs and configures MariaDB server packages.'
|
||||
recipe 'mariadb-cluster-client', 'Installs MariaDB Cluster client packages.'
|
||||
recipe 'mariadb-cluster-server', 'Installs and configures MariaDB Cluster server packages.'
|
||||
recipe 'openstack-db', 'Creates necessary tables, users, and grants for OpenStack.'
|
||||
|
||||
%w(ubuntu redhat centos).each do |os|
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# encoding: UTF-8
|
||||
#
|
||||
# Cookbook Name:: openstack-ops-database
|
||||
# Recipe:: mariadb-cluster-client
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
include_recipe 'openstack-ops-database::mariadb-client'
|
|
@ -0,0 +1,66 @@
|
|||
# encoding: UTF-8
|
||||
#
|
||||
# Cookbook Name:: openstack-ops-database
|
||||
# Recipe:: mariadb-cluster-server
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
class ::Chef::Recipe
|
||||
include ::Openstack
|
||||
end
|
||||
|
||||
## INFO: to use this recipe, set node['openstack']['db']['service_type'] = 'mariadb-cluster' in your environment
|
||||
|
||||
bind_db = node['openstack']['bind_service']['db']
|
||||
if bind_db['interface']
|
||||
listen_address = address_for bind_db['interface']
|
||||
node.normal['mariadb']['galera']['options']['port'] = bind_db['port']
|
||||
else
|
||||
listen_address = bind_db['host']
|
||||
node.normal['mariadb']['galera']['options']['port'] = node['openstack']['endpoints']['db']['port']
|
||||
end
|
||||
node.normal['mariadb']['galera']['options']['bind-address'] = listen_address
|
||||
|
||||
## CLUSTER SPECIFIC CONFIG
|
||||
node.normal['mariadb']['galera']['cluster_name'] = 'openstack'
|
||||
node.normal['mariadb']['galera']['wsrep_provider_options']['gmcast.listen_addr'] = "tcp://#{listen_address}:4567"
|
||||
### find all nodes in the mariadb cluster
|
||||
cluster_nodes = search(:node, 'recipes:"openstack-ops-database\:\:mariadb-cluster-server"').sort
|
||||
# if it's the first node make sure that wsrep_cluster_address is set to nothing to be able to bootstrap.
|
||||
is_first_node = cluster_nodes.empty? || (cluster_nodes.size == 1 && cluster_nodes.first['fqdn'] == node['fqdn'])
|
||||
if is_first_node
|
||||
node.normal['mariadb']['galera']['gcomm_address'] = 'gcomm://'
|
||||
else
|
||||
# otherwise set the correct cluster address with all cluster nodes
|
||||
family = node['openstack']['endpoints']['family']
|
||||
cluster_nodes_addresses = []
|
||||
cluster_nodes.each do |cluster_node|
|
||||
address = address_for bind_db['interface'], family, cluster_node
|
||||
cluster_nodes_addresses << address
|
||||
end
|
||||
cluster_address = cluster_nodes_addresses.join(',')
|
||||
node.normal['mariadb']['galera']['gcomm_address'] = "gcomm://#{cluster_address}"
|
||||
end
|
||||
|
||||
include_recipe 'openstack-ops-database::mariadb-client'
|
||||
include_recipe 'mariadb::galera'
|
||||
|
||||
# Install clustercheck tool
|
||||
cookbook_file '/usr/bin/clustercheck' do
|
||||
source 'clustercheck'
|
||||
owner 'root'
|
||||
group 'root'
|
||||
mode '0755'
|
||||
action :create_if_missing
|
||||
end
|
Loading…
Reference in New Issue