Download as pdf or txt
Download as pdf or txt
You are on page 1of 84

DEVOPS

BOOTCAMP Container Orchestration


with Kubernetes
Official Definition

Open source container orchestration tool


Developed by Google
Automates many processes involved in deploying, managing and scaling
containerized applications

Most used container orchestration platform


Also known as "K8s" or "Kube"
The need for Kubernetes
Trend from Monolith to
Microservices
Containers are the perfect host for
microservice applications
Microservices
Resulted in an increased usage of monolith microservices
in containers
containers

Manually managing hundreds or hundreds of 1000s containers is a lot of effort

Kubernetes automates many of those manual tasks and provides


High Availability or no downtime Disaster Recovery - Backup and Restore
Automatic Scaling Self-Healing
Core Kubernetes Components - 1
Kubernetes has many components, but these are the main ones you need to know:

SERVICE CONFIGMAP
POD
INGRESS SECRET

DEPLOYMENT
VOLUMES
STATEFULSET
Core Kubernetes Components - 2

POD

Group of 1 or more containers

Smallest unit of K8s

An abstraction over container

Usually 1 application/container per Pod

Pods are ephemeral

New IP address assigned on re-creation


Core Kubernetes Components - 3

Internal vs External Service


SERVICE
When creating a service you can specify its type:
Basically a static or
Internal Service: By default, for example a
permanent IP address that
database, which should not be accessible
can be attached to each Pod

Also serves as a loadbalancer from outside

Lifecycles of Service and Pod External Service: Application accessible

are not connected through browser

If Pod crashes, the Service and

its IP address will be the same


Core Kubernetes Components - 4

URL of external Service: http://124.89.101.2:8080

URL of Ingress Service: https://my-app.com

INGRESS

Ingress is the entrypoint to your K8s cluster

Request goes to Ingress first, which does the

forwarding to the Service


Core Kubernetes Components - 5
For external configuration, Kubernetes has these 2 components:

CONFIGMAP
Pods can consume
To store non-confidential
ConfigMaps and Secrets as
data in key-value pairs
environment variables, CLI
SECRET arguments or as config files in a

Similar to ConfigMap, but to Volume

store sensitive data such as

passwords or tokens
Storing the data in a Secret component doesn't automatically make it secure. There are built-in
mechanisms (like encryption, defining authorization policies) for basic security, which are not enabled
by default! Recommended to use third-party secret management tools, because the provided
capabilities by K8s are not enough for most companies
Core Kubernetes Components - 6
When a container crashes, K8s restarts the container but with a clean state. Meaning your data is lost!

VOLUME

Volume component basically

attaches a physical storage on a

hard drive to your Pod


Think of storage as an external hard
Storage could be either on a local drive plugged in to your K8s cluster
server or outside the K8s cluster

K8s doesn't manage any data persistence,


meaning you are responsible for
backing up, replicating the data etc.
Core Kubernetes Components - 7
Deployment and StatefulSet are an abstraction of Pods

DEPLOYMENT STATEFULSET

Blueprint for Pods Blueprint for stateful applications

You work with Deployments Like databases etc

and by defining the number of In addition to replicating features,

replicas, K8s creates Pods StatefulSet makes sure database

reads and writes are synchronized to

avoid data inconsistencies

Having load balanced replicas our


setup is much more robust
2 Types of Nodes

A Kubernetes cluster consists of a set of worker machines, called "Nodes"

Worker Node Control Plane

The containerized applications Manages the Worker Nodes

run on the Worker Nodes and the Pods in the cluster

Each Node runs multiple Pods on Much more important and


Control Plane
it needs to be replicated

Much more compute resources So in production, replicas run

needed, because the actual across multiple machines

workload runs on them


Worker Node Components

Each worker node needs to have 3 processes installed:

1) Container Runtime 2) Kubelet

Software responsible for Agent that makes sure

running containers containers are running in a Pod

For example containerd, CRI-O Talks to underlying server (to

or Docker get resources for Pod) and

container runtime (to start


3) Kube-proxy
containers in Pod)
A network proxy with

intelligent forwarding of

requests to the Pods


Control Plane Components - 1

Each control plane needs to have 4 processes installed:

1) API Server 2) Scheduler

3) Controller Manager 4) etcd

Control Plane makes global decisions about the cluster

Detects and responds to cluster events Control Plane


Control Plane Components - 2

1) API Server 2) Scheduler

The cluster gateway - single Decides on which Node new Pod

entrypoint to the cluster should be scheduled

Acts as a gatekeeper for Factors taken into account for

authentication, validating the request scheduling decisions: resource

Clients to interact with the API server: requirements, hardware/software/

