diff options
| author | Michal Arbet <michal.arbet@ultimum.io> | 2021-01-05 16:32:06 +0100 |
|---|---|---|
| committer | Michal Arbet <michal.arbet@ultimum.io> | 2021-09-16 19:23:10 +0200 |
| commit | febbb5b40b88173f7167b384697617330a46bdea (patch) | |
| tree | f2288e49326c105a2d554394086b32806a114343 /docker | |
| parent | f98ad9462b7bd70ba79e448f97c7d3b21cf5e14b (diff) | |
| download | kolla-febbb5b40b88173f7167b384697617330a46bdea.tar.gz kolla-febbb5b40b88173f7167b384697617330a46bdea.zip | |
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
Diffstat (limited to 'docker')
| -rw-r--r-- | docker/base/Dockerfile.j2 | 5 | ||||
| -rw-r--r-- | docker/base/proxysql.repo | 6 | ||||
| -rw-r--r-- | docker/proxysql/Dockerfile.j2 | 35 | ||||
| -rw-r--r-- | docker/proxysql/kolla_extend_start | 34 | ||||
| -rw-r--r-- | docker/proxysql/kolla_proxysql_config_sync | 152 | ||||
| -rw-r--r-- | docker/proxysql/kolla_proxysql_start | 9 |
6 files changed, 241 insertions, 0 deletions
diff --git a/docker/base/Dockerfile.j2 b/docker/base/Dockerfile.j2 index b6344b37d..44afb8aa8 100644 --- a/docker/base/Dockerfile.j2 +++ b/docker/base/Dockerfile.j2 @@ -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'}, ] %} diff --git a/docker/base/proxysql.repo b/docker/base/proxysql.repo new file mode 100644 index 000000000..70bc14d96 --- /dev/null +++ b/docker/base/proxysql.repo @@ -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 diff --git a/docker/proxysql/Dockerfile.j2 b/docker/proxysql/Dockerfile.j2 new file mode 100644 index 000000000..4e8e3ca7c --- /dev/null +++ b/docker/proxysql/Dockerfile.j2 @@ -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 %} diff --git a/docker/proxysql/kolla_extend_start b/docker/proxysql/kolla_extend_start new file mode 100644 index 000000000..d7d20cb8d --- /dev/null +++ b/docker/proxysql/kolla_extend_start @@ -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 diff --git a/docker/proxysql/kolla_proxysql_config_sync b/docker/proxysql/kolla_proxysql_config_sync new file mode 100644 index 000000000..956f69188 --- /dev/null +++ b/docker/proxysql/kolla_proxysql_config_sync @@ -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() diff --git a/docker/proxysql/kolla_proxysql_start b/docker/proxysql/kolla_proxysql_start new file mode 100644 index 000000000..f24ee732a --- /dev/null +++ b/docker/proxysql/kolla_proxysql_start @@ -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 |
