Rekube

Rekube is a toolkit for Kubernetes configuration management.

The main components of the project are:

Note: This project is currently unstable and unreleased.

Quickstart

To install rekube in an esy project, add the following dependency to your package.json file:

"dependencies": {
  "rekube": "github:rizo/rekube#a7c4d09"
}

If you are using opam, run: opam install rekube.

In your dune project add the following dependencies to your dune file:

(executable
  (name Infra)
  (public_name gen-infra)
  (libraries rekube console.lib)
  (preprocess (pps rekube.ppx)))

Finally, describe your configuration in a file called Infra.re and execute it to generate the raw JSON files.

$ esy gen-infra

Kubernetes API

The full API can be explored from the Rekube.Kubernetes module.

Here are some popular APIs:

Configuration DSL

Writing declarative configuration that represents an application is the main way to describe deployments and resources in Kubernetes. The standard format used for configuration in the Kubernetes ecosystem is YAML. Although it is a very terse and human-friendly format, it lacks compositional and validation properties that would help it scale for large clusters.

Avoiding unnecessary boilerplate and repetition is important for lowering maintenance effort in any non-trivial distributed system. The configuration DSL in rekube achieves exactly that by building directly on top of the official Kubernetes API and relying on excellent modularity and safety properties of ReasonML.

Example

Here is a small example of a node.js app defined using the rekube DSL:

open Kubernetes.Definitions.Api.Apps.V1;
open Kubernetes.Definitions.Api.Core.V1;

let name = "my-app";

let deployment = (~replicas=1, ~namespace) => {
  let metadata = Meta {
    "name": name,
    "namespace": namespace,
    "labels": [("app", name)]
  };
  Deployment {
    "metadata": metadata,
    "spec": Deployment_spec {
      "replicas": replicas,
      "template": Pod_template_spec {
        "metadata": metadata,
        "spec": Pod_spec {
          "containers": [
            Container {
              "name": name,
              "image": "gcr.io/hello-minikube-zero-install/hello-node",
              "ports": [Port { "name": "app", "container_port": 8080 }],
              "resources": Resources {
                "requests": [("cpu", "100m"), ("memory", "500Mi")],
                "limits":   [("cpu", "500m"), ("memory", "1Gi")]
              },
            }
          ]
        }
      }
    }
  }
}

The deployment object is defined as a function that accepts a namespace and the number of replicas. It can be instantiated multiple times and used, for example, in different Kubernetes clusters.

Syntax Extension

The PPX (preprocessor extension) works by translating all expressions that start with a constructor and are followed by a JSON object to function calls in the Kubernetes API. The following example describes the mapping:

Object {"key1": value1, "key2": value2}
==>
Object.make(~key1=value1, ~key2=value2)()

Note: The extra () is needed to avoid partial application of the labeled arguments with default values.

The full power of ReasonML can be used in this configuration. Variables can be declared, common definitions can be grouped into modules, standard library functions can be used, etc.

Troubleshooting

Here is a list of common issues and suggested solutions:

YAML-to-Reason converter

To facilitate the transition from existing Kubernetes configuration, rekube provides a CLI tool called rekube-conv that will convert any valid YAML manifest file to the ReasonML configuration DSL described above. As part of this process it will validate and infer the types of all the objects.

$ esy rekube-conv my-deployment.yaml