Exploring microservices using Kubernetes!
Explore the codeΒ»
This project is about creating a system that can check and provide feedback on programming assignments for students. The system is designed for students, teachers, and administrators. Students can upload their assignments and see the results.
The project is built using Kubernetes, a tool that helps us create a cloud-agnostic scalable system. The services in our system are designed to communicate securely and work independently.
We are using existing tools for monitoring our system because they are reliable and well-maintained. These tools include:
Regarding the infrastructure, we are using:
Our user interface is built using Django and Svelte. We chose different frameworks to allow our teams to work independently and reduce the need for communication. This means we can develop different parts of the system separately and connect them later. The user interface includes a panel for users, a panel for teachers, and a panel for administrators.
The picture depicted below provides a comprehensive overview of the architecture. An arrow pointing from a source to a target signifies that the source is dependent on the target.
Finally, our project is live on Google Cloud and can be accessed on https://zeruscloud.com with additional services exposed on /api/...
, /grafana, /adminer, or /keycloak.
To run the project, you need to install Docker, Minikube, and Helm. Docker packages the application with its dependencies. Minikube allows running Kubernetes, which manages the application locally. Helm is for Kubernetes deployment.
Deploying locally has been simplified with the use of VSCode tasks. These tasks mimic a real pipeline, efficiently managing the necessary stages of deployment. This process includes the creation of helm Charts and the building custom Docker images that are referenced in the Kubernetes YAML files.
The tasks are designed with inherent dependencies, allowing the execution of a single task to trigger multiple stages, enhancing performance. The entire project can be deployed using the minikube start
-> Enable Ingress
-> Helm Deploy
-> minikube tunnel
tasks. However, there are several tasks available for specific needs:
Build Grafana
: For creating a custom Grafana image.Build User
: For creating a custom User service image.Build Teacher
: For creating a custom Teacher service image.Enable Ingress
: Initialize ingress to use NGINX.Deploy Deploy Infrastructure
: For deploying the infrastructure.Deploy Deploy Monitoring
: For deploying the monitoring.Deploy Deploy Frontend
: For deploying the frontend.Deploy Helm
: For deploying the entire project.A minimal values.yaml
are provided for the three helm charts: infrastructure
, monitoring
, and frontend
. For each of the three helm charts, a values-prod.yaml
is provided to overwrite the default values.yaml
for production.
We value ensuring that the development environment mirrors the production environment. The only differences are the values in values-prod.yaml
and minimal if-statements in the templates. The services are configured to persist solely on the server they are run on.
This separation of environments is achieved by creating two secret configurations: one with hard-coded development secrets, and the other pulling secrets from the pipeline variables. To illustrate, let's look at how the Keycloak password is accessed during deployment.
This ensures a secure and efficient deployment process.
We have integrated SonarCloud into our development process to ensure the consistent and efficient delivery of high-quality code. This code review tool seamlessly integrates with GitHub, enhancing our CI/CD workflow with quality gates. It provides immediate feedback on all pull requests, enabling us to maintain our coding standards. Anyone can access our SonarCloud dashboard. Besides analyzing pull requests, it is also possible to synchronize the SonarLint plugin in our IDE with the rules defined in our SonarCloud server. This ensures that the code violations identified by SonarLint match those detected by SonarCloud after pushing to the repository. We have not implemented this yet, but it could be a worthwhile addition to our workflow.
In addition, we have set up Dependabot to scan our repository for updates to packages and Docker images. Using outdated versions can often lead to vulnerabilities that have not been addressed. Dependabot helps mitigate these risks by automatically creating pull requests for these updates. We can then review and merge these updates as deemed appropriate. This ensures our codebase remains secure and up-to-date.
The Pipeline automates the build, test and deployment stages. It is currently configured to function with Google Cloud Kubernetes Engine (GCKE) and its associated services, but can be migrated to any cloud platform.
Prerequisite: Before you can run the workflow, you need to create a Google Cloud service account with the following permissions: Kubernetes Engine Admin Artifact Registry Admin Remote Build Execution Admin
Once You have created the account, you can export the service account secret key as a .json
.
Github Action secrets:
To run the CI/CD Pipeline you will need to add some secrets in the Github
-> Settings
-> Secrets & Variables
:
.json
file.Running the workflow:
Once everything has been set up according to the directions here, the workflow can be executed by going to Github
-> Actions
-> CI/CD Pipeline
-> Run Workflow
and then specify the branch to run the file on. Alternatively, you can edit the part of the CI/CD Pipeline file that looks like this:
on:
workflow_dispatch:
To specify a set of branches to automatically deploy on when a push to that branch occurs:
on:
push:
branches: [ "main", "otherBranch" ]
pull_request:
branches: [ "main", "otherBranch" ]
workflow_dispatch:
We have prepared a detailed guide on how to interact with our application's API. This guide includes information about the available endpoints and the structure of the returned JSON objects. You can find this guide at the following location: API. Enjoy your development journey!
We have automated our local development process using VSCode tasks to create a simulated pipeline. This allows us to streamline our development workflow and ensure consistency across our team. Detailed instructions on how to set up and use these tasks is provided in the section Getting Started.
For deployment on the Google Cloud Platform (GCP), we leverage GitHub Actions. This powerful tool allows us to build, test, and deploy our project directly from our GitHub repository to GCP. The advantage of this approach is twofold:
To maintain the integrity of our main branch, we have implemented branch protection rules. These rules help us manage the changes to the project and ensure that the main branch always has production-ready code. Each merge to the master branch triggers a deployment on the Google Cloud Platform (GCP) using GitHub Actions, and each pull request triggers a CI build on our SonarCloud. A PR must always pass the SonarCloud quality gate; otherwise, merge to master is disallowed.
We welcome contributions from all developers. Before contributing, please read through the above guidelines and ensure your changes adhere to them. Thank you for your interest in our project!
This section is dedicated to highlighting areas in the project that require further attention or improvement. These areas could be related to functionality, maintainability, or even critical aspects such as security. The following list provides a brief overview of the tasks that need to be addressed:
Remember, this is a living document. As the project evolves, new tasks may emerge and existing ones may become irrelevant.
For a succinct overview of the hard requirements, please refer to PROJECT_TASKS, and our user stories are available as a PDF document - this is an export from Atlassian Jira.
Distributed under the MIT License. See LICENSE for more information.