Introduction to Kubernetes StatefulSet
Tags: kubernetes, statefulset, etcd
Published: 2023-07-28 02:15:55

StatefulSet is one of the workload APIs in Kubernetes that manages the deployment and scaling of a set of Pods. It maintains a sticky identity for each of their pods and guarantees that these identities are unique across the cluster. This makes it suitable for applications that require stable, unique network identifiers, stable persistent storage, and ordered deployment and scaling.

One such application is `etcd`, a reliable key-value store used in clusters environments for distributed configuration management and service discovery.

## Kubernetes StatefulSet in Brief
StatefulSet maintains a sticky, unique identity for each pod, making them a perfect solution for maintaining the state or identity of an application. StatefulSets are crucial when running distributed computing systems or systems that maintain their own client connections, like databases.

StatefulSet's key properties are:

1. __Stable, unique network identifiers:__ Each pod from a StatefulSet gets a hostname that is derived from the name of the StatefulSet and the ordinal of the Pod.
2. __Stable, persistent storage:__ Pods in a StatefulSet can have stable persistent storage volumes, ensuring that data persists across pod rescheduling.
3. __Ordered, graceful deployment and scaling:__ Pods are created sequentially and in reverse order during scaling.

[Limitations](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#limitations)

## etcd in Brief
etcd is a distributed, reliable key-value store that is simple, secure, and fast. It is primarily used as the primary datastore of Kubernetes to store all its cluster state, including the state of nodes, pods, configs, secrets, accounts, roles, bindings, and others.

__Key features of etcd include:__

1. __Simple:__ etcd has a simple binary that you can run locally or in a docker container. Its APIs are also simple to understand and use, making it ideal for use with almost any programming language.

2. __Secure:__ etcd supports automatic TLS with optional client cert authentication.

3. __Fast:__ A typical etcd cluster can do 10,000 writes per second.

4. __Reliable:__ With its distributed nature, etcd gracefully handles network partitions and machine failures, even in the leader node.

__The following are some of the main use cases of etcd:__

1. __Store configuration data:__ You can use etcd to store configurations for your applications and continuously watch for any changes.

2. __Service discovery:__ etcd allows systems to announce themselves to others, which can find them using etcd's watch functionality.

3. __Distributed coordination:__ etcd provides primitives like distributed locks which can be used to build distributed coordination systems.

etcd is written in Go and uses the Raft consensus algorithm to manage a highly-available replicated log.

### Deploying etcd as a Kubernetes Cluster Service
Now let's go through the deployment process for an etcd cluster.

- __etcd StatefulSet Configuration__

Create a StatefulSet configuration file named etcd-statefulset.yaml.
```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: etcd
spec:
  serviceName: "etcd"
  replicas: 3
  selector:
    matchLabels:
      app: etcd
  template:
    metadata:
      labels:
        app: etcd
    spec:
      containers:
      - name: etcd
        image: quay.io/coreos/etcd:v3.4.15
        ports:
        - containerPort: 2379
          name: client
        - containerPort: 2380
          name: peer
        volumeMounts:
        - name: data
          mountPath: /var/run/etcd
        env:
        - name: ETCD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: ETCD_INITIAL_CLUSTER
          value: etcd-0=http://etcd-0.etcd:2380,etcd-1=http://etcd-1.etcd:2380,etcd-2=http://etcd-2.etcd:2380
        - name: ETCD_INITIAL_CLUSTER_STATE
          value: new
        - name: ETCD_DATA_DIR
          value: /var/run/etcd/default.etcd
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi
```
This configuration declares a StatefulSet named etcd that runs 3 replicas of the etcd server.

- __Deploy the StatefulSet__

Apply the StatefulSet configuration using the kubectl apply command.

```sh
kubectl apply -f etcd-statefulset.yaml
```

- __Verifying the etcd Cluster__

Use the following command to check if the etcd pods are running:

```sh
kubectl get pods -l "app=etcd"
```
Output:

```sh
NAME     READY   STATUS    RESTARTS      AGE
etcd-0   1/1     Running   1 (26s ago)   57s
etcd-1   1/1     Running   1 (25s ago)   56s
etcd-2   1/1     Running   1 (23s ago)   54s
```
- __Accessing the etcd Cluster__

For accessing the etcd service, you can expose it as a NodePort or LoadBalancer service. Here is an example of how to expose it as a NodePort service:

```sh
apiVersion: v1
kind: Service
metadata:
  name: etcd-client
spec:
  type: NodePort
  ports:
    - port: 2379
      targetPort: 2379
      nodePort: 32379
  selector:
    app: etcd
```

Save the above service configuration as etcd-service.yaml and then use kubectl apply command to deploy it.

```sh
kubectl apply -f etcd-service.yaml
```

Use the following command to check the service:

```sh
kubectl get services
```

Output:

```sh
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
etcd-client   NodePort    10.96.144.250   <none>        2379:32379/TCP   17s

```

You should now be able to interact with your etcd cluster from any machine that can reach your Kubernetes nodes.

With Kubernetes StatefulSet, you can easily deploy stateful applications like etcd. It provides stable network identity, storage, and ordered, graceful deployment and scaling, which are vital in the real-world applications.