diff --git a/docs/tutorials/replicated-stateful-application/Dockerfile b/docs/tutorials/replicated-stateful-application/Dockerfile new file mode 100644 index 0000000000..8016958d83 --- /dev/null +++ b/docs/tutorials/replicated-stateful-application/Dockerfile @@ -0,0 +1,17 @@ +# This is an image with Percona XtraBackup, mysql-client and ncat installed. +FROM debian:jessie + +RUN \ + echo "deb http://repo.percona.com/apt jessie main" > /etc/apt/sources.list.d/percona.list \ + && echo "deb-src http://repo.percona.com/apt jessie main" >> /etc/apt/sources.list.d/percona.list \ + && apt-key adv --keyserver keys.gnupg.net --recv-keys 8507EFA5 + +RUN \ + apt-get update && apt-get install -y --no-install-recommends \ + percona-xtrabackup-24 \ + mysql-client \ + nmap \ + && rm -rf /var/lib/apt/lists/* + +CMD ["bash"] + diff --git a/docs/tutorials/replicated-stateful-application/my.cnf b/docs/tutorials/replicated-stateful-application/my.cnf new file mode 100644 index 0000000000..c15357b9fd --- /dev/null +++ b/docs/tutorials/replicated-stateful-application/my.cnf @@ -0,0 +1,5 @@ +# Create a ConfigMap resource from this file: +# kubectl create configmap mysql --from-file=./my.cnf +[mysqld] +log-bin + diff --git a/docs/tutorials/replicated-stateful-application/mysql-headless-service.yaml b/docs/tutorials/replicated-stateful-application/mysql-headless-service.yaml new file mode 100644 index 0000000000..5f9fdcbc23 --- /dev/null +++ b/docs/tutorials/replicated-stateful-application/mysql-headless-service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: mysql + labels: + app: mysql +spec: + ports: + - name: mysql + port: 3306 + clusterIP: None + selector: + app: mysql + diff --git a/docs/tutorials/replicated-stateful-application/mysql-statefulset.yaml b/docs/tutorials/replicated-stateful-application/mysql-statefulset.yaml new file mode 100644 index 0000000000..4687eff9b0 --- /dev/null +++ b/docs/tutorials/replicated-stateful-application/mysql-statefulset.yaml @@ -0,0 +1,144 @@ +apiVersion: apps/v1beta1 +kind: StatefulSet +metadata: + name: mysql +spec: + serviceName: mysql + replicas: 3 + template: + metadata: + labels: + app: mysql + annotations: + pod.beta.kubernetes.io/init-containers: '[ + { + "name": "init-mysql", + "image": "mysql:5.7", + "command": ["bash", "-c", " + set -ex\n + # mysqld --initialize expects an empty data dir.\n + rm -rf /mnt/data/lost+found\n + # Copy conf.d from config-map to emptyDir.\n + cp /mnt/config-map/* /mnt/conf.d/\n + # Generate mysql server-id from pod ordinal index.\n + [[ `hostname` =~ -([0-9]+)$ ]] || exit 1\n + echo [mysqld] > /mnt/conf.d/server-id.cnf\n + echo server-id=$((100 + ${BASH_REMATCH[1]})) >> /mnt/conf.d/server-id.cnf\n + "], + "volumeMounts": [ + {"name": "data", "mountPath": "/mnt/data"}, + {"name": "conf", "mountPath": "/mnt/conf.d"}, + {"name": "config-map", "mountPath": "/mnt/config-map"} + ] + }, + { + "name": "clone-mysql", + "image": "enisoc/xtrabackup", + "command": ["bash", "-c", " + set -ex\n + # Skip the clone if data already exists.\n + [[ -d /var/lib/mysql/mysql ]] && exit 0\n + # Skip the clone on master (ordinal index 0).\n + [[ `hostname` =~ -0$ ]] && exit 0\n + # Clone data from master.\n + ncat --recv-only mysql-0.mysql 3307 | xbstream -x -C /var/lib/mysql\n + # Prepare the backup.\n + xtrabackup --prepare --target-dir=/var/lib/mysql\n + "], + "volumeMounts": [ + {"name": "data", "mountPath": "/var/lib/mysql"}, + {"name": "conf", "mountPath": "/etc/mysql/conf.d"} + ] + } + ]' + spec: + containers: + - name: mysql + image: mysql:5.7 + env: + - name: MYSQL_ALLOW_EMPTY_PASSWORD + value: "1" + ports: + - name: mysql + containerPort: 3306 + volumeMounts: + - name: data + mountPath: /var/lib/mysql + - name: conf + mountPath: /etc/mysql/conf.d + resources: + requests: + cpu: 1 + memory: 1Gi + livenessProbe: + exec: + command: ["mysqladmin", "ping"] + initialDelaySeconds: 30 + timeoutSeconds: 5 + readinessProbe: + exec: + # Check we can execute queries over TCP (skip-networking is off). + command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"] + initialDelaySeconds: 5 + timeoutSeconds: 1 + - name: xtrabackup + image: enisoc/xtrabackup:latest + ports: + - name: xtrabackup + containerPort: 3307 + command: + - bash + - "-c" + - | + set -ex + + # Check if we need to complete a clone by starting replication. + cd /var/lib/mysql + if [[ -f xtrabackup_binlog_info ]]; then + echo "Waiting for mysqld to accept connections" + until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; done + + echo "Initializing replication from clone position" + [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1 + mv xtrabackup_binlog_info xtrabackup_binlog_info.orig + mysql -h 127.0.0.1 <