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

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

External Service Access

LoadBalancers provide external access for a single service

External Routing

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

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

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:s3cr3t@postgres: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>

Last updated