Skip to content
Open
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
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,39 @@ helm install valkey valkey/valkey

This chart bootstraps a [Valkey](https://valkey.io) deployment using the Helm package manager.

---
## Deployment Options

### Standalone Mode
The chart deploys Valkey in standalone mode.

### Cluster Mode
To deploy Valkey in cluster mode for availability and scalability, use the following options:

#### Using Local Chart Files
To deploy the cluster mode using the local chart files:

```bash
# Navigate to the directory containing the chart
cd ./valkey-helm

# Install the chart from local files
helm install valkey-cluster ./valkey-cluster
```

#### Configuration
You can customize the installation by providing values:

```bash
helm install valkey-cluster ./valkey-cluster -f my-values.yaml
```

Cluster mode features:
- Automatic deployment of 3 master nodes and 3 replica nodes (minimum 6 nodes)
- Master-replica replication for data redundancy
- Automatic failover if a master node becomes unavailable
- Data sharding across multiple master nodes

---

## Prerequisites
Expand Down
25 changes: 25 additions & 0 deletions valkey-cluster/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

.github/
14 changes: 14 additions & 0 deletions valkey-cluster/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: v2
name: valkey-cluster
description: A Helm chart for Kubernetes
type: application
version: 0.7.5
appVersion: "8.1.4"
home: https://valkey.io/valkey-helm/
sources:
- https://github.com/valkey-io/valkey-helm.git
- https://valkey.io
maintainers:
- name: raven
url: https://github.com/mk-raven
icon: https://dyltqmyl993wv.cloudfront.net/assets/stacks/valkey/img/valkey-stack-220x234.png
103 changes: 103 additions & 0 deletions valkey-cluster/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# valkey-cluster

![Version: 0.7.5](https://img.shields.io/badge/Version-0.7.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 8.1.4](https://img.shields.io/badge/AppVersion-8.1.4-informational?style=flat-square)

A Helm chart for Kubernetes to start valkey in cluster mode with 3 master and 3 replicas

**Homepage:** <https://valkey.io/valkey-helm/>

**Cluster Mode Activation**
Valkey follows Redis clustering principles, which means:

* Cluster mode is enabled only when `replicaCount` is set to 6 or higher

This minimum of 6 nodes typically represents:

* 3 master nodes
* 3 replica nodes (one replica per master)

## Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| affinity | object | `{}` | |
| auth.aclConfig | string | `"# Users and permissions can be defined here\n# Example:\n# user default off\n# user default on >defaultpassword ~* &* +@all \n"` | |
| auth.enabled | bool | `false` | |
| commonLabels | object | `{}` | |
| containerPorts.bus | int | `16379` | |
| containerPorts.valkey | int | `6379` | |
| dataStorage.accessModes[0] | string | `"ReadWriteOnce"` | |
| dataStorage.annotations | object | `{}` | |
| dataStorage.className | string | `nil` | |
| dataStorage.enabled | bool | `false` | |
| dataStorage.labels | object | `{}` | |
| dataStorage.persistentVolumeClaimName | string | `nil` | |
| dataStorage.requestedSize | string | `nil` | |
| dataStorage.volumeName | string | `"valkey-data"` | |
| extraInitContainers | list | `[]` | |
| env | object | `{}` | |
| existingSecret | string | `""` | |
| existingSecretPasswordKey | string | `""` | |
| extraSecretValkeyConfigs | bool | `false` | |
| extraStorage | list | `[]` | |
| extraValkeyConfigs | list | `[]` | |
| extraValkeySecrets | list | `[]` | |
| fullnameOverride | string | `""` | |
| global.imageRegistry | string | `""` | |
| image.pullPolicy | string | `"IfNotPresent"` | |
| image.registry | string | `"docker.io"` | |
| image.repository | string | `"docker.io/valkey/valkey"` | |
| image.tag | string | `""` | |
| imagePullSecrets | list | `[]` | |
| initResources | object | `{}` | |
| lifecycleHooks | object | `{}` | |
| metrics.containerPorts.http | int | `9121` | |
| metrics.enabled | bool | `false` | |
| metrics.exporter.extraExporterSecrets | list | `[]` | |
| metrics.extraArgs | object | `{"is-cluster":"true","redis.addr":"redis://127.0.0.1:6379"}` | |
| metrics.image.registry | string | `"docker.io"` | |
| metrics.image.repository | string | `"oliver006/redis_exporter"` | |
| metrics.image.tag | string | `"v1.78.0-alpine"` | |
| metrics.resources | object | `{}` | |
| metrics.service.clusterIP | string | `""` | |
| metrics.service.type | string | `"ClusterIP"` | |
| nameOverride | string | `""` | |
| networkPolicy | object | `{}` | |
| nodeSelector | object | `{}` | |
| pdb.create | bool | `true` | |
| pdb.maxUnavailable | string | `""` | |
| pdb.minAvailable | string | `""` | |
| podAnnotations | object | `{}` | |
| podDisruptionBudget | object | `{}` | |
| podLabels | object | `{}` | |
| podSecurityContext.fsGroup | int | `1000` | |
| podSecurityContext.runAsGroup | int | `1000` | |
| podSecurityContext.runAsUser | int | `1000` | |
| replicaCount | int | `6` | |
| resources | object | `{}` | |
| securityContext.capabilities.drop[0] | string | `"ALL"` | |
| securityContext.readOnlyRootFilesystem | bool | `true` | |
| securityContext.runAsNonRoot | bool | `true` | |
| securityContext.runAsUser | int | `1000` | |
| service.type | string | `"ClusterIP"` | |
| serviceAccount.annotations | object | `{}` | |
| serviceAccount.automount | bool | `false` | |
| serviceAccount.create | bool | `true` | |
| serviceAccount.name | string | `""` | |
| tls.enabled | bool | `false` | |
| tolerations | list | `[]` | |
| topologySpreadConstraints | object | `{}` | |
| valkeyConfig | string | `""` | |
| valkeyLogLevel | string | `"notice"` | |


## Source Code

* <https://github.com/valkey-io/valkey-helm.git>
* <https://valkey.io>

## Maintainers

| Name | Email | Url |
| ---- | ------ | --- |
| raven | | <https://github.com/mk-raven> |
67 changes: 67 additions & 0 deletions valkey-cluster/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{{/*
NOTES for Valkey Cluster Helm Chart
This file is rendered after `helm install` / `helm upgrade`.
*/}}

⭐ Valkey has been deployed!

Release: {{ .Release.Name }}
Namespace: {{ include "valkey-cluster.names.namespace" . }}
Chart: {{ .Chart.Name }} {{ .Chart.Version }}
App version: {{ .Chart.AppVersion }}

Service: {{ include "valkey-cluster.fullname" . }}
Type: {{ .Values.service.type }}
Port: {{ .Values.service.port }}

1) In-cluster access
From another Pod:
$ valkey-cli -h {{ include "valkey-cluster.fullname" . }} -p {{ .Values.service.port }} PING

2) Local access via kubectl port-forward
$ kubectl -n {{ .Release.Namespace }} port-forward svc/{{ include "valkey-cluster.fullname" . }} 6379:{{ .Values.service.port }}
In another terminal:
$ valkey-cli -h 127.0.0.1 -p 6379 PING

