Deploying your App
Deploying on Kubernetes

Deploying on Kubernetes

Moose applications can be deployed to Kubernetes clusters, whether it's your own on-prem cluster or through a cloud service like Google's Kubernetes Engine (GKE) or Amazon's Elastic Kubernetes Service (EKS).

Launch a Single Instance

Note at this time, we recommend that you only launch a single instance of moose in one cluster. We're currently developing for multi-instance concurrent usage.

Essentially you'll need to create a moose-deployment YAML file. Here is an example:

moose-deployment.yaml-fragment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: moosedeployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: moosedeploy
  template:
    metadata:
      labels:
        app: moosedeploy
        ver: v1
    spec:
      containers:
        - name: moosedeploy
          image: 514labs/moose-df-deployment-x86_64-unknown-linux-gnu:latest
          ports:
            - containerPort: 4000

Make sure to update the image key above with the location of your repository and image tag.

You may also need to configure a load balancer to route external traffic to your moose ingest points.

moose-lb-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: moose-service
spec:
  selector:
    app: moosedeploy
  ports:
    - protocol: TCP
      port: 4000
      targetPort: 4000
  type: LoadBalancer

Another approach would be to use a service type of ClusterIP:

moose-service.yaml
piVersion: v1
kind: Service
metadata:
  name: moose-service
spec:
  selector:
    app: moosedeploy
  type: ClusterIP
  ports:
    - protocol: TCP
      port: 4000
      targetPort: 4000

The approach you decide on will depend on your specific GKE networking requirements.

Setting up a health check

Your generated moose docker containers feature an internal health check:

  # Setup healthcheck
  HEALTHCHECK --interval=30s --timeout=3s \
    CMD curl -f http://localhost:4000/health || exit 1

In the moose-deployment.yaml file below, you'll see a block that describes the health check endpoint.

  readinessProbe:
    httpGet:
      path: /health
      port: 4000

This will allow Kubernetes to determine the health of your moose application.

Configuring container environment variables

Inside your moose-deployment.yaml file, you will need to add an env section for environment variables. In the following example, we use Kubernetes secrets, an industry best practice for this.

moose-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: moosedeployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: moosedeploy
  template:
    metadata:
      labels:
        app: moosedeploy
        ver: v1
    spec:
      containers:
        - name: moosedeploy
          image: 514labs/moose-df-deployment-x86_64-unknown-linux-gnu:latest
          ports:
            - containerPort: 4000
          readinessProbe:
            httpGet:
              path: /health
              port: 4000
          env:
            - name: RUST_BACKTRACE
              value: "1"
            - name: MOOSE_REDPANDA_CONFIG__BROKER
              valueFrom:
                secretKeyRef:
                  name: sn-moose-redpanda-config--broker
                  key: sk-moose-redpanda-config--broker
            - name: MOOSE_REDPANDA_CONFIG__MESSAGE_TIMEOUT_MS
              valueFrom:
                secretKeyRef:
                  name: sn-moose-redpanda-config--message-timeout-ms
                  key: sk-moose-redpanda-config--message-timeout-ms
            - name: MOOSE_REDPANDA_CONFIG__SASL_USERNAME
              valueFrom:
                secretKeyRef:
                  name: sn-moose-redpanda-config--sasl-username
                  key: sk-moose-redpanda-config--sasl-username
            - name: MOOSE_REDPANDA_CONFIG__SASL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: sn-moose-redpanda-config--sasl-password
                  key: sk-moose-redpanda-config--sasl-password
            - name: MOOSE_REDPANDA_CONFIG__SASL_MECHANISM
              valueFrom:
                secretKeyRef:
                  name: sn-moose-redpanda-config--sasl-mechanism
                  key: sk-moose-redpanda-config--sasl-mechanism
            - name: MOOSE_REDPANDA_CONFIG__SECURITY_PROTOCOL
              valueFrom:
                secretKeyRef:
                  name: sn-moose-redpanda-config--security-protocol
                  key: sk-moose-redpanda-config--security-protocol
            - name: MOOSE_CLICKHOUSE_CONFIG__DB_NAME
              valueFrom:
                secretKeyRef:
                  name: sn-moose-clickhouse-config--db-name
                  key: sk-moose-clickhouse-config--db-name
            - name: MOOSE_CLICKHOUSE_CONFIG__USER
              valueFrom:
                secretKeyRef:
                  name: sn-moose-clickhouse-config--user
                  key: sk-moose-clickhouse-config--user
            - name: MOOSE_CLICKHOUSE_CONFIG__PASSWORD
              valueFrom:
                secretKeyRef:
                  name: sn-moose-clickhouse-config--password
                  key: sk-moose-clickhouse-config--password
            - name: MOOSE_CLICKHOUSE_CONFIG__HOST
              valueFrom:
                secretKeyRef:
                  name: sn-moose-clickhouse-config--host
                  key: sk-moose-clickhouse-config--host
            - name: MOOSE_CLICKHOUSE_CONFIG__HOST_PORT
              valueFrom:
                secretKeyRef:
                  name: sn-moose-clickhouse-config--host-port
                  key: sk-moose-clickhouse-config--host-port
            - name: MOOSE_CLICKHOUSE_CONFIG__USE_SSL
              valueFrom:
                secretKeyRef:
                  name: sn-moose-clickhouse-config--use-ssl
                  key: sk-moose-clickhouse-config--use-ssl
            - name: MOOSE_CLICKHOUSE_CONFIG__POSTGRES_PORT
              valueFrom:
                secretKeyRef:
                  name: sn-moose-clickhouse-config--postgres-port
                  key: sk-moose-clickhouse-config--postgres-port
            - name: MOOSE_CLICKHOUSE_CONFIG__KAFKA_PORT
              valueFrom:
                secretKeyRef:
                  name: sn-moose-clickhouse-config--kafka-port
                  key: sk-moose-clickhouse-config--kafka-port
            - name: MOOSE_HTTP_SERVER_CONFIG__HOST
              valueFrom:
                secretKeyRef:
                  name: sn-moose-http-server-config--host
                  key: sk-moose-http-server-config--host
            - name: MOOSE_HTTP_SERVER_CONFIG__PORT
              valueFrom:
                secretKeyRef:
                  name: sn-moose-http-server-config--port
                  key: sk-moose-http-server-config--port
            - name: MOOSE_LOGGER_STDOUT
              value: "true"
      imagePullSecrets:
        - name: moose-repo-credentials

To simplify this, we have created a shell script you can use in your cloud shell to create the above secrets.

To use the script, you simply pass the environment variable name, and the script will create the secretKeyRef name and key values for you.

Terminal
$ ./set-env-secret.sh MOOSE_REDPANDA_CONFIG__SASL_PASSWORD
set-env-secret.sh
#!/bin/bash
# Helper script to set a secret in the Kubernetes cluster using the environment name and secret value
# Example: ./set-env-secret.sh MOOSE_CLICKHOUSE_CONFIG__DB_NAME hosteddb
if [ -z "$1" ]
then
      echo "You must specify the environment key name as the first argument. Example: ./set-env-secret.sh MOOSE_CLICKHOUSE_CONFIG__DB_NAME hosteddb"
      exit 1
fi
 
if [ -z "$2" ]
then
      echo "You must specify the secret value as the second argument. Example: ./set-env-secret.sh MOOSE_CLICKHOUSE_CONFIG__DB_NAME hosteddb"
      exit 1
fi
 
lc_str=${1,,}
lc_str=${lc_str//_/-}
 
kubectl delete secret "sn-${lc_str}"
kubectl create secret generic "sn-${lc_str}" --from-literal="sk-${lc_str}"=$2