1
0
mirror of https://github.com/erlang/docker-erlang-example.git synced 2025-07-29 11:41:10 +03:00
Files
2020-11-25 13:20:19 +01:00
..
2019-10-02 18:08:45 +02:00

Using Minikube, Erlang and Prometheus

This is a quick demo of using minikube to run an Erlang node with prometheus and grafana. The example we will use is the Docker Watch node. This demo assumes that you have done the Using Minikube demo.

This is only meant to be an example of how to get started. It is not the only, nor neccesarily the best way to setup minikube with Erlang.

Prerequisites

To start with you should familiarize yourself with minikube through this guide: https://kubernetes.io/docs/setup/minikube/

In a nutshell:

Install

Start and test

> minikube start
> kubectl run hello-minikube --image=k8s.gcr.io/echoserver:1.10 --port=8080
> kubectl expose deployment hello-minikube --type=NodePort
> curl $(minikube service hello-minikube --url)
## Should print a lot of text
> kubectl delete services hello-minikube
> kubectl delete deployment hello-minikube
> minikube stop

Deploying Dockerwatch and Prometheus

In this demo we will be doing three things:

  • Extend dockerwatch with prometheus metrics support
  • Create Deployments for Prometheus and Grafana
  • Create a Service that will be used to access the dockerwatch API
  • Create a Secret for our ssl keys
  • Create a Deployment of dockerwatch that implements the Service

First however, make sure that the minikube cluster is started:

> minikube start

and that you have cloned this repo and changed to the correct directory:

> git clone https://github.com/erlang/docker-erlang-example
> cd docker-erlang-example/advanced_examples/minikube-simple

Extend dockerwatch

In this demo we will be using the prometheus, prometheus_process_collector and prometheus_cowboy hex packages to get the instrumentation we need. So we need to add those packages to the rebar.conf file.

{deps, [{jsone,  "1.4.7"},   %% JSON Encode/Decode
        {cowboy, "2.5.0"},   %% HTTP Server
        {prometheus,"4.2.0"},
        {prometheus_process_collector,"1.4.0"}
        {prometheus_cowboy,"0.1.4"}]}.

And also the corresponding modificaion to the app.src file:

{applications, [
        kernel,
        stdlib,
        jsone,
        cowboy,
        prometheus,
        prometheus_process_collector,
        prometheus_cowboy
	]},

We then need to add a new http endpoint that takes requests from the prometheus server and returns the correct results. This service traditionally runs on port 9000 so we add another child to the dockerwatch supervisor.

PromConfig =
    #{ env => #{ dispatch =>
                     cowboy_router:compile(
                       [{'_', [{"/metrics/[:registry]", prometheus_cowboy2_handler, []}]}]) }
     },

Prometheus = ranch:child_spec(
               cowboy_prometheus, 100, ranch_tcp,
               [{port, 9000}],
               cowboy_clear,
               PromConfig),

We also need to add the correct instrumentation to the cowboy servers so that we can measure things like requests per minute and the 95th percentile latency of requests. This is done by modifying the cowboy config to include a metric_callback and two stream handlers.

CowConfig = #{ env => #{ dispatch => Dispatch },
               metrics_callback => fun prometheus_cowboy2_instrumenter:observe/1,
               stream_handlers => [cowboy_metrics_h, cowboy_stream_h] },

You can view the entire new supervisor module here.

Deploy Dockerwatch

Now we should deploy the dockerwatch service almost the same way as was done in Using Minikube: Simple. So:

> kubectl create service nodeport dockerwatch --tcp=8080:8080 --tcp=8443:8443
service/dockerwatch created
> ./create-certs $(minikube ip)
......
> kubectl create secret generic dockerwatch --from-file=ssl/
secret/dockerwatch created
> eval $(minikube docker-env)
> docker build -t dockerwatch .

We will have to modify the deployment somewhat from the original example:

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  ## Name and labels of the Deployment
  labels:
    app: dockerwatch
  name: dockerwatch
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dockerwatch
  template:
    metadata:
      labels:
        app: dockerwatch
      annotations: ## These annotations will tell prometheus to scrape us
        prometheus.io/scrape: "true"
        prometheus.io/port: "9000"
    spec:
      containers:
      ## The container to launch
      - image: dockerwatch
        name: dockerwatch
        imagePullPolicy: Never
        ports:
        - containerPort: 8080
          protocol: TCP
        - containerPort: 8443
          protocol: TCP
        - containerPort: 9000 ## Expose the prometheus port
          protocol: TCP
        volumeMounts:
            - name: kube-keypair
              readOnly: true
              mountPath: /etc/ssl/certs
      volumes:
        - name: kube-keypair
          secret:
            secretName: dockerwatch
EOF

We can then setup prometheus and grafana following the excellent example by bakins.

> kubectl apply -f monitoring-namespace.yaml
> kubectl apply -f prometheus-config.yaml
> kubectl apply -f prometheus-deployment.yaml
> kubectl apply -f prometheus-service.yaml

You should now be able to view the prometheus dashboard through the url given by:

minikube service --namespace=monitoring prometheus

Then we can start Grafana:

> kubectl apply -f grafana-deployment.yaml
> kubectl apply -f grafana-service.yaml

Grafana can then be found under:

minikube service --namespace=monitoring grafana

The username and password is admin. You then need to add a new prometheus datasource to grafana. The url to prometheus within the cluster is http://prometheus.monitoring.svc.cluster.local:9090.

There are some ready made dashboards at: https://github.com/deadtrickster/beam-dashboards that can be imported to get something quick up and running. If done correcly it could look like this:

BEAM Dashboard