---
# System prepended metadata

title: Birds Eye View

---

Birds Eye View
===

## Table of Contents

[TOC]


# Introduction
Let's take a high-level look at the architecture of our infrastucture.

## Overview
Our application is a `web application`.
As every wep application it needs:
* Facade for handling the incoming traffic coming from the users (`CDN`).
* Computing middleware for processing the business logics (`GCP in our case`).
* Some tools to maintain the development-related activities:
    * Source Control Manangement
    * CI/CD Engine
    * Docker Image Registry (in our case)


## Application
### Stack
* Front-End
    * `HTML`, `CSS`, `JS`
    * `Angular 1`
* Back-end
    * `PHP 7`
    * `Magento 2`
* DBMS
    * `MySQL 5.6`
* Cache
    * `Redis`

## Infrastructure

### Environments
We consider `3` environments for different purposes:
* `production`
* `staging`
* `develop`

### CloudFlare
#### CDN  
We are using CDN to resolve the following goals:
1) Reduce the response timings of feeding the static content to the end users consistently over the different geo-locations and improve the `UX`.
2) Reduce computation load on our servers on the backend and improve the capacity of our infrastructure.

#### DNS
We manage all the DNS records over `CloudFlare`.

## Google Cloud Platform
### Production implementation

#### Ingress
* `Load balancer`
So we are using the `L4 load balancer` to `route` and `balance` the `incoming traffic` over the `servers` on the `backend`.
#### Processing
* `Compute Engine`
* `Function`

Our backend is hosted on the `Compute Engine` `virtual machines`. `VMs` are joint into `instance groups`:
* `general`
* `admin`

Groups are enabled for `auto-scaling` from min `1` to max `15` virtual machines. `Trigger` is the following:
* `Target CPU usage` 90%
* `LB capacity fraction` 90%

`Machine type` is:
* custom (2 vCPUs, 6 GB memory)

#### Storage
* `Persistent Disk`
* `FileStore`
* `Bucket`

`Persistent Disks` are per `VM`.  
Single `FileStore` is mounted over all of the VMs, storing media files.  
`Bucket` is storing the media files as well.

#### DBMS
* `SQL`
We are using `MySQL 5.6` engine.  
We have `3` instances (by one per environment).

### Kubernetes
#### Introduction
`Kubernetes` approach is running across all `environments`.
#### Engine
We use `Google Kubernetes Engine`.  

#### Clusters
We host `2 GKE clusters`:
* `dev-staging`
* `prod`

`dev-staging` cluster is serving and hosting all workloads related to `2` environments: `staging` and `development` 
`prod` cluster is serving `production` environment

#### Ingress Controller
We refused using `Google Load Balancer` and replaced it with `Nginx Ingress Controller` to `reduce the running costs` and simplify the `configuration`.  

#### Node Pools
We are using `2` kinds of the `node pools`:
* `persistent`
* `preemtible`

Both pools are enabled for `auto-scaling`:
* `persistent`: `1-3`
* `preemtible`: `1-15`

#### Volumes
We are using `2` major `volume classes`:
* `NFS`
* `Google Persistent Storage` (SSD)

We use `NFS` when `multiple nodes read-write` mount type required. *(i.e. when we want to make multiple nodes hosted on different nodes being able to share single filesystem with RW permissions: i.e. media or generated static cache)*

In all other cases we use `Google Persistent Storage`

Approximate throughput of `NFS` is `~38 Mbytes/second` which is handling the current load well.
We create dedicated `NFS` server per `share`. We do that to keep throughput at the highest possible rate for each `shared filesystem` *(i.e. when we need shared `media` for `production` environment we create `nfs-production-media` volume class; for shared `cache` for `production` environment - we create `nfs-production-cache` volume class)*.
*(details: that makes sense since each `NFS volume class` is being created based on `NFS server`, so `1 NFS volume class` = `1 NFS server`)*



#### Image Registry
We are using `Docker Hub` as our `image registry` for `Docker containers`. 

#### Orchestration
We are using both:
* `GKE Dashboard`
* `Rancher`  

for orchestrating the `K8s Cluster`

### CI/CD
#### Engine
We are using `Jenkins`.
#### Integrations
A couple of other tools are engaged into `CI/CD` process:
* `Beanstalk` (SCM)
* `Gitea` (SCM)
* `Persistent Jenkins workers`

`Jenkins workers` are being persistently hosted as `pods` in `k8s cluster`.
Each `GKE cluster` has its own `master Jenkins` + `Jenkins worker(s)`:
* `dev-staging` cluster has 1 `master Jenkins` and 2 `Jenkins workers`: 1 for `staging` environment and 1 for `develop` environment
* `prod` cluster has 1 `master Jenkins` and 1 `Jenkins worker`


Several words regarding the `CI/CD flow`.
`Jenkins` is pulling codebase from `Beanstalk SCM` and then compiling Angular and Magento `static content` and uploading that to `Gitea SCM`.
*(So, `Beanstalk` is storing the `codebase` and `Gitea` is storing the `static content`.)*
After that `Jenkins` is triggering `static-content-sync` pod to pull updated `static content` from `Gitea`.