Skip to content
This repository has been archived by the owner on Feb 22, 2022. It is now read-only.

[incubator/percona-xtradb-cluster] New Chart! #2995

Merged
merged 7 commits into from
Feb 2, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions incubator/percona-xtradb-cluster/.helmignore
Original file line number Diff line number Diff line change
@@ -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
21 changes: 21 additions & 0 deletions incubator/percona-xtradb-cluster/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: percona-xtradb-cluster
version: 0.0.1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add appVersion

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

description: free, fully compatible, enhanced, open source drop-in replacement for
MySQL with Galera Replication (xtradb)
keywords:
- mysql
- percona
- database
- sql
- xtradb
- galera
- wsrep
home: https://www.percona.com/
icon: https://www.percona.com/sites/all/themes/percona2015/logo.png
sources:
- https://github.com/kubernetes/charts
- https://github.com/percona-lab/percona-docker/
maintainers:
- name: Paul Czarkowski
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Github username

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

email: username.taken@gmail.com
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup 😆

engine: gotpl
102 changes: 102 additions & 0 deletions incubator/percona-xtradb-cluster/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Percona XtraDB Cluster

[Percona Server](https://MySQL.org) for MySQL® is a free, fully compatible, enhanced, open source drop-in replacement for MySQL that provides superior performance, scalability and instrumentation. With over 3,000,000 downloads, Percona Server for MySQL's self-tuning algorithms and support for extremely high-performance hardware delivers excellent performance and reliability.

Notable users include Netflix, Amazon Web Services, Alcatel-Lucent, and Smug Mug.

## Introduction

This chart, based off of the Percona chart (which in turn is based off the MySQL chart), bootstraps a multi-node Percona XtraDB Cluster deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.

The chart exploits the deterministic nature of StatefulSet and KubeDNS to ensure the cluster bootstrap is performed in the correct order.

## Prerequisites

- Kubernetes 1.8+ with Beta APIs enabled
- PV provisioner support in the underlying infrastructure

## Installing the Chart

To install the chart with the release name `my-release`:

```bash
$ helm install --name my-release incubator/percona-xtradb-cluster
```

The command deploys Percona Server on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.

The root password can only be used inside each `pod`. You should set a default `mysqlDatabase`, `mysqlUser` and `mysqlPassword` in the values.yaml file.

By default an **insecure** password will be generated for the root and replication users. If you'd like to set your own password change the `mysqlRootPassword` or `xtraBackupPassword` respectively
in the values.yaml.

You can retrieve your root password (usable only via localhost in each pod) by running the following command. Make sure to replace [YOUR_RELEASE_NAME]:

printf $(printf '\%o' `kubectl get secret [YOUR_RELEASE_NAME]-percona -o jsonpath="{.data.mysql-root-password[*]}"`)

> **Tip**: List all releases using `helm list`

## Uninstalling the Chart

To uninstall/delete the `my-release` deployment:

```bash
$ helm delete my-release
```

The command removes all the Kubernetes components associated with the chart and deletes the release.

## Configuration

The following tables lists the configurable parameters of the Percona chart and their default values.

| Parameter | Description | Default |
| ----------------------- | ---------------------------------- | ---------------------------------------------------------- |
| `image.repository` | `percona-xtradb-cluster` image Repo. | 5.7.19 release |
| `image.tag` | `percona-xtradb-cluster` image tag. | `percona/percona-xtradb-cluster` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent`
| `replicas` | Number of pods to join the Percona XtraDB Cluster | 3 |
| `mysqlRootPassword` | Password for the `root` user. | `not-a-secure-password` |
| `xtraBackupPassword` | Password for the `xtrabackup` user. | `replicate-my-data` |
| `mysqlUser` | Username of new user to create. | `nil` |
| `mysqlPassword` | Password for the new user. | `nil` |
| `mysqlDatabase` | Name for new database to create. | `nil` |
| `persistence.enabled` | Create a volume to store data | false |
| `persistence.size` | Size of persistent volume claim | 8Gi RW |
| `persistence.storageClass` | Type of persistent volume claim | nil (uses alpha storage class annotation) |
| `persistence.accessMode` | ReadWriteOnce or ReadOnly | ReadWriteOnce |
| `resources` | CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `100m` |
| `configFiles` | files to write to /etc/mysql/conf.d | see values.yaml |
| `logTail` | if set to true runs a container to tail /var/log/mysqld.log in the pod | true |
| `metricsExporter` | if set to true runs a [mysql metrics exporter](https://github.com/prometheus/mysqld_exporter) container in the pod | false |


Some of the parameters above map to the env variables defined in the [Percona Server DockerHub image](https://hub.docker.com/_/percona/).

Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,

```bash
$ helm install --name my-release \
--set mysqlRootPassword=secretpassword,mysqlUser=my-user,mysqlPassword=my-password,mysqlDatabase=my-database \
stable/percona
```

The above command sets the MySQL `root` account password to `secretpassword`. Additionally it creates a standard database user named `my-user`, with the password `my-password`, who has access to a database named `my-database`.

Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,

```bash
$ helm install --name my-release -f values.yaml stable/percona
```

> **Tip**: You can use the default [values.yaml](values.yaml)

## Persistence

The [Percona Server](https://hub.docker.com/_/percona/) image stores the MySQL data and configurations at the `/var/lib/mysql` path of the container.

By default, an emptyDir volume is mounted at that location.

> *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."*

You can change the values.yaml to enable persistence and use a PersistentVolumeClaim instead.
35 changes: 35 additions & 0 deletions incubator/percona-xtradb-cluster/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Percona can be accessed via port 3306 on the following DNS name from within your cluster:
{{ template "percona-xtradb-cluster.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local

To get your root password run (this password can only be used from inside the container):

$ kubectl get secret --namespace {{ .Release.Namespace }} {{ template "percona-xtradb-cluster.fullname" . }} -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo

To get your xtradb backup password run:

$ kubectl get secret --namespace {{ .Release.Namespace }} {{ template "percona-xtradb-cluster.fullname" . }} -o jsonpath="{.data.xtrabackup-password}" | base64 --decode; echo

To check the size of the xtradb cluster:

$ kubectl exec --namespace {{ .Release.Namespace }} -ti {{ template "percona-xtradb-cluster.fullname" . }}-0 -c database -- mysql -e "SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size'"

To connect to your database:

1. Run a command in the first pod in the StatefulSet:

$ kubectl exec --namespace {{ .Release.Namespace }} -ti {{ template "percona-xtradb-cluster.fullname" . }}-0 -c database -- mysql

{{- if .Values.mysqlUser }}{{ if .Values.mysqlPassword }}{{ if .Values.mysqlDatabase }}

2. Run a percona pod that you can use as a client:

$ kubectl run -i --tty --rm percona-client --image=percona:5.7 --restart=Never -- mysql -h {{ template "percona-xtradb-cluster.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local -u{{ .Values.mysqlUser }} \
-p$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "percona-xtradb-cluster.fullname" . }} -o jsonpath="{.data.mysql-password}" | base64 --decode; echo) \
{{ .Values.mysqlDatabase }}
{{ end }}{{ end }}{{ end }}

{{- if .Values.logTail }}
To view your Percona XtraDB Cluster logs run:

$ kubectl logs -f {{ template "percona-xtradb-cluster.fullname" . }}-0 logs
{{ end }}
17 changes: 17 additions & 0 deletions incubator/percona-xtradb-cluster/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "percona-xtradb-cluster.name" -}}
{{- default "pxc" .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "percona-xtradb-cluster.fullname" -}}
{{- $name := default "pxc" .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: {{ template "percona-xtradb-cluster.fullname" . }}-config-files
labels:
app: {{ template "percona-xtradb-cluster.fullname" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
data:
{{ toYaml .Values.configFiles | indent 2 }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: {{ template "percona-xtradb-cluster.fullname" . }}-startup-scripts
labels:
app: {{ template "percona-xtradb-cluster.fullname" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
data:
entrypoint.sh: |+
#!/bin/bash
set -e

if [[ -n "${DEBUG}" ]]; then
set -x
fi

. /startup-scripts/functions.sh

ipaddr=$(hostname -i | awk ' { print $1 } ')
hostname=$(hostname)
echo "I AM $hostname - $ipaddr"

# if command starts with an option, prepend mysqld
if [ "${1:0:1}" = '-' ]; then
CMDARG="$@"
fi

cluster_join=$(resolveip -s "${K8S_SERVICE_NAME}" || echo "")
if [[ -z "${cluster_join}" ]]; then
echo "I am the Primary Node"
init_mysql
write_password_file
exec mysqld --user=mysql --wsrep_cluster_name=$CLUSTER_NAME --wsrep_node_name=$hostname \
--wsrep_cluster_address=gcomm:// --wsrep_sst_method=xtrabackup-v2 \
--wsrep_sst_auth="xtrabackup:$XTRABACKUP_PASSWORD" \
--wsrep_node_address="$ipaddr" $CMDARG
else
echo "I am not the Primary Node"
chown -R mysql:mysql /var/lib/mysql
touch /var/log/mysqld.log
chown mysql:mysql /var/log/mysqld.log
write_password_file
exec mysqld --user=mysql --wsrep_cluster_name=$CLUSTER_NAME --wsrep_node_name=$hostname \
--wsrep_cluster_address="gcomm://$cluster_join" --wsrep_sst_method=xtrabackup-v2 \
--wsrep_sst_auth="xtrabackup:$XTRABACKUP_PASSWORD" \
--wsrep_node_address="$ipaddr" $CMDARG
fi

functions.sh: |+
#!/bin/bash

write_password_file() {
if [[ -n "${MYSQL_ROOT_PASSWORD}" ]]; then
cat <<EOF > /root/.my.cnf
[client]
user=root
password=${MYSQL_ROOT_PASSWORD}
EOF
fi
}

init_mysql() {
DATADIR=/var/lib/mysql
# if we have CLUSTER_JOIN - then we do not need to perform datadir initialize
# the data will be copied from another node
if [ ! -e "$DATADIR/mysql" ]; then
if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" -a -z "$MYSQL_ROOT_PASSWORD_FILE" ]; then
echo >&2 'error: database is uninitialized and password option is not specified '
echo >&2 ' You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ROOT_PASSWORD_FILE, MYSQL_ALLOW_EMPTY_PASSWORD or MYSQL_RANDOM_ROOT_PASSWORD'
exit 1
fi

if [ ! -z "$MYSQL_ROOT_PASSWORD_FILE" -a -z "$MYSQL_ROOT_PASSWORD" ]; then
MYSQL_ROOT_PASSWORD=$(cat $MYSQL_ROOT_PASSWORD_FILE)
fi
mkdir -p "$DATADIR"

echo "Running --initialize-insecure on $DATADIR"
ls -lah $DATADIR
mysqld --initialize-insecure
chown -R mysql:mysql "$DATADIR"
chown mysql:mysql /var/log/mysqld.log
echo 'Finished --initialize-insecure'

mysqld --user=mysql --datadir="$DATADIR" --skip-networking &
pid="$!"

mysql=( mysql --protocol=socket -uroot )

for i in {30..0}; do
if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then
break
fi
echo 'MySQL init process in progress...'
sleep 1
done
if [ "$i" = 0 ]; then
echo >&2 'MySQL init process failed.'
exit 1
fi

# sed is for https://bugs.mysql.com/bug.php?id=20545
mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | "${mysql[@]}" mysql
"${mysql[@]}" <<-EOSQL
-- What's done in this file shouldn't be replicated
-- or products like mysql-fabric won't work
SET @@SESSION.SQL_LOG_BIN=0;
CREATE USER 'root'@'127.0.0.1' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
GRANT ALL ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION ;
ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}';
CREATE USER 'xtrabackup'@'localhost' IDENTIFIED BY '$XTRABACKUP_PASSWORD';
GRANT RELOAD,PROCESS,LOCK TABLES,REPLICATION CLIENT ON *.* TO 'xtrabackup'@'localhost';
GRANT REPLICATION CLIENT ON *.* TO monitor@'%' IDENTIFIED BY 'monitor';
GRANT PROCESS ON *.* TO monitor@localhost IDENTIFIED BY 'monitor';
DROP DATABASE IF EXISTS test ;
FLUSH PRIVILEGES ;
EOSQL
if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then
mysql+=( -p"${MYSQL_ROOT_PASSWORD}" )
fi

if [ "$MYSQL_DATABASE" ]; then
echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}"
mysql+=( "$MYSQL_DATABASE" )
fi

if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" | "${mysql[@]}"

if [ "$MYSQL_DATABASE" ]; then
echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" | "${mysql[@]}"
fi

echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}"
fi

if [ ! -z "$MYSQL_ONETIME_PASSWORD" ]; then
"${mysql[@]}" <<-EOSQL
ALTER USER 'root'@'%' PASSWORD EXPIRE;
EOSQL
fi
if ! kill -s TERM "$pid" || ! wait "$pid"; then
echo >&2 'MySQL init process failed.'
exit 1
fi

echo
echo 'MySQL init process done. Ready for start up.'
echo
fi

}
26 changes: 26 additions & 0 deletions incubator/percona-xtradb-cluster/templates/secrets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ template "percona-xtradb-cluster.fullname" . }}
labels:
app: {{ template "percona-xtradb-cluster.fullname" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
type: Opaque
data:
{{ if .Values.mysqlRootPassword }}
mysql-root-password: {{ .Values.mysqlRootPassword | b64enc | quote }}
{{ else }}
mysql-root-password: {{ randAlphaNum 10 | b64enc | quote }}
{{ end }}
{{ if .Values.mysqlPassword }}
mysql-password: {{ .Values.mysqlPassword | b64enc | quote }}
{{ else }}
mysql-password: {{ randAlphaNum 10 | b64enc | quote }}
{{ end }}
{{ if .Values.xtraBackupPassword }}
xtrabackup-password: {{ .Values.xtraBackupPassword | b64enc | quote }}
{{ else }}
xtrabackup-password: {{ randAlphaNum 10 | b64enc | quote }}
{{ end }}
Loading