Cloud native
= scalable apps running in modern cloud environments, how they are architected and operated
using containers, microservices etc.
apps could be on a public cloud (AWS, Azure etc.) or on-premises (on my own hardware in my own facility)
allows for IaaC (infrastructure as a code, declarative management)
pros:
loosely coupled system that is resilient, manageable and observable
dynamic scaling of the apps, different tech stacks for different apps
companies and teams are able to do frequent changes with minimal effort pushing into production (of course, after whole set-up it is minimal effort :))
cons:
increased complexity, harder to debug
cultural shift in the company required (DevOps, new technologies, different way of programming)
often high costs
security concerns, frequent attacks
CNCF = nonprofit foundation which helps companies to shift into cloud
their path:
start with containerization
package apps in Docker containers (almost all apps could be containerized)
try to split existing apps into microservices
set-up CI/CD
orchestration
using Kubernetes or Swarm (not dominant, deprecated)
observability
employ solutions for observing, monitoring, logging etc.
metrics (Grafana), logs (ELK stack)
Kubernetes
Orchestrace kontejnerů
manages a set of containerized applications and separates application deployment from the infrastructure
so I am able to deploy, scale and update an application without worrying about the infrastructure underneath
it’s called declarative configuration
I define, what to run without specifying where it runs
could be used in the cloud or on the premises (my own servers)
Desired state model
user defines a desired state with YAML files (manifests)
and Kubernetes performs the “control loop” where it checks:
current state and it’s differences to the desired state
acts on those differences automatically to reach the desired state
through restarting, rescheduling or scaling Pods
Features
automatic allocation of containers on nodes (based on resource requirements and other constraints) - “binpacking”
horizontal scaling with simple commands
automated rollouts and rollbacks
Kubernetes progressivelly rollouts my changes, monitoring app health and rollbacks if something goes wrong
automatic mounting of the storage system
self-healing
restarting containers, replacing and rescheduling containers from nodes that die
load-balancing and service discovery (each Pod has it’s own IP address and DNS name)
Building blocks
Pod - the smallest deployable unit in Kubernetes
includes one or more tightly coupled containers (sharing network and storage)
because they share the Linux namespaces underneath
common usecase is just for only one container
runs a single instance of given application
could be destroyed and recreated (then their IP can change)
Node - a worker machine in Kubernetes (Virtual machine or physical machine)
runs Pods scheduled by Control plane
have a kubelet agent, which manages all Pods on the current Node
kube-proxy - handles network routing
Control plane - manages the overall state of the cluster
schedules workloads on Nodes and responds to cluster events
starting Pods and assigning them onto available Node (based on contraints)
exposes API server, which is the frontend of the Control plane (allowing users to control it)
Cluster - a set of worker Nodes and a Control plane
Workloads - represent a whole application running on Kubernetes
they run in a set of Pods
user defines the desired state of the application with a specification document
defining containers, replicas etc.
Job - task that runs once and is completed
CronJob - repeated task on some schedule
Sets:
= “Pod managers”, I don’t have to create individual Pods, I define a set and Kubernetes will create the set of Pods for me
Deployment
abstraction over ReplicaSets
I define Deployment set of Pods and it handles everything around deployment (rolling updates, rollbacks, version history, rollout strategies)
e.g. I define the rollout strategy and Deployment handles it infrastructure-wise
used on stateless apps (each Pods can be quickly replaced)
ReplicaSet
creates X replicas for me and manages it (when a Pod dies → new is created, when there are more than X replicas → one is killed)
is created depending on the number of replicas defined in the Deployment
StatefulSet
manages stateful applications that need stable and persistent storage, stable network etc.
different from Deployment, here we have to be more careful with replacements because of the state
DaemonSet
automatically creates a Pod on each Node (for logging, health checks, monitoring, network plugins etc.)
Service - abstraction defining a logical set of Pods and a policy to access them
solving problem:
we have an app on 3 Pods
each Pod can change it’s IP
no load-balancing
how to find new Pods when created etc.
solving:
stable IP and DNS name for a set of Pods
automatic load balancing
automatic discovery of new/deleted Pods in the set
user can define Service using label :
we define some name and all Pods with the same name will be included
types of Service:
ClusterIP - for internal communication within the cluster
each Service get a cluster IP to communicate with other Services
NodePort - exposes a Service on each Node’s IP at a static port
Service is now available from outside the cluster
LoadBalancer
provides connection to external load balancer (supplier by the cloud provider)
ExternalName
maps the Service to an external DNS name (to reference external Services)
Technical notes
while Docker uses containerd and runc to interact with the Linux namespaces
the Kubernetes can use different container runtime implementations (CRI)
e.g. CRI-O from RedHat/IBM, containerd, Kata Containers…
Kubernetes have namespaces allowing:
better organization of objects and resources (multiple teams, projects etc. on the same cluster)
preventing name collisions, resource limits and access control per namespace
separate namespaces for dev, test, prod