blob: 6298c0d08f057bf0930c8b4f7438820b977988cb [file] [view]
# 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
***note
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.
***
***note
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.enabled`to
true in the `values.yaml`. This will then install the
[mysql chart](https://github.com/helm/charts/tree/master/stable/mysql)
onto the Kubernetes cluster as a dependency.
To install the chart with the release name `reviewdb`, execute:
```sh
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
| Parameter | Description | Default |
|--------------------------------------------|------------------------------------------------------|----------------------------------------------------------------------|
| `images.registry.name` | The image registry to pull the container images from | `` |
| `images.registry.ImagePullSecret.name` | Name of the ImagePullSecret | `image-pull-secret` (if empty no image pull secret will be deployed) |
| `images.registry.ImagePullSecret.create` | Whether to create an ImagePullSecret | `false` |
| `images.registry.ImagePullSecret.username` | The image registry username | `nil` |
| `images.registry.ImagePullSecret.password` | The image registry password | `nil` |
| `images.version` | The image version (image tag) to use | `latest` |
| `images.imagePullPolicy` | Image pull policy | `Always` |
#### Storage classes
For information of how a `StorageClass` is configured in Kubernetes, read the
[official Documentation](https://kubernetes.io/docs/concepts/storage/storage-classes/#introduction).
| Parameter | Description | Default |
|----------------------------------------|-------------------------------------------------------------------|---------------------------------------------------|
| `storageClasses.default.name` | The name of the default StorageClass (RWO) | `default` |
| `storageClasses.default.create` | Whether to create the StorageClass | `false` |
| `storageClasses.default.provisioner` | Provisioner of the StorageClass | `kubernetes.io/aws-ebs` |
| `storageClasses.default.reclaimPolicy` | Whether to `Retain` or `Delete` volumes, when they become unbound | `Delete` |
| `storageClasses.default.parameters` | Parameters for the provisioner | `parameters.type: gp2`, `parameters.fsType: ext4` |
#### Replication
***note
Currently, only master-slave replication is possible. Thus, enabling replication
always means to use the database as slave.
***
| Parameter | Description | Default |
|-----------|--------------------------------------------------------|---------|
| `isSlave` | Whether to switch on replication from another database | `false` |
#### MySQL
***note
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](https://github.com/helm/charts/blob/master/stable/mysql/README.md).
***
| Parameter | Description | Default |
|--------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| `mysql.enabled` | Whether to install the MySQL database | `true` |
| `mysql.replication` | Only used, if `isSlave` is `true` | `{}` |
| `mysql.replication.config.masterHost` | Hostname of the Mysql database master | `mysql.example.com` |
| `mysql.replication.config.masterPort` | Port of the Mysql database master | `3306` |
| `mysql.replication.config.masterUser` | Username of technical user created for replication | `repl` |
| `mysql.replication.config.masterPassword` | Password of technical user created for replication | `password` |
| `mysql.replication.config.masterLogFile` | Transaction log file at timepoint of dump as retrieved [here](#Create-database-dump-and-note-database-state) | `mysql-bin.000001` |
| `mysql.replication.config.masterLogPos` | Transaction log position at timepoint of dump as retrieved [here](#Create-database-dump-and-note-database-state) | `111` |
| `mysql.replication.dbDumpAcceptPath` | Path, where the replication init script will expect the database dump file to appear | `/var/data/db/master_dump.sql` |
| `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 Gerrit) | `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 | `{}` (check the [Configuration files-section](#Configuration-files) for configuration options) |
| `mysql.initializationFiles` | Add scripts that are executed, when the database is started the first time | `{}` (check the [Initialization files-section](#Initialization-files) for details) |
| `mysql.service.type` | Type of the Service used to expose the database | `NodePort` |
| `mysql.service.port` | The port used to expose the database | `3306` |
| `mysql.ssl.enabled` | Setup and use SSL for MySQL connections | `false` |
| `mysql.ssl.secret` | Name 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].name` | Name 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].ca` | CA certificate (if using replication use the CA created [here](#create-certificates-for-ssl_encrypted-communication)) | `-----BEGIN CERTIFICATE-----` |
| `mysql.ssl.certificates[0].cert` | Server certificate (public key) (if using replication use the certificate created [here](#create-certificates-for-ssl_encrypted-communication)) | `-----BEGIN CERTIFICATE-----` |
| `mysql.ssl.certificates[0].key` | Server key (private key) (if using replication use the key created [here](#create-certificates-for-ssl_encrypted-communication)) | `-----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:
| Parameter | Description | Default |
|-----------------|----------------------------------------------------------|-------------------|
| `log-bin` | Name of transaction logs (used for database replication) | `mysql-bin` |
| `log-bin-index` | Name of transaction log indices | `mysql-bin.index` |
| `log-error` | Error log file | `error.log` |
| `binlog_format` | Format 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:
```sh
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:
| Parameter | Description | Default |
|-------------|------------------------------|---------|
| `server-id` | ID unique in the MySQL setup | `1` |
- `mysql-slave.cnf`: Contains configuration specific for the slave database:
| Parameter | Description | Default |
|-----------------------|-----------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|
| `relay-log` | The slave's relay log location | `/var/lib/mysql/relay.log` |
| `relay-log-info-file` | The slave's relay log info file location | `/var/lib/mysql/relay-log.info` |
| `relay-log-index` | The slave's relay log index location | `/var/lib/mysql/relay-log.index` |
| `log_slave_updates` | Whether to log slave update | `1` |
| `sql_mode` | Configure SQL-mode | `"ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"` |
| `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` |
| `server-id` | ID unique in the MySQL setup | `42` |
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:
```sh
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
```
***note
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:
```sql
STOP MASTER;
```
Retrieve the status of the master:
```sql
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:
```sh
mysqldump --user=root -p --databases reviewdb > ./master_dump.sql
```
Afterwards, the master can be started again:
```sql
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:
```sh
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.