Running Twemproxy In Kubernetes

2 minute read

In this post, i would like share on how to setup twemproxy for redis cluster sharding running in kubernetes.

Setup

These are the tasks required:

  • Running twemproxy as a single replica deployment in kubernetes.
  • Running redis replicas as statefulsets with with in kubernetes.
  • Allowing other pods in kubernetes to access twemproxy.
  • Allowing twemproxy to connect to the redis’s pods.

Twemproxy

We can run twemproxy as a single deployment in kubernetes. We can use the following community image jgoodall/twemproxy

twemproxy’s deployment & service spec:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: twemproxy
  name: twemproxy
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: twemproxy
    spec:
      containers:
      - image: jgoodall/twemproxy:latest
        name: twemproxy
        ports:
        - containerPort: 63791
        - containerPort: 63792
        - containerPort: 6222
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: twemproxy
  name: twemproxy
spec:
  selector:
    app: twemproxy
  ports:
  - name: "63791"
    port: 63791
    targetPort: 63791
  - name: "63792"
    port: 63792
    targetPort: 63792
  - name: "6222"
    port: 6222
    targetPort: 6222

The configuration above will deploy twemproxy’s deployment and service. service in kubernetes allow pods to network with each other, this service will allow other pods to reach twemproxy.

twemproxy.yml:

local:
  listen: 0.0.0.0:63791
  hash: fnv1a_64
  hash_tag: "{}"
  distribution: ketama
  timeout: 500
  redis: true
  servers:
    - redis-0:6379:1
    - redis-1:6379:1
    - redis-2:6379:1

session:
  listen: 0.0.0.0:63792
  hash: fnv1a_64
  hash_tag: "{}"
  distribution: ketama
  auto_eject_hosts: true
  server_retry_timeout: 30000
  server_failure_limit: 3
  timeout: 500
  redis: true
  servers:
    - redis-0:6379:1
    - redis-1:6379:1
    - redis-2:6379:1

Above is twemproxy’s configuration which need to be mount as configmap volume in twemproxy’s deployment.

Redis Statefulset

Next, we need to create redis’s statefulset. Statefulset with 3 replicas will create the following pods redis-0, redis-1 and redis-2. Pods created by statefulset will be labeled as statefulset.kubernetes.io/pod-name: , we can use this as selector for the service. Unfortunably, we will still need to create 3 services to allow each pod to be addressable by twemproxy,

redis statefulset:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: redis
  serviceName: "redis"
  replicas: 3
  template:
    metadata:
      labels:
        app: redis
    spec:
      terminationGracePeriodSeconds: 3
      containers:
      - name: redis
        image: redis:3.0.7
        ports:
        - containerPort: 6379

redis services:

apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    app: redis
spec:
  ports:
  - port: 6379
    name: redis
  clusterIP: None
  selector:
    app: redis
---
apiVersion: v1
kind: Service
metadata:
  name: redis-1
  labels:
    app: redis-1
spec:
  ports:
  - port: 6379
    name: redis-1
  clusterIP: None
  selector:
    statefulset.kubernetes.io/pod-name: redis-1
---
apiVersion: v1
kind: Service
metadata:
  name: redis-1
  labels:
    app: redis-1
spec:
  ports:
  - port: 6379
    name: redis-1
  clusterIP: None
  selector:
    statefulset.kubernetes.io/pod-name: redis-1
---
apiVersion: v1
kind: Service
metadata:
  name: redis-2
  labels:
    app: redis-2
spec:
  ports:
  - port: 6379
    name: redis-2
  clusterIP: None
  selector:
    statefulset.kubernetes.io/pod-name: redis-2