Deploy the same deployment several times in Kubernetes

10/17/2016

I intend to deploy my online service that depends on Redis servers in Kubernetes. So far I have:

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
    name: "redis"
spec:
    replicas: 1
template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - name: redis
          image: redis
          ports:
            - containerPort: 6379
              protocol: TCP

I can also expose redis as a service with:

apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    app: redis
spec:
  ports:
  - port: 6379
    protocol: TCP
  selector:
    app: redis

With this, I can run a single pod with a Redis server and expose it.

However, my application needs to contact several Redis servers (this can be configured but ideally should not change live). It does care which Redis server it talks to so I can't just use replicas and expose it a single service as the service abstraction would not allow me to know which instance I am talking too. I understand that the need for my application to know this hinders scalability and am happy to loose some flexibility as a result.

I thought of deploying the same deployment several times and declaring a service for each, but I could not find anything to do that in the Kubernetes documentation. I could of course copy-paste my deployment and service YAML files and adding a suffix for each but this seems silly and way too manual (and frankly too complex).

Is there anything in Kubernetes to help me achieve my goal ?

-- ereOn
kubernetes
redis

1 Answer

10/18/2016

You should look into pet sets. A pet set will get a unique, but determinable, name per instance like redis0, redis1, redis2. They are also treated as pets opposed to deployment pods, which are treated as cattle.

Be advised that pet sets are harder to upgrade, delete and handle in general, but thats the price of getting the reliability and determinability.

Your deployment as pet set:

apiVersion: apps/v1alpha1
kind: PetSet
metadata:
  name: redis
spec:
  serviceName: "redis"
  replicas: 3
  template:
    metadata:
      labels:
        app: redis
      annotations:
        pod.alpha.kubernetes.io/initialized: "true"
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: redis
        image: redis
        ports:
        - containerPort: 6379
          protocol: TCP

Also consider to use volumes to make it easier to access data in the pods.

-- Emil Ingerslev
Source: StackOverflow