UI, API or CLI policy constraints, data locality, ...


Control Plane Components - 3

3) Controller Manager 4) etcd

Detects state changes, like crashing K8s' backing store for all cluster data. A

of Pods and tries to recover the consistent, high-available key-value store

cluster state as soon as possible Think of it as a cluster brain, every change in the cluster gets saved or
For that it makes request to the updated into it
Scheduler to reschedule those Pods All other processes like Scheduler, Controller Manager etc work based
and the same cycle happens on the data in etcd as well as communicate with each other through etcd

store

The actual application data is NOT


stored in the etcd store
Increase Kubernetes Cluster Capacity
As your application grows and its demand for resources increases, you may actually add more Nodes t​ o your

cluster, thus forming a more powerful and robust cluster to meet your application resource requirements

Add a Control Plane Node Add a Worker Node

1. Get a fresh new server


1. Get a fresh new server
2. Install all the Worker Node processes, like
2. Install all control plane processes on it
container runtime, Kubelet and KubeProxy on it
3. Join it to the K8s cluster using a K8s command
3. Join it to the K8s cluster using a K8s command

Control Plane Control Plane


Minikube - Local Cluster Setup
Minikube implements a local K8s cluster

Useful for local K8s application development,

because running a test cluster would be complex

Control Plane and Worker

processes run on ONE machine

Run Minikube either as a container or virtual machine on your laptop

So you need a container runtime or virtual

machine manager on your laptop


Kubectl - Command Line Tool

CLI Tool to interact with your K8s cluster


Basic kubectl commands:

In order for kubectl to access a K8s cluster, it needs a

kubeconfig file, which is created automatically when

deploying your minikube cluster Get status of different


components
By default, config file is located at ~/.kube/config

CRUD

kubectl API server Debugging


K8s YAML Configuration File - 1
Also called "Kubernetes manifest" Config files are in YAML format, which is user-friendly,

Declarative: A manifest specifies the but strict indentation!

desired state of a K8s component Config files should be stored in version control

Each configuration file has 3 parts:

1) metadata 2) specification

Attributes of "spec" are specific to the kind


K8s YAML Configuration File - 2
3) status

Automatically generated and added by Kubernetes


Current status: 1 replica
K8s gets this information from etcd, which holds the

current status of any K8s component

Desired status: 2 replica


Deployment Configuration File
Deployment Configuration is a bit special

Since it's an abstraction over Pod, we have

the Pod configuration inside Deployment

configuration

Own "metadata" and "spec" section

Blueprint for Pod


Labels & Selectors
Labels
Label Selectors
Labels are key/value pairs that are attached to Labels do not provide uniqueness

resources, such as Pods. Via selector the user can identify a set of

Used to specify identifying attributes that are resources

meaningful and relevant to users

Connecting Services to Deployments


Ports in Service and Pod
In Service component you need to specify: In Deployment component:

port = the port where the service itself is accessible containerPort = port, the container

targetPort = port, the container accepts traffic on accepts traffic on


Browser Request Flow through the K8s components
URL: IP address of Node + Port of external Service
K8s Components needed in this setup
Example Setup: 2 Deployment / Pod
2 Services
Mongo Express as UI 1 ConfigMap
1 Secret
MongoDB as database

User updates entries in database via browser

ConfigMap and Secret holds the MongoDB's

endpoint (Service name of MongoDB) and

credentials (user, pwd), which gets injected to

MongoExpress Pod, so MongoExpress can connect

to the DB
Namespaces - 1
Namespaces provide a mechanism for isolating groups of resources within a single cluster

Names of resources need to be unique within a namespace, but not across namespaces

Like a virtual cluster inside a cluster


"Default" namespace

Namespaces per default Start deploying your application in the default

Namespaces per namespace called "default"

default, when you Create a new namespace


install K8s
Via kubectl command: kubectl create namespace my-ns
"kube-system" has
Via configuration file:
control plane processes

running

DON'T modify kube-system!!


Namespaces - 2
Use Cases for when to use namespaces:

1 - Group resources logically 2 - Isolate team resources

Instead of having all in the "default" namespace To avoid conflicts


Namespaces - 3
Use Cases for when to use namespaces:

3 - Share resources between different 4 - Limit permissions and compute


environments resources for teams
Namespaces - 4
There are resources, which can't be created within a namespace, called cluster-wide resources:

Namespaced resources Cluster-wide resources

Most K8s resources (e.g. pods, services, etc.) are Live globally in a cluster, you can't isolate them

in some namespaces Low-level resources, like Volumes, Nodes

Access service in another namespace:


