person-svc-go
This is a really simple and basic implementation of a go lang based microservice. It's main purpose is to demonstrate how to containerize it, how to work with this locally and how to run this on that Kubernetes thing.
Building
We'll experiment with different ways of building this very simple service.
We'll try the following tools:
- buildah
- podman-compose
- GitHub Actions
- Openshift BuildConfig (s2i)
buildah
Experimenting with buildah and podman instead of running a docker daemon. Testing podman-compose as well.
buildah bud -f Dockerfile -t person-svc-go
podman-compose
podman-compose build
Running
In this section we'll explore different ways of running the container we built and other supporting containers we need to test or run this application.
We'll go into the following tools for running it or generating manifests to run it on kuberntes using diffrent tools like:
- podman
- podman-compose
- kompose or podman 3.0
- metagraf / mg
On my local machine
podman
Podman command to run the Postgres instance our person-svc-go service needs:
podman run --env-file configs/envfiles/postgres.env docker.io/library/postgres
# or with --detach to get your shell back
podman run --detach --env-file configs/envfiles/postgres.env docker.io/library/postgres
Podman command to run the person-svc-go container we built:
# Run the locally built image
podman run <imageid>
# or
podman run localhost/person-svc-go
podman-compose
# or
podman-compose up
# Need to issue restart since the go application starts before the database is ready.
# A deployment to Kubernetes would take care of this on it's own.
podman-compose restart person-svc-go
For Kubernetes
kompose
We can use a tool called kompose to transform a docker-compose.yaml to Kubernetes manifests.
This is a quick way to get some basic Kubernetes manifests going.
#todo
kompose ....
metaGraf - Generating manifests with mg
We'll use the mg tool from the https://github.com/laetho/metagraf project and the person-svc-go-db.metagraf.json we wrote. We're using the mg specific config files in configs/mg/ as input for some of the commands.
To generate an empty .properties file from a metaGraf specification you can do the following:
> mg create properties person-svc-go-db.metagraf.json > configs/mg/person-svc-go-db.properties
> mg create properties person-svc-go.metagraf.json > configs/mg/person-svc-go.properties
The mg tool can also validate your .properties file against the metaGraf specification:
> mg inspect properties person-svc-go.metagraf.json configs/mg/person-svc-go.properties
The configs/mg/person-svc-go.properties configuration is valid for this metaGraf specification.
Generate kubernetes manifests for the ephemeral PosgreSQL instance.
Snippet from: scripts/mg-generate-manifests.sh:
...
# Service{}
mg create service \
--output \
--dryrun \
--namespace person \
-o yaml \
person-svc-go-db.metagraf.json \
| tee deployments/mg/person-svc-go-db.service.yaml
# Deployment{}
mg create deployment \
--output \
--dryrun \
--namespace person \
--disable-aliasing \
-o yaml \
--cvfile configs/mg/person-go-svc-db.properties \
person-svc-go-db.metagraf.json \
| tee deployments/mg/person-svc-go-db.deployment.yaml
...
Produced:
Generate Kubernetes manifests for the person-svc-go service:
Snippet from: scripts/mg-generate-manifests.sh:
# person-svc-gov1 Service{}
mg create service \
--output \
--dryrun \
--namespace person \
-o yaml \
person-svc-go.metagraf.json \
| tee deployments/mg/person-svc-go.service.yaml
# person-svc-gov1 Deployment{}
# --disable-aliasing is used because default behaviour is to expect a retag image with the
# application name and not the upstream name on your internal registry. This should be the
# other way around as default.
mg create deployment \
--output \
--dryrun \
--namespace person \
--disable-aliasing \
-o yaml \
--cvfile configs/mg/person-svc-go.properties \
person-svc-go.metagraf.json \
| tee deployments/mg/person-svc-go.deployment.yaml
Produced:
Performance testing
My old and trusty workstation from yesteryears:
...
model name : Intel(R) Xeon(R) CPU W3530 @ 2.80GHz
...
Run that connects to Postgres and queries for persons and returns the results.
wrk -c 100 -d 60 -t 8 http://localhost:8080/persons
Running 1m test @ http://localhost:8080/persons
8 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.48ms 3.90ms 45.51ms 63.03%
Req/Sec 3.02k 157.93 4.21k 68.25%
1442493 requests in 1.00m, 537.89MB read
Requests/sec: 24031.57
Transfer/sec: 8.96MB
Run that calls a status enpoint with a static JSON response.
wrk -c 100 -d 60 -t 8 http://localhost:8080/status
Running 1m test @ http://localhost:8080/status
8 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.17ms 3.11ms 57.00ms 87.35%
Req/Sec 9.80k 2.23k 23.82k 68.21%
4682922 requests in 1.00m, 553.78MB read
Requests/sec: 77947.51
Transfer/sec: 9.22MB