ActiveMQ on Kuberenetes with Shared storage

7/31/2019

I have existing applications built with Apache Camel and ActiveMQ. As part of migration to Kubernetes, what we are doing is moving the same services developed with Apache Camel to Kubernetes. I need to deploy ActiveMQ such that I do not lose the data in case one of the Pod dies.

What I am doing now is running a deployment with RelicaSet value to 2. This will start 2 pods and with a Service in front, I can serve any request while atleast 1 Pod is up. However, if one Pod dies, i do not want to lose the data. I want to implement something like a shared file system between the Pods. My environment is in AWS so I can use EBS. Can you suggest, how to achieve that.

Below is my deployment and service YAML.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: smp-activemq
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: smp-activemq
    spec:
      containers:
        - name: smp-activemq
          image: dasdebde/activemq:5.15.9
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 61616
          resources:
            limits:
              memory: 512Mi

---
apiVersion: v1
kind: Service
metadata:
  name: smp-activemq
spec:
  type: NodePort
  selector:
    app: smp-activemq
  ports:
    - nodePort: 32191
      port: 61616
      targetPort: 61616
-- Debdeep Das
activemq
kubernetes
kubernetes-pvc

2 Answers

8/2/2019

StatefulSets are valuable for applications that require stable, persistent storage. Deleting and/or scaling a StatefulSet down will not delete the volumes associated with the StatefulSet. This is done to ensure data safety. The "volumeClaimTemplates" part in yaml will provide stable storage using PersistentVolumes provisioned by a PersistentVolume Provisioner.

In your case, StatefulSet file definition will look similar to this:

apiVersion: v1
kind: Service
metadata:
  name: smp-activemq
  labels:
    app: smp-activemq
spec:
  type: NodePort
  selector:
    app: smp-activemq
  ports:
  - nodePort: 32191
    port: 61616
    name: smp-activemq
    targetPort: 61616

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: smp-activemq
spec:
  selector:
    matchLabels:
      app: smp-activemq
  serviceName: smp-activemq
  replicas: 1
  template:
    metadata:
      labels:
        app: smp-activemq
    spec:
      containers:
      - name: smp-activemq
        image: dasdebde/activemq:5.15.9
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 61616
          name: smp-activemq
        volumeMounts:
        - name: www
          mountPath: <mount-path>
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "<storageclass-name>"
      resources:
        requests:
          storage: 1Gi

That what you need to define is your StorageClass name and mountPath. I hope it will helps you.

-- muscat
Source: StackOverflow

7/31/2019

In high-level terms, what you want is a StatefulSet instead of a Deployment for your ActiveMQ. You are correct that you want "shared file system" -- in kubernetes this is expressed as a "Persistent Volume", which is made available to the pods in your StatefulSet using a "Volume Mount".

These are the things you need to look up.

-- Andrew McGuinness
Source: StackOverflow