PolarSPARC |
GCP Fundamentals :: Core Infrastructure - Summary Notes - Part 3
Bhaskar S | 10/13/2019 |
Containers
⇒ Containers Concepts
Google Compute Engine (GCE) is GCP's Infrastructure as a Service (IaaS) offering, with access to servers, storage, and networking
App Engine is GCP's Platform as a Service (PaaS) offering
Containers and Kubernetes engine is a hybrid that conceptually sits between IaaS and PaaS with benefits from both
IaaS allows one to share compute resources with users by virtualizing the hardware using virtual machines (VMs). Each user can deploy their own operating system, access the hardware, and build their applications in a self-contained environment with access to memory, storage, networking, and so on. The smallest unit of compute for an application, in this case, is the VM
On the VM, the guest OS maybe large and may take minutes to boot, but has tools of choice to configure and tune the system environment (the VM). One can install their favorite runtime, web server, database, middleware, configure the underlying system resources such as disk space, disk I/O, or networking, and build the VM to their liking
As demand for the application increases, one has to copy the entire VM and boot the guest OS for each instance of the application, which can be slow and costly
With App Engine one gets access to programming services. All one has to do is write code as self-contained workloads that use these services and include any dependent libraries. As demand for the application increases, the platform scales the app seamlessly and independently by workload and infrastructure. This scales rapidly but one will not be able to fine tune the underlying architecture to save cost
The idea of a Container is to give users the independent scalability of workloads and an abstraction layer of the OS and hardware. What one gets is an invisible box around the code and its dependencies, with limited access to their own partition of the file system and hardware. It only requires a few system calls to create the Container environment and starts as quickly as a process. All one needs on each host is an OS kernel that supports Containers, and a Container runtime
In essence, we are virtualizing the OS. It scales like PaaS, but gives users nearly the same flexibility as IaaS. With this abstraction, the code is ultra-portable, and one can treat the OS and hardware as a black box. So, the users can go from development, to staging, to production, or from their laptop to the cloud without changing or rebuilding anything. If one wants to scale their containerized application, they can do so in seconds and deploy dozens or hundreds of them, depending on the size of the workload on a single host
Containers are loosely coupled to their environments. This implies that Containers are easy to move around, deploying a containerized application consumes less resources, and is less error-prone than deploying an application in virtual machines, and Containers abstract away unimportant details of their environments. Deploying applications using Containers makes it simpler to migrate workloads
Kubernetes
⇒ Kubernetes Concepts
Users will likely want to build their application using lots of Containers, each performing their own function like microservices. If they build them like this and connect them with network connections, one can make them modular, deploy easily, and scale independently across a group of hosts. The host can scale up or down and start and stop the Containers on-demand as demand for their application changes, or as hosts fail. The tool that helps us do this well is Kubernetes
Kubernetes makes it easy to orchestrate many Containers on many hosts, scale them as microservices, and deploy rollouts and rollbacks
To build and run Containers, one can use an open source tool called Docker, that defines a format for bundling applications, its dependencies, and machine-specific settings into a Container. Another option is to use a different tool like Google Container Builder
Use a Docker file to specify how the code gets packaged into a Container. Then use the docker build command to build the Container. This builds the Container and stores it locally as a runnable image. One can save and upload the image into a Container registry service, and share or download it from there. Then, use the docker run command to run the image
Kubernetes is an open-source orchestrator that abstracts Containers at a higher level so users can better manage and scale their applications. At the highest level, Kubernetes is a set of APIs that one can use to deploy Containers on a set of nodes called a Cluster. The system is divided into a set of master components that run as a control plane, and a set of nodes that run Containers. In Kubernetes, a node represents a computing instance like a machine. In Google Cloud, nodes are virtual machines running in Compute Engine
Kubernetes can be configured with many options and add-ons, but can be time consuming to bootstrap from the ground up. Instead, one can bootstrap Kubernetes using the Google Kubernetes Engine (GKE). GKE clusters can be customized, they can support different machine types, numbers of nodes, and network settings
A Pod is the smallest unit of deployment in Kubernetes. A Pod represents a running process on the cluster as either a component of the application or an entire application. Generally, we only have one Container per Pod, but if we have multiple Containers with a hard dependencies, we can package them into a single Pod, and share networking and storage. The Pod provides a unique network IP, and set of ports for the Containers and options that govern how a Container should run. Containers inside a Pod can communicate with one another using localhost and ports that remain fixed as they are started and stopped on different nodes
One way to run a container in a Pod in Kubernetes is to use the kubectl run command
In Kubernetes, all Containers run in Pods. This use of the kubectl run command causes Kubernetes to create a deployment consisting of a single Pod containing the specified Container. A Kubernetes deployment keeps a given number of Pods up and running even in the event of failures among the nodes on which they run
A deployment represents a group of replicas of the same Pod and keeps the Pod running even when nodes they run on fail. It could represent a component of an application or an entire application
To see the running Pods, run the kubectl get pods command
By default, Pods in a deployment are only accessible inside the GKE cluster. To make them publicly available, one can connect a Load Balancer to their deployment by running the kubectl expose command. This instructs the Kubernetes Controller to create a Service with a fixed IP for the Pods, and attach an external Load Balancer with a public IP address to that Service so others outside the cluster can access it. Any client that hits that IP address will be routed to a Pod behind the Service
The Service is an abstraction which defines a logical set of Pods and a policy by which to access them. As deployments create and destroy Pods, Pods get their own IP addresses, but those addresses don't remain stable over time. A Kubernetes Service fronts a set of Pods and provides a stable endpoint or fixed IP for them
Kubernetes creates a Service and an external load balancer with a public IP address attached to it. The IP address remains the same for the life of the Service. Any network traffic to that public IP address is routed to Pods behind that Service
Run the kubectl get services command to get the public IP to hit the deployed application Container remotely. To scale a deployment, run the kubectl scale command
The real strength of Kubernetes comes when we work in a declarative way. Instead of issuing commands, we provide a configuration file that tells Kubernetes what the desired state looks like and Kubernetes figures out how to do it
To get the deployment configuration file, run the kubectl get pods command
To change the configuration (for example change the number of replicas), all we have to do is update the configuration file, and run the kubectl apply command to use the updated config file. To see the updated state, use the kubectl get pods command
What is the option when we want to roll out an updated version of our app? Use the kubectl rollout command, or change the deployment configuration file, and apply the changes using kubectl apply command. New Pods will be created according to the updated strategy
There are a lot of features in Kubernetes and GKE such as configuring health checks, setting session affinity, managing different rollout strategies, and deploying Pod s across regions for high availability
Google keeps the Kubernetes Engine refreshed with successive versions of Kubernetes
Kubernetes Lab
The following are some of the gcloud and kubectl commands from the Kubernetes lab:
Start a Kubernetes cluster named webfrontend in the us-central1-a zone and configured to run 2 nodes:
gcloud container clusters create webfrontend --zone us-central1-a --num-nodes 2
To check your installed version of Kubernetes:
kubectl version
To launch a single instance of the nginx container in a pod:
kubectl run nginx --image=nginx:1.10.0
To view the pod running the nginx container:
kubectl get pods
To expose the nginx container to the Internet via a load balancer:
kubectl expose deployment nginx --port 80 --type LoadBalancer
To view the newly created service:
kubectl get services
To scale up the number of pods running the nginx service to 3 instances (replicas):
kubectl scale deployment nginx --replicas 3
Google App Engine
⇒ App Engine Concepts
The App Engine platform manages the hardware and networking infrastructure required to run users application code. There are no servers to provision or manage
To deploy an application on App Engine, users just hand App Engine the application code and the App Engine service takes care of the rest
App Engine provides users with built-in services that many web applications need. No SQL databases, in-memory caching, load balancing, health checks, logging and a way to authenticate users
App Engine will scale a users application automatically in response to the amount of traffic it receives. So the user only pay for those resources they use
App Engine is especially suited for applications where the workload is highly variable or unpredictable like web applications and mobile backend
App Engine offers two environments: Standard and Flexible
The Standard environment is the simpler. It offers a simpler deployment experience and a fine-grained auto-scale
The Standard environment offers a free daily usage quota for the use of some services
With the Standard environment, low utilization applications might be able to run at no charge
Google provides App Engine software development kits in several languages, so that one can test their application locally before they upload it to the Google App Engine service
The App Engine SDKs provide simple commands for deployment
The following is the illustration of a typical App Engine workflow:
App Engine's term for the application executable binary is called the Runtime
In the Standard environment, you use a Runtime provided by Google
The Standard environment provides Runtimes for specific versions of Java, Python, PHP and Go. The Runtimes also include libraries that support App Engine APIs
If a user wants to code in another language, the Standard environment is not right choice and the user will want to consider the Flexible environmentZ
The Standard environment also enforces restrictions on the application code by making it run in a so-called Sandbox
A Sandbox is independent of the hardware, operating system, or physical location of the server it runs on. The Sandbox is one of the reasons why the Standard environment can scale and manage users application in a very fine-grained way
Sandboxes imposes some constraints. For example, an application code cannot write to the local file system. It will have to write to a database service instead if it needs to make data persistent. Also, all the requests the application receives has a 60-second timeout, and one can't install arbitrary third party software. If these constraints don't work for a user, they should choose the Flexible environment
Each App Engine application runs in a GCP project. App Engine automatically provisions server instances and scales and load balances them
In App Engine a user application can make calls to a variety of services using dedicated APIs. Here are a few examples: a NoSQL data store to make data persistent, caching of that data using Memcache, searching logging, user logging, and the ability to launch actions not triggered by direct user requests, like task queues and a task scheduler
Instead of the Sandbox, the Flexible environment lets a user specify the Container their application runs in
User application runs inside Docker containers on Google Compute Engine VMs and th App Engine manages these Compute Engine VMs. They are health checked, healed as necessary, and allows one to choose which geographical region they run in, and critical backward-compatible updates to their operating systems are automatically applied
The following is a side-by-side comparison of Standard and Flexible environments:
The Standard environment starts up instances of users application faster, but that users get less access to the infrastructure in which their application runs
The Flexible environment lets the users SSH into the virtual machines on which their application runs. It lets the users use local disk for scratch base, it lets the users install third-party software, and it lets their application make calls to the network without going through App Engine
The Standard environment's billing can drop to zero for the completely idle application
The following is a side-by-side comparison of App Engine and Kubernetes:
The Standard environment is for people who want the service to take maximum control of their application's deployment and scaling
The following is a comparison of the various Compute options in GCP:
Google Cloud Endpoints
⇒ Cloud Endpoints Concepts
When application developers structure the software they write in such a way that it presents a clean, well-defined interface that abstracts away needless details, that is an API
Cloud Endpoints allows one to expose an API to their software service in such a way that it is only consumed by other developers whom they trust, have an easy way to monitor and log its use, and have a single coherent way for them to know which end user is making the call
Cloud Endpoints implements these capabilities and more using an easy to deploy proxy in front of the software service, and it provides an API console to wrap up those capabilities in an easy-to-manage interface
Cloud Endpoints supports applications running in GCP's compute platforms in ones choice of languages and ones choice of client technologies
Google Apigee Edge
⇒ Apigee Edge Concepts
Apigee Edge is also a platform for developing and managing API proxies. It has a different purpose though. It has a focus on business problems like rate limiting, quotas, and analytics
Many users of Apigee Edge are providing a software service to other companies and those features come in handy. Because of the backend services for Apigee Edge need not be in GCP, engineers often use it when they are "taking apart" a legacy application. Instead of replacing a monolithic application in one risky move, they can instead use Apigee Edge to peel off its services one by one, standing up microservices to implement each in turn, until the legacy application can be finally retired
Use Apigee Edge to do business analytics and billing on a customer-facing API
References
Coursera - Google Cloud Platform Fundamentals: Core Infrastructure
GCP Fundamentals :: Core Infrastructure - Summary Notes - Part 1
GCP Fundamentals :: Core Infrastructure - Summary Notes - Part 2