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`.