To install a MySQL slave database with the gerrit-slave chart, set database.provider
to mysql
and mysql.enabled
to true in the values.yaml
. This will then install the mysql chart onto the Kubernetes cluster as a dependency of the gerrit-slave chart.
For the replication to work, the MySQL database master has to be configured accordingly and some data about the database state has to be collected. The necessary steps are detailed in this section. If it is not planned to replicate the master database, skip this section.
Connect to the MySQL database master and create a technical user to handle the replication:
CREATE USER 'repl' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl' IDENTIFIED BY 'password' REQUIRE SUBJECT '/C=DE/O=Gerrit/CN=gerrit-db-slave'; FLUSH PRIVILEGES;
The username, password and certificate subject can be chosen as needed, but should be written down, since they are needed in coming steps.
For SSL-encrypted communication, a set of certificates is needed. If the master does not yet possess a CA, private- and public key, use the following commands to create them after adjusting the subject strings:
openssl genrsa -out ./ca.key.pem 4096 openssl req \ -key ./ca.key.pem \ -new \ -x509 \ -days 7300 \ -sha256 \ -out ./ca.cert.pem \ -subj "/C=DE/O=Gerrit/CN=gerrit-db-master" \ -nodes openssl genrsa -out ./master.key.pem 4096 openssl req \ -key ./master.key.pem \ -new \ -sha256 \ -out ./master.csr.pem \ -subj "/C=DE/O=Gerrit/CN=gerrit-db-master" \ -nodes openssl x509 \ -req \ -CA ./ca.cert.pem \ -CAkey ./ca.key.pem \ -CAcreateserial \ -in ./master.csr.pem \ -out ./master.cert.pem
Then a private and a public key for the slave has to be created. If the master did already possess a CA, change the corresponding paths in the commands below. The subject string has to be the same as the one used, when creating the MySQL user for replication. The content of the CA-certificate and the slave's private and public key (here: slave.key.pem
and slave.cert.pem
) have to be noted for later use.
openssl genrsa -out ./slave.key.pem 4096 openssl req \ -key ./slave.key.pem \ -new -sha256 \ -out ./slave.csr.pem \ -subj "/C=DE/O=Gerrit/CN=gerrit-db-slave" \ -nodes openssl x509 \ -req \ -CA ./ca.cert.pem \ -CAkey ./ca.key.pem \ -CAcreateserial \ -in ./slave.csr.pem \ -out ./slave.cert.pem
The master DB has to be configured for replication by adding the following entries to the configuration-file of the MySQL instance:
[mysqld] server-id=1 # Has to be unique under all masters/slaves. log_bin=mysql-bin # Name of the logs used for replication ssl-ca=/ssl/ca.pem # Location of the CA-certificate ssl-cert=/ssl/server-cert.pem # Location of the public key ssl-key=/ssl/server-key.pem # Location of the private key
In the next steps the content of the database has to be retrieved and the corresponding status of the transaction logs has to be retrieved. Depending on the traffic the database receives, the master DB should be stopped for these steps, since the information could get out off sync, if the data is changed inbetween the steps:
STOP MASTER;
Retrieve the status of the master:
SHOW MASTER STATUS; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000004 | 69444891 | | | | +------------------+----------+--------------+------------------+-------------------+
The filename and position should be written down, since they will be needed for the configuration of the slave.
Dump the content of the database:
mysqldump --user=root -p --all-databases > ./master_dump.sql
Afterwards, the master can be started again:
START MASTER;
The configuration of the database is done in the values.yaml
of the gerrit-slave chart under the mysql
-key. The complete list of options for the mysql-chart can be viewed in the chart‘s documentation. The options referenced in the gerrit-slave chart’s values.yaml
are listed here:
Parameter | Description | Default |
---|---|---|
mysql.enabled | Whether to install the MySQL database | true |
mysql.image | Which container image containing MySQL to use | mysql |
mysql.imageTag | Tag of container image (usually the database version) | 5.5.61 |
mysql.mysqlRootPassword | Password of the database root user | big_secret |
mysql.mysqlUser | Database user (The technical user used by the Gerrit slave) | gerrit |
mysql.mysqlPassword | Password of the database user | secret |
mysql.livenessProbe.initialDelaySeconds | Delay before liveness probe is initiated | 30 |
mysql.livenessProbe.periodSeconds | How often to perform the probe | 10 |
mysql.livenessProbe.timeoutSeconds | When the probe times out | 5 |
mysql.livenessProbe.successThreshold | Minimum consecutive successes for the probe to be considered successful after having failed. | 1 |
mysql.livenessProbe.failureThreshold | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 3 |
mysql.readinessProbe.initialDelaySeconds | Delay before readiness probe is initiated | 5 |
mysql.readinessProbe.periodSeconds | How often to perform the probe | 10 |
mysql.readinessProbe.timeoutSeconds | When the probe times out | 1 |
mysql.readinessProbe.successThreshold | Minimum consecutive successes for the probe to be considered successful after having failed. | 1 |
mysql.readinessProbe.failureThreshold | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 3 |
mysql.persistence.enabled | Create a volume to store data | true |
mysql.persistence.size | Size of persistent volume claim | 8Gi |
mysql.persistence.storageClass | Type of persistent volume claim | default |
mysql.persistence.accessMode | ReadWriteOnce or ReadOnly | ReadWriteOnce |
mysql.resources | Configure the amount of resources the pod requests/is allowed | requests.cpu: 250m |
requests.memory: 1Gi | ||
limits.cpu: 250m | ||
limits.memory: 1Gi | ||
mysql.configurationFiles | Add configuration files for MySQL | mysql.cnf (check the mysql.cnf-section for configuration options) |
mysql.initializationFiles | Add scripts that are executed, when the database is started the first time | initialize_reviewdb.sql (Should not be changed) |
mysql.service.type | Type of the Service used to expose the database | NodePort |
mysql.service.port | The port used to expose the database | 3306 |
ssl.enabled | Setup and use SSL for MySQL connections | false |
ssl.secret | Name of the secret containing the SSL certificates | slave-ssl-certs |
ssl.certificates[0].name | Name of the secret containing the SSL certificates | slave-ssl-certs |
ssl.certificates[0].ca | CA certificate (if using replication use the CA created peviously) | -----BEGIN CERTIFICATE----- |
ssl.certificates[0].cert | Server certificate (public key) (if using replication use the certificate created peviously) | -----BEGIN CERTIFICATE----- |
ssl.certificates[0].key | Server key (private key) (if using replication use the key created peviously) | -----BEGIN RSA PRIVATE KEY----- |
The configuration file for the MySQL-server is provided under the key mysql.configurationsFiles.mysql.cnf
. The provided values provide necessary configuration to receive replicated databases from the master database. The following options should normally not be changed:
[mysqld] log-bin=/var/lib/mysql/bin.log log-bin-index=/var/lib/mysql/log-bin.index log-error=/var/lib/mysql/error.log relay-log=/var/lib/mysql/relay.log relay-log-info-file=/var/lib/mysql/relay-log.info relay-log-index=/var/lib/mysql/relay-log.index log-error=/var/lib/mysql/error.log log_slave_updates = 1 sql_mode="ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
The other provided options should be adapted to the respective setup:
Parameter | Description | Default |
---|---|---|
read_only | Toggle read only mode. In production this should be on (1 ). The test mode of the Gerrit slave expects it to be off (0 ). | 0 |
replicate-ignore-db | Databases not to replicate (replicating the mysql -DB for example would overwrite database users) | mysql |
binlog_format | Format of the binlogs (Has to be the same as on master) | row |
server-id | ID unique in the MySQL setup | 42 |
In addition, if using SSL for MySQL-requests the following options have to be made available by uncommenting them. The values must not be changed, when using the chart:
ssl-ca=/ssl/ca.pem ssl-cert=/ssl/server-cert.pem ssl-key=/ssl/server-key.pem
The replication of the MySQL database from master to slave is performed using the replication functionality provided by MySQL. To start replication a database dump from the master has to be loaded into the database slave. Then the slave has to be configured for replication and replication has to be started. This is done by a job provided by the chart.
The Job needs to be configured with the data retrieved from the database master by configuring the corresponding values in the values.yaml
-file:
Parameter | Description | Default |
---|---|---|
database.replication.mysql.config.masterHost | Hostname of the Mysql database master | mysql.example.com |
database.replication.mysql.config.masterPort | Port of the Mysql database master | 3306 |
database.replication.mysql.config.masterUser | Username of technical user created previously | repl |
database.replication.mysql.config.masterPassword | Password of technical user created previously | password |
database.replication.mysql.config.masterLogFile | Transaction log file at timepoint of dump as retrieved previously | mysql-bin.000001 |
database.replication.mysql.config.masterLogPos | Transaction log position at timepoint of dump as retrieved previously | 111 |
database.replication.mysql.dbDumpAcceptPath | Path, where the replication init script will expect the database dump file to appear | /var/data/db/master_dump.sql |
Deploying the gerrit-slave chart with the configuration detailed above, will create a MySQL database with a technical user to be used by the Gerrit slave and an empty ReviewDB database. In addition a Job will be deployed that waits for a database dump to be copied into the container to the location specified in database.replication.mysql.dbDumpAcceptPath
. The dump file can be copied using kubectl:
JOB_POD=$(kubectl get pod -l app=mysql-replication-init -o jsonpath="{.items[0].metadata.name}") kubectl cp <PATH_TO_DUMP> ${JOB_POD}:<DB_DUMP_ACCEPT_PATH>
As soon as the file is fully copied into the container, the script will load the dump into the database and initialize the replication in the slave. The database is then fully configured.