January 2018
Image from: https://docs.docker.com/engine/docker-overview
Image from: https://docs.docker.com/engine/docker-overview
.. and all of this at scale.
A simple way of describing a set of containers to run.
Example:
version: '3'
services:
web:
build: . (in this case no image req'd)
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: "redis:alpine"
..then code can refer to container by name, eg: cache = redis.Redis(host='redis', port=6379)
Docker centric container orchestration. A swarm is a cluster of docker engine 'nodes' running in swarm mode.
Docker have recently added initial Kubernetes support to service deployment apis, which indicates the broad industry support k8s has gained.
How does k8s deal with containers at scale?
K8s provides the following features out of the box in a cloud agnostic/extensible manner.
Some of these can be swapped out with other products if desired, eg. Consul for discovery and config mgmt.
The k8s control plane consists of a 'Master' node, and services used to orchestrate the cluster.
A manual install of k8s requires that you take responsibility for these more complex aspects.
Managed k8s such as Google Kubernetes Engine (GKE), or EKS look after this for you, including node upgrades.
ConfigMaps can be used to inject environment variables that can be referenced within containers.
note: a similar construct "secret" is used for sensitive values
Pods are the smallest deployable workload, and are the mechanism of container abstraction.
They generally contain a single container, with perhaps a 'sidecar' container for platform ops.
Labels are name/value pairs assigned to pods, and can be targetted by services, and other actions. eg. release: stable, environment: dev1.
Containers in a pod instance are always on the same node. And the system is monitored continually to ensure the correct scale, and that pods are scheduled efficiently to nodes.
The following properties affect which node a pod is scheduled to:
spec.containers[].resources.limits.cpu
spec.containers[].resources.limits.memory
spec.containers[].resources.requests.cpu
spec.containers[].resources.requests.memory
The k8s "Deployment" schema defines a replica set template to be used to scale pods.
This means that we scale out using kubectl on a passed in "deployment" eg.
kubectl scale --replicas=2 deployment/jenkins-jenkins
Note that the node autoscaling approach below this is provider specific. If the cluster has capacity in existing nodes, no new nodes are created - and if the autoscaling group is at capacity, the scale event will fail.
Managed k8s ingress can be mapped to an instance of the ELB/ALB of the given service.
Alternatively, an nginx ingress controller among others is available, supporting name and path based virtual hosting, with support for LetsEncrypt cert mgmt via KubeLego
Defines a pod that must run on all nodes. Pods specified in this way will be automatically provisioned and garbage collected accordingly.
DaemonSets are typically used for purposes such as logging and monitoring.
The kube-dns add-on causes each created 'Service' to have a unique private DNS name auto allocated. ie.
my-svc.my-namespace.svc.cluster.local
Each service has a dedicated private cluster ip assigned, which does not change as pods come and go. The namespace domain is added as a search domain to each node via etcd, so reference to 'my-svc' works.
For details:
https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/
Follow Pod container logs
kubectl logs -f <pod> --container=<container>
Container logs by label
kubectl logs --label env=dev1 --container=<container>
Centralized logging is implementation specific. In GKE it is StackDriver. Kubernetes uses Fluentd log collector, so this can be plugged into other systems such as Splunk.
Centralized tracing can be acheived by instrumenting the OpenTracing APIs in deployed apps, and deploying CNCF Jaeger to Kubernetes. Jaeger is backwards compatible with Zipkin.
Jaeger was contributed to the CNCF by Uber, and is easily deployable to a k8s cluster, including a modern web ui.
Monitoring and alerting for k8s clusters can be achieved by deploying a monitoring DaemonSet leveraging tools such as CNCF Prometheus.
Depending on cloud provider this area may be provided via managed service tools such as Stackdriver/CloudWatch.
Helm is the k8s package manager. It's intent is to simplify the distribution and control of deployments, via a construct called a 'Chart'.
https://helm.sh/
Charts for many popular services are available directly from the K8s github org.
https://github.com/kubernetes/charts/tree/master/stable
or via a web app store:
https://kubeapps.com/
One key advantage of using Helm, is versioning and simplified rollback of deployments
Linkerd supported by CNCF can easily be deployed as a DaemonSet to k8s nodes. Istio sidecar containers are also supported.
ServiceMesh is a separate topic, but briefly this brings: