Add proxysql image

Replacement for MySQL balancing solution
provided by haproxy.

Needed-By: https://review.opendev.org/c/openstack/kolla-ansible/+/770215

Change-Id: I85ebe3b20294cd9dc847a3582053d3e21f6a2216
This commit is contained in:
Michal Arbet 2021-01-05 16:32:06 +01:00
parent f98ad9462b
commit febbb5b40b
9 changed files with 273 additions and 0 deletions

View File

@ -76,6 +76,7 @@ COPY dnf.conf /etc/dnf/dnf.conf
'elasticsearch.repo',
'grafana.repo',
'influxdb.repo',
'proxysql.repo',
'rabbitmq_rabbitmq-server.repo',
'rabbitmq_rabbitmq-erlang.repo',
'td.repo',
@ -89,11 +90,13 @@ COPY dnf.conf /etc/dnf/dnf.conf
'https://repos.influxdata.com/influxdb.key',
'https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc',
'https://packages.treasuredata.com/GPG-KEY-td-agent',
'https://repo.proxysql.com/ProxySQL/repo_pub_key',
] %}
{% elif base_arch == 'aarch64' %}
{% set base_yum_repo_files = [
'elasticsearch.repo',
'grafana.repo',
'proxysql.repo',
'rabbitmq_rabbitmq-server.repo',
'td.repo',
] %}
@ -101,6 +104,7 @@ COPY dnf.conf /etc/dnf/dnf.conf
{% set base_yum_repo_keys = [
'https://packages.grafana.com/gpg.key',
'https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc',
'https://repo.proxysql.com/ProxySQL/repo_pub_key',
] %}
# FIXME(mgoddard): Not available for CentOS 8 yet.
#
@ -328,6 +332,7 @@ COPY apt_preferences /etc/apt/preferences.d/kolla-custom
{'name': 'grafana', 'url': 'https://packages.grafana.com/gpg.key'},
{'name': 'influxdb', 'url': 'https://repos.influxdata.com/influxdb.key'},
{'name': 'mariadb', 'url': 'https://downloads.mariadb.com/MariaDB/mariadb-keyring-2019.gpg', 'type': 'gpg'},
{'name': 'proxysql', 'url': 'https://repo.proxysql.com/ProxySQL/repo_pub_key'},
{'name': 'treasuredata', 'url': 'https://packages.treasuredata.com/GPG-KEY-td-agent'},
] %}

View File

@ -0,0 +1,6 @@
[proxysql]
name = ProxySQL
baseurl = https://repo.proxysql.com/ProxySQL/proxysql-2.3.x/centos/$releasever
gpgkey = https://repo.proxysql.com/ProxySQL/repo_pub_key
gpgcheck = 1
enabled = 0

View File

@ -0,0 +1,35 @@
FROM {{ namespace }}/{{ infra_image_prefix }}base:{{ tag }}
{% block labels %}
LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" build-date="{{ build_date }}"
{% endblock %}
{% block proxysql_header %}{% endblock %}
{% import "macros.j2" as macros with context %}
{{ macros.enable_extra_repos(['proxysql']) }}
{% set proxysql_packages = [
'proxysql',
] %}
{% if base_package_type == 'rpm' %}
{% set proxysql_packages = proxysql_packages + [
'python3-PyYAML',
] %}
{% elif base_package_type == 'deb' %}
{% set proxysql_packages = proxysql_packages + [
'python3-yaml',
] %}
{% endif %}
{{ macros.configure_user(name='proxysql') }}
{{ macros.install_packages(proxysql_packages | customizable("packages")) }}
COPY kolla_proxysql_start kolla_proxysql_config_sync kolla_extend_start /usr/local/bin/
RUN chmod 755 /usr/local/bin/kolla_proxysql_start \
&& chmod 755 /usr/local/bin/kolla_proxysql_config_sync \
&& chmod 755 /usr/local/bin/kolla_extend_start
{% block proxysql_footer %}{% endblock %}
{% block footer %}{% endblock %}

View File

@ -0,0 +1,34 @@
#!/bin/bash
PROXYSQL_LIB_DIR="/var/lib/proxysql"
PROXYSQL_LOG_DIR="/var/log/kolla/proxysql"
if [[ ! -d "${PROXYSQL_LOG_DIR}" ]]; then
mkdir -p "${PROXYSQL_LOG_DIR}"
fi
chown -R proxysql:kolla "${PROXYSQL_LOG_DIR}"
# Proxysql has configuration stored in
# its own internal DB and config file
# is used only for bootstrap DB by default.
# Once DB is bootstraped, config
# file is ignored.
#
# This behaviour is not what we want
# while configuring via kolla-ansible.
# Therefore let's remove internal DB
# and bootstrap it every time as config
# file is generated on kolla-ansible side.
rm -f ${PROXYSQL_LIB_DIR}/proxysql.db
# Remove old pid
rm -f ${PROXYSQL_LIB_DIR}/proxysql.pid
# As proxysql supports only one
# configuration file, there is a
# script which reads global and services
# configs (similar to haproxy) and
# generate single configuration file
# from which is internal DB created
# every time.
kolla_proxysql_config_sync

View File

@ -0,0 +1,152 @@
#!/usr/bin/python3
# Copyright 2021 Michal Arbet
#
# 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.
import logging
import os
import yaml
# Default paths
PROXYSQL_CONFIG_DIR = "/etc/proxysql"
PROXYSQL_CONFIG = "/etc/proxysql.cnf"
# Logging
log_format = '%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s'
logging.basicConfig(format=log_format,
datefmt='%H:%M:%S',
level=logging.DEBUG)
LOG = logging.getLogger("proxysql_config_sync")
class ProxySQLConfig:
def __init__(self, conf_dir, conf_file):
self.configs = dict()
self.config = dict()
self.configs['global'] = "{}/proxysql.yaml".format(conf_dir)
self.configs['users'] = "{}/users".format(conf_dir)
self.configs['rules'] = "{}/rules".format(conf_dir)
self.conf_file = conf_file
self._load_config()
def _load_config(self):
users = dict()
rules = dict()
for cfg, path in self.configs.items():
if not os.path.isdir(path):
with open(path) as config_file:
self.config.update(
yaml.safe_load(config_file))
else:
users['mysql_users'] = list()
rules['mysql_query_rules'] = list()
user_paths = [os.path.join(self.configs['users'], f)
for f in os.listdir(self.configs['users'])]
rule_paths = [os.path.join(self.configs['rules'], f)
for f in os.listdir(self.configs['rules'])]
for user_conf in user_paths:
with open(user_conf) as config_file:
tmp_users = yaml.safe_load(config_file)
for i in tmp_users['mysql_users']:
users['mysql_users'].append(i)
self.config.update(users)
for rule_conf in rule_paths:
with open(rule_conf) as config_file:
tmp_rules = yaml.safe_load(config_file)
for i in tmp_rules['mysql_query_rules']:
rules['mysql_query_rules'].append(i)
self.config.update(rules)
self._sanity()
def _sanity(self):
self._users_sanity()
self._rules_sanity()
def _users_sanity(self):
users_added = list()
users = list()
for user in self.config['mysql_users']:
if user['username'] not in users_added:
users_added.append(user['username'])
users.append(user)
else:
LOG.warning("User {} already exist, ignoring."
.format(user['username']))
self.config['mysql_users'] = users
def _rules_sanity(self):
rules_added = list()
rules = list()
rule_id = 1
for rule in self.config['mysql_query_rules']:
if rule['schemaname'] not in rules_added:
rules_added.append(rule['schemaname'])
rule['rule_id'] = rule_id
rules.append(rule)
rule_id += 1
else:
LOG.warning("Rule witch schemaname {} already exist, ignoring."
.format(rule['schemaname']))
self.config['mysql_query_rules'] = rules
def _write_dict(self, key, value):
if not isinstance(value, list):
value = [value]
with open(self.conf_file, "a+") as f:
if key:
f.write("{} =\n".format(key))
for i in range(len(value)):
f.write(" {\n")
for k, v in value[i].items():
if isinstance(v, str):
v = '"{}"'.format(v)
f.write(" {} = {}\n".format(k, v))
if i == len(value)-1:
f.write(" }\n")
else:
f.write(" },\n")
def _write_list(self, key, values):
with open(self.conf_file, "a+") as f:
f.write("{} =\n".format(key))
f.write("(\n")
self._write_dict(key=None, value=values)
with open(self.conf_file, "a+") as f:
f.write(")\n")
def _write(self, key, value):
with open(self.conf_file, "a+") as f:
if isinstance(value, str):
value = '"{}"'.format(value)
f.write("{} = {}\n".format(key, value))
def write_config(self):
LOG.info("Writing config to {}".format(self.conf_file))
if os.path.exists(self.conf_file):
os.remove(self.conf_file)
for k, v in self.config.items():
if isinstance(v, dict):
self._write_dict(k, v)
elif isinstance(v, list):
self._write_list(k, v)
else:
self._write(k, v)
if __name__ == "__main__":
config = ProxySQLConfig(PROXYSQL_CONFIG_DIR, PROXYSQL_CONFIG)
config.write_config()

