apiVersion: v1
kind: Namespace
metadata:
  name: kv-store
---
apiVersion: v1
kind: Service
metadata:
  name: etcd-headless
  namespace: kv-store
  labels:
    app.kubernetes.io/name: etcd
spec:
  clusterIP: None
  publishNotReadyAddresses: true
  selector:
    app.kubernetes.io/name: etcd
  ports:
    - name: client
      port: 2379
      targetPort: client
    - name: peer
      port: 2380
      targetPort: peer
---
apiVersion: v1
kind: Service
metadata:
  name: etcd
  namespace: kv-store
  labels:
    app.kubernetes.io/name: etcd
spec:
  type: ClusterIP
  selector:
    app.kubernetes.io/name: etcd
  ports:
    - name: client
      port: 2379
      targetPort: client
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: etcd
  namespace: kv-store
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: etcd
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: etcd
  namespace: kv-store
  labels:
    app.kubernetes.io/name: etcd
spec:
  serviceName: etcd-headless
  replicas: 3
  podManagementPolicy: Parallel
  updateStrategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app.kubernetes.io/name: etcd
  template:
    metadata:
      labels:
        app.kubernetes.io/name: etcd
    spec:
      terminationGracePeriodSeconds: 30
      securityContext:
        fsGroup: 1001
      containers:
        - name: etcd
          image: quay.io/coreos/etcd:v3.5.15
          imagePullPolicy: IfNotPresent
          command:
            - /bin/sh
            - -ec
            - |
              exec etcd \
                --name="${POD_NAME}" \
                --data-dir=/var/lib/etcd \
                --listen-client-urls=http://0.0.0.0:2379 \
                --advertise-client-urls=http://${POD_NAME}.etcd-headless.${POD_NAMESPACE}.svc.cluster.local:2379 \
                --listen-peer-urls=http://0.0.0.0:2380 \
                --initial-advertise-peer-urls=http://${POD_NAME}.etcd-headless.${POD_NAMESPACE}.svc.cluster.local:2380 \
                --initial-cluster=etcd-0=http://etcd-0.etcd-headless.kv-store.svc.cluster.local:2380,etcd-1=http://etcd-1.etcd-headless.kv-store.svc.cluster.local:2380,etcd-2=http://etcd-2.etcd-headless.kv-store.svc.cluster.local:2380 \
                --initial-cluster-state=new \
                --initial-cluster-token=kv-store-prod-2026 \
                --heartbeat-interval=100 \
                --election-timeout=1000 \
                --auto-compaction-mode=periodic \
                --auto-compaction-retention=1h \
                --quota-backend-bytes=8589934592
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: client
              containerPort: 2379
            - name: peer
              containerPort: 2380
          readinessProbe:
            httpGet:
              path: /readyz
              port: client
            initialDelaySeconds: 10
            periodSeconds: 5
            timeoutSeconds: 3
            failureThreshold: 3
          livenessProbe:
            httpGet:
              path: /livez
              port: client
            initialDelaySeconds: 30
            periodSeconds: 10
            timeoutSeconds: 3
            failureThreshold: 5
          resources:
            requests:
              cpu: 500m
              memory: 1Gi
            limits:
              cpu: "2"
              memory: 4Gi
          volumeMounts:
            - name: data
              mountPath: /var/lib/etcd
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: gp3
        resources:
          requests:
            storage: 50Gi