Mittens

Mittens

  • Docs
  • GitHub

›Installation

About

  • Introduction
  • Getting Started

Installation

  • How to Build
  • How to Run

Contributing

  • How to Contribute

How to Run

The simplest way to run Mittens is as a cmd application. It receives a number of command line arguments (see flags). You can also run it as a linked Docker container or even as a sidecar in Kubernetes.

Please ensure that your service provides endpoints for both HTTP and gRPC requests, with the HTTP endpoint being exposed at /hotel/potatoes and the gRPC endpoint at service/method before running the below commands.

Run as a cmd application

You can run the binary executable as follows:

./mittens -target-readiness-http-path=/health -target-grpc-port=6565 -max-duration-seconds=60 -concurrency=3 -http-request=get:/hotel/potatoes -grpc-requests=service/method:"{\"foo\":\"bar\", \"bar\":\"foo\"}"

Run as a linked Docker container

version: "2"

services:

  foo:
    image: lorem/ipsum:1.0
    ports:
      - "8080:8080"

  mittens:
    image: expediagroup/mittens:latest
    links:
      - app
    command: "-target-readiness-http-path=/health -target-grpc-port=6565 -max-duration-seconds=60 -concurrency=3 -http-requests=get:/hotel/potatoes -grpc-requests=service/method:{\"foo\":\"bar\", \"bar\":\"foo\"}"

Note: If you use Docker for Mac/Windows you might need to set the target host (target-http-host, target-grpc-host) to host.docker.internal so that your container can resolve localhost. If you use an older version of Docker (< 18.03), the value will depend on your Operating System, e.g. docker.for.mac.host.internal or docker.for.win.host.internal. For target-http-host, you need to prefix the host with the scheme, e.g. http://host.docker.internal.

Run as a sidecar on Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: foo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: foo
  template:
    metadata:
      labels:
        app: foo
    spec:
      containers:
      # primary container goes here
      # - name: foo
      #   image: lorem/ipsum:1.0
      # sidecar follows
      - name: mittens
        image: expediagroup/mittens:latest
        resources:
          limits:
            memory: 50Mi
            cpu: 50m
          requests:
            memory: 50Mi
            cpu: 50m
        readinessProbe:
          exec:
            command:
            - "cat"
            - "ready"
          initialDelaySeconds: 10
          periodSeconds: 30
        livenessProbe:
          exec:
            command:
            - "cat"
            - "alive"
          initialDelaySeconds: 10
          periodSeconds: 30
        args:
        - "--concurrency=3"
        - "--max-duration-seconds=60"
        - "--target-readiness-http-path=/health"
        - "--target-grpc-port=6565"
        - "--http-requests=get:/health"
        - "--http-requests=post:/hotel/aubergines:{\"foo\":\"bar\"}"
        - "--grpc-requests=service/method:{\"foo\":\"bar\",\"bar\":\"foo\"}"

Using Config Maps for complex POST queries

If your application is using complex POST requests, you can move them to a separate file. To do that in Kubernetes, you can make use of ConfigMaps and define the body of your requests there, and then use a volume mount to make them accessible to Mittens.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: foo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: foo
  template:
    metadata:
      labels:
        app: foo
    spec:
      containers:
      # primary container goes here
      # - name: foo
      #   image: lorem/ipsum:1.0
      # sidecar follows
      - name: mittens
        image: expediagroup/mittens:latest
        resources:
          limits:
            memory: 50Mi
            cpu: 50m
          requests:
            memory: 50Mi
            cpu: 50m
        readinessProbe:
          exec:
            command:
            - "cat"
            - "ready"
          initialDelaySeconds: 10
          periodSeconds: 30
        livenessProbe:
          exec:
            command:
            - "cat"
            - "alive"
          initialDelaySeconds: 10
          periodSeconds: 30
        args:
        - "--concurrency=3"
        - "--max-duration-seconds=60"
        - "--target-readiness-http-path=/health"
        - "--target-grpc-port=6565"
        - "--http-requests=get:/health"
        # Inlined request body
        - "--http-requests=post:/hotel/aubergines:{\"foo\":\"bar\"}"
        # Request body comes from a json file (defined in a config map)
        - "--http-requests=post:/hotel/aubergines:file:/mittens/req_1.json"
        - "--http-headers=content-type:application/json"
        volumeMounts:
          - name: mittens-config
            mountPath: /mittens
      volumes:
        - name: mittens-config
          configMap:
            name: mittens-config
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mittens-config
data:
  req_1.json: |
    {
      "name": "foo",
      "age": 123
    }

gRPC health checks on Kubernetes

Kubernetes does not natively support gRPC health checks.

This leaves you with a couple of options which are documented here.

gRPC Server Reflection is needed

Mittens uses grpcurl to call the gRPC target server, which needs gRPC reflection to be enabled on the server.

gRPC Server Reflection assists clients in runtime construction of requests without having stub information precompiled into the client. For more info see here.

Note about warm-up duration

-max-duration-seconds includes the time needed for your application to start. Let's say that your application takes 30 seconds to start (ie, for /ready to start returning 200). What happens is that after these initial 30 seconds, mittens will start but it will only run for 60 seconds. This is because we already spent 30 seconds waiting for the app to start.

If the application is not ready after 90 seconds, we skip the warmup routine.

← How to BuildHow to Contribute →
  • Run as a cmd application
  • Run as a linked Docker container
  • Run as a sidecar on Kubernetes
    • gRPC health checks on Kubernetes
  • gRPC Server Reflection is needed
  • Note about warm-up duration
Mittens
Docs
Introduction
Community
User Showcase
More
GitHubStar
Expedia Group Open Source
Copyright © 2024 Expedia, Inc.