Sparky – hacking minikube with mini tool

RMAG news

TL; DR: How to deploy docker to minikube when one does not need anything fancy, but pure Raku.

So, you have your own pet K8s cluster deployed as minikube and you want to play with it. You have few microservices to build and you don’t want to bother with kubernetes low level commands at all.

From other hand you setup is complex enough to express it in a bunch of yaml files or kubectl commands. Here is an elegant way to handle this in pure Raku, and it’s called Sparky …

Show me the design

|————————————-|
| Sparky -> kubectl -> MiniKube |
| / / / |
| pod pod pod |
|————————————-|

So the infrastructure part is simple – on the same host we install minikube and Sparky that underlying uses kubectl to deploy containers into k8s cluster.

Show me the code

As usually Sparky job is a pure Raku code, but here we also use another cool feature of Sparky – called plugins.

Sparky is integrated with repository of plugins – Sparrowhub – https://sparrowhub.io with many useful plugins available

Let’s use couple of them – k8s-deployment and k8s-pod-check to deploy and check pods in Kubernetes respectively. From Sparky point of view those are just Raku functions, with some input parameters.

taskrun dpl create“, k8s-deployment“, %(
:deployment_name<nginx>,
:app_name<nginx>,
:image<nginx:1.14.2>,
:3replicas,
);

# give it some time to allow all pods to start …
sleep(5);

taskrun nginx pod check“, k8s-pod-check“, %(
:name<nginx>,
:namespace<default>,
:dieoncheckfail,
:3num,
);

For the post purposes we are going to deploy nginx servers with 3 replicas, k8s-deployment does all the job.

Let’s see our first run.

First run

When we open up Sparky report we will see this:

… some output …

11:03:34 :: deployment.apps/nginx created
11:03:34 :: [repository] – installing k8s-pod-check, version 0.000012
11:03:34 :: [repository] – install Data::Dump to /home/astra/.sparrowdo/minikube/sparrow6/plugins/k8s-pod-check/raku-lib
All candidates are currently installed
No reason to proceed. Use –force-install to continue anyway
[task run: task.pl6 – nginx pod check]
[task stdout]
11:03:41 :: ${:die-on-check-fail(Bool::True), :name(“nginx”), :namespace(“default”), :num(3)}
11:03:41 :: ===========================
11:03:41 :: NAME READY STATUS RESTARTS AGE
11:03:41 :: nginx-77d8468669-5gxbf 0/1 ErrImagePull 0 5s
11:03:41 :: nginx-77d8468669-c5vbl 0/1 ErrImagePull 0 5s
11:03:41 :: nginx-77d8468669-lhc54 0/1 ErrImagePull 0 5s
11:03:41 :: ===========================
11:03:41 :: nginx-77d8468669-5gxbf POD_NOT_OK
11:03:41 :: nginx-77d8468669-c5vbl POD_NOT_OK
11:03:41 :: nginx-77d8468669-lhc54 POD_NOT_OK
[task check]
stdout match <^^ ‘nginx’ S+ s+ POD_OK $$> False

As we can see even though the deployment has been successfully created, further k8s-pod-check plugin failed to verify that all the pods are running.

Use of die-on-check-fail option made the job stops strait away after this point.

Error – ErrImagePull means the docker image is not accessible from within a minikube, which a known minkube DNS issue, let’s fix it …

It’s fixed!

In that case, the fix is easy, all we need is to upload nginx docker image manually, so that minukube will pick it up from the file cache:

minikube image load nginx:1.14.2

And then rebuild the last job:

… some output …

11:05:42 :: deployment.apps/nginx unchanged
[task run: task.pl6 – nginx pod check]
[task stdout]
11:05:47 :: ${:die-on-check-fail(Bool::False), :name(“nginx”), :namespace(“default”), :num(3)}
11:05:47 :: ===========================
11:05:47 :: NAME READY STATUS RESTARTS AGE
11:05:47 :: nginx-77d8468669-5gxbf 1/1 Running 0 2m10s
11:05:47 :: nginx-77d8468669-c5vbl 1/1 Running 0 2m10s
11:05:47 :: nginx-77d8468669-lhc54 1/1 Running 0 2m10s
11:05:47 :: ===========================
11:05:47 :: nginx-77d8468669-5gxbf POD_OK
11:05:47 :: nginx-77d8468669-c5vbl POD_OK
11:05:47 :: nginx-77d8468669-lhc54 POD_OK
[task check]
stdout match <^^ ‘nginx’ S+ s+ POD_OK $$> True
<3 pods are running> True

The last deployment has not changed (with is denoted by “deployment.apps/nginx unchanged” line), as we did not change anything, however minikube now is able to pick a recently uploaded nginx docker image from file cache and all the pods now are running.

Congratulation with the very first successfully deployment to Kubernetes via Sparky!

Clean up

In the end we may add some clean up code, just to demonstrate another feature of k8s-deployment plugin:

taskrun dpl delete“, k8s-deployment“, %(
:deployment_name<nginx>,
:action<delete>,
);

Further thoughts

This simple scenario is going to give us some ideas on how to deploy to Kubernetes in imperative way using pure Raku, I, personally like this approach better, as having a bunch of helm charts and yaml files seems overkill when one need just to deploy some none production code, however, as always YMMV, thanks for reading …