README
¶
= GSE: "Go Show Env" micro HTTP service
:author: David Buret
:source-highlighter: rouge
:pygments-style: github
:icons: font
:sectnums:
:toclevels: 4
:toc:
:imagesdir: images/
:gitplant: http://www.plantuml.com/plantuml/proxy?src=https://raw.githubusercontent.com/DBuret/gse/master/
ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]
== Introduction
GSE is a small standalone web app designed to help debugging the environment of orchestred containers, through a very small go app.
It can be be easly packaged into a < 3 MB docker image that will run with less than 20 Mo of ram, making it easly to deploy.
.It offers 3 endpoints
* displays its env and the details of the http request it received
** usefull to understand what env and request your containers receive
* healthcheck that can also be turned in ok or ko state through a simple http call
** usefull to play with your container orchestrator (kubernetes, nomad...) routing system.
* logger tonoutput what you want on the log output
** usefull to test your that log gathering system
WARNING: This was my first attempt as golang. Quick'n Dirty, but this tool has been proven usefull during our journey with Nomad or Kube...
== Endpoints
GSE offers 3 end points
=== Display environment
* `/gse` endpoint can be queried through any HTTP method (GET, PUT, ...). It will answer an HTTP 200 status, with an HTML content displaying information about the HTTP request received
** headers
** hostname
** path
** POST/PUT/... parameters
* note that this endpoint will write a one line log to stdout
* `/gse` can be changed to another path via the `GSE_BASEPATH` pararameter. Other endpoints (version, healthcheck) will inherit this parameters.
=== Display version & stamp
* `/gse/version` endpoint can be queried through any HTTP method (GET, PUT, ...). It will answer an HTTP 200 status,with a single text line content made of program version and its stamp (if one has been specified, default stamp being empty)
* the "stamp" allows us to test rolling, blue/green, or canary update with our container orchestrator: the same docker image (=same version) can be run with a given stamp (see GSE_STAMP bellow) given as parameter by the orchestrator, so we can differenciate to deployments, exemple:
** with no stamp, the answer will be `3.0`
** with GSE_STAMP="A", the answer will be `3.0A`
=== Healthcheck
* `/gse/health` is a endpoint to be used as healthcheck through an HTTP `GET` query. Answer will be
** when healtcheck is on: HTTP 200 status, content will be the text string _I'm alive_
** when healthcheck is off: HTTP 503 status, content will be the text string _I'm sick_
** no log will be written to stdout
* healthcheck can be switched on/off (flip/flop) with an access with HTTP `POST` or `PUT` methods:
*** `curl -X POST http://127.0.0.1:28657/gse/health`
*** `curl -X PUT http://127.0.0.1:28657/gse/health`
*** note that `POST` or `PUT` access to this endpoint writes log to stdout:
healthcheck has been switched to false
healthcheck has been switched to true
=== logger
WARNING: This endpoint is not activated by default since input sanitization is crappy. Use at your own risk
* `/gse/logger` is an HTTP `POST` endpoint that will write to stdout the payload of the POST request
* answer: HTTP 200 status, content will be the text string _data ingested._
== Parameters
GSE accepts some parameters, either through command line flags or env vars.
.GSE parameters
[cols="3,^1,^1,^1,^1"]
|===
| parameter | env var name | cli name | type |default value
| path in the url (note: impacts all endpoints)| `GSE_BASEPATH` | `-basepath` |string | `/gse`
| tcp port to listen to | `GSE_PORT` | `-port` | int | `28657`
| stamp added to version endpoint | `GSE_STAMP`| `-stamp` | string | empty
| set healthcheck answer to HTTP 200 or HTTP 503 | `GSE_HEALTHCHECK` | `-healthcheck` | boolean | `true`
| activate logger endpoint | `GSE_LOGGER` | `-logger` | boolean | `false`
|===
.We also have the standard -h cli arg
[source,console]
----
$ ./gse -h
----
Since we use https://github.com/namsral/flag to parse arguments, they can be fed either through command line or env vars.
CAUTION: flag parsing when value is `/...` seems to be bugged on windows. You cannot change the basepath on gse if you run on windows.
== Compile
Goal is to create a small but standalone binary to allow us to build a small container image.
.Build with static linking so we can Dockerfile FROM scratch
[source,console]
----
$ CGO_ENABLED=0 GOOS=linux go build -a -tags netgo -ldflags "-s -w" .
----
The resulting binary should be < 9 Mb.
TIP: If that's too big, you can use upx to reduce file size to ~ 2.5 Mb
.Run
[source,console]
----
$ ./gse
----
point your web browser to http://localhost:28657/gse
== Create docker image
the following is a multi stage docker build.
first we compile and compress executable in the _builder_ stage, then we create an image `FROM scratch'
.Dockerfile
[source,dockerfile]
----
FROM devalias/upx:devel AS upx
FROM golang AS builder
COPY --from=upx /usr/bin/upx /usr/bin/upx
WORKDIR /go/src/github.com/DBuret/gse
RUN go get -d -v github.com/namsral/flag
COPY gse.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -tags netgo -ldflags "-s -w" .
RUN /usr/bin/upx --brute gse
FROM scratch
LABEL version="4.1"
LABEL link="https://github.com/DBuret/gse"
LABEL description="Go Show Env - micro HTTP service to help understanding container orchestrators environment"
WORKDIR /
COPY --from=builder /go/src/github.com/DBuret/gse .
ADD template.html .
CMD ["/gse"]
----
.Build image
[source,console]
----
$ sudo docker build -t gse .
----
== Run locally with docker
=== Using default config
[source,console]
----
$ sudo docker run -p 28657:28657 gse
----
point your web browser to http://localhost:28657/gse
=== using parameters
[source,console]
----
$ sudo docker run -e GSE_BASEPATH=/foo -e GSE_PORT=2000 -e GSE_STAMP=A -e GSE_HEALTHCHECK=false -e GSE_LOGGER=true -p 2000:2000 gse
----
.Point your web browser to
* http://localhost:2000/foo
* http://localhost:2000/foo/version
* http://localhost:2000/foo/health
.Set healthcheck endpoint to "ok"
$ curl -X PUT http://localhost:2000/foo/health
=== RAM usage
WARNING: gse will eat around 14 Mb of _RAM_ (even if your _file_ has been shrinked by upx, upon execution it will be uncompressed to RAM. Using upx just saves disk space and download time). When setting ressources quota to a gse container, allow 20 Mb of RAM to the container and you will be safe.
[source,console]
----
$ ps -ef |grep gse
root 20034 17983 0 20:20 pts/0 00:00:00 sudo docker run -e GSE_BASEPATH=/foo -e GSE_PORT=2000 -e GSE_STAMP=A -e GSE_HEALTHCHECK=false -e GSE_LOGGER=true -p 2000:2000 gse
root 20035 20034 0 20:20 pts/0 00:00:00 /usr/bin/docker-current run -e GSE_BASEPATH=/foo -e GSE_PORT=2000 -e GSE_STAMP=A -e GSE_HEALTHCHECK=false -e GSE_LOGGER=true -p 2000:2000 gse
root 20068 20055 0 20:20 ? 00:00:00 /gse
$ sudo pmap -x 20068
20068: /gse
Address Kbytes RSS Dirty Mode Mapping
0000000000400000 3324 3324 3324 r-x-- [ anon ]
000000000073f000 3740 3740 3740 r---- [ anon ]
0000000000ae6000 372 280 280 rw--- [ anon ]
000000c000000000 65536 2048 2048 rw--- [ anon ]
00007f3397dc5000 35524 4216 4216 rw--- [ anon ]
00007fffa460b000 132 32 32 rw--- [ stack ]
00007fffa468f000 8 4 0 r-x-- [ anon ]
ffffffffff600000 4 0 0 r-x-- [ anon ]
---------------- ------- ------- -------
total kB 108640 13644 13640
----
== screenshots
=== main endpoint
image:ss1.png[]
Documentation
¶
Overview ¶
GSE - Go Show Env - see https://github.com/DBuret/gse
Click to show internal directories.
Click to hide internal directories.