Links

Kubernetes

Introduction to Kubernetes

Why choose Kubernetes?

  • An open-source system for automating deployment, scaling, and management of containerized applications.
  • No Vendor Lock-In
  • Large Community of support
  • Robust platform for container orchestration
  • Based on 15 years of experience of running production workloads at Google, combined with best-of-breed ideas and practices from the community

Kubernetes is an Orchestration Platform

  • Scheduling: decide where containers run
  • Lifecycle and Health: keep containers running and restart them if they fail
  • Scaling: grow and shrink deployments as needed
  • Naming and Discovery: help containers find each other
  • LoadBalancing: distribute traffic across containers ...and a whole lot more

Why Do You Need Container Orchestration?

  • Deploy applications to servers without worrying about specific servers
  • Scale the application horizontally up and dow
  • This is called container auto-healing or Restore the application if the server on which it worked fails rescheduling

Kubernetes has a Declarative API

Kubernetes is a Declarative Model
You express the desired state
Kubernetes maintains it
What could be simpler?

Kubernetes Architecture

  • There can be one or more Master Nodes (HA)
  • There can be zero or more Worker Nodes
  • Everyone communicates via the API Server
  • Kubelet on each Worker Node acting as an agent
  • Everything can be on one node for development use

Kubernetes All-In-One

  • You can run Kubernetes all in one VM for development work (not for production!)
  • MiniKube is great for setting this up
  • MiniShift will deploy a development version of RedHat OpenShift 3.x which uses Kubernetes
  • CRC (Code Ready Container) will deploy OpenShift 4.x

Kubernetes is the new "Cloud OS"

Managing Containers with VMs:
  • SysAdmins must decide where to place container
  • Workload balancing is manual
Managing Containers with Kubernetes:
  • Kubernetes schedules and optimizes workloads automatically

Kubernetes Pods

  • Containers run in Pods
  • The Pod is the smallest deployment possible
  • Containers are deployed from a container registry (public or private)

Kubernetes ReplicaSets

  • ReplicaSets allow multiple copies of containers to be deployed
  • Each one in it's own Pod
  • If a container dies, the ReplicaSet will spawn a new one

Kubernetes Volume Mounts

Volumes
  • ConfigMaps hold configuration parameters
  • Secrets hold credentials and other secrets
  • Persistent Volume Claims are used to ask for persistent storage for data/state

Kubernetes Deployments

Deployment
  • Sets up the ReplicaSets for you
  • Also specified the Secrets, ConfigMaps, and Volume Mounts
  • Provides features for rolling out updates and handling their rollbacks

Kubernetes Service

Service exposes Pods to the outside as:
  • ClusterIP
  • NodePort
  • Load Balancer

Types of Services

  • LoadBalancer: Only available via cloud providers. Front end for service that balances the load across multiple backends from a single IP address
  • NodePort: Exposes the service as an arbitrary port on every worker node in the cluster
  • ClusterIP: Service is only accessible from other services within the cluster (no external exposure)

Kubernetes Ingress Controller

Ingress
  • Exposes Service outside of Kubernetes
  • Maps URL paths to services

Services Map to Pods via Labels

Services Map to Pods via Labels

Use Case for Multiple Containers in a Pod

Pods can be used to host vertically integrated application stacks (e.g. LAMP), but their primary motivation is to support co-located, co-managed helper programs, such as:
  • Content management systems, file and data loaders, local cache managers, etc.
  • Log and checkpoint backup, compression, rotation, snapshotting, etc.
  • Data change watchers, log tailers, logging and monitoring adapters, event publishers, etc.
  • Proxies, bridges, and adapters
  • Controllers, managers, configurators, and updaters

Linking Service to Pods

Service:
apiVersion: v1
kind: Service
metadata:
name: hitcounter-service
spec:
type: NodePort
selector:
app: hitcounter # label
ports:
- name: primary
protocol: TCP
port: 8080
Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hitcounter
spec:
replicas: 3
selector:
matchLabels:
app: hitcounter # <-- should match this label
template:
metadata:
labels:
app: hitcounter
spec:
containers:
- image: hitcounter:1.0
imagePullPolicy: IfNotPresent
name: hitcounter
ports:
- containerPort: 8080
- protocol: TCP
restartPolicy: Always

