diff --git a/mariadb/.helmignore b/mariadb/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/mariadb/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/mariadb/Chart.yaml b/mariadb/Chart.yaml new file mode 100644 index 0000000000..4cb81e13b7 --- /dev/null +++ b/mariadb/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: A helm chart for mariadb +name: mariadb +version: 0.1.0 diff --git a/mariadb/README.md b/mariadb/README.md new file mode 100644 index 0000000000..55eb3a4c3f --- /dev/null +++ b/mariadb/README.md @@ -0,0 +1,2 @@ +Please remember to label nodes with control_node_label from values.yaml +And remember that number of control nodes should be odd. diff --git a/mariadb/templates/bootstrap-db.sh.yaml b/mariadb/templates/bootstrap-db.sh.yaml new file mode 100644 index 0000000000..186fe18a19 --- /dev/null +++ b/mariadb/templates/bootstrap-db.sh.yaml @@ -0,0 +1,56 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: bootstrap-db +data: + bootstrap-db.sh: | + #!/bin/sh + + set -ex + + SLEEP_TIMEOUT=5 + + # Initialize system .Values.database. + mysql_install_db --datadir=/var/lib/mysql + + # Start mariadb and wait for it to be ready. + mysqld_safe --defaults-file=/etc/my.cnf \ + --console \ + --wsrep-new-cluster \ + --wsrep_cluster_address='gcomm://' \ + --bind-address='127.0.0.1' \ + --wsrep_node_address='127.0.0.1' \ + --wsrep_provider_options='gcache.size=512M; gmcast.listen_addr=tcp://127.0.0.1:{{ .Values.network.port.wsrep }}' & + + + TIMEOUT=120 + while [[ ! -f /var/lib/mysql/mariadb.pid ]]; do + if [[ ${TIMEOUT} -gt 0 ]]; then + let TIMEOUT-=1 + sleep 1 + else + exit 1 + fi + done + + # Reset permissions. + # kolla_security_reset requires to be run from home directory + cd /var/lib/mysql ; DB_ROOT_PASSWORD="{{ .Values.database.root_password }}" kolla_security_reset + + mysql -u root --password="{{ .Values.database.root_password }}" --port="{{ .Values.network.port.mariadb }}" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '{{ .Values.database.root_password }}' WITH GRANT OPTION;" + mysql -u root --password="{{ .Values.database.root_password }}" --port="{{ .Values.network.port.mariadb }}" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '{{ .Values.database.root_password }}' WITH GRANT OPTION;" + + # Restart .Values.database. + mysqladmin -uroot -p"{{ .Values.database.root_password }}" --port="{{ .Values.network.port.mariadb }}" shutdown + + # Wait for the mariadb server to shut down + SHUTDOWN_TIMEOUT=60 + while [[ -f /var/lib/mysql/mariadb.pid ]]; do + if [[ ${SHUTDOWN_TIMEOUT} -gt 0 ]]; then + let SHUTDOWN_TIMEOUT-=1 + sleep 1 + else + echo "MariaDB instance couldn't be properly shut down" + exit 1 + fi + done diff --git a/mariadb/templates/charsets.cnf.yaml b/mariadb/templates/charsets.cnf.yaml new file mode 100644 index 0000000000..a2c5c5d663 --- /dev/null +++ b/mariadb/templates/charsets.cnf.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-charsets +data: + charsets.cnf: |+ + [mysqld] + character_set_server=utf8 + collation_server=utf8_unicode_ci + skip-character-set-client-handshake + + [client] + default_character_set=utf8 diff --git a/mariadb/templates/engine.cnf.yaml b/mariadb/templates/engine.cnf.yaml new file mode 100644 index 0000000000..9660d7255a --- /dev/null +++ b/mariadb/templates/engine.cnf.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-engine +data: + engine.cnf: |+ + [mysqld] + default-storage-engine=InnoDB + innodb=FORCE + binlog_format=ROW diff --git a/mariadb/templates/galera-my.cnf.yaml b/mariadb/templates/galera-my.cnf.yaml new file mode 100644 index 0000000000..dab8819bde --- /dev/null +++ b/mariadb/templates/galera-my.cnf.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-mycnf +data: + my.cnf: |+ + [mysqld] + datadir=/var/lib/mysql + basedir=/usr + + [client-server] + !includedir /etc/my.cnf.d/ diff --git a/mariadb/templates/log.cnf.yaml b/mariadb/templates/log.cnf.yaml new file mode 100644 index 0000000000..4fca1214d7 --- /dev/null +++ b/mariadb/templates/log.cnf.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-log +data: + log.cnf: |+ + [mysqld] + slow_query_log=off + slow_query_log_file=/var/log/mysql/mariadb-slow.log + log_warnings=2 + + # General logging has huge performance penalty therefore is disabled by default + general_log=off + general_log_file=/var/log/mysql/mariadb-error.log + + long_query_time=3 + log_queries_not_using_indexes=on diff --git a/mariadb/templates/mariadb-daemonset.yaml b/mariadb/templates/mariadb-daemonset.yaml new file mode 100644 index 0000000000..772246d945 --- /dev/null +++ b/mariadb/templates/mariadb-daemonset.yaml @@ -0,0 +1,133 @@ +apiVersion: extensions/v1beta1 +kind: DaemonSet +metadata: + name: mariadb +spec: + selector: + matchLabels: + galera: enabled + template: + metadata: + labels: + app: mariadb + galera: enabled + spec: + nodeSelector: + {{ .Values.deployment.control_node_label }}: enabled + # TODO(DTadrzak): it must be removed in the future + securityContext: + runAsUser: 0 + containers: + - name: mariadb + image: {{ .Values.deployment.image }} + imagePullPolicy: Always + env: + - name: INTERFACE_NAME + value: "eth0" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: COMMAND + value: "bash /tmp/start.sh" + - name: DEPENDENCY_CONFIG + value: "/etc/my.cnf.d/wsrep.cnf" + ports: + - containerPort: {{ .Values.network.port.mariadb }} + readinessProbe: + exec: + command: + - python + - /mariadb-readiness.py + volumeMounts: + - name: mycnfd + mountPath: /etc/my.cnf.d + - name: startsh + mountPath: /tmp/start.sh + subPath: start.sh + - name: bootstrapdb + mountPath: /tmp/bootstrap-db.sh + subPath: bootstrap-db.sh + - name: peer-finder + mountPath: /tmp/peer-finder.py + subPath: peer-finder.py + - name: charsets + mountPath: /etc/my.cnf.d/charsets.cnf + subPath: charsets.cnf + - name: engine + mountPath: /etc/my.cnf.d/engine.cnf + subPath: engine.cnf + - name: log + mountPath: /etc/my.cnf.d/log.cnf + subPath: log.cnf + - name: mycnf + mountPath: /etc/my.cnf + subPath: my.cnf + - name: networking + mountPath: /etc/my.cnf.d/networking.cnf + subPath: networking.cnf + - name: pid + mountPath: /etc/my.cnf.d/pid.cnf + subPath: pid.cnf + - name: tuning + mountPath: /etc/my.cnf.d/tuning.cnf + subPath: tuning.cnf + - name: wsrep + mountPath: /configmaps/wsrep.cnf + - name: mysql + mountPath: /var/lib/mysql + - name: replicas + mountPath: /tmp/replicas.py + subPath: replicas.py + - name: readiness + mountPath: /mariadb-readiness.py + subPath: mariadb-readiness.py + volumes: + - name: mycnfd + emptyDir: {} + - name: startsh + configMap: + name: mariadb-startsh + - name: bootstrapdb + configMap: + name: bootstrap-db + - name: peer-finder + configMap: + name: mariadb-peer-finder + - name: charsets + configMap: + name: mariadb-charsets + - name: engine + configMap: + name: mariadb-engine + - name: log + configMap: + name: mariadb-log + - name: mycnf + configMap: + name: mariadb-mycnf + - name: networking + configMap: + name: mariadb-networking + - name: pid + configMap: + name: mariadb-pid + - name: tuning + configMap: + name: mariadb-tuning + - name: wsrep + configMap: + name: mariadb-wsrep + - name: replicas + configMap: + name: mariadb-replicas + - name: readiness + configMap: + name: mariadb-readiness + - name: mysql + hostPath: + path: /var/lib/mysql-openstack-{{ .Values.database.cluster_name }} diff --git a/mariadb/templates/mariadb-readiness.py.yaml b/mariadb/templates/mariadb-readiness.py.yaml new file mode 100644 index 0000000000..db85b5e2df --- /dev/null +++ b/mariadb/templates/mariadb-readiness.py.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-readiness +data: + mariadb-readiness.py: |+ + #!/usr/bin/env python + import os + import sys + import time + import pymysql + + DB_HOST = "127.0.0.1" + DB_PORT = int(os.environ.get('MARIADB_SERVICE_PORT', '3306')) + + while True: + try: + pymysql.connections.Connection(host=DB_HOST, port=DB_PORT, + connect_timeout=1) + sys.exit(0) + except pymysql.err.OperationalError as e: + code, message = e.args + + if code == 2003 and 'time out' in message: + print('Connection timeout, sleeping') + time.sleep(1) + continue + if code == 1045: + print('Mysql ready to use. Exiting') + sys.exit(0) + + # other error + raise diff --git a/mariadb/templates/mariadb-seed-job.yaml b/mariadb/templates/mariadb-seed-job.yaml new file mode 100644 index 0000000000..dfe026b6b0 --- /dev/null +++ b/mariadb/templates/mariadb-seed-job.yaml @@ -0,0 +1,110 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: mariadb-seed +spec: + template: + metadata: + labels: + app: mariadb + spec: + restartPolicy: Never + terminationGracePeriodSeconds: 10000 + containers: + - name: mariadb-init + image: {{ .Values.deployment.image }} + imagePullPolicy: Always + env: + - name: INTERFACE_NAME + value: "eth0" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: COMMAND + value: "bash /tmp/seed.sh" + - name: DEPENDENCY_CONFIG + value: "/etc/my.cnf.d/wsrep.cnf" + ports: + - containerPort: {{ .Values.network.port.mariadb }} + volumeMounts: + - name: mycnfd + mountPath: /etc/my.cnf.d + - name: seedsh + mountPath: /tmp/seed.sh + subPath: seed.sh + - name: bootstrapdb + mountPath: /tmp/bootstrap-db.sh + subPath: bootstrap-db.sh + - name: peer-finder + mountPath: /tmp/peer-finder.py + subPath: peer-finder.py + - name: charsets + mountPath: /etc/my.cnf.d/charsets.cnf + subPath: charsets.cnf + - name: engine + mountPath: /etc/my.cnf.d/engine.cnf + subPath: engine.cnf + - name: log + mountPath: /etc/my.cnf.d/log.cnf + subPath: log.cnf + - name: mycnf + mountPath: /etc/my.cnf + subPath: my.cnf + - name: networking + mountPath: /etc/my.cnf.d/networking.cnf + subPath: networking.cnf + - name: pid + mountPath: /etc/my.cnf.d/pid.cnf + subPath: pid.cnf + - name: tuning + mountPath: /etc/my.cnf.d/tuning.cnf + subPath: tuning.cnf + - name: wsrep + mountPath: /configmaps/wsrep.cnf + - name: replicas + mountPath: /tmp/replicas.py + subPath: replicas.py + volumes: + - name: mycnfd + emptyDir: {} + - name: seedsh + configMap: + name: mariadb-seedsh + - name: bootstrapdb + configMap: + name: bootstrap-db + - name: peer-finder + configMap: + name: mariadb-peer-finder + - name: charsets + configMap: + name: mariadb-charsets + - name: engine + configMap: + name: mariadb-engine + - name: log + configMap: + name: mariadb-log + - name: mycnf + configMap: + name: mariadb-mycnf + - name: networking + configMap: + name: mariadb-networking + - name: pid + configMap: + name: mariadb-pid + - name: tuning + configMap: + name: mariadb-tuning + - name: wsrep + configMap: + name: mariadb-wsrep + - name: replicas + configMap: + name: mariadb-replicas diff --git a/mariadb/templates/mariadb-service.yaml b/mariadb/templates/mariadb-service.yaml new file mode 100644 index 0000000000..5b3dae0490 --- /dev/null +++ b/mariadb/templates/mariadb-service.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Service +metadata: + name: mariadb +spec: + ports: + - port: {{ .Values.network.port.mariadb }} + selector: + app: mariadb diff --git a/mariadb/templates/networking.cnf.yaml b/mariadb/templates/networking.cnf.yaml new file mode 100644 index 0000000000..9f77533f45 --- /dev/null +++ b/mariadb/templates/networking.cnf.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-networking +data: + networking.cnf: |+ + [mysqld] + bind_address=0.0.0.0 + port={{ .Values.network.port.mariadb }} + + # When a client connects, the server will perform hostname resolution, + # and when DNS is slow, establishing the connection will become slow as well. + # It is therefore recommended to start the server with skip-name-resolve to + # disable all DNS lookups. The only limitation is that the GRANT statements + # must then use IP addresses only. + skip_name_resolve + + [client] + protocol=tcp + port={{ .Values.network.port.mariadb }} diff --git a/mariadb/templates/peer-finder.py.yaml b/mariadb/templates/peer-finder.py.yaml new file mode 100644 index 0000000000..e020c28c7f --- /dev/null +++ b/mariadb/templates/peer-finder.py.yaml @@ -0,0 +1,84 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-peer-finder +data: + peer-finder.py: |+ + import json + import os + import urllib2 + import ssl + import socket + import sys + import time + + + URL = ('https://kubernetes.default.svc.cluster.local/api/v1/namespaces/{namespace}' + '/endpoints/{service_name}') + TOKEN_FILE = '/var/run/secrets/kubernetes.io/serviceaccount/token' + + + def get_service_endpoints(service_name): + url = URL.format(namespace=os.environ['NAMESPACE'], service_name=service_name) + try: + token = file (TOKEN_FILE, 'r').read() + except KeyError: + exit("Unable to open a file with token.") + header = {'Authorization': " Bearer {}".format(token)} + req = urllib2.Request(url=url, headers=header) + + ctx = create_ctx() + connection = urllib2.urlopen(req, context=ctx) + data = connection.read() + + # parse to dict + json_acceptable_string = data.replace("'", "\"") + output = json.loads(json_acceptable_string) + + return output + + + def get_ip_addresses(output): + subsets = output['subsets'][0] + if not 'addresses' in subsets: + return [] + ip_addresses = [x['ip'] for x in subsets['addresses']] + my_ip = get_my_ip_address() + if my_ip in ip_addresses: + ip_addresses.remove(my_ip) + return ip_addresses + + + def get_my_ip_address(): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(('kubernetes.default.svc.cluster.local', 0)) + return s.getsockname()[0] + + + def create_ctx(): + ctx = ssl.create_default_context() + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE + return ctx + + + def print_galera_cluster_address(service_name): + while True: + output = get_service_endpoints(service_name) + if len(get_ip_addresses(output)): + wsrep_cluster_address = '--wsrep_cluster_address=gcomm://{}'.format( + ','.join(get_ip_addresses(output))) + print wsrep_cluster_address + break + time.sleep(5) + + + def main(): + if len(sys.argv) != 2: + exit('peer-finder: You need to pass argument') + service_name = sys.argv[1] + print_galera_cluster_address(service_name) + + + if __name__ == '__main__': + main() diff --git a/mariadb/templates/pid.cnf.yaml b/mariadb/templates/pid.cnf.yaml new file mode 100644 index 0000000000..ff638ed250 --- /dev/null +++ b/mariadb/templates/pid.cnf.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-pid +data: + pid.cnf: |+ + [mysqld] + pid_file=/var/lib/mysql/mariadb.pid diff --git a/mariadb/templates/replicas.py.yaml b/mariadb/templates/replicas.py.yaml new file mode 100644 index 0000000000..092f90586c --- /dev/null +++ b/mariadb/templates/replicas.py.yaml @@ -0,0 +1,46 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-replicas +data: + replicas.py: | + #!/usr/bin/env python + import json + import os + import ssl + import sys + import urllib2 + + URL = ('https://kubernetes.default.svc.{{ .Values.network.dns.kubernetes_domain }}/apis/extensions/v1beta1/daemonsets') + TOKEN_FILE = '/var/run/secrets/kubernetes.io/serviceaccount/token' + + def create_ctx(): + ctx = ssl.create_default_context() + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE + return ctx + + def get_daemonsets(): + url = URL.format() + try: + token = file(TOKEN_FILE, 'r').read() + except KeyError: + exit("Unable to open a file with token.") + header = {'Authorization': " Bearer {}".format(token)} + req = urllib2.Request(url=url, headers=header) + + ctx = create_ctx() + response = urllib2.urlopen(req, context=ctx) + output = json.load(response) + + return output + + def main(): + reply = get_daemonsets() + name = "mariadb" + namespace = "default" if not os.environ["NAMESPACE"] else os.environ["NAMESPACE"] + mariadb = filter(lambda d: d["metadata"]["namespace"] == namespace and d["metadata"]["name"] == name, reply["items"]) + print mariadb[0]["status"]['desiredNumberScheduled'] + + if __name__ == "__main__": + main() diff --git a/mariadb/templates/seed.sh.yaml b/mariadb/templates/seed.sh.yaml new file mode 100644 index 0000000000..0ec433b099 --- /dev/null +++ b/mariadb/templates/seed.sh.yaml @@ -0,0 +1,82 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-seedsh +data: + seed.sh: |+ + #!/bin/sh + + set -ex + + SLEEP_TIMEOUT=5 + + function wait_for_cluster { + + # Wait for the mariadb server to be "Ready" before starting the security reset with a max timeout + TIMEOUT=120 + while [[ ! -f /var/lib/mysql/mariadb.pid ]]; do + if [[ ${TIMEOUT} -gt 0 ]]; then + let TIMEOUT-=1 + sleep 1 + else + exit 1 + fi + done + + REPLICAS=$(python /tmp/replicas.py) + # We need to count seed instance here. + MINIMUM_CLUSTER_SIZE=$(( $REPLICAS + 1 )) + + # wait until we have at least two more members in a cluster. + while true ; do + CLUSTER_SIZE=`mysql -uroot -p"{{ .Values.database.root_password }}" --port="{{ .Values.network.port.mariadb }}" -e'show status' | grep wsrep_cluster_size | awk ' { if($2 ~ /[0-9]/){ print $2 } else { print 0 } } '` + if [ "${CLUSTER_SIZE}" -lt ${MINIMUM_CLUSTER_SIZE} ] ; then + echo "Cluster seed not finished, waiting." + sleep ${SLEEP_TIMEOUT} + continue + fi + CLUSTER_STATUS=`mysql -uroot -p"{{ .Values.database.root_password }}" --port="{{ .Values.network.port.mariadb }}" -e'show status' | grep wsrep_local_state_comment | awk ' { print $2 } '` + if [ "${CLUSTER_STATUS}" != "Synced" ] ; then + echo "Cluster not synced, waiting." + sleep ${SLEEP_TIMEOUT} + continue + fi + # Count number of endpoint separators. + ENDPOINTS_CNT=`python /tmp/peer-finder.py mariadb | grep -o ',' | wc -l` + # TODO(tomasz.paszkowski): Fix a corner case when only one endpoint is on the list. + # Add +1 for seed node and +1 as first item does not have a separator + ENDPOINTS_CNT=$(($ENDPOINTS_CNT+2)) + if [ "${ENDPOINTS_CNT}" != "${CLUSTER_SIZE}" ] ; then + echo "Cluster not synced, waiting." + sleep ${SLEEP_TIMEOUT} + continue + fi + echo "Cluster ready, exiting seed." + kill -- -$$ + break + done + } + + # With the DaemonSet implementation, there may be a difference + # in the number of replicas and actual number of nodes matching + # mariadb node selector label. Problem will be solved when + # the implementation will be switched to Deployment + # (using anti-affinity feature). + + REPLICAS=$(python /tmp/replicas.py) + + if [ "$REPLICAS" -eq 1 ] ; then + echo "Requested to build one-instance MariaDB cluster. There is no need to run seed. Exiting." + exit 0 + elif [ "$REPLICAS" -eq 2 ] ; then + echo "2-instance cluster is not a valid MariaDB configuration." + exit 1 + fi + + bash /tmp/bootstrap-db.sh + mysqld_safe --defaults-file=/etc/my.cnf \ + --console \ + --wsrep-new-cluster \ + --wsrep_cluster_address='gcomm://' & + wait_for_cluster + exit 0 diff --git a/mariadb/templates/start.sh.yaml b/mariadb/templates/start.sh.yaml new file mode 100644 index 0000000000..885dc1bc90 --- /dev/null +++ b/mariadb/templates/start.sh.yaml @@ -0,0 +1,37 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-startsh +data: + start.sh: |+ + #!/bin/bash + set -ex + trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT + + sudo chown mysql: /var/lib/mysql + + REPLICAS=$(python /tmp/replicas.py) + INIT_MARKER="/var/lib/mysql/init_done" + + # Remove mariadb.pid if exists + if [[ -f /var/lib/mysql/mariadb.pid ]]; then + if [[ `pgrep -c $(cat /var/lib/mysql/mariadb.pid)` -eq 0 ]]; then + rm -vf /var/lib/mysql/mariadb.pid + fi + fi + + if [ "$REPLICAS" -eq 1 ] ; then + if [[ ! -f ${INIT_MARKER} ]]; then + cd /var/lib/mysql + echo "Creating one-instance MariaDB." + bash /tmp/bootstrap-db.sh + touch ${INIT_MARKER} + fi + exec mysqld_safe --defaults-file=/etc/my.cnf \ + --console \ + --wsrep-new-cluster \ + --wsrep_cluster_address='gcomm://' + else + export WSREP_OPTIONS=`python /tmp/peer-finder.py mariadb` + exec mysqld --defaults-file=/etc/my.cnf --console $WSREP_OPTIONS + fi diff --git a/mariadb/templates/tuning.cnf.yaml b/mariadb/templates/tuning.cnf.yaml new file mode 100644 index 0000000000..83651675e2 --- /dev/null +++ b/mariadb/templates/tuning.cnf.yaml @@ -0,0 +1,53 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-tuning +data: + tuning.cnf: |+ + [mysqld] + user=mysql + max_allowed_packet=256M + open_files_limit=10240 + max_connections=8192 + max-connect-errors=1000000 + + ## Generally, it is unwise to set the query cache to be larger than 64-128M + ## as the costs associated with maintaining the cache outweigh the performance + ## gains. + ## The query cache is a well known bottleneck that can be seen even when + ## concurrency is moderate. The best option is to disable it from day 1 + ## by setting query_cache_size=0 (now the default on MySQL 5.6) + ## and to use other ways to speed up read queries: good indexing, adding + ## replicas to spread the read load or using an external cache. + query_cache_size =0 + query_cache_type=0 + + sync_binlog=0 + thread_cache_size=16 + table_open_cache=2048 + table_definition_cache=1024 + + # + # InnoDB + # + # The buffer pool is where data and indexes are cached: having it as large as possible + # will ensure you use memory and not disks for most read operations. + # Typical values are 50..75% of available RAM. + # TODO(tomasz.paszkowski): This needs to by dynamic based on avaliable RAM. + innodb_buffer_pool_size=4096M + innodb_log_file_size=2000M + innodb_flush_method=O_DIRECT + innodb_flush_log_at_trx_commit=2 + innodb_old_blocks_time=1000 + innodb_autoinc_lock_mode=2 + innodb_doublewrite=0 + innodb_file_format=Barracuda + innodb_file_per_table=1 + innodb_io_capacity=500 + innodb_locks_unsafe_for_binlog=1 + innodb_read_io_threads=8 + innodb_write_io_threads=8 + + + [mysqldump] + max-allowed-packet=16M diff --git a/mariadb/templates/wsrep.cnf.yaml b/mariadb/templates/wsrep.cnf.yaml new file mode 100644 index 0000000000..97bbb444a1 --- /dev/null +++ b/mariadb/templates/wsrep.cnf.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mariadb-wsrep +data: + wsrep.cnf: |+ + [mysqld] + wsrep_cluster_name="{{ .Values.database.cluster_name }}" + wsrep_provider=/usr/lib/galera/libgalera_smm.so + wsrep_provider_options="gcache.size=512M" + wsrep_slave_threads=12 + wsrep_sst_auth=root:{{ .Values.database.root_password }} + wsrep_sst_method=xtrabackup-v2 + wsrep_node_name={{ .Values.database.node_name }} + wsrep_node_address={{ .Values.network.ip_address }}:{{ .Values.network.port.wsrep }} diff --git a/mariadb/values.yaml b/mariadb/values.yaml new file mode 100644 index 0000000000..dd624dedb8 --- /dev/null +++ b/mariadb/values.yaml @@ -0,0 +1,14 @@ +deployment: + image: quay.io/stackanetes/stackanetes-mariadb:newton + control_node_label: openstack-control-plane +network: + port: + wsrep: 4567 + mariadb: 3306 + dns: + kubernetes_domain: cluster.local + ip_address: "{{ .IP }}" +database: + root_password: password + cluster_name: mariadb + node_name: master