View File

@ -0,0 +1,9 @@
#!/bin/bash
PROXYSQL_LOG_FILE="/var/log/kolla/proxysql/proxysql.log"
proxysql \
--exit-on-error \
--idle-threads \
--no-version-check \
-f -D /var/lib/proxysql -c /etc/proxysql.cnf >> ${PROXYSQL_LOG_FILE} 2>&1

View File

@ -62,6 +62,7 @@ _PROFILE_OPTS = [
'mariadb',
'memcached',
'openvswitch',
'proxysql',
'qdrouterd',
'rabbitmq',
'redis',
@ -133,6 +134,7 @@ _PROFILE_OPTS = [
'neutron',
'nova-',
'placement',
'proxysql',
'openvswitch',
'rabbitmq',
],
@ -944,6 +946,10 @@ USERS = {
'uid': 42486,
'gid': 42486,
'group': 'haclient',
},
'proxysql-user': {
'uid': 42487,
'gid': 42487,
}
}

View File

@ -16,6 +16,7 @@ centos:
openvswitch: "centos-nfv-openvswitch"
opstools: "centos-opstools"
powertools: "powertools"
proxysql: "proxysql"
rabbitmq: "rabbitmq_rabbitmq-server"
td-agent: "treasuredata"
@ -35,6 +36,7 @@ centos-aarch64:
openvswitch: "centos-nfv-openvswitch"
opstools: "centos-opstools"
powertools: "powertools"
proxysql: "proxysql"
rabbitmq: "rabbitmq_rabbitmq-server"
td-agent: "treasuredata"
@ -80,6 +82,11 @@ debian:
suite: "bullseye"
component: "contrib"
gpg_key: "treasuredata.asc"
proxysql:
url: "https://repo.proxysql.com/ProxySQL/proxysql-2.3.x/bullseye/"
suite: "./"
component: ""
gpg_key: "proxysql.asc"
debian-aarch64:
elasticsearch:
@ -123,6 +130,11 @@ debian-aarch64:
suite: "bullseye"
component: "contrib"
gpg_key: "treasuredata.asc"
proxysql:
url: "https://repo.proxysql.com/ProxySQL/proxysql-2.3.x/bullseye/"
suite: "./"
component: ""
gpg_key: "proxysql.asc"
ubuntu:
elasticsearch:
@ -175,6 +187,11 @@ ubuntu:
suite: "focal"
component: "contrib"
gpg_key: "treasuredata.asc"
proxysql:
url: "https://repo.proxysql.com/ProxySQL/proxysql-2.3.x/focal/"
suite: "./"
component: ""
gpg_key: "proxysql.asc"
ubuntu-aarch64:
elasticsearch:
@ -222,3 +239,8 @@ ubuntu-aarch64:
suite: "focal"
component: "contrib"
gpg_key: "treasuredata.asc"
proxysql:
url: "https://repo.proxysql.com/ProxySQL/proxysql-2.3.x/focal/"
suite: "./"
component: ""
gpg_key: "proxysql.asc"

View File

@ -0,0 +1,4 @@
---
features:
- Adds proxysql image. Proxysql provides
intelligent load balancing for databases.