Kubernetes Services - 1
Why Service?
Abstract way to expose an application running
Stable IP address
on a set of Pods
Loadbalancing
Different types of services:
Loose coupling

3 Service type attributes Within & Outside Cluster

ClusterIP is the default type, when you don't specify a type


Kubernetes Services - 2

Service defines a logical set of Pods

The set of Pods targeted by a

Service is determined by a

selector

This creates a new Service named


"miroservice-one-service", which
targets port 3000 on any Pod with
the app=microservice-one label.

PORTS:
The service port is arbitrary

targetPort must match the port the container is listening at


ClusterIP Service & its subtypes
ClusterIP is an internal service, not accessible from outside the cluster

All Pods in the cluster can talk to this internal service


Multi-Port Internal Service
Headless Internal Service
When you need to expose more than 1 port
When client needs to communicate with 1 specific
K8s lets you configure multiple port definitions on a
Pod directly, instead of randomly selected
Service

Use Case: When Pod In that case, you must

replicas are not give all of your ports

identical. For example names so that these

stateful apps, like when are unambiguous

only master is allowed

to write to database
NodePort Service
Unlike internal Service, is accessible directly from outside cluster

Exposes the Service on each Node's IP at a static port

Node
URL = IP address of Worker Node : nodePort

A ClusterIP Service, to which the NodePort

Service routes, is automatically created

Not Secure: External traffic has access to fixed port on each Worker Node
Loadbalancer Service
Exposes the Service externally using a cloud provider's load balancer

NodePort and ClusterIP Services, to which the external load balancer routes, are automatically created

More secure, more


efficient with 1 entry point

Node Loadbalancer
Ingress - 1
External Services are a way to access applications in K8s from outside

In production a better alternative is Ingress!

Not a Service type, but acts as the entry point for your cluster

More intelligent and flexible: Let's you consolidate your routing rules into a single resource as it

can expose multiple services under the same IP address


Configure multiple paths for same host:
Ingress - 2

Configure multiple sub-domains or domains:

Configure TLS

Certificate - https://
Ingress - 3

How to configure Ingress in your cluster Ingress Controller

You need an implementation for Ingress Evaluates all the rules

Manages redirections
Which is Ingress Controller
Entry point to the cluster

Many third-party implementations

K8s Nginx Ingress Controller


Ingress - 4

Before Ingress Controller you still need 1 load balancer

Option 1 - Cloud service provider: have out-of-the-box K8s solutions

Option 2 - Bare Metal: You need to configure some kind of entry point. Either

inside the cluster or outside as separate server

Source: https://kubernetes.io/docs/concepts/services-networking/ingress/
Volumes - 1

K8s offers no data persistence out of the box

At its core, a volume is a directory (with some data in it), which is accessible to the containers in a Pod

K8s supports many types of volumes

Ephemeral volume types have a lifetime of a Pod, persistent volumes exist beyond the lifetime of a Pod

Storage Requirements

In this lecture we talk about persistent Storage that doesn't depend on pod lifecycle

Storage must be available on all Nodes


volumes, with these storage requirements:
Storage needs to survive even if cluster

crashes
Volumes - 2

The way to persist data in K8s using Volumes is with these 3 resources:

Persistent Volume (PV) Storage Class (SC)

Storage in the cluster that has been provisioned by SC provisions PV dynamically when PVC claims it

an administrator or dynamically provisioned using

Storage Classes

Persistent Volume Claim (PVC)

A request for storage by a user

Similar to Pods. While Pods consume node

resources, PVCs consume PV resources


Persistent Volume - 1

Persistent Volumes are NOT

namespaced, so PV resource is
Configuration Example
accessible to the whole cluster:

Depending on storage type, spec

attributes differ

In official documentation you can

find a complete list of storage

backends supported by K8s:


Persistent Volume - 2

Local vs Remote Volume Types


For DB persistence use remote storage!

Each volume type has its own use case!

Local volume types violate 2. and 3. requirement for data persistence:

Being tied to 1 specific Node

Not surviving cluster crashes


Persistent Volume Claim
Request for storage by a user

Claims can request specific size and access modes (e.g. they can be mounted

ReadWriteOnce, ReadOnlyMany or ReadWriteMany).


Storage Class
Storage Class Usage

1. Pod claims storage via PVC


Provisions PV dynamically
2. PVC requests storage from SC

3. SC creates PV that meets the

needs of the Claim

StorageBackend is defined in the SC resource


via "provisioner" attribute
each storage backend has own provisioner
internal provisioner - "kubernetes.io"
external provisioner
configure parameters for storage we want to
request for PV
StatefulSet
Used to manage stateful applications, like databases

