Skip to content

Commit

Permalink
Merge pull request #114 from spotahome/improve-documentation
Browse files Browse the repository at this point in the history
Improve docs. Add examples. Fix typos.
  • Loading branch information
jchanam authored Feb 19, 2019
2 parents c12bdee + 4c3568d commit bd10e54
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 109 deletions.
76 changes: 60 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# redis-operator

[![Build Status](https://travis-ci.org/spotahome/redis-operator.png)](https://travis-ci.org/spotahome/redis-operator)
[![Go Report Card](http://goreportcard.com/badge/spotahome/redis-operator)](http://goreportcard.com/report/spotahome/redis-operator)

Expand All @@ -7,62 +8,78 @@
Redis Operator creates/configures/manages redis-failovers atop Kubernetes.

## Requirements

Redis Operator is meant to be run on Kubernetes 1.8+.
All dependecies have been vendored, so there's no need to any additional download.

### Versions deployed

The image versions deployed by the operator can be found on the [constants file](operator/redisfailover/service/constants.go) for the RedisFailover service.

## Images

### Redis Operator

[![Redis Operator Image](https://quay.io/repository/spotahome/redis-operator/status "Redis Operator Image")](https://quay.io/repository/spotahome/redis-operator)

## Operator deployment on kubernetes

In order to create Redis failovers inside a Kubernetes cluster, the operator has to be deployed. It can be done with [deployment](example/operator) or with the provided [Helm chart](charts/redisoperator).

### Using a Deployment

To create the operator, you can directly create it with kubectl:

```
kubectl create -f https://raw.githubusercontent.com/spotahome/redis-operator/master/example/operator/all-redis-operator-resources.yaml
```

This will create a deployment named `redisoperator`.

### Using the Helm chart

From the root folder of the project, execute the following:

```
helm install --name redisfailover charts/redisoperator
```

## Usage

Once the operator is deployed inside a Kubernetes cluster, a new API will be accesible, so you'll be able to create, update and delete redisfailovers.

In order to deploy a new redis-failover a [specification](example/redisfailover/all-options.yaml) has to be created:
In order to deploy a new redis-failover a [specification](example/redisfailover/basic.yaml) has to be created:

```
kubectl create -f https://raw.githubusercontent.com/spotahome/redis-operator/master/example/redisfailover/all-options.yaml
kubectl create -f https://raw.githubusercontent.com/spotahome/redis-operator/master/example/redisfailover/basic.yaml
```

This redis-failover will be managed by the operator, resulting in the following elements created inside Kubernetes:
* `rfr-<NAME>`: Redis configmap
* `rfr-<NAME>`: Redis statefulset
* `rfr-<NAME>`: Redis service (if redis-exporter is enabled)
* `rfs-<NAME>`: Sentinel configmap
* `rfs-<NAME>`: Sentinel deployment
* `rfs-<NAME>`: Sentinel service

- `rfr-<NAME>`: Redis configmap
- `rfr-<NAME>`: Redis statefulset
- `rfr-<NAME>`: Redis service (if redis-exporter is enabled)
- `rfs-<NAME>`: Sentinel configmap
- `rfs-<NAME>`: Sentinel deployment
- `rfs-<NAME>`: Sentinel service

**NOTE**: `NAME` is the named provided when creating the RedisFailover.
**IMPORTANT**: the name of the redis-failover to be created cannot be longer that 48 characters, due to prepend of redis/sentinel identification and statefulset limitation.

### Persistance
The operator has the ability of add persistance to Redis data. By default an `emptyDir` will be used, so the data is not saved.
### Persistence

The operator has the ability of add persistence to Redis data. By default an `emptyDir` will be used, so the data is not saved.

In order to have persistance, a PersistentVolumeClaim usage is allowed. The full [PVC definition has to be added](example/redisfailover/persistant-storage.yaml) to the Redis Failover Spec under the `Storage` section.
In order to have persistence, a `PersistentVolumeClaim` usage is allowed. The full [PVC definition has to be added](example/redisfailover/persistent-storage.yaml) to the Redis Failover Spec under the `Storage` section.

**IMPORTANT**: By default, the persistent volume claims will be deleted when the Redis Failover is. If this is not the expected usage, a `keepAfterDeletion` flag can be added under the `storage` section of Redis. [An example is given](example/redisfailover/persistant-storage-no-pvc-deletion.yaml).
**IMPORTANT**: By default, the persistent volume claims will be deleted when the Redis Failover is. If this is not the expected usage, a `keepAfterDeletion` flag can be added under the `storage` section of Redis. [An example is given](example/redisfailover/persistent-storage-no-pvc-deletion.yaml).

### Custom configurations

It is possible to configure both Redis and Sentinel. This is done with the `customConfig` option inside their spec. It is a list of configurations and their values.

Example:

```yaml
sentinel:
customConfig:
Expand All @@ -74,32 +91,46 @@ redis:
- "hz 50"
```
**Important**: this options will be set via `config set` or `sentinel set mymaster`. In the Sentinel options, there are some "conversions" to be made.
In order to have the ability of this configurations to be changed "on the fly", without the need of reload the redis/sentinel processes, the operator will apply them with calls to the redises/sentinels, using `config set` or `sentinel set mymaster` respectively. Because of this, **no changes on the configmaps** will appear regarding this custom configurations.

**Important**: in the Sentinel options, there are some "conversions" to be made:

- Configuration on the `sentinel.conf`: `sentinel down-after-milliseconds mymaster 2000`
- Configuration on the `configOptions`: `down-after-milliseconds 2000`

**Important 2**: do **NOT** change the options used for control the redis/sentinel such as `port`, `bind`, `dir`, etc.

### Custom shutdown script

By default, a custom shutdown file is given. This file makes redis to `SAVE` it's data, and in the case that redis is master, it'll call sentinel to ask for a failover.

This behavior is configurable, creating a configmap and indicating to use it. An example about how to use this option can be found on the [shutdown example file](example/redisfailover/custom-shutdown.yaml).

**Important**: the configmap has to be in the same namespace. The configmap has to have a `shutdown.sh` data, containing the script.

### Connection

In order to connect to the redis-failover and use it, a [Sentinel-ready](https://redis.io/topics/sentinel-clients) library has to be used. This will connect through the Sentinel service to the Redis node working as a master.
The connection parameters are the following:

```
url: rfs-<NAME>
port: 26379
master-name: mymaster
```

#### Connection example

- To get Sentinel service's port
```
kubectl get service -l component=sentinel
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
rfs-<NAME> ClusterIP 10.99.222.41 <none> 26379/TCP 20m
```
- To get a Sentinel's name
```
```
kubectl get pods -l component=sentinel
NAME READY STATUS RESTARTS AGE
NAME READY STATUS RESTARTS AGE
rfs-<NAME> 1/1 Running 0 20m
```
- To get network information of the Redis node working as a master
Expand All @@ -118,16 +149,29 @@ master-name: mymaster
kubectl exec -it rfs-<NAME>-- redis-cli -h 10.244.2.15 -p 6379 GET hello
"world!"
```

## Cleanup

### Operator and CRD

If you want to delete the operator from your Kubernetes cluster, the operator deployment should be deleted.

Also, the CRD has to be deleted too:

```
kubectl delete crd redisfailovers.storage.spotahome.com
```

### Single Redis Failover

Thanks to Kubernetes' `OwnerReference`, all the objects created from a redis-failover will be deleted after the custom resource is.

```
kubectl delete redisfailover <NAME>
```
## Documentation
For the code documentation, you can lookup on the [GoDoc](https://godoc.org/github.com/spotahome/redis-operator).
Also, you can check more deeply information on the [docs folder](docs).
73 changes: 39 additions & 34 deletions docs/development.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,48 @@
# Development

## Folder structure

### Code folder structure
* **api**: definition of the RedisFailover CRD.
* **client**: autogenerated client to interact with redis-failovers.
* **cmd**: contains the starting point of the application.
* **log**: wrapper of logrus, created to be able to mock it.
* **metrics**: exposer of status of the failovers created.
* **mocks**: contains the mocked interfaces for testing the application.
* **operator**: the main logic. Manages the requests from k8s and creates/updates/deletes the pieces as needed.
* **service**: services/clients to interact with k8s and redises.
* **vendor**: vendored packages used by the application.

- **api**: definition of the RedisFailover CRD.
- **client**: autogenerated client to interact with redis-failovers.
- **cmd**: contains the starting point of the application.
- **log**: wrapper of logrus, created to be able to mock it.
- **metrics**: exposer of status of the failovers created.
- **mocks**: contains the mocked interfaces for testing the application.
- **operator**: the main logic. Manages the requests from k8s and creates/updates/deletes the pieces as needed.
- **service**: services/clients to interact with k8s and redises.
- **vendor**: vendored packages used by the application.

### Non-code folder structure
* **charts**: helm chart to deploy the operator.
* **docker**: Dockerfiles to generate redis-failover docker images.
* **example**: yaml files with spec of redis-failover.
* **hack**: scripts to generate the redis-failover api-client.
* **scripts**: scripts used to build and run the app.

- **charts**: helm chart to deploy the operator.
- **docker**: Dockerfiles to generate redis-failover docker images.
- **example**: yaml files with spec of redis-failover.
- **hack**: scripts to generate the redis-failover api-client.
- **scripts**: scripts used to build and run the app.

## Make development commands

You can do the following commands with make:
* Build the development container.
`make docker-build`
* Generate mocks.
`make go-generate`
* Generate client
`make update-codegen`
* Run tests.
`make test`
* Build the executable file.
`make build`
* Run the app.
`make run`
* Access the docker instance with a shell.
`make shell`
* Install dependencies
`make get-deps`
* Update dependencies
`make update-deps`
* Build the app image.
`make image`

- Build the development container.
`make docker-build`
- Generate mocks.
`make go-generate`
- Generate client
`make update-codegen`
- Run tests.
`make test`
- Build the executable file.
`make build`
- Run the app.
`make run`
- Access the docker instance with a shell.
`make shell`
- Install dependencies
`make get-deps`
- Update dependencies
`make update-deps`
- Build the app image.
`make image`
39 changes: 22 additions & 17 deletions docs/logic.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
# Controller logic

## Creation pipeline

The Redis-Operator creates Redis Failovers, with all the needed pieces. So, when a event arrives from Kubernetes (add or sync), the following steps are executed:
* Ensure: checks that all the pieces needed are created. It is important to notice that if a change is performed manually on the objects created, the operator will override them. This is done to ensure a healthy status. It will create the following:
* Redis configmap
* Redis statefulset
* Redis service (if exporter enabled)
* Sentinel configmap
* Sentinel deployment
* Sentinel service
* Check & Heal: will connect to every Redis and Sentinel and will ensure that they are working as they are supposed to do. If this is not the case, it will reconfigure the nodes to move them to the desire state. It will check the following:
* Number of Redis is equal as the set on the RF spec
* Number of Sentinel is equal as the set on the RF spec
* Only one Redis working as a master
* All Redis slaves have the same master
* All Redis slaves are connected to the master
* All Sentinels points to the same Redis master
* Sentinel has not death nodes
* Sentinel knows the correct slave number

Most of the problems that may occur will be treated and tried to fix by the controller, except the case that there are a [split-brain](https://en.wikipedia.org/wiki/Split-brain_(computing)). **If happens to be a split-brain, an error will be logged waiting for manual fix**.
- Ensure: checks that all the pieces needed are created. It is important to notice that if a change is performed manually on the objects created, the operator will override them. This is done to ensure a healthy status. It will create the following:
- Redis service (if exporter enabled)
- Redis configmap
- Redis shutdown configmap
- Redis statefulset
- Sentinel service
- Sentinel configmap
- Sentinel deployment
- Check & Heal: will connect to every Redis and Sentinel and will ensure that they are working as they are supposed to do. If this is not the case, it will reconfigure the nodes to move them to the desire state. It will check the following:
- Number of Redis is equal as the set on the RF spec
- Number of Sentinel is equal as the set on the RF spec
- Only one Redis working as a master
- All Redis slaves have the same master
- All Redis slaves are connected to the master
- All Sentinels points to the same Redis master
- Sentinel has not death nodes
- Sentinel knows the correct slave number
- Ensure Redis has the custom configuration set
- Ensure Sentinel has the custom configuration set

Most of the problems that may occur will be treated and tried to fix by the controller, except the case that there are a [split-brain](<https://en.wikipedia.org/wiki/Split-brain_(computing)>). **If happens to be a split-brain, an error will be logged waiting for manual fix**.
32 changes: 0 additions & 32 deletions example/redisfailover/all-options.yaml

This file was deleted.

21 changes: 21 additions & 0 deletions example/redisfailover/basic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: storage.spotahome.com/v1alpha2
kind: RedisFailover
metadata:
name: redisfailover
spec:
sentinel:
replicas: 3
resources:
requests:
cpu: 100m
limits:
memory: 100Mi
redis:
replicas: 3
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 400m
memory: 500Mi
16 changes: 16 additions & 0 deletions example/redisfailover/custom-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: storage.spotahome.com/v1alpha2
kind: RedisFailover
metadata:
name: redisfailover
spec:
sentinel:
replicas: 3
customConfig:
- "down-after-milliseconds 2000"
- "failover-timeout 3000"
redis:
replicas: 3
customConfig:
- "maxclients 100"
- "hz 50"
- "timeout 60"
Loading

0 comments on commit bd10e54

Please sign in to comment.