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