(Randomly generated repository and app name)
- This project was developed and tested locally using minikube in a home lab environment. This may affect my runtime versus native Kubernetes runtime commands/application.
- I chose Python for the hello world web app as it's the language I'm most comfortable in, however I could have also chosen Rust using Rocket.rs or TypeScript using Express.
- I've utilised GitHub Container Registry to host my Docker image for use within the K8s deployment.
- As this is a technical test I have left
flask
running in it's debug mode. In a production environment we'd switch to another WSGI instead of the nativeFlask.run()
method.
- With the consideration of security for a web app, I would never run this facing an exposed interface, meaning that the container would be directly accessible on the public internet. I would personally run this behind a reverse proxy like NGINX or Caddy with SSL/TLS configured.
- Added to the previous note, we would also switch to using a dedicated WSGI application, instead of the Flask native method of running, which also defaults to running in debug mode. This has been considered and deemed outside the scope of the test, minus the discussion around it's security implication.
- If we were going the route of no public endpoints, we would implement an authentication system like OAuth2 or an alternate means of securely providing API tokens or similar.
If this were in a cloud/enterprise environment then the steps above might not be as fitting. If we use Azure hosting as the example then you would use Azure Firewall and other related cloud native security features, like RBAC and API Gateway.
- Git
- Docker
- Kubernetes runtime (kubectl, kubelet etc...)
- Minikube (Optional in place of above)
- Clone the repository and enter directory
git clone https://github.com/AbstractUmbra/obnoxious-albatross.git
cd obnoxious-albatross
Build the image locally
Build the image using the provided Dockerfile.
docker build -t ghcr.io/abstractumbra/obnoxious-albatross:latest .
Spin up a test container using the image.
docker run -p 8000:8000 ghcr.io/abstractumbra/obnoxious-albatross:latest # add the -d flag to `run` to detach
Kubernetes deployment and service
Create the Kubernetes namespace.
kubectl create namespace obnoxious-albatross
Create the deployment.
kubectl apply -f k8s/deployment.yaml -n obnoxious-albatross
(Optional) View deployment logs.
kubectl logs -f deployment/obnoxious-albatross-deploy -n obnoxious-albatross
Create the service
kubectl apply -f k8s/service.yaml -n obnoxious-albatross
(Optional) Verify service was created and IP assigned
kubectl get svc -n obnoxious-albatross # add the -w flag to `get svc` to watch command output for changes
# (minikube) once above is complete, I had to port-forward as minikube did not allow the allocation of an external ip
# to access the cluster externally
kubectl port-forward deployment/obnoxious-albatross-deploy -n obnoxious-albatross 8080:8000
# open a new terminal and issue the following command to check the deployed pods and containers are working
# and that we get the hello world response
curl -s http://localhost:8080 # or port 8000 if you did not need to portforward as above
Clean up and delete resources
Remove Kubernetes service
kubectl delete -f k8s/service.yaml
Remove Kubernetes deployment
kubectl delete -f k8s/deployment.yaml
Remove Kubernetes namespace
kubectl delete namespace obnoxious-albatross
Remove Docker image
docker image rm ghcr.io/abstractumbra/obnoxious-albatross:latest