Helm Chart for an etcd Cluster
Tags: etcd, helm, kubernetes
Published: 2023-08-06 03:43:52


Deploying applications on Kubernetes can often be a complex process. Helm charts simplify this by creating a package of pre-configured Kubernetes resources. In this post, we're going to create a Helm chart to deploy a production-ready etcd cluster.

## What is a Helm Chart?
A Helm chart is a collection of files that describe a related set of Kubernetes resources. A single chart might be used to deploy something simple, like a memcached pod, or something complex, like a full web application stack with HTTP servers, databases, caches, and so on.

## Prerequisites
- A Kubernetes Cluster ready
- [kubectl](https://kubernetes.io/docs/reference/kubectl/)
- [Helm3](https://helm.sh/blog/helm-3-released/)

__Installation__

First, download Helm's installation script:
```sh
$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh
```
Next, give the script executable permissions:
```sh
$ chmod 700 get_helm.sh
```
Finally, run the installation script:
```sh
$ ./get_helm.sh
```

## Setting Up the Helm Chart

Creating a Helm chart involves creating a specific directory structure with several different files. Here's a simple outline of our etcd Helm chart:

```sh
etcd/
├── Chart.yaml
├── templates/
│   ├── _helpers.tpl
│   ├── service.yaml
│   ├── statefulset.yaml
│   └── pvc.yaml
└── values.yaml
```

## Understanding the Chart Files
__Chart.yaml:__ This is where we define the chart's metadata. 
Here's an example:
```yaml
apiVersion: v3
name: etcd
version: 0.1.0
description: A Helm chart for deploying an etcd cluster in Kubernetes
```
__templates/:__ This directory contains the template files that generate Kubernetes manifest files when the chart is installed.

**_helpers.tpl:** This is a place to put template helpers that you can reuse throughout your chart.

```yaml
{{/* Generate the name */}}
{{- define "etcd.fullname" -}}
{{- .Chart.Name }}-{{ .Release.Name }}
{{- end -}}
```
__service.yaml:__ This file defines a Service, which can be used to access your etcd cluster from other applications in your Kubernetes cluster.
```yaml
apiVersion: v1
kind: Service
metadata:
  name: {{ include "etcd.fullname" . }}
spec:
  clusterIP: None
  ports:
    - port: 2379
      name: client
    - port: 2380
      name: peer
  selector:
    app: etcd
```
__statefulset.yaml:__ This file defines a StatefulSet, which is used to manage the etcd Pods.
```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ include "etcd.fullname" . }}
spec:
  serviceName: "{{ include "etcd.fullname" . }}"
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: etcd
  template:
    metadata:
      labels:
        app: etcd
    spec:
      containers:
      - name: etcd
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        ports:
        - containerPort: 2379
          name: client
        - containerPort: 2380
          name: peer
        volumeMounts:
        - name: data
          mountPath: /var/run/etcd
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: {{ .Values.storageClass }}
      resources:
        requests:
          storage: {{ .Values.storageSize }}
```
__pvc.yaml:__ Persistent Volume Claim (PVC) for storage of etcd data.

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: {{ .Values.storageClass }}
  resources:
    requests:
      storage: {{ .Values.storageSize }}
```
__values.yaml:__ This is where you define the default values for your chart. Here's a simple example:
```yaml
replicaCount: 3
image:
  repository: quay.io/coreos/etcd
  tag: v3.5.0
storageClass: standard
storageSize: 1Gi
```
## Run your etcd Helm chart
Make sure you are in the proper `kubectl` context and create a namespace named `etcd`.

```sh
$ kubectl create namespace etcd
```
Navigate to the directory containing the Chart files
```sh
$ helm install etcd-cluster . --namespace etcd
```
Output:
```sh
NAME: etcd-cluster
LAST DEPLOYED: Sat Aug  5 23:15:25 2023
NAMESPACE: etcd
STATUS: deployed
REVISION: 1
TEST SUITE: None
```
Get the resources
```sh
$ kubectl get all -n etcd 
```

Output:
```sh
NAME                      READY   STATUS    RESTARTS   AGE
pod/etcd-etcd-cluster-0   1/1     Running   0          104s
pod/etcd-etcd-cluster-1   1/1     Running   0          96s
pod/etcd-etcd-cluster-2   1/1     Running   0          91s

NAME                        TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)             AGE
service/etcd-etcd-cluster   ClusterIP   None         <none>        2379/TCP,2380/TCP   104s

NAME                                 READY   AGE
statefulset.apps/etcd-etcd-cluster   3/3     104s
```
## Conclusion
This Helm chart sets up an etcd cluster on a Kubernetes environment, using best practices such as StatefulSets for pod identity and PVCs for data persistence.

This setup, however, is quite basic and might need to be adjusted based on your specific use case or production environment. Always remember to test your Helm charts thoroughly in a staging environment before deploying them in production.