Kubernetes Orchestration Primer
Kubernetes, or K8s, is a robust, opensource platform for the orchestration of containers at scale. The word itself stems from Ancient Greek, and it means helmsman or pilot. It was released by Google in 2014 and quickly became an industry standard. A container image, loosely considered a lightweight virtual machine, is an efficient way to package and run an app across various platforms. Kubernetes will wrap containers in pods and provide features such as service discovery, fail-over, load balancing, monitoring, DNS, secrets management, autoscaling, self-healing, automation, and batch processing, among others.
Many cloud providers have their own, proprietary container orchestration systems; if you choose to leverage one however, remember you’re tying yourself to that vendor in more ways than one. As with any relationship, it comes with risk and costs. The vendor will dictate the management, features, and timelines of the platform and its technologies, and it may not be easy to detach from that if you decide to change course at some point. Alternatively, many cloud providers offer hosted Kubernetes solutions, so one could manage the infrastructure while you retain the flexibility to move to another vendor, or your own infrastructure at a later time, without implementing an entirely new platform, working to integrate it with related systems, and training staff accordingly.
KUBERNETES ARCHITECTURE
The control plane includes the following components:
·??????? API server – supports API calls as well as the kubectl CLI
·??????? An etcd database – a reliable key / value store housing cluster data
·??????? Scheduler – assigns pods to nodes based on policies and resources
·??????? Controller – runs processes for nodes, jobs, service accounts, etc.
·??????? Cloud Controller – integrates the cluster and cloud, if applicable
The worker nodes are physical or virtual machines that host containers, and each has a container runtime, a kubelet agent that manages the Kubernetes pods, and a proxy for networking.
Various addons are often implemented as well including cluster DNS, the Web UI Dashboard, container resource monitoring, cluster-level logging, and network plug-ins for example.
Users typically access an application hosted on Kubernetes via a load balancer that fronts worker nodes running an ingress controller, and requests are mapped to containers based on the URL. By default, Kubernetes is a closed, secure system, so you need to expose a node port for external access to a deployment, or better yet configure load balancing through an ingress controller to allow more flexible ingress with high availability.
OBJECTS AND DEPLOYMENTS
An object is a persistent entity in Kubernetes, and it’s defined by fields in its manifest file, which is in yaml or json format. Required fields include:
·??????? apiVersion?- version of the Kubernetes API used to create this object
·??????? kind?- the type of object you want Kubernetes to create
·??????? metadata?– identity date such as name,?UID, and optional?namespace
·??????? spec?– the state that you want for the object
Examples of objects include a deployment, daemonSet, service account, secret, job or cronjob, autoscaler, and pod disruption budget, among others. You create, modify, and delete objects through direct API calls, the kubectl CLI, or the dashboard. Objects can be managed imperatively or declaratively, but it’s best to stick with one approach to avoid problems. Here’s a sample manifest you could declaratively deploy via ‘kubectl apply -f deployment.yaml’
KUBECTL CLI FOR KUBERNETES MANAGEMENT
The CLI, named kubectl, can be run on a client machine to remotely connect to the API server via a kubeconfig file obtained from Kubernetes, which contains an access token and endpoint. You can leverage subcommands to manage the cluster and deployments. Alternatively, you can use the Kubernetes Dashboard to manage orchestration via its web application.
* Obtain kubectl from https://kubernetes.io/docs/tasks/tools/install-kubectl/
* A kubeconfig file is typically created when defining a cluster or adding users
* Set a KUBECONFIG environment variable that references one or more kubeconfig files, or simply pass that file as a kubectl parameter, for example: kubectl --kubeconfig [kubeconfig-file] get pods -n [namespace]
* Use kubectl imperatively, with or without configuration files to create and manage live objects, or use it declaratively via the apply command and an associated yaml file for example. With the declarative approach, the system keeps track of changes, which avoids conflicts with multiple writers.
KUBECTL COMMON SUBCOMMANDS
kubectl ?(Enter kubectl alone to see a list of commands available)
kubectl [command] --help ?(See details about a particular subcommand)
kubectl version ?(Show client and server versions for the current context)
kubectl config current-context ?(List the current context defined)
kubectl get nodes ?(Retrieve a list of all nodes in the Kubernetes cluster)
kubectl apply -f [yaml_file] ?(Declaratively update an object in the yaml file)
领英推荐
kubectl create -f [yaml_file] -n [namespace] ?(Imperatively create an object)
kubectl delete deployment [workload] -n [namespace] ?(Remove deployment)
kubectl rolling-update NAME --image=IMAGE:TAG ?(Do an image rolling update)
kubectl get pods --all-namespaces ?(Display pods in all cluster namespaces)
kubectl logs [pod_name] -n [namespace] ?(Show logs from a pod in a ns)
kubectl describe pod [pod_name] -n [namespace] ?(Show pod info and status)
kubectl get deployment -n [namespace] ??(Get a list of objects, e.g. deployments)
kubectl describe deployment [deployment] -n [namespace] ?(Get in-depth detail)
kubectl edit deployment/[deployment] -n [namespace] ?(Edit the object yaml)
kubectl cp [namespace]/[pod]:/pathtofile /localpath (Copy from pod to local)
·??????? Copy works the other direction as well assuming you have access
kubectl --kubeconfig [kubeconfig-file] -n [namespace] exec -t -i [pod] -- sh
·??????? If you have access, execute a shell in a pod running in a remote cluster
kubectl --kubeconfig [kubeconfig-file] top pods --namespace [namespace]
·??????? Obtain a snapshot of cpu and memory utilization for pods in a namespace
kubectl --kubeconfig [kubeconfig-file] top nodes ?(See node cpu and memory)
?
MANAUL OR AUTO SCALING OPTIONS
Scaling can be done manually or automatically based on metrics such as memory and cpu, schedules, or events. A range of adapters also exist for the latter (e.g. AWS CloudWatch metrics). Types of scaling include:
1.??????? Horizontal Pod Autoscaling (HPA) where pods are added or removed
2.??????? Vertical Pod Autoscaling (VPA) where memory and CPU are adjusted
3.??????? Cluster Infrastructure scaling to add and remove worker nodes
Use of the HPA is most common, and settings are typically defined through yaml in the HPA manifest file. It can be used with workloads such as deployments and statefulSets, but not deamonSets, which typically run a pod(s) on each node.
SUGGESTED BEST PRACTICES
? Favor microservices over large monoliths when possible; ideally microservices should be stateless and data stored in databases, but persistent volumes can be created if warranted. Large monoliths with excessive memory requirements may be better suited for virtual machines.
? Avoid creating a cluster for each application unless truly warranted. That's a costly, intricate approach and it undermines the primary purpose of Kubernetes. If you must go that route, consider removing Kubernetes.
? Deploy at least 2 replicas of any given container image for High Availability purposes; if that's not feasible then it might be worth reviewing the application's design and architecture.
? Deploy replicas to different nodes based on hostname and / zone parameters if applicable, and use a pod disruption budget to ensure at least one replica remains up during node maintenance.
? Set memory and cpu limits accordingly via the deployment yaml. With Java for example, the memory limit should generally be 50% higher than the JVM's max heap to account for various overhead.
? YAML is a sensitive syntax, so use an editor that supports such formatting to avoid trouble, such as Atom, VS Code, or Notepad++ for example
? Consider leveraging YAML rather than JSON; though these formats can be used interchangeably in most scenarios, YAML is simply more user-friendly.
? If an app doesn't gracefully shutdown after receiving the SIGTERM signal, even with a sufficient grace period defined, then consider developing a preStop hook.
? Don’t specify default values unnecessarily; use simple, minimal configuration.
? Consider grouping related objects into a single file when it might make sense.
? kubectl subcommands can apply to a directory’s files, such as kubectl create.