A ReviewDB for Gerrit on Kubernetes

Gerrit requires a database to store user and change data. The database is commonly called ReviewDB. Gerrit provides a set of options, which database technology to use. This chart is meant to install a database and initialize it, so it can be used as a ReviewDB for Gerrit-master and -slave setups installed with the respective charts. Currently, the following databases sre supported by this chart:

  • MySQL
The gerrit-master and gerrit-slave charts also support H2, but since H2-databases do not require a separate server, this chart is not required in that case.
With upcoming versions of Gerrit, the ReviewDB will be completely migrated to NoteDB, removing the dependency on a external relational database.

Installation

To install a MySQL database with the reviewdb chart, set mysql.enabledto true in the values.yaml. This will then install the mysql chart onto the Kubernetes cluster as a dependency.

To install the chart with the release name reviewdb, execute:

cd $(git rev-parse --show-toplevel)/helm-charts
helm install ./reviewdb \
  --dep-up \
  -n reviewdb \
  -f <path-to-custom-values>.yaml

Configuration

Common

Container images

ParameterDescriptionDefault
images.registry.nameThe image registry to pull the container images from``
images.registry.ImagePullSecret.nameName of the ImagePullSecretimage-pull-secret (if empty no image pull secret will be deployed)
images.registry.ImagePullSecret.createWhether to create an ImagePullSecretfalse
images.registry.ImagePullSecret.usernameThe image registry usernamenil
images.registry.ImagePullSecret.passwordThe image registry passwordnil
images.versionThe image version (image tag) to uselatest
images.imagePullPolicyImage pull policyAlways

Storage classes

For information of how a StorageClass is configured in Kubernetes, read the official Documentation.

ParameterDescriptionDefault
storageClasses.default.nameThe name of the default StorageClass (RWO)default
storageClasses.default.createWhether to create the StorageClassfalse
storageClasses.default.provisionerProvisioner of the StorageClasskubernetes.io/aws-ebs
storageClasses.default.reclaimPolicyWhether to Retain or Delete volumes, when they become unboundDelete
storageClasses.default.parametersParameters for the provisionerparameters.type: gp2, parameters.fsType: ext4

Replication

Currently, only master-slave replication is possible. Thus, enabling replication always means to use the database as slave.
ParameterDescriptionDefault
isSlaveWhether to switch on replication from another databasefalse

MySQL

Not all options available in the mysql-chart that is used as a dependency are listed in the values.yaml-file of this chart. The complete list of options for the mysql-chart can be viewed in the chart's documentation.
ParameterDescriptionDefault
mysql.enabledWhether to install the MySQL databasetrue
mysql.replicationOnly used, if isSlave is true{}
mysql.replication.config.masterHostHostname of the Mysql database mastermysql.example.com
mysql.replication.config.masterPortPort of the Mysql database master3306
mysql.replication.config.masterUserUsername of technical user created for replicationrepl
mysql.replication.config.masterPasswordPassword of technical user created for replicationpassword
mysql.replication.config.masterLogFileTransaction log file at timepoint of dump as retrieved heremysql-bin.000001
mysql.replication.config.masterLogPosTransaction log position at timepoint of dump as retrieved here111
mysql.replication.dbDumpAcceptPathPath, where the replication init script will expect the database dump file to appear/var/data/db/master_dump.sql
mysql.imageWhich container image containing MySQL to usemysql
mysql.imageTagTag of container image (usually the database version)5.5.61
mysql.mysqlRootPasswordPassword of the database root userbig_secret
mysql.mysqlUserDatabase user (The technical user used by Gerrit)gerrit
mysql.mysqlPasswordPassword of the database usersecret
mysql.livenessProbe.initialDelaySecondsDelay before liveness probe is initiated30
mysql.livenessProbe.periodSecondsHow often to perform the probe10
mysql.livenessProbe.timeoutSecondsWhen the probe times out5
mysql.livenessProbe.successThresholdMinimum consecutive successes for the probe to be considered successful after having failed.1
mysql.livenessProbe.failureThresholdMinimum consecutive failures for the probe to be considered failed after having succeeded.3
mysql.readinessProbe.initialDelaySecondsDelay before readiness probe is initiated5
mysql.readinessProbe.periodSecondsHow often to perform the probe10
mysql.readinessProbe.timeoutSecondsWhen the probe times out1
mysql.readinessProbe.successThresholdMinimum consecutive successes for the probe to be considered successful after having failed.1
mysql.readinessProbe.failureThresholdMinimum consecutive failures for the probe to be considered failed after having succeeded.3
mysql.persistence.enabledCreate a volume to store datatrue
mysql.persistence.sizeSize of persistent volume claim8Gi
mysql.persistence.storageClassType of persistent volume claimdefault
mysql.persistence.accessModeReadWriteOnce or ReadOnlyReadWriteOnce
mysql.resourcesConfigure the amount of resources the pod requests/is allowedrequests.cpu: 250m
requests.memory: 1Gi
limits.cpu: 250m
limits.memory: 1Gi
mysql.configurationFilesAdd configuration files for MySQL{} (check the Configuration files-section for configuration options)
mysql.initializationFilesAdd scripts that are executed, when the database is started the first time{} (check the Initialization files-section for details)
mysql.service.typeType of the Service used to expose the databaseNodePort
mysql.service.portThe port used to expose the database3306
mysql.ssl.enabledSetup and use SSL for MySQL connectionsfalse
mysql.ssl.secretName of the secret containing the SSL certificates (Has to be different between multiple instances running in the same cluster)ssl-certs
mysql.ssl.certificates[0].nameName of the secret containing the SSL certificates (Has to be different between multiple instances running in the same cluster)ssl-certs
mysql.ssl.certificates[0].caCA certificate (if using replication use the CA created here)-----BEGIN CERTIFICATE-----
mysql.ssl.certificates[0].certServer certificate (public key) (if using replication use the certificate created here)-----BEGIN CERTIFICATE-----
mysql.ssl.certificates[0].keyServer key (private key) (if using replication use the key created here)-----BEGIN RSA PRIVATE KEY-----
Configuration files

