Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Addon] add redis-operator addon #437

Merged
merged 5 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions experimental/addons/redis-operator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# redis-operator

Redis Operator creates/configures/manages high availability redis with sentinel automatic failover atop Kubernetes.

This addon will give you the ability to use `redis-failover` Components in Applications.

## Quick Start

In this example, we will :
- start a high-availability Redis cluster with Sentinel
- scale it up/down
- use `redis-cli` to connect and read/write some data

Let's get started.

After you enable this addon, apply this Application yaml to create a Redis cluster:

```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: redis-operator-sample
spec:
components:
# This component is provided by redis-operator addon.
# In this example, 2 redis instance and 2 sentinel instance
# will be created.
- type: redis-failover
# Remember this name, we will use it to find the Service to connect.
name: ha-redis
properties:
# You can increase/decrease this later to add/remove instances.
replicas: 2
```

Verify if we have 2 Redis instances available:

```shell
$ vela status redis-operator-sample --tree --detail
# DETAIL
# NAME: ha-redis REDIS: 2 SENTINELS: 2
# AGE: 17m
```
As we can see, 2 instances are available. Great.

Scale up/down. As an example, we will scale it down to 1:

```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: redis-operator-sample
spec:
components:
- type: redis-failover
name: ha-redis
properties:
# Change this value. For example, we try to scale it down to 1.
replicas: 1
```

After applying this yaml, we should see we only have 1 Redis instance available now:

```shell
$ vela status redis-operator-sample --tree --detail
# DETAIL
# NAME: ha-redis REDIS: 1 SENTINELS: 1
# AGE: 34m
```

Now, we will try to connect to the Redis cluster (specifically, connect to Sentinel service). To connect, we need to know where to connect to first. Use vela status to get the Sentinel endpoint:

```shell
$ vela status redis-operator-sample --endpoint
# +---------+-----------+------------------------------+----------------------------+-------+
# | CLUSTER | COMPONENT | REF(KIND/NAMESPACE/NAME) | ENDPOINT | INNER |
# +---------+-----------+------------------------------+----------------------------+-------+
# | local | ha-redis | Service/default/rfs-ha-redis | rfs-ha-redis.default:26379 | true |
# +---------+-----------+------------------------------+----------------------------+-------+
```

We know the endpoint is `rfs-ha-redis.default:26379`. To use `redis-cli`, we will attach a terminal to one of the Redis pods.

```shell
vela exec redis-operator-sample -- /bin/sh
# Choose rfr-ha-redis-0
```
charlie0129 marked this conversation as resolved.
Show resolved Hide resolved

Your terminal should be attached to the Pod. Inside that terminal, type:

```shell
# Connect to Sentinel
# rfs-ha-redis is the Service name of Sentinel.
# Remember our Component name (ha-redis)? It is rfs-<component-name>.
# And the port is 26379
redis-cli -h rfs-ha-redis.default -p 26379

# You should have redis-cli connected to Sentinel now.
# Now, find where the master is. `mymaster` is hard-coded by the operator
SENTINEL get-master-addr-by-name mymaster
# For example, you have results: 1) "172.17.0.6" 2) "6379"
# ctrl+D to exit and
# Use this info to connect to the master node.
redis-cli -h 172.17.0.6

# Try to store a value.
SET mykey "Hello, RedisFailover"

# Get the value.
GET mykey
# "Hello, RedisFailover"
```

## Notes

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 persistence, set `persistence.enabled` to `true`.

**IMPORTANT:** By default, the persistent volume claims will be deleted when the Redis Failover is. If this is not the expected usage, set `persistence.keepAfterDeletion` to `true`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import "encoding/base64"

"redis-failover": {
alias: "rf"
annotations: {}
attributes: {
workload: type: "autodetects.core.oam.dev"
// Currently, health checks are not achievable, because RedisFailover itself
// don't hava any fields to determine it is healthy or not (no status or anything similar).
//
// The only way I can think of is to inspect the status of Redis ReplicaSets. But
// that is not possible without VelaQL.
//
// TODO(charlie0129): add status checks once RedisFailover have `status` field
// or we can use VelaQL in healthPolicy.
//
// status: {}
}
description: "RedisFailover represents a Redis failover"
labels: {}
type: "component"
}

template: {
output: {
apiVersion: "databases.spotahome.com/v1"
kind: "RedisFailover"
metadata: name: context.name
spec: {
redis: {
replicas: parameter.replicas
if parameter.persistence.enabled {
storage: {
keepAfterDeletion: parameter.persistence.keepAfterDeletion
persistentVolumeClaim: {
metadata: name: "redisfailover-persistent-" + context.name
spec: {
accessModes: ["ReadWriteOnce"]
if parameter.persistence.size != _|_ {
resources: requests: storage: parameter.persistence.size
}
}
}
}
}
}
sentinel: {
replicas: parameter.replicas
}
if parameter.password != _|_ {
auth: secretPath: context.name + "-password"
}
}
}
outputs: {
if parameter.password != _|_ {
authSecret: {
apiVersion: "v1"
kind: "Secret"
type: "Opaque"
metadata: {
name: context.name + "-password"
}
data: password: base64.Encode(null, parameter.password)
}
}
}
parameter: {
//+usage=Number of replicas for redis and sentinel instances.
replicas: *3 | int
//+usage=Persistence-related settings.
persistence: {
//+usage=Persist to pvc. Note that data will still be deleted once redis-failover is deleted.
enabled: *false | bool
//+usage=pvc size.
size?: =~"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"
//+usage=Keep pvc even if redis-failover is deleted.
keepAfterDeletion: *false | bool
}
//+usage=Provide a Redis password to enable authorization.
password?: string
}
}
10 changes: 10 additions & 0 deletions experimental/addons/redis-operator/metadata.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: redis-operator
description: Redis Operator creates/configures/manages high availability redis with sentinel automatic failover atop Kubernetes.
tags:
- redis
version: 0.0.1
url: https://github.com/spotahome/redis-operator

system:
vela: ">=v1.5.0"
kubernetes: ">=1.19"
8 changes: 8 additions & 0 deletions experimental/addons/redis-operator/parameter.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
parameter: {
//+usage=Redis Operator image.
image: *"quay.io/spotahome/redis-operator:v1.1.0" | string
//+usage=Namespace to deploy to, defaults to vela-system
namespace?: *"vela-system" | string
//+usage=Deploy to specified clusters. Leave empty to deploy to all clusters.
clusters?: [...string]
}
Loading