{{ if eq .Values.service.type "LoadBalancer" }}
3) External access (LoadBalancer)
$ export SERVICE_IP=$(kubectl -n {{ .Release.Namespace }} get svc {{ include "valkey-cluster.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ valkey-cli -h $SERVICE_IP -p {{ .Values.service.port }} PING
{{ else if eq .Values.service.type "NodePort" }}
3) External access (NodePort)
$ export NODE_PORT=$(kubectl -n {{ .Release.Namespace }} get svc {{ include "valkey-cluster.fullname" . }} -o jsonpath='{.spec.ports[0].nodePort}')
$ export NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')
$ valkey-cli -h $NODE_IP -p $NODE_PORT PING
{{ end }}

{{ if .Values.existingSecretPasswordKey }}
🔐 Authentication is ENABLED
- Provide the username and password
- Default user:
$ valkey-cli -h {{ include "valkey-cluster.fullname" . }}-headless -p {{ .Values.containerPorts.valkey }} -a <password> PING
- Named user:
$ valkey-cli -h {{ include "valkey-cluster.fullname" . }}-headless -p {{ .Values.containerPorts.valkey }} --user <user> -a <password> PING
{{ else }}
🔓 Authentication is DISABLED
- Enable with: `--set auth.enabled=true` and provide `.auth.aclConfig`.
{{ end }}

✅ Quick test
$ valkey-cli -h {{ include "valkey-cluster.fullname" . }}-headless -p {{ .Values.containerPorts.valkey }}{{ if .Values.existingSecretPasswordKey }} --user <user> -a <password>{{ end }} -c
valkey> SET foo bar
valkey> GET foo
"bar"

{{ if .Values.dataStorage.enabled }}
💾 Persistence
- A PVC is enabled. To see it:
$ kubectl -n {{ include "valkey-cluster.names.namespace" . }} get pvc -l app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/name={{ include "valkey-cluster.name" . }}
- Note: `dataStorage.keepPvc={{ .Values.dataStorage.keepPvc }}` controls whether the PVC is kept on uninstall.
{{ else }}
💾 Persistence
- Persistence is DISABLED. Data will not survive Pod restarts.
- Enable with: `--set dataStorage.enabled=true --set dataStorage.requestedSize=5Gi` (optionally set `dataStorage.className`).
{{ end }}

🧹 Uninstall
$ helm -n {{ include "valkey-cluster.names.namespace" . }} uninstall {{ .Release.Name }}
Loading