Kubernetes - Container as a Service
Quick Reference
Overview
Kubernetes aka K8s …manage containerized workloads and services
- …supports declarative configuration …automates deployment
- …runs on virtual and physical environments …on-premise & public clouds
- …reference infrastructure for cloud-native1˒2 applications
- Benefits of the Kubernetes architecture…
- …service discovery …networks, devices, service, metadata, etc
- …storage orchestration …decouple storage allocation from back-ends
- …container run-time agnostic …use any OCI compliant container engine
- …provider agnostic …no vendor lock-in to a specific IaaS
- …productivity …enables fast deployment CI/CD & DevOps
What can be difficult with Kubernetes?
- Hard multi-tenancy…
- …options for cluster-level sharing are available
- …however difficult where the tenants do not trust each other
- …typically each tenant is hosted a dedicated cluster instance
- Most deployments are virtual …and run on a cloud infrastructure
- …many use-cases & examples specific to cloud providers
- …bare-metal deployment not widely used …hence more challenging to build
Architecture
Control plane …manages worker nodes & pods in the cluster…
- …usually runs distributed over multiple nodes (fault-tolerance, highly-available)
- Control plane components …global decisions about the cluster:
- API server
- …core component server …exposes the Kubernetes API
- …runs several instances of
kube-apiserver
to scale horizontally
- Cluster Storage
- …consistent and highly-available key value store
- …
etcd
3 …uses Raft consensus algorithm - …data is consistently replicated across multiple nodes
- …supports built-in snapshots for backup
- Scheduler
- …
kube-scheduler
…basically assigns pods to nodes - …monitors cluster resources …uses various policies for placement
- …
- Controllers …manage the cluster state
- …
kube-controller-manager
…runs individual controller processes - …different controllers for nodes, jobs, services, etc.
- …
- API server
Worker nodes host pods that house containerized applications…
- …provide the Kubernetes run-time environment
- Components that run on every node:
kubelet
4 …primary “node agent”- …works in terms of a PodSpec …YAML/JSON object describing a pod
- …ensures that pods are running and healthy
kube-proxy
(optional) …connects pods with a network- …uses the OS packet filter …otherwise forwards the traffic itself
- …other network plugins implement CNI (Container Network Interface)
- Container run-time …Kubernetes CRI (Container Runtime Interface)
Pods
Smallest deployable compute object in Kubernetes…
- …workloads run inside a pod …pods represents a set of running containers
- Pod life-cycle in multiple phases…
Pending
ready for scheduling …not started yetRunning
pod bound to a node …containers createdSucceeded
pod containers terminated in success (no restart)Failed
container terminated in failure (non-zero status)Unknown
pod state could not be obtained
- Container states inside a pod…
Waiting
…running operations to complete startupRunning
…container is executing without issuesTerminated
…container ran to completion or failed for some reason
Create and manage pods with kubectl run
5:
# Create and run a particular image in a pod...
kubeclt run #...
# ...list pods in the cluster
kubectl get pods
# …remove a pod after exit
kubectl delete pods $pod_name
Interactive
Start an interactive container…
kubectl run busybox --image=busybox --restart=Never --stdin --tty
# ...clean up
kubectl delete pods busybox
--image
…container image to use--stdin
&--tty
…or-it
for short- …allocate a terminal for each container
- …keep
stdin
open (even if empty)
--restart=Never
…pod should never be restarted
kubectl run ubuntu-bash --image=ubuntu --restart=Never -it --rm -- /bin/bash
--rm
automatically remove pod after exit--
command to execute in the container (include options & arguments)
Execute Program
Execute a program in the container…
pod_name=perl-pi
kubectl run $pod_name --image=perl --restart=OnFailure \
-- perl -Mbignum=bpi -wle 'print bpi(2000)'
# check state of a pods containers
kubectl describe pod $pod_name
# check logs
kubectl logs $pod_name
Objects
Kubernetes objects…
- …are persistent entities in the Kubernetes system
- After an object is created…
- …system will constantly work to ensure that the object exists
- …effectively tells Kubernetes the desired state
- An object includes two nested object fields:
- …object spec describes the desired state for the object
- …object status describes the actual state of the object
The spec format is described in the Kubernetes API6…
kubectl api-resources # list supported resources
kubectl explain $object # describe associated fields
kubectl explain $object --recursive # list all possible fields and subfields
kubectl explain $object.metadata # get details on fields
Address fields with JSON path identifier <type>.<fieldName>[.<fieldName>]
Imperative Commands
Imperative commands (fail if a resource exists already)
# run an instance of the nginx container by creating a deployment object
kubectl create deployment nginx --image nginx
# create the objects defined in a configuration file
kubectl create -f nginx/deployment.yaml
# update the objects defined in a configuration file
# note: dropping all changes to the object missing from the configuration file
kubectl replace -f nginx/deployment.yaml
Declarative Commands
Declarative commands …work on existing resources…
- …create, update, and delete operations are automatically detected per-object
- …retains changes, even if the changes are not in the object configuration file
# apply changes
kubectl apply -f nginx/
# see what changes are going to be made
kubectl diff -f nginx/
# use option -R for recursive directory decent
Namespaces
Mechanism for isolating groups of resources within a single cluster
- …scoping is applicable only for namespaced objects
- …divide cluster resources between multiple users (via resource quota)
- Namespaces
default
for new clusters without first creating a namespace
# list current namespaces
kubectl get namespace
# set the namespace for a current request
kubectl <...> --namespace=$name
# set namespace preference
kubectl config set-context --current --namespace=$name
# ...to unset
kubectl config set-context --current --namespace=''
Labels & Annotations
Labels are key/value pairs to specify identifying attributes of objects…
- …used to organize and to select subsets of objects
- …each key must be unique for a given object
- …common set of labels allows tools to work interoperable
- …labels without a prefix are private to users
Labels are defined in the metadata.labels
object:
apiVersion: v1
kind: Pod
metadata:
# ...
labels:
environment: prod
name: mariadb
component: database
part-of: slurm
#...
# list objects with a given label
kubectl get <...> -l 'component=database,part-of=slurm'
kubectl get <...> -l 'environment in (prod,dev)'
# list all labels of an object
kubectl get <...> -o json | jq .metadata.labels
Shared labels/annotations have a common prefix <prefix>/<name>
<prefix>
(optional) needs to be a valid DNS subdomain<name>
arbitrary property name of the label
Annotations attach arbitrary non-identifying metadata to objects
Workloads
Workload objects represents a higher abstraction level than a Pod
- Job …one-off tasks that run to completion and then stop
- CronJob …one-time Jobs on a repeating schedule
- Deployment …manage stateless application workload
- StatefulSet …persistent storage & unique network identity
- DaemonSet …local to a specific node
- …performs a role similar to a system daemon
- …facilities to enhance the container platform
Jobs
job_name=hello
cat > $job_name.yml <<EOF
apiVersion: batch/v1
kind: Job
metadata:
name: $job_name
spec:
template:
spec:
containers:
- name: hello
image: busybox
command: ["echo", "Hello, World!"]
restartPolicy: OnFailure
EOF
# create job (if not existing)
kubectl create -f $job_name.yml
# inspect job state
kubectl get jobs $job_name
kubectl describe jobs $job_name
# print the logs
kubectl logs job/$job_name
# clean up
kubectl delete job $job_name
Run the parallel job example:
job_name=sleep-parallel
cat > $job_name.yml <<EOF
apiVersion: batch/v1
kind: Job
metadata:
name: $job_name
spec:
completions: 6
parallelism: 2
template:
spec:
containers:
- name: sleep
image: busybox
command: ["sleep", "60"]
restartPolicy: Never
EOF
kubectl create -f $job_name.yml
# watch the status of pods created
kubectl get -w pods -l job-name=$job_name
# clean up
kubectl delete -f $job_name.yml
completions
number of pods to completeparallelism
number of pods to run in parallel
Cronjob
job_name=hello
cat > $job_name.yml <<EOF
apiVersion: batch/v1
kind: CronJob
metadata:
name: $job_name
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
command: ["echo", "Hello, World!"]
restartPolicy: OnFailure
EOF
# start & inspect
kubectl create -f $job_name.yml
kubectl get cronjob $job_name
# list periodically created pods
kubectl get pods | grep ^$job_name
# clean up
kubectl delete cronjob $job_name
Deployment
A deployment7 is a higher-level concept that manages ReplicaSets
- ReplicaSets manage a number of Pod replicas and their life-cycle
- It provide rollback functionality and update control
Download nginx-deployment.yaml
Kubernetes example:
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
# inspect the deployment
kubectl get deployments
# see the ReplicaSet created by the Deployment
kubectl get kubectl get replicaset
# list the pods (using a label)
kubectl get pods -l app=nginx
Rolling update incremental replacement of multiple pods
- …no downtime …network traffic load-balanced to available pods
- …facilitates CI/CD deployments …support rollback to previous version
# update pods to a new container version
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
# check the revisions of this Deployment
kubectl rollout history deployment/nginx-deployment
# undo the current rollout and rollback to the previous revision
kubectl rollout undo deployment/nginx-deployment
Scaling an application on demand…
- …increase the number of pods to a desired state
- …supports (horizontal) autoscaling depending to load
# scale a deployment
kubectl scale deployment/nginx-deployment --replicas=5
# remove a deployment
kubectl delete deployment nginx-deployment
Storage
Long-term & temporary storage for pods…
- Container storage is ephemeral (aka temporary)…
- …data created/modified during lifetime is lost
- …restart boots a container with clean state
- Volumes8 (directory accessible to the container)
- …many types of volumes …pods can use multiple types simultaneously
- …mount at the specified paths within the container
- Ephemeral volumes …have the lifetime of a pod
- Persistent volumes …exist beyond the lifetime of a pod
Example
An emptyDir
volume is created when a pod is assigned to a node…
- …deleted when the pod is removed
- …user for temporary scratch space
- …safe across container crashes
- …on storage local to the worker node
pod_name=emptydir-example
cat > $pod_name.yml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: $pod_name
spec:
volumes:
- name: opt
emptyDir: {}
containers:
- name: container-one
volumeMounts:
- name: opt
mountPath: /opt
image: alpine
command: ["/bin/sh"]
args: ["-c", "sleep 10000"]
- name: container-two
volumeMounts:
- name: opt
mountPath: /opt
image: alpine
command: ["/bin/sh"]
args: ["-c", "sleep 10000"]
EOF
Create a pod with containers sharing /opt
kubectl create -f $pod_name.yml
# write a file into the mounted volume from the first container
kubectl exec $pod_name -c container-one -- cp /etc/hostname /opt
# read the file from the second container
kubectl exec $pod_name -c container-two -- cat /opt/hostname
kubectl delete pod $pod_name
Storage Classes
Storage Classes are an abstraction layer over the underlying storage infrastructure
- Define properties/behavior of PVs, quality-of-service levels, (backup) policies
- Enable automatic provisioning of storage characteristics…
- …type of the storage (for example SSD, HDD)
- …access modes (read-only, read-write, etc.)
kubectl get sc
CSI (Container Storage Interface) volume plugins…
- …enable storage vendors to create custom storage plugins
- …uses the
csi
volume type to attach or mount the volumes
Persistent Volumes
Persistent Volumes9 (PV) are a way to abstract and represent physical or networked storage resources
Why use persistent volumes?
- Data persistence vital to stateful applications and databases
- Abstraction of the back-end storage
- …allows to manage storage resources independently
- …enables admins control utilization and optimization of storage hardware
- Access control to ensure data integrity and security
Persistent Volume Claims (PVC) request storage resources for pods
- Used to specific requirements to the storage resource
- …independent of the internals of the storage provider
- Ensures a volume ‘claim’ to be portable across numerous back-ends
- Isolates storage-related concerns from the workload
example.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-storage
spec:
capacity:
storage: 500Mi
# Indicating that this PV is intended for file-based storage
volumeMode: Filesystem
# Can be mounted as read-write by a single node at a time
accessModes:
- ReadWriteOnce
# Data is retained even if the associated PVC is deleted
# …requires to be removed manual for cleanup
persistentVolumeReclaimPolicy: Retain
# Associates to a particular StorageClass
storageClassName: local-storage
# Specify the actual location on the host machine
hostPath:
path: /srv
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: example-claim
spec:
# can be mounted as read-write by a single node at a time
accessModes:
- ReadWriteOnce
resources:
requests:
# request minimum storage capacity
storage: 200Mi
# associates with a StorageClass
storageClassName: local-storage
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
# mount volumes to the container
volumeMounts:
# which volume to mount
- name: example-nginx-storage
# where to mount the volume inside the container
mountPath: /usr/share/nginx/html
# define volumes available to the pod
volumes:
- name: example-nginx-storage
persistentVolumeClaim:
claimName: example-claim
kubectl apply -f example.yml
# check ...clean up
kubectl get -f example.yml
kubectl delete -f example.yml
Footnotes
CNCF (Cloud Native Computing Foundation)
https://landscape.cncf.io/↩︎Open Service Broker API Specification
https://www.openservicebrokerapi.org
https://github.com/openservicebrokerapi/servicebroker↩︎etcd
Documentation
https://etcd.io/docs
https://raft.github.io↩︎kubelet
, Documentation
https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/↩︎kubectl run
, Documentation
https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#run↩︎Kuberneter API Documentation
https://kubernetes.io/docs/reference/using-api
https://kubernetes.io/docs/reference/#api-reference↩︎Kubernetes Deployments https://kubernetes.io/docs/concepts/workloads/controllers/deployment↩︎
Kubernetes Volumes
https://kubernetes.io/docs/concepts/storage/volumes/↩︎Persistent Volumes, Kubernetes Documentation
https://kubernetes.io/docs/concepts/storage/persistent-volumes/↩︎