Creating a Custom Competitive Kubernetes Training Experience on AKS — Part 2
By: Adrian Hynes
Tags: Komp, Azure Kubernetes Service, Kubernetes, Self Service, Training

Intro

In the last section we’ve made some initial design decisions which will influence our solution.

In this section we’ll pick a database, review and insert some questions, review the apis and a sample sequence flow, review our overall architecture and finally deploy our kubernetes applications.

Database

We are going to simply pick Sqlite for our relational database needs, due it’s small nature and ease of use and it’s file based nature. We’ll mount the Sqlite database onto a PVC (Azure Disk) to maintain state.

Question and Levels

New Level

Inserting a new level is straight forward

replace into level (id, name, description) values(3, 'Level 3 - Going Places', 'This level will test your knowledge of pod design patterns');

New Question — Hands on

This question type may setup some k8s resources inside your namespace and then ask you to perform some additional tasks. In the below example we create a random deployment into your namespace and you are then required to create a kubernetes docker secret called regcred. The validation will then be performed by executing the answer_query against the namespace and comparing the output to the answer_value. See Question 1 in the Demo on Part 1

replace into question (id, levelid, description, setup, answer_query, answer_value, type) values(10, 3, '<p>In this question, your task is to create a kubernetes docker secret called regcred.</p><p>Click Setup to get your namespace and environment setup.</p><p>Once you have created your kubernetes docker secret, then Validate to capture your flag.</p>', '{"kind":"Deployment"...}', 'kubectl get secret regcred -o jsonpath={.metadata.name}', 'regcred', 'setup' );

New Question — Hands on Multiple Choice

Like the previous question, this one also sets up some kubernetes resources in your namespace but doesn’t require you to perform any deployments to your namespace. Instead you are required to do some investigative work inside the namespace and then pick a multiple choice answer.

In the example below, we deploy a secret and ask you to identify the name of this secret giving you 3 possible answers. See Question 3 in the Demo on Part 1

replace into question (id, levelid, description, setup, answer_query, answer_value, type) values(11, 3, '<p>In this question we will deploy a secret to your namespace. Your task is to identity the name of this secret.</p><p>Click setup to setup your namespace and environment.</p><p>Then select one of the answers shown below, then click Validate to capture your flag.</p>', '{ "kind": "Secret", "apiVersion": "v1", "metadata": { "name": "yolosecret", "creationTimestamp": null }, "data": { "secret1": "eW9sbw==" }}', '', '', 'setup' ); replace into answer (id, qid, description, correct) values(1, 11, 'mysupersecret', 'false'); replace into answer (id, qid, description, correct) values(2, 11, 'yolosecret', 'true'); replace into answer (id, qid, description, correct) values(3, 11, 'secret123', 'false');

New Question — Multiple Choice

This question type doesn’t require the user to sign in to their namespace, instead it is just a simple multiple choice question. See Question 2 in the Demo on Part 1

replace into question (id, levelid, description, setup, answer_query, answer_value, type) values(12, 3, '<p>What command would you use to get all the pods in your namespace</p><p>Select one of the answers shown below, then click Validate to capture your flag.</p>', '', '', '', 'nosetup' ); replace into answer (id, qid, description, correct) values(4, 12, 'kubectl get pods -n namespace', 'true'); replace into answer (id, qid, description, correct) values(5, 12, 'kubectl get ships => namespace', 'false'); replace into answer (id, qid, description, correct) values(6, 12, 'kubectl pods -n namespace', 'false');

API’s

At a high level we’ll need to create the following simple api’s.

High Level APIs

High Level Sequence Diagram of “Hands on” Question Type

“Hands On” Question Type Sequence Flow

AKS Architecture

High Level AKS Architecture

Azure Resources

In the above Architecture, we’ll setup Azure Resources from our previous medium article: https://adrianhynes.medium.com/exposing-your-aks-workloads-using-external-dns-and-nginx-ingress-controller-434482ea153b

This includes our AKS cluster, load balancer, private DNS, our windows VM etc

Kubernetes Resources

High Level K8s Objects

As we are using a private domain name (hynes.pri) which does not exist outside our Azure Subscription, we will generate a Self Signed Cert for both kompui.hynes.pri and kompservice.hynes.pri and create kubernetes tls secrets from the resulting key and cert.

openssl req -x509 -newkey rsa:4096 -keyout key1.pem -out cert.pem -days 365 -subj '/CN=kompservice.hynes.priv' kubectl create secret tls tls-secret-svc --cert=cert.pem --key=key.pem --dry-run -o yaml > sec.yaml

UI Application Source Code (Including Dockerfile and K8s Manifests)

https://github.com/aido123/komp-ui

Server Application Source Code (Including Dockerfile and K8s Manifests)

https://github.com/aido123/komp-service

Conclusion

I hope you have found this set of articles and source code useful for your own AKS solution whether that be a custom AKS training experience or something else. Thanks for reading.