Compare commits
2 Commits
78ea6b1f46
...
2cd70a52bb
Author | SHA1 | Date |
---|---|---|
Daniel Berteaud | 2cd70a52bb | |
Daniel Berteaud | 6fdd883d32 |
|
@ -0,0 +1,2 @@
|
|||
# mariadb
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
Kind = "service-intentions"
|
||||
Name = "mariadb"
|
||||
Sources = [
|
||||
{
|
||||
Name = "traefik"
|
||||
Action = "allow"
|
||||
},
|
||||
{
|
||||
Name = "mariadb-manage"
|
||||
Action = "allow"
|
||||
},
|
||||
{
|
||||
Name = "mariadb-backup"
|
||||
Action = "allow"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
FROM danielberteaud/mariadb-client:24.1-1
|
||||
MAINTAINER Daniel Berteaud <dbd@ehtrace.com>
|
||||
|
||||
RUN set -eux &&\
|
||||
apk --no-cache update &&\
|
||||
apk --no-cache add supercronic
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
FROM danielberteaud/mariadb-client:24.1-1
|
||||
MAINTAINER Daniel Berteaud <dbd@ehtrace.com>
|
||||
|
||||
ENV MYSQL_CONF_10_section=mysqld \
|
||||
MYSQL_CONF_11_innodb_buffer_pool_size=50%
|
||||
|
||||
RUN set -eux &&\
|
||||
apk --no-cache upgrade &&\
|
||||
apk --no-cache add mariadb mariadb-server-utils &&\
|
||||
chown mysql:mysql /etc/my.cnf.d &&\
|
||||
rm -f /etc/my.cnf.d/* &&\
|
||||
mkdir /data /run/mysqld &&\
|
||||
chown mysql:mysql /data /run/mysqld &&\
|
||||
chmod 700 /data
|
||||
|
||||
COPY root/ /
|
||||
|
||||
EXPOSE 3306
|
||||
USER mysql
|
||||
CMD ["mariadbd", "--console", "--skip-name-resolve"]
|
|
@ -0,0 +1,44 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
get_max_mem(){
|
||||
if [ -e /sys/fs/cgroup/memory.max ]; then
|
||||
# Read /sys/fs/cgroup/memory.max
|
||||
MAX=$(cat /sys/fs/cgroup/memory.max)
|
||||
# If it's "max", then the container has no limit, and we must detect the available RAM
|
||||
if [ "${MAX}" = "max" ]; then
|
||||
echo $(($(cat /proc/meminfo | grep MemTotal | sed -E 's/MemTotal:\s+([0-9]+)\s+kB/\1/')/1024))
|
||||
else
|
||||
echo $(($(cat /sys/fs/cgroup/memory.max)/1024/1024))
|
||||
fi
|
||||
else
|
||||
echo $(($(cat /proc/meminfo | grep MemTotal | sed -E 's/MemTotal:\s+([0-9]+)\s+kB/\1/')/1024))
|
||||
fi
|
||||
}
|
||||
|
||||
if mount | grep -q ' /etc/my.cnf '; then
|
||||
echo "/etc/my.cnf is mounted, skiping config from env vars"
|
||||
else
|
||||
echo "Configuring from env vars"
|
||||
for VAR in $(printenv | grep -E '^MYSQL_CONF_' | sed -E 's/MYSQL_CONF_([^=]+)=.*/\1/' | sort -V); do
|
||||
DIRECTIVE=$(echo ${VAR} | sed -E 's/^[0-9]+_//')
|
||||
VALUE=$(printenv MYSQL_CONF_${VAR})
|
||||
|
||||
if [ "${DIRECTIVE}" = "section" ]; then
|
||||
echo "[${VALUE}]" >> /etc/my.cnf.d/env.cnf
|
||||
else
|
||||
|
||||
# Allow some memory related settings to be expressed as a %
|
||||
if echo ${DIRECTIVE} | grep -q -E "^(innodb_buffer_pool_size)$"; then
|
||||
if echo ${VALUE} | grep -q -E "[0-9]+%$"; then
|
||||
PERCENT=$(echo $VALUE | sed -E 's|%$||')
|
||||
MAX_MEM=$(get_max_mem)
|
||||
VALUE=$((${MAX_MEM}*${PERCENT}/100))MB
|
||||
fi
|
||||
fi
|
||||
echo "Adding ${DIRECTIVE} = ${VALUE} in /etc/my.cnf.d/env.cnf"
|
||||
echo "${DIRECTIVE} = ${VALUE}" >> /etc/my.cnf.d/env.cnf
|
||||
fi
|
||||
done
|
||||
fi
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
mkdir -p /data/db
|
||||
|
||||
if [ -d /data/db/mysql ]; then
|
||||
echo "MariaDB is already initialized"
|
||||
else
|
||||
echo "Bootstraping MariaDB"
|
||||
|
||||
mysql_install_db
|
||||
|
||||
MYSQL_DATABASE=${MYSQL_DATABASE:-""}
|
||||
MYSQL_USER=${MYSQL_USER:-""}
|
||||
MYSQL_PASSWORD=${MYSQL_PASSWORD:-""}
|
||||
|
||||
cat << EOF > /tmp/mariainit.sql
|
||||
USE mysql;
|
||||
FLUSH PRIVILEGES;
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' identified by '$MYSQL_ROOT_PASSWORD' WITH GRANT OPTION;
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' identified by '$MYSQL_ROOT_PASSWORD' WITH GRANT OPTION;
|
||||
DROP DATABASE test;
|
||||
EOF
|
||||
if [ "$MYSQL_DATABASE" != "" ]; then
|
||||
echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` CHARACTER SET utf8 COLLATE utf8_general_ci;" >> $tfile
|
||||
|
||||
if [ "$MYSQL_USER" != "" ]; then
|
||||
echo "GRANT ALL ON \`$MYSQL_DATABASE\`.* to '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD';" >> $tfile
|
||||
fi
|
||||
fi
|
||||
|
||||
mariadbd --bootstrap --verbose=0 --skip-name-resolve < /tmp/mariainit.sql
|
||||
rm -f /tmp/mariainit.sql
|
||||
|
||||
fi
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
[client-server]
|
||||
port = 3306
|
||||
socket = /run/mysqld/mysqld.sock
|
||||
|
||||
[mysqld]
|
||||
pid-file = /tmp/mysql.pid
|
||||
symbolic-links = 0
|
||||
datadir = /data/db
|
||||
default_storage_engine = InnoDB
|
||||
innodb_log_file_size = 512M
|
||||
|
||||
!includedir /etc/my.cnf.d
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [ "$(vault secrets list -format json | jq -r '.["database/"].type')" != "database" ]; then
|
||||
vault secrets enable -path database database
|
||||
fi
|
||||
|
||||
if [ "$(vault list -format json database/config | jq '.[] | test("^mariadb$")')" = "false" ]; then
|
||||
vault write database/config/mariadb \
|
||||
plugin_name="mysql-database-plugin" \
|
||||
connection_url="{{username}}:{{password}}@tcp(mariadb.example.org:3306)/" \
|
||||
allowed_roles="*" \
|
||||
username=vault \
|
||||
password="$(vault kv get -field vault_initial_pwd kv/service/mariadb)" \
|
||||
disable_escaping=true
|
||||
vault write -force database/rotate-root/mariadb
|
||||
fi
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
job "mariadb-manage" {
|
||||
type = "batch"
|
||||
|
||||
datacenters = ["dc1"]
|
||||
|
||||
|
||||
meta {
|
||||
# Force job to run each time
|
||||
run = "${uuidv4()}"
|
||||
}
|
||||
|
||||
group "manage" {
|
||||
network {
|
||||
mode = "bridge"
|
||||
}
|
||||
|
||||
service {
|
||||
name = "mariadb-manage"
|
||||
connect {
|
||||
sidecar_service {
|
||||
proxy {
|
||||
upstreams {
|
||||
destination_name = "mariadb"
|
||||
local_bind_port = 3306
|
||||
}
|
||||
}
|
||||
}
|
||||
sidecar_task {
|
||||
resources {
|
||||
cpu = 50
|
||||
memory = 64
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# wait for required services tp be ready before starting the main task
|
||||
task "wait-for" {
|
||||
|
||||
driver = "docker"
|
||||
user = 1053
|
||||
|
||||
config {
|
||||
image = "danielberteaud/wait-for:24.1-1"
|
||||
readonly_rootfs = true
|
||||
pids_limit = 20
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
hook = "prestart"
|
||||
}
|
||||
|
||||
env {
|
||||
SERVICE_0 = "mariadb.service.consul"
|
||||
}
|
||||
|
||||
resources {
|
||||
cpu = 10
|
||||
memory = 10
|
||||
memory_max = 30
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
task "manage" {
|
||||
driver = "docker"
|
||||
|
||||
config {
|
||||
image = "danielberteaud/mariadb-client:24.1-1"
|
||||
pids_limit = 50
|
||||
readonly_rootfs = true
|
||||
command = "/local/manage.sh"
|
||||
volumes = [
|
||||
"secrets/my.cnf:/root/.my.cnf:ro"
|
||||
]
|
||||
}
|
||||
|
||||
vault {
|
||||
policies = ["mariadb"]
|
||||
}
|
||||
|
||||
env {
|
||||
|
||||
LANG = "fr_FR.utf8"
|
||||
TZ = "Europe/Paris"
|
||||
|
||||
}
|
||||
|
||||
template {
|
||||
data = <<_EOT
|
||||
# Databases
|
||||
# Users
|
||||
_EOT
|
||||
destination = "secrets/userdb.env"
|
||||
uid = 100000
|
||||
gid = 100000
|
||||
perms = 0400
|
||||
env = true
|
||||
}
|
||||
|
||||
template {
|
||||
data = <<_EOT
|
||||
#!/bin/sh
|
||||
|
||||
# vim: syntax=sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "Create vault user"
|
||||
mysql <<_EOSQL
|
||||
CREATE USER IF NOT EXISTS 'vault'@'%' IDENTIFIED BY '${VAULT_INITIAL_PASSWORD}';
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'vault'@'%' WITH GRANT OPTION;
|
||||
_EOSQL
|
||||
|
||||
echo "Create databases"
|
||||
for IDX in $(printenv | grep -E '^MY_DB_([0-9]+)=' | sed -E 's/^MY_DB_([0-9]+)=.*/\1/'); do
|
||||
DB_NAME=$(printenv MY_DB_${IDX})
|
||||
echo "Found DB ${DB_NAME} to create"
|
||||
DB_CHARSET=$(printenv MY_DB_${IDX}_CHARSET || echo "utf8mb4")
|
||||
DB_COLLATE=$(printenv MY_DB_${IDX}_COLLATE || echo "utf8mb4_general_ci")
|
||||
echo "Create database ${DB_NAME} (CHARACTER SET \"${DB_CHARSET}\" COLLATE \"${DB_COLLATE}\") if needed"
|
||||
mysql <<_EOSQL
|
||||
CREATE DATABASE IF NOT EXISTS ${DB_NAME} CHARACTER SET "${DB_CHARSET}" COLLATE "${DB_COLLATE}"
|
||||
_EOSQL
|
||||
done
|
||||
|
||||
echo "Create users"
|
||||
for IDX in $(printenv | grep -E '^MY_USER_([0-9]+)=' | sed -E 's/^MY_USER_([0-9]+)=.*/\1/'); do
|
||||
DB_USER=$(printenv MY_USER_${IDX})
|
||||
echo "Found DB User ${DB_USER} to create"
|
||||
DB_HOST=$(printenv MY_USER_${IDX}_HOST || echo '%')
|
||||
DB_PASSWORD=$(printenv MY_USER_${IDX}_PASSWORD || echo '')
|
||||
if [ "${DB_PASSWORD}" = "" ]; then
|
||||
mysql <<_EOSQL
|
||||
CREATE USER IF NOT EXISTS '${DB_USER}'@'${DB_HOST}';
|
||||
_EOSQL
|
||||
else
|
||||
mysql <<_EOSQL
|
||||
CREATE USER IF NOT EXISTS '${DB_USER}'@'${DB_HOST}' IDENTIFIED BY '${DB_PASSWORD}';
|
||||
_EOSQL
|
||||
fi
|
||||
|
||||
echo "Applying grants for ${DB_USER}"
|
||||
for GRANT in $(printenv | grep -E "^MY_USER_${IDX}_GRANT_([0-9]+)=)" | sed -E "s/^MY_USER_${IDX}_GRANT_([0-9]+)=.*/\1/"); do
|
||||
mysql <<_EOSQL
|
||||
GRANT $(printenv MY_USER_${IDX}_GRANT_${GRANT});
|
||||
_EOSQL
|
||||
done
|
||||
done
|
||||
|
||||
_EOT
|
||||
destination = "local/manage.sh"
|
||||
uid = 100000
|
||||
gid = 100000
|
||||
perms = 755
|
||||
}
|
||||
|
||||
template {
|
||||
data = <<_EOT
|
||||
[client]
|
||||
host = 127.0.0.1
|
||||
user = root
|
||||
password = {{ with secret "kv/service/mariadb" }}{{ .Data.data.root_pwd }}{{ end }}
|
||||
_EOT
|
||||
destination = "secrets/my.cnf"
|
||||
uid = 100100
|
||||
gid = 100101
|
||||
perms = 640
|
||||
}
|
||||
|
||||
template {
|
||||
data = <<_EOT
|
||||
{{ with secret "kv/service/mariadb" }}
|
||||
VAULT_INITIAL_PASSWORD={{ .Data.data.vault_initial_pwd }}
|
||||
BACKUP_PASSWORD={{ .Data.data.backup_pwd }}
|
||||
{{ end }}
|
||||
_EOT
|
||||
destination = "secrets/manage.env"
|
||||
uid = 100000
|
||||
gid = 100000
|
||||
perms = 400
|
||||
env = true
|
||||
}
|
||||
|
||||
resources {
|
||||
cpu = 20
|
||||
memory = 64
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
job "mariadb" {
|
||||
|
||||
|
||||
datacenters = ["dc1"]
|
||||
|
||||
|
||||
group "server" {
|
||||
|
||||
network {
|
||||
mode = "bridge"
|
||||
}
|
||||
|
||||
volume "mariadb" {
|
||||
type = "csi"
|
||||
source = "mariadb-data"
|
||||
access_mode = "single-node-writer"
|
||||
attachment_mode = "file-system"
|
||||
per_alloc = true
|
||||
}
|
||||
|
||||
service {
|
||||
name = "mariadb"
|
||||
port = 3306
|
||||
|
||||
connect {
|
||||
sidecar_service {
|
||||
disable_default_tcp_check = true
|
||||
}
|
||||
sidecar_task {
|
||||
resources {
|
||||
cpu = 50
|
||||
memory = 64
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
check {
|
||||
name = "alive"
|
||||
type = "script"
|
||||
task = "mariadb"
|
||||
command = "mysqladmin"
|
||||
args = [
|
||||
"ping"
|
||||
]
|
||||
timeout = "10s"
|
||||
interval = "5s"
|
||||
}
|
||||
}
|
||||
|
||||
# Run mysql_upgrade
|
||||
task "upgrade" {
|
||||
driver = "docker"
|
||||
|
||||
lifecycle {
|
||||
hook = "poststart"
|
||||
}
|
||||
|
||||
config {
|
||||
image = "danielberteaud/mariadb:24.1-1"
|
||||
pids_limit = 100
|
||||
command = "/local/mysql_upgrade.sh"
|
||||
}
|
||||
|
||||
vault {
|
||||
policies = ["mariadb"]
|
||||
env = false
|
||||
disable_file = true
|
||||
}
|
||||
|
||||
template {
|
||||
data = <<_EOT
|
||||
[client]
|
||||
user = root
|
||||
host = 127.0.0.1
|
||||
password = {{ with secret "kv/service/mariadb" }}{{ .Data.data.root_pwd }}{{ end }}
|
||||
_EOT
|
||||
destination = "secrets/.my.cnf"
|
||||
uid = 100100
|
||||
gid = 100101
|
||||
perms = 640
|
||||
}
|
||||
|
||||
template {
|
||||
data = <<_EOT
|
||||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
HOME=/secrets
|
||||
|
||||
COUNT=0
|
||||
while true; do
|
||||
if mysqladmin ping; then
|
||||
echo "MariaDB is ready, running mysql_upgrade"
|
||||
mysql_upgrade
|
||||
exit 0
|
||||
fi
|
||||
echo "MariaDB not ready yet, waiting a bit more"
|
||||
COUNT=$((COUNT+1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
|
||||
_EOT
|
||||
destination = "local/mysql_upgrade.sh"
|
||||
perms = 755
|
||||
}
|
||||
|
||||
volume_mount {
|
||||
volume = "mariadb"
|
||||
destination = "/data"
|
||||
}
|
||||
|
||||
resources {
|
||||
cpu = 10
|
||||
memory = 32
|
||||
memory_max = 64
|
||||
}
|
||||
}
|
||||
|
||||
task "mariadb" {
|
||||
driver = "docker"
|
||||
leader = true
|
||||
|
||||
kill_timeout = "5m"
|
||||
|
||||
config {
|
||||
image = "danielberteaud/mariadb:24.1-1"
|
||||
volumes = [
|
||||
"secrets/:/etc/my.cnf.d",
|
||||
"secrets/my.conf:/var/lib/mysql/.my.cnf:ro",
|
||||
]
|
||||
pids_limit = 300
|
||||
#readonly_rootfs = true
|
||||
}
|
||||
|
||||
vault {
|
||||
policies = ["mariadb"]
|
||||
env = false
|
||||
disable_file = true
|
||||
}
|
||||
|
||||
env {
|
||||
MYSQL_CONF_11_bind-address = "127.0.0.1"
|
||||
|
||||
LANG = "fr_FR.utf8"
|
||||
TZ = "Europe/Paris"
|
||||
|
||||
}
|
||||
|
||||
template {
|
||||
data = <<_EOT
|
||||
{{ with secret "kv/service/mariadb" }}
|
||||
MYSQL_ROOT_PASSWORD={{ .Data.data.root_pwd }}
|
||||
{{ end }}
|
||||
_EOT
|
||||
destination = "secrets/mariadb.env"
|
||||
uid = 100000
|
||||
gid = 100000
|
||||
perms = 400
|
||||
env = true
|
||||
}
|
||||
|
||||
template {
|
||||
data = <<_EOT
|
||||
[client]
|
||||
user = root
|
||||
password = {{ with secret "kv/service/mariadb" }}{{ .Data.data.root_pwd }}{{ end }}
|
||||
_EOT
|
||||
destination = "secrets/my.conf"
|
||||
uid = 100100
|
||||
gid = 100101
|
||||
perms = 640
|
||||
}
|
||||
|
||||
volume_mount {
|
||||
volume = "mariadb"
|
||||
destination = "/data"
|
||||
}
|
||||
|
||||
resources {
|
||||
cpu = 1000
|
||||
memory = 512
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if ! vault kv list kv/service 2>/dev/null | grep -q -E '^mariadb$'; then
|
||||
vault kv put kv/service/mariadb \
|
||||
root_pwd=$(pwgen -s -n 50 1) \
|
||||
vault_initial_pwd=$(pwgen -s -n 50 1)
|
||||
fi
|
||||
|
||||
for PWD in root_pwd vault_initial_pwd; do
|
||||
if ! vault kv get -field ${PWD} kv/service/mariadb >/dev/null 2>&1; then
|
||||
vault kv patch kv/service/mariadb \
|
||||
${PWD}=$(pwgen -s -n 50 1)
|
||||
fi
|
||||
done
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
|
||||
|
||||
if [ "mariadb" != "mariadb" ]; then
|
||||
for DIR in vault consul nomad; do
|
||||
if [ -d output/${DIR} ]; then
|
||||
for FILE in $(find output/${DIR} -name "*mariadb*.hcl" -type f); do
|
||||
NEW_FILE=$(echo "${FILE}" | sed -E "s/mariadb/mariadb/g")
|
||||
mv "${FILE}" "${NEW_FILE}"
|
||||
done
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
path "kv/data/service/mariadb" {
|
||||
capabilities = ["read"]
|
||||
}
|
|
@ -9,7 +9,7 @@ mariadb:
|
|||
server:
|
||||
|
||||
# The image to use
|
||||
image: '[[ .docker.repo ]]mariadb:23.12-1'
|
||||
image: '[[ .docker.repo ]]mariadb:24.1-1'
|
||||
|
||||
# Resource allocation
|
||||
resources:
|
||||
|
@ -85,7 +85,7 @@ mariadb:
|
|||
|
||||
# Backup service, which can create regular dumps of the databases
|
||||
backup:
|
||||
image: '[[ .docker.repo ]]mariadb-backup:23.12-1'
|
||||
image: '[[ .docker.repo ]]mariadb-backup:24.1-1'
|
||||
|
||||
# Resource allocation
|
||||
resources:
|
||||
|
|
Loading…
Reference in New Issue