diff --git a/README.md b/README.md index edb08582e..d4532eea6 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,159 @@ ## Overview -Redis Cluster Operator setup a [Redis Cluster](https://redis.io/topics/cluster-spec) atop Kubernetes. \ No newline at end of file +Redis Cluster Operator manages [Redis Cluster](https://redis.io/topics/cluster-spec) atop Kubernetes. + +The operator itself is built with the [Operator framework](https://github.com/operator-framework/operator-sdk). + +![Redis Cluster atop Kubernetes](/static/redis-cluster.png) + +## Prerequisites + +* go version v1.12+. +* Access to a Kubernetes v1.13.3 cluster. + +## Features + +- __Customize the number of master nodes and the number of replica nodes per master__ + +- __Password__ + +- __Safely Scaling the Redis Cluster__ + +- __Backup and Restore__ + +- __Persistent Volume__ + +- __Custom Configuration__ + +- __Prometheus Discovery__ + + +## Quick Start + +### Deploy redis cluster operator + +Register the DistributedRedisCluster and RedisClusterBackup custom resource definition (CRD). +``` +$ kubectl create -f deploy/crds/redis.kun_distributedredisclusters_crd.yaml +$ kubectl create -f deploy/crds/redis.kun_redisclusterbackups_crd.yaml +``` + +A namespace-scoped operator watches and manages resources in a single namespace, whereas a cluster-scoped operator watches and manages resources cluster-wide. +You can chose run your operator as namespace-scoped or cluster-scoped. +``` +// cluster-scoped +$ kubectl create -f deploy/service_account.yaml +$ kubectl create -f deploy/cluster/cluster_role.yaml +$ kubectl create -f deploy/cluster/cluster_role_binding.yaml +$ kubectl create -f deploy/cluster/operator.yaml + +// namespace-scoped +$ kubectl create -f deploy/service_account.yaml +$ kubectl create -f deploy/namespace/role.yaml +$ kubectl create -f deploy/namespace/role_binding.yaml +$ kubectl create -f deploy/namespace/operator.yaml +``` + +Verify that the redis-cluster-operator is up and running: +``` +$ kubectl get deployment +NAME READY UP-TO-DATE AVAILABLE AGE +redis-cluster-operator 1/1 1 1 1d +``` + +#### Deploy a sample Redis Cluster + +``` +$ kubectl apply -f deploy/example/redis.kun_v1alpha1_distributedrediscluster_cr.yaml +``` + +Verify that the cluster instances and its components are running. +``` +$ kubectl get distributedrediscluster +NAME MASTERSIZE STATUS AGE +example-distributedrediscluster 3 Scaling 11s + +$ kubectl get all -l redis.kun/name=example-distributedrediscluster +NAME READY STATUS RESTARTS AGE +pod/drc-example-distributedrediscluster-0 1/1 Running 0 4m5s +pod/drc-example-distributedrediscluster-1 1/1 Running 0 3m31s +pod/drc-example-distributedrediscluster-2 1/1 Running 0 2m54s +pod/drc-example-distributedrediscluster-3 1/1 Running 0 2m20s +pod/drc-example-distributedrediscluster-4 1/1 Running 0 103s +pod/drc-example-distributedrediscluster-5 1/1 Running 0 62s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/example-distributedrediscluster ClusterIP None 6379/TCP,16379/TCP 4m5s + +NAME READY AGE +statefulset.apps/drc-example-distributedrediscluster 6/6 4m5s + +$ kubectl get distributedrediscluster +NAME MASTERSIZE STATUS AGE +example-distributedrediscluster 3 Healthy 4m +``` + +#### Scaling the Redis Cluster + +Increase the masterSize to trigger the scaling. + +``` +apiVersion: redis.kun/v1alpha1 +kind: DistributedRedisCluster +metadata: + name: example-distributedrediscluster +spec: + # Increase the masterSize to trigger the scaling. + masterSize: 4 + ClusterReplicas: 1 + image: redis:5.0.4-alpine +``` + +#### Backup and Restore + +Backup +``` +$ kubectl create -f deploy/example/backup-restore/redisclusterbackup_cr.yaml +``` + +Restore from backup +``` +$ kubectl create -f deploy/example/backup-restore/restore.yaml +``` + +#### Prometheus Discovery + +``` +$ kubectl create -f deploy/example/prometheus-exporter.yaml +``` + +#### Create Redis Cluster with password + +``` +$ kubectl create -f deploy/example/custom-password.yaml +``` + +#### Persistent Volume + +``` +$ kubectl create -f deploy/example/persistent.yaml +``` + +#### Custom Configuration + +``` +$ kubectl create -f deploy/example/custom-config.yaml +``` + +#### Custom Headless Service + +``` +$ kubectl create -f deploy/example/custom-service.yaml +``` + +#### Custom Resource + +``` +$ kubectl create -f deploy/example/custom-resources.yaml +``` \ No newline at end of file diff --git a/deploy/role.yaml b/deploy/cluster/cluster_role.yaml similarity index 100% rename from deploy/role.yaml rename to deploy/cluster/cluster_role.yaml diff --git a/deploy/cluster/cluster_role_binding.yaml b/deploy/cluster/cluster_role_binding.yaml new file mode 100644 index 000000000..19673ee10 --- /dev/null +++ b/deploy/cluster/cluster_role_binding.yaml @@ -0,0 +1,12 @@ +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: redis-cluster-operator +subjects: +- kind: ServiceAccount + name: redis-cluster-operator + namespace: default +roleRef: + kind: ClusterRole + name: redis-cluster-operator + apiGroup: rbac.authorization.k8s.io diff --git a/deploy/cluster/operator.yaml b/deploy/cluster/operator.yaml new file mode 100644 index 000000000..f4c73bb2c --- /dev/null +++ b/deploy/cluster/operator.yaml @@ -0,0 +1,31 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis-cluster-operator +spec: + replicas: 1 + selector: + matchLabels: + name: redis-cluster-operator + template: + metadata: + labels: + name: redis-cluster-operator + spec: + serviceAccountName: redis-cluster-operator + containers: + - name: redis-cluster-operator + # Replace this with the built image name + image: uhub.service.ucloud.cn/operator/redis-cluster-operator:latest + command: + - redis-cluster-operator + imagePullPolicy: Always + env: + - name: WATCH_NAMESPACE + value: "" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: "redis-cluster-operator" diff --git a/deploy/crds/redis.kun_v1alpha1_redisclusterbackup_cr.yaml b/deploy/crds/redis.kun_v1alpha1_redisclusterbackup_cr.yaml deleted file mode 100644 index fd9e18bef..000000000 --- a/deploy/crds/redis.kun_v1alpha1_redisclusterbackup_cr.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: redis.kun/v1alpha1 -kind: RedisClusterBackup -metadata: - name: example-redisclusterbackup -spec: - # Add fields here - size: 3 diff --git a/deploy/example/backup-restore/redisclusterbackup_cr.yaml b/deploy/example/backup-restore/redisclusterbackup_cr.yaml new file mode 100644 index 000000000..d881435ec --- /dev/null +++ b/deploy/example/backup-restore/redisclusterbackup_cr.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +data: + AWS_ACCESS_KEY_ID: dGVzdA== + AWS_SECRET_ACCESS_KEY: dGVzdA== +kind: Secret +metadata: + name: s3-secret +type: Opaque +--- +apiVersion: redis.kun/v1alpha1 +kind: RedisClusterBackup +metadata: + name: example-redisclusterbackup +spec: + image: uhub.service.ucloud.cn/operator/redis-tools:5.0.4 + redisClusterName: example-distributedrediscluster + storageSecretName: s3-secret + # Replace this with the s3 info + s3: + endpoint: REPLACE_ENDPOINT + bucket: REPLACE_BUCKET diff --git a/deploy/example/backup-restore/restore.yaml b/deploy/example/backup-restore/restore.yaml new file mode 100644 index 000000000..a25bc23e3 --- /dev/null +++ b/deploy/example/backup-restore/restore.yaml @@ -0,0 +1,9 @@ +apiVersion: redis.kun/v1alpha1 +kind: DistributedRedisCluster +metadata: + name: example-restore +spec: + init: + backupSource: + name: example-redisclusterbackup + namespace: default \ No newline at end of file diff --git a/deploy/example/custom-config.yaml b/deploy/example/custom-config.yaml new file mode 100644 index 000000000..09ce59a01 --- /dev/null +++ b/deploy/example/custom-config.yaml @@ -0,0 +1,28 @@ +apiVersion: redis.kun/v1alpha1 +kind: DistributedRedisCluster +metadata: + name: example-distributedrediscluster +spec: + image: uhub.service.ucloud.cn/operator/redis:5.0.4-alpine + masterSize: 3 + clusterReplicas: 1 + config: + activerehashing: "yes" + appendfsync: everysec + appendonly: "yes" + hash-max-ziplist-entries: "512" + hash-max-ziplist-value: "64" + hll-sparse-max-bytes: "3000" + list-compress-depth: "0" + maxmemory-policy: noeviction + maxmemory-samples: "5" + no-appendfsync-on-rewrite: "no" + notify-keyspace-events: "" + set-max-intset-entries: "512" + slowlog-log-slower-than: "10000" + slowlog-max-len: "128" + stop-writes-on-bgsave-error: "yes" + tcp-keepalive: "0" + timeout: "0" + zset-max-ziplist-entries: "128" + zset-max-ziplist-value: "64" diff --git a/deploy/example/custom-password.yaml b/deploy/example/custom-password.yaml new file mode 100644 index 000000000..2295fad8c --- /dev/null +++ b/deploy/example/custom-password.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Secret +metadata: + name: mysecret +type: Opaque +data: + password: MWYyZDFlMmU2N2Rm +--- +apiVersion: redis.kun/v1alpha1 +kind: DistributedRedisCluster +metadata: + name: example-distributedrediscluster +spec: + image: uhub.service.ucloud.cn/operator/redis:5.0.4-alpine + masterSize: 3 + clusterReplicas: 1 + rootPasswordSecret: + name: mysecret + resources: + limits: + cpu: 200m + memory: 200Mi + requests: + cpu: 200m + memory: 100Mi diff --git a/deploy/example/custom-resources.yaml b/deploy/example/custom-resources.yaml new file mode 100644 index 000000000..0ba03edbc --- /dev/null +++ b/deploy/example/custom-resources.yaml @@ -0,0 +1,15 @@ +apiVersion: redis.kun/v1alpha1 +kind: DistributedRedisCluster +metadata: + name: example-distributedrediscluster +spec: + image: uhub.service.ucloud.cn/operator/redis:5.0.4-alpine + masterSize: 3 + clusterReplicas: 1 + resources: + limits: + cpu: 200m + memory: 200Mi + requests: + cpu: 200m + memory: 100Mi \ No newline at end of file diff --git a/deploy/example/custom-service.yaml b/deploy/example/custom-service.yaml new file mode 100644 index 000000000..76d561d5e --- /dev/null +++ b/deploy/example/custom-service.yaml @@ -0,0 +1,9 @@ +apiVersion: redis.kun/v1alpha1 +kind: DistributedRedisCluster +metadata: + name: example-distributedrediscluster +spec: + image: uhub.service.ucloud.cn/operator/redis:5.0.4-alpine + masterSize: 3 + clusterReplicas: 1 + serviceName: redis-svc \ No newline at end of file diff --git a/deploy/example/persistent.yaml b/deploy/example/persistent.yaml new file mode 100644 index 000000000..9699185c0 --- /dev/null +++ b/deploy/example/persistent.yaml @@ -0,0 +1,13 @@ +apiVersion: redis.kun/v1alpha1 +kind: DistributedRedisCluster +metadata: + name: example-distributedrediscluster +spec: + image: uhub.service.ucloud.cn/operator/redis:5.0.4-alpine + masterSize: 3 + clusterReplicas: 1 + storage: + type: persistent-claim + size: 1Gi + class: csi-rbd-sc + deleteClaim: true \ No newline at end of file diff --git a/deploy/example/prometheus-exporter.yaml b/deploy/example/prometheus-exporter.yaml new file mode 100644 index 000000000..007381c72 --- /dev/null +++ b/deploy/example/prometheus-exporter.yaml @@ -0,0 +1,10 @@ +apiVersion: redis.kun/v1alpha1 +kind: DistributedRedisCluster +metadata: + name: example-distributedrediscluster +spec: + image: uhub.service.ucloud.cn/operator/redis:5.0.4-alpine + masterSize: 3 + clusterReplicas: 1 + monitor: + image: oliver006/redis_exporter \ No newline at end of file diff --git a/deploy/crds/redis.kun_v1alpha1_distributedrediscluster_cr.yaml b/deploy/example/redis.kun_v1alpha1_distributedrediscluster_cr.yaml similarity index 86% rename from deploy/crds/redis.kun_v1alpha1_distributedrediscluster_cr.yaml rename to deploy/example/redis.kun_v1alpha1_distributedrediscluster_cr.yaml index 14469e586..d9c38e17a 100644 --- a/deploy/crds/redis.kun_v1alpha1_distributedrediscluster_cr.yaml +++ b/deploy/example/redis.kun_v1alpha1_distributedrediscluster_cr.yaml @@ -6,4 +6,4 @@ spec: # Add fields here masterSize: 3 ClusterReplicas: 1 - serviceName: redis-nodes + image: redis:5.0.4-alpine diff --git a/deploy/operator.yaml b/deploy/namespace/operator.yaml similarity index 91% rename from deploy/operator.yaml rename to deploy/namespace/operator.yaml index 19366e547..e4aec0982 100644 --- a/deploy/operator.yaml +++ b/deploy/namespace/operator.yaml @@ -16,7 +16,7 @@ spec: containers: - name: redis-cluster-operator # Replace this with the built image name - image: REPLACE_IMAGE + image: uhub.service.ucloud.cn/operator/redis-cluster-operator:latest command: - redis-cluster-operator imagePullPolicy: Always diff --git a/deploy/namespace/role.yaml b/deploy/namespace/role.yaml new file mode 100644 index 000000000..a32cb4e48 --- /dev/null +++ b/deploy/namespace/role.yaml @@ -0,0 +1,95 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: redis-cluster-operator +rules: + - apiGroups: + - "" + resources: + - pods + - secrets + - endpoints + - persistentvolumeclaims + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - configmaps + - secrets + - services + - events + - persistentvolumeclaims + verbs: + - create + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - batch + resources: + - jobs + verbs: + - create + - get + - list + - patch + - update + - watch + - apiGroups: + - apps + resources: + - deployments + - replicasets + - statefulsets + verbs: + - create + - get + - list + - patch + - update + - watch + - apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - create + - get + - list + - patch + - update + - watch + - apiGroups: + - apps + resourceNames: + - redis-operator + resources: + - deployments/finalizers + verbs: + - update + - apiGroups: + - redis.kun + resources: + - '*' + - redisclusterbackups + verbs: + - delete + - deletecollection + - get + - list + - patch + - update + - watch \ No newline at end of file diff --git a/deploy/role_binding.yaml b/deploy/namespace/role_binding.yaml similarity index 92% rename from deploy/role_binding.yaml rename to deploy/namespace/role_binding.yaml index e8728a8ac..fd81daee2 100644 --- a/deploy/role_binding.yaml +++ b/deploy/namespace/role_binding.yaml @@ -5,6 +5,7 @@ metadata: subjects: - kind: ServiceAccount name: redis-cluster-operator + namespace: default roleRef: kind: Role name: redis-cluster-operator diff --git a/static/redis-cluster.png b/static/redis-cluster.png new file mode 100644 index 000000000..57a819656 Binary files /dev/null and b/static/redis-cluster.png differ