Running Twemproxy In Kubernetes
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 inkubernetes
. - Running
redis
replicas as statefulsets with with inkubernetes
. - Allowing other
pods
inkubernetes
to accesstwemproxy
. - Allowing
twemproxy
to connect to the redis’spods
.
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