Skip to content

Instantly share code, notes, and snippets.

@MdSahil-oss
Last active February 22, 2024 10:03
Show Gist options
  • Save MdSahil-oss/4200b7f1d882d0e1dde2dc31995d6fbb to your computer and use it in GitHub Desktop.
Save MdSahil-oss/4200b7f1d882d0e1dde2dc31995d6fbb to your computer and use it in GitHub Desktop.

Auto Deploymemt & Traffic Management & Monitoring of a microservices based web application

Screenshot from 2024-02-21 12-38-58

Technologies (I used):

  • AWS
  • Kubernetes
  • CI/CD (Jenkins)
  • Docker
  • Service Mesh (Istio)
  • Monitoring tool (Prometheus)

Link to the project

Description:

What Exactly this project does: Automates the Deployment of microservices based Web application inside K8s cluster, Which monitored by Prometheus & managed for external traffic by Istio service mesh inside K8s cluster.

Created Resources:

  • In this project, Firstly I created a source code repository on github.
  • Created a Kubernete cluster using AWS-EKS.
  • Created public Docker repositories to store images.
  • Created a Jenkins pipeline and K8s user for Jenkins to handle K8s workloads seamlessly.
  • Installed & Setup Istio service mesh inside Kubernetes cluster.
  • Installed & Setup Prometheus-Operator for microservices of my application.

Workflow (Working):

  • On every push or update to the source-code repository Jenkins pipeline gets triggered.
  • On getting triggered Jenkins does the followings:
    • Fetch the new/updated source code from the repository.
    • Build container/docker images of microservices from fetched source code.
    • pushes the built images to the dockerhub repositories.
    • And Deploy the YAML files (K8s resources) into Kubernetes (AWS EKS) cluster.
  • At the end K8s pulls the latest builds from the dockerhub (image registry) and start/restart the all the microservices.
  • Started microservices generates metrics individually that can be accessed using co-working prometheus instances, If the access requests exceeds the set value & conditions matches the set rules then an alert is generated to notify the configured user via email.
  • And the microservices application is made accessible to the users out of cluster using IstioIngressGateway, When users access the application using IstioIngressGateway then the following Traffic-Management rules are applied to them set by VirtualService & DestinationRule components of Istio.
    • Only the known users access requests will be successfully forwarded in mesh.
    • Any user can access metrics of any of the microservices.
    • Round-Robin load-balancing technique will be used by amongst various versions of microservices.

How did I build this project 🤔?

  • Created a source code repository.

  • Created public container repositories for various microservices like Go-App, Python-app-v0, Python-app-v1 & Python-app-v2.

  • Created YAMLs (k8s resources) for various microservices to be installed(launched) into K8s cluster at the path /k8s/.

  • Created EKS cluster in my AWS environment.

  • Created a Jenkins user in my K8s cluster by following steps, That's used by Jenkins to handle(Creating/Deleting) workloads inside K8s cluster.

    • Generated a private key:

      $ openssl genrsa -out jenkins.key 2048
    • Created Certificate Signing Request (CSR):

      $ openssl req -new -key jenkins.key -out jenkins.csr -subj "/CN=jenkins"
    • Created CertificateSigningRequest resource for K8s:

      # csr.yaml
      apiVersion: certificates.k8s.io/v1
      kind: CertificateSigningRequest
      metadata:
        name: jenkins
      spec:
        request: BASE64_ENCODED_CSR
        signerName: kubernetes.io/kube-apiserver-client
        usages:
          - client auth
    • Applied & Approved CSR in my Kubernetes cluster:

      # Applying
      $ kubectl apply -f csr.yaml
      
      # Approved
      $ kubectl certificate approve jenkins
    • Created ClusterRole & ClusterRoleBinding for jenkins user:

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: jenkins
      rules:
        - apiGroups: ["*"]
          resources: ["*"]
          verbs: ["*"]
      
      ---
      
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: jenkins
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: jenkins
      subjects:
      - kind: User
        name: jenkins
  • Then, Set up the created key and crt for jenkins user inside Jenkins as k8s-creadentials.

  • Installed Istio service-mesh & configured inside K8s cluster by following steps:

    • Labeled the default namespace because I'll be installing all the microservices inside this namespace.

      # labeling the `default` namespace
      $ kubectl label ns default istio-injection=enabled
    • Created YAMLs for VirtualService & DestinationRule components at the path /k8s/istio-comps.yaml to manage microservices traffic.

  • Installed Prometheus-Operator inside K8s and created YAMLs to create prometheus workloads for various microservices at k8s/monitoring.

  • Then, I Created a Jenkins pipeline with the following Jenkinsfile:

    pipeline {
      environment {
        dockerGoAppImageName = "mdsahiloss/microservices-monitoring-go-app"
        dockerGoAppImage = ""
        dockerPythonAppV0ImageName = "mdsahiloss/microservices-monitoring-python-app"
        dockerPythonAppV0Image = ""
        dockerPythonAppV1ImageName = "mdsahiloss/microservices-monitoring-python-app-v1"
        dockerPythonAppV1Image = ""
        dockerPythonAppV2ImageName = "mdsahiloss/microservices-monitoring-python-app-v2"
        dockerPythonAppV2Image = ""
      }
      agent any
      stages {
        stage('Checkout Source') {
          steps {
            git 'https://github.com/MdSahil-oss/microservices-monitoring.git'
          }
        }
        stage('Build image') {
          steps{
            script {
              dockerGoAppImage       = docker.build(dockerGoAppImageName, "./go-app/")
              dockerPythonAppV0Image = docker.build(dockerPythonAppV0ImageName, "./python-app/v0/")
              dockerPythonAppV1Image = docker.build(dockerPythonAppV1ImageName, "./python-app/v1/")
              dockerPythonAppV2Image = docker.build(dockerPythonAppV2ImageName, "./python-app/v2/")
            }
          }
        }
        stage('Pushing Image') {
          environment {
              registryCredential = 'DockerhubCredentials'
            }
          steps{
            script {
              docker.withRegistry( 'https://registry.hub.docker.com', registryCredential ) {
                dockerGoAppImage.push("latest")
                dockerPythonAppV0Image.push("latest")
                dockerPythonAppV1Image.push("latest")
                dockerPythonAppV2Image.push("latest")
              }
            }
          }
        }
        stage('Deploying Application container to Kubernetes') {
          steps {
                withKubeConfig([
                            clusterName: 'CLUSTER_NAME',
                            namespace: 'default',
                            contextName: 'CONTEXT_NAME',
                            serverUrl:   'CLUSTER_URL',
                            credentialsId: 'k8s-creadentials'
                            ]) {
                sh 'kubectl delete -R -f ./k8s/ && kubectl apply -R -f ./k8s/'
            }
          }
        }
      }
    }

    Jenkins does followings using this Jenkinsfile:

    • Builds container images.
    • Push all the container images to dockerhub.
    • Deploy/Redeploy YAMLs resources at the path k8s/ into K8s cluster and launches all the microservices, prometheus instances & Istio components inside K8s so that everything get up.

This is how I built this project 😉.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment