Adding MariaDB
This commit is contained in:
21
mariadb/.helmignore
Normal file
21
mariadb/.helmignore
Normal file
@@ -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
|
||||||
4
mariadb/Chart.yaml
Normal file
4
mariadb/Chart.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
description: A helm chart for mariadb
|
||||||
|
name: mariadb
|
||||||
|
version: 0.1.0
|
||||||
2
mariadb/README.md
Normal file
2
mariadb/README.md
Normal file
@@ -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.
|
||||||
56
mariadb/templates/bootstrap-db.sh.yaml
Normal file
56
mariadb/templates/bootstrap-db.sh.yaml
Normal file
@@ -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
|
||||||
13
mariadb/templates/charsets.cnf.yaml
Normal file
13
mariadb/templates/charsets.cnf.yaml
Normal file
@@ -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
|
||||||
10
mariadb/templates/engine.cnf.yaml
Normal file
10
mariadb/templates/engine.cnf.yaml
Normal file
@@ -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
|
||||||
12
mariadb/templates/galera-my.cnf.yaml
Normal file
12
mariadb/templates/galera-my.cnf.yaml
Normal file
@@ -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/
|
||||||
17
mariadb/templates/log.cnf.yaml
Normal file
17
mariadb/templates/log.cnf.yaml
Normal file
@@ -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
|
||||||
133
mariadb/templates/mariadb-daemonset.yaml
Normal file
133
mariadb/templates/mariadb-daemonset.yaml
Normal file
@@ -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 }}
|
||||||
33
mariadb/templates/mariadb-readiness.py.yaml
Normal file
33
mariadb/templates/mariadb-readiness.py.yaml
Normal file
@@ -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
|
||||||
110
mariadb/templates/mariadb-seed-job.yaml
Normal file
110
mariadb/templates/mariadb-seed-job.yaml
Normal file
@@ -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
|
||||||
9
mariadb/templates/mariadb-service.yaml
Normal file
9
mariadb/templates/mariadb-service.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mariadb
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.network.port.mariadb }}
|
||||||
|
selector:
|
||||||
|
app: mariadb
|
||||||
20
mariadb/templates/networking.cnf.yaml
Normal file
20
mariadb/templates/networking.cnf.yaml
Normal file
@@ -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 }}
|
||||||
84
mariadb/templates/peer-finder.py.yaml
Normal file
84
mariadb/templates/peer-finder.py.yaml
Normal file
@@ -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()
|
||||||
8
mariadb/templates/pid.cnf.yaml
Normal file
8
mariadb/templates/pid.cnf.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: mariadb-pid
|
||||||
|
data:
|
||||||
|
pid.cnf: |+
|
||||||
|
[mysqld]
|
||||||
|
pid_file=/var/lib/mysql/mariadb.pid
|
||||||
46
mariadb/templates/replicas.py.yaml
Normal file
46
mariadb/templates/replicas.py.yaml
Normal file
@@ -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()
|
||||||
82
mariadb/templates/seed.sh.yaml
Normal file
82
mariadb/templates/seed.sh.yaml
Normal file
@@ -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
|
||||||
37
mariadb/templates/start.sh.yaml
Normal file
37
mariadb/templates/start.sh.yaml
Normal file
@@ -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
|
||||||
53
mariadb/templates/tuning.cnf.yaml
Normal file
53
mariadb/templates/tuning.cnf.yaml
Normal file
@@ -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
|
||||||
15
mariadb/templates/wsrep.cnf.yaml
Normal file
15
mariadb/templates/wsrep.cnf.yaml
Normal file
@@ -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 }}
|
||||||
14
mariadb/values.yaml
Normal file
14
mariadb/values.yaml
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user