The configuration file for the MySQL-server is provided under the keys mysql.configurationsFiles.*.cnf. There are three different config-files provided:

  • common.cnf: Contains configuration, which is the same for master- and slave- databases:
ParameterDescriptionDefault
log-binName of transaction logs (used for database replication)mysql-bin
log-bin-indexName of transaction log indicesmysql-bin.index
log-errorError log fileerror.log
binlog_formatFormat of the binlogs (Has to be the same as on master)row

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
  • mysql-master.cnf: Contains configuration specific for the master database:
ParameterDescriptionDefault
server-idID unique in the MySQL setup1
  • mysql-slave.cnf: Contains configuration specific for the slave database:
ParameterDescriptionDefault
relay-logThe slave's relay log location/var/lib/mysql/relay.log
relay-log-info-fileThe slave's relay log info file location/var/lib/mysql/relay-log.info
relay-log-indexThe slave's relay log index location/var/lib/mysql/relay-log.index
log_slave_updatesWhether to log slave update1
sql_modeConfigure SQL-mode"ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
read_onlyToggle 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-dbDatabases not to replicate (replicating the mysql-DB for example would overwrite database users)mysql
server-idID unique in the MySQL setup42

The mysql-master.cnf- and mysql-slave.cnf-files are mutually exclusive. Comment out the contents of the file, that is not needed, depending on installing a master or slave database.

Initialization files
  • initialize_reviewdb.sql

Creates a database called ‘reviewdb’, that can be used by Gerrit for the ReviewDB. Leave this file unchanged.

  • create_repl_user.sql

Creates a user, that can be used for database replication. This user is only needed on the master database and only, when the data is supposed to be replicated to slaves. To use it, uncomment the code and change the username, password and certificate subject as needed.

Aditional configuration steps

Create certificates for SSL-encrypted communication

For SSL-encrypted communication, a set of certificates is needed. 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

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 CN has to be the hostname of the database instances. In case the database is running on Kubernetes it can be the service name.

Configuring a master DB instance for replication

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.

Create database dump and note database state

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 have to be entered in the database slave's values.yaml under mysql.replication.config.masterLogFile and mysql.replication.config.masterLogPos.

Dump the content of the database:

mysqldump --user=root -p --databases reviewdb > ./master_dump.sql

Afterwards, the master can be started again:

START MASTER;

Initialize replication

MySQL

Deploying the reviewdb chart with replication enabled, 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 mysql.replication.dbDumpAcceptPath. The dump file can be copied into the container 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.