Manages the deployment and scaling of a set of Pods and provides guarantees about the

ordering and uniqueness of these Pods

Stateless Applications Stateful Applications

Doesn't depend on previous data Update data based on previous data

Deployed using Deployment Query data

Depends on most up-to-date data/state

Both manage Pods based on container specification


Deployment vs StatefulSet
Unlike a Deployment, a StatefulSet maintains a sticky identity for

each of their Pods

These pods are created from the same spec, but are not

interchangeable: each has a persistent identifier that it maintains $(statefulset name)-$(ordinal)

across any rescheduling


Pods created from
Pods created from
Deployment
StatefulSet
Identical and interchangeable
More difficult
Created in random order with
Can't be created/deleted at
random hashes
same time
1 Service that load balances to
Can't be randomly addressed
any Pod
Scaling database applications

Only 1 replica, can make changes

So replicas are not identical

Each replica has its own storage

These storages are constantly

synchronized
Kubernetes on Cloud platform
2 options to create a Kubernetes cluster on a cloud platform

Create own cluster from scratch Use Managed K8s Service

You need to manage everything You only care about Worker Nodes

yourself Everything pre-installed

Not practical, when you want to Control Plane Nodes created and managed by cloud

setup things fast and easy provider

You only pay for the Worker Nodes

Use cloud native load balancer for Ingress controller

Use cloud storage

Less effort and time


Example Managed Kubernetes Services

AWS: Elastic Kubernetes Service (EKS)

Azure: Azure Kubernetes Service (AKS)

Google: Google Kubernetes Engine (GKE)

Linode: Linode Kubernetes Engine (LKE)


Helm - Package Manager
Helm is the package manager for Kubernetes. Think of it like apt/yum for Kubernetes

Packages YAML files and distributes them in public and private repositories

Helm Helm Chart

Tool that installs and manages K8s Helm package that contain

applications description of the package Chart.yaml

This is done via Charts, so Helm manages 1 or more templates, which contain K8s

these Charts manifest files

You can create your own Helm Charts with

Helm, push to Helm Repository

Download and use existing ones


Helm Charts
Why Helm Charts?

Instead of everyone creating their own

K8s config files, 1 bundle of all needed

K8s manifests

Use existing official Charts: Sharing Helm Charts:

Many of these created by the official sources. Charts are hosted on their own repositories

Mysql Chart from Mysql or ElasticSearch Chart There are public repos, but you can have own

from ElasticSearch private repos in your company. E.g. Nexus

helm search <keyword> or Helm Hub website


Helm as Templating Engine - 1
How to:
Helm renders the templates and communicates
1. Define a common blueprint
with the Kubernetes API 2. Dynamic values are replaced by

placeholders

Helm Chart Structure

Top level mychart folder name of chart

Chart.yaml meta info about chart

values.yaml values for the template files

charts folder chart dependencies

templates folder the actual template files


Helm as Templating Engine - 2

many YAML files just 1 YAML file

Many

values are

the same!

Another use case: Deploy the same

bundle of K8s YAML files across

multiple clusters:
Pull Docker Images into K8s cluster
PRIVATE REPO: For K8s to fetch

the Docker Image into K8s

cluster, it needs explicit access

PUBLIC REPO: For public

images, like mongodb etc.

pulled from public repositories

no credentials needed
Steps to pull image from Private Registry

1 - Create Secret Component 2 - Configure Deployment

Contains credentials for Docker registry Use Secret using imagePullSecrets

docker login token is stored in dockerconfig file


Kubernetes Operators - 1

Stateful applications need constant management and syncing after deployment. So

stateful applications, like database need to be operated

Instead of a human operator, you have an automated scripted operator

Operators are created


by official maintainers
Stateless applications:

Is managed by Kubernetes

Stateful applications:
Operators
K8s can't automate the process natively
Kubernetes Operators - 2
How it works:

Control loop mechanism

Custom Resource Definitions


Makes use of CRD's Custom K8s component (extends the K8s API)

Include domain/App-specific-knowledge, e.g. mysql:

How to create mysql cluster

How to run it

How to synchronize the data

How to update
Layers of Security
In K8s, you must be authenticated

(logged in) before your request can Request to K8s cluster

be authorized (granted permission

to access)

Authentication Authorization
K8s doesn't manage Users natively K8s supports multiple authorization modules, such
No K8s resources exist for representing normal as ABAC mode, RBAC Mode and Webhook mode
user accounts On cluster creation, admins configure the
Admins can choose from different authentication authorization modules that should be used
strategies K8s checks each module, and if any module
authorizes the request, then the request can
proceed
Authentication
API server handles authentication of all the requests

Available authentication strategies:

Client Certificates Static Token File 3rd Party Identitiy Service, like LDAP

A csv file with a minimum of 3

columns: token, user name, user

uid, followed by optional group

names
Authorization
As a security best practice, we only want to give people or services just enough permission to do

their tasks: Least Privilege Rule

Developers need only limited


Admins need cluster-wide
access for example to deploy
access to do tasks like configure
applications to 1 specific
namespaces etc.
namespace
Authorization with RBAC - 1
Role-based access control (RBAC)

A method of regulating access to resources based on the roles of users within the organization

Enabling RBAC: kube-apiserver --authorization-mode=RBAC --other-options

4 kinds of K8s resources: ClusterRole, Role, ClusterRoleBinding, RoleBinding

Role and ClusterRole RoleBinding and ClusterRoleBinding


Contains rules that represent a set Link ("Bind") a Role or ClusterRole to a
of permissions User or Group
Permissions are additive
Authorization with RBAC - 2

ClusterRole
Role

Define permissions cluster wide


Define namespaced permissions
For example: configure cluster-
through Role
wide volumes, namespaces
Bound to a specific namespace

What resources in that namespace

you can access

What action you can do with this

resource
Authorization with RBAC - 3

ClusterRoleBinding RoleBinding

Link ("Bind") ClusterRole to a User or Group Link ("Bind") Role to a User or Group
Authorization for Applications

ServiceAccounts provide an identity for processes

that run in a Pod, for example Jenkins or Prometheus

A RoleBinding or

ClusterRoleBinding can also

bind a role to a

ServiceAccount
Introduction to Microservices

Microservices are an architectural approach to software development

Software is composed of small independent services (instead of having a huge monolith)

Each business functionality is encapsulated into own Microservice (MS)

Benefits

Each MS can be developed, packaged and released

independently

Changes in 1 MS doesn't affect other MS

Less interconnected logic, loosely coupled

Each MS can be developed by separate developer teams


Communication between Microservices

Communication between those services can happen in different ways:

Service-to-Service API Calls Message-Based Communication Service Mesh Architecture

Direct communication Communication through a Platform layer on top of the

message broker, like Rabbitmq infrastructure layer, like Istio,

or Redis Linkerd, HashiCorp Consul

Enables managed, observable

and secure communication


DevOps Task: Deploy Microservices App - 1

Information you need from developer:

1. Which services you need to deploy?

2. Which service is talking to which

service?
Developers develop the As a DevOps engineer your
3. How are they communicating?
microservice applications task would be to deploy the
4. Which database are they using? 3rd
existing microservices
party services
application in a K8s cluster
5. On which port does each service

run?
DevOps Task: Deploy Microservices App - 2

HOW TO 1. Prepare K8s environment

a. Deploy any 3rd party apps

b. Create Secrets and ConfigMaps for microservices

2. Create Deployment and Service for each microservices

1) 2) When deploying multiple


similar services to K8s, you
can use helm chart with 1
common template and
replace specific values for
each service on the fly
during deployment
Best Practices - 1

Specify a pinned version on each container image

Why? Otherwise, latest version is fetched, which makes it unpredictable and intransparent as to which
versions are deployed in the cluster

Configure a liveness probe on each container

Why? K8s knows the Pod state, not the application state. Sometimes
pod is running, but container inside crashed. With liveness probe we
can let K8s know when it needs to restart the container

Configure a readiness probe on each container

Why? Let's K8s know if application is ready to receive traffic


Best Practices - 2

Configure resource limits & requests for each container

Why? To make sure 1 buggy container doesn't eat up all

resources, breaking the cluster

Don't use NodePort in production

Why? NodePort exposes Worker Nodes directly, multiple points of entry to

secure. Better alternative: Loadbalancer or Ingresss

Always deploy more than 1 replica for for each application

Why? To make sure your application is always available, no downtime for users!
Best Practices - 3

Always have more than 1 Worker Node

Why? Avoid single point of failure with just 1 Node

Label all your K8s resources

Why? Have an identifier for your components to group pods and reference in Service e.g.

Use namespaces to group your resources

Why? To organize resources and to define

access rights based on namespaces e.g.


Security Best Practices

Ensure Images are free of vulnerabilities

Why? Third-party libraries or base images can have known vulnerabilities. You

can do manual vulnerability scans or better automated scans in CI/CD pipeline

No root access for containers

Why? With root access they have access to host-level resources. Much more

damage possible, if container gets hacked!

Keep K8s version up to date

Why & How? Latest versions include patches to previous security issues etc.

Upgrade with zero downtime by having multiple nodes and pod replicas on different nodes

You might also like