Service Discovery

Kubernetes provides internal routing so services can find each other
Internal Service Discovery

External Service Access

LoadBalancers provide external access for a single service
LoadBalancer

External Routing

Kubernetes provides an Ingress Controller to allow external network access or you can use NodePorts.
External Routing

Ingress Example

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ecommerce
spec:
rules:
- host: ecommerce.containers.mybluemix.net
http:
paths:
- path: /shopcarts
backend:
serviceName: shopcart-service
servicePort: 5000
- path: /catalog
backend:
serviceName: catalog-service
servicePort: 5000
- path: /orders
backend:
serviceName: order-service
servicePort: 5000
- path: /recommendations
backend:
serviceName: recommendation-service
servicePort: 5000

Ingress Controller

Single entry point into multiple kubernetes services
Ingress Controller

Persistent Volumes

  • Kubernetes loosely couples physical storage devices with containers by introducing an intermediate resource called persistent volume claims (PVCs).
  • A PVC defines the disk size, disk type (ReadWriteOnce, ReadOnlyMany, ReadWriteMany) and dynamically links a storage device to a volume defined against a pod
  • The binding process can either be done in a static way using PVs or dynamically be using a persistent storage provider

Example Volume Mount

There is a volume named redis-storage and that is connected to the redis container via the VolumeMount: /data/redis
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}

Configurations Management: ConfigMaps

  • Containers generally use environment variables for parameterizing their runtime configurations
  • Kubernetes provides a way of managing more complex configuration files using a simple resource called ConfigMaps
  • ConfigMaps can be created using directories, files or literal values using following CLI command:
$ kubectl create configmap <map-name> <data-source>
# map-name: name of the config map
# data-source: directory, file or literal value

Credentials Management: Secrets

  • Similar to ConfigMaps, Kubernetes provides another valuable resource called Secrets for managing sensitive information such as passwords, OAuth tokens, and ssh keys.
  • A secret can be created for managing basic auth credentials using the following way:
# write credentials to two files
$ echo -n 'admin' > ./username.txt
$ echo -n '1f2d1e2e67df' > ./password.txt
# create a secret
$ kubectl create secret generic app-credentials --from-file=./
username.txt --from-file=./password.txt

Credentials From Environment Variables

$ export DATABASE_URI='postgres://admin:[email protected]:5432/postgres'
$ kubectl create secret generic db-creds --from-literal=databaseuri=$DATABASE_URI
Creates the following
apiVersion: v1
kind: Secret
data:
database-uri: cG9zdGdyZXM6Ly9hZG1pbjpzM2NyM3RAcG9zdGdyZXM6NTQzMi9wb3N0Z3Jlcw==

Create Secrets from Literals

kubectl create secret generic dev-db-secret \
--from-literal=username=devuser \
--from-literal=password='s3cr3t' \
--dry-run=client -o yaml
Output from create command:
apiVersion: v1
kind: Secret
metadata:
name: dev-db-secret
type: Opaque
data:
username: ZGV2dXNlcgo=
password: czNjcjN0Cg==

Secret Yaml Example

apiVersion: v1
kind: Secret
metadata:
name: ecommerce-apikey
namespace: default
data:
secret: <place base64 encoded secret here>

Using Secrets

apiVersion: apps/v1
kind: Deployment
---
spec:
containers:
- name: pet-demo
image: pet-demo:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5000
protocol: TCP
env:
- name: DATABASE_URI
valueFrom:
secretKeyRef:
name: pet-creds
key: binding

Kubernetes Rolling Updates (Zero Downtime Deployments)

$ kubectl set image deployment/<application-name> <container-name>=<container-image-name>:<new-version>

Kubernetes Autoscaling

Kubernetes allows pods to be manually scaled either using ReplicaSets or Deployments. This can be achieved using the following CLI command:
$ kubectl scale --replicas=<desired-instance-count> deployment/<application-name>