Search code examples
kubernetesactivemq-classickubernetes-pvc

ActiveMQ on Kuberenetes with Shared storage


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

Solution

  • 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.