GitOps is used to automate the process of provisioning infrastructure. It consists of:
- IaC
- MRs
- CI/CD
With these tools GitOps provides a set of best practices for automated deployment and management of infrastructure.
Infrastructure as code (IaC) is the process of managing and provisioning infrastructure. IaC allows versioned configuration of infrastructure which can be deployed to test, dev and prod environments. IaC enables reproducible and backed up infrastructure.
The IaC configuration can be deployed locally, through CICD processes or both. With GitOps we apply techniques to further improve the benefits of IaC granting faster deployments and enhance developer workflow.
With GitOps we use a Git repository as the single source of truth for infrastructure definitions. Merge Requests are used as the change process for updating infrastructure. The changes are applied through CICD pipelines.
Kubernetes application in GitHub with minikube and GitHub actions
In this project we will manage a simple webserver with GitOps principles. The webserver is configured in a Dockerfile and run in a container. The container is managed through a Kubernetes deployment. GitHub actions is responsible to deploy new changes and the code is stored in a git repository.
Webserver
Lighttdp is a high-performance open source Web server.
FROM alpine:3.13.6
RUN apk update \
&& apk add lighttpd \
&& rm -rf /var/cache/apk/*
COPY ./index.html /var/www/localhost/htdocs
CMD ["lighttpd","-D","-f","/etc/lighttpd/lighttpd.conf"]
index.html
contains:
hello world
Kubernetes deployment
We deploy the webserver container and expose port 80.
apiVersion: apps/v1
kind: Deployment
metadata:
name: webserver
spec:
replicas: 1
template:
spec:
containers:
- name: webserver-api
imagePullPolicy: Never
image: lighttpd-webserver:0.1.0
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: webserver
spec:
ports:
- port: 80
targetPort: 80
Minikube
Minikube is a utility you can use to run Kubernetes locally or with GitHub actions. This allows us to run the entire pipeline and deploy the application locally and in the GitHub environment.
โ minikube start
๐ minikube v1.15.1 on Darwin 11.6
โช MINIKUBE_ACTIVE_DOCKERD=minikube
โจ Using the hyperkit driver based on existing profile
๐ Starting control plane node minikube in cluster minikube
๐ Restarting existing hyperkit VM for "minikube" ...
๐ณ Preparing Kubernetes v1.19.4 on Docker 19.03.13 ...
๐ Verifying Kubernetes components...
๐ Enabled addons: storage-provisioner, default-storageclass, dashboard
๐ Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
โ kubectl apply -f deployment.yml
deployment.apps/webserver created
โ minikube service list
|----------------------|---------------------------|--------------|---------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|----------------------|---------------------------|--------------|---------------------------|
| default | webserver | 80 | http://192.168.64.3:30295 |
| default | kubernetes | No node port |
| default | redis-master | No node port |
| default | webserver | No node port |
| kube-system | kube-dns | No node port |
| kubernetes-dashboard | dashboard-metrics-scraper | No node port |
| kubernetes-dashboard | kubernetes-dashboard | No node port |
|----------------------|---------------------------|--------------|---------------------------|
โ curl $(minikube service webserver --url)
hello world
GitHub Actions
GitHub Actions makes it easy to automate software workflows. With GitHub Actions we can configure CI/CD pipelines to build, test, and deploy code.
We limit deployments on main branch to pull requests.
on:
pull_request:
branches:
- main
types: [closed]
The deployment builds a new container image and deploys it to minikube. To verify the deployment, we check if the webserver is responding.
jobs:
job1:
runs-on: ubuntu-latest
name: build webserver and deploy to minikube
steps:
- uses: actions/checkout@v2
- name: Start minikube
uses: medyagh/setup-minikube@master
- name: Try the cluster !
run: kubectl get pods -A
- name: Build image
run: |
export SHELL=/bin/bash
eval $(minikube -p minikube docker-env)
docker build -f ./Dockerfile -t lighttpd-webserver:0.1.0 .
echo -n "verifying images:"
docker images
- name: Deploy to minikube
run:
kubectl apply -f deployment.yml
- name: Test service URLs
run: |
minikube service list
minikube service webserver --url
echo "------------------opening the service------------------"
curl $(minikube service webserver --url)
Conclusion
In this project we have shown how GitOps principles can be used to automate management and deployment of an application.
1 comment
Nice!! Looks interesting. Will look into it.