In this chapter, we will introduce you to Kubernetes. Kubernetes is a big platform and it's difficult to do justice to it in just one chapter. Luckily, we have a whole book to explore it. Don't worry if you feel a little overwhelmed. I'll mention many concepts and capabilities briefly. In later chapters, we will cover many of these in detail, as well as the connections and interactions between those Kubernetes concepts. To spice things up and get hands-on early, you will also create a local Kubernetes cluster (Minikube) on your machine. This chapter will cover the following topics:
- Kubernetes in a nutshell
- The Kubernetes architecture
- Kubernetes and microservices
- Creating a local cluster
In this chapter, you will need the following tools:
To install Docker, follow the instructions here: https://docs.docker.com/install/#supported-platforms. I will use Docker for macOS.
To install kubectl, follow the instructions here: https://kubernetes.io/docs/tasks/tools/install-kubectl/.
Kubectl is the Kubernetes CLI and we will use it extensively throughout the book.
To install Minikube, follow the instructions here: https://kubernetes.io/docs/tasks/tools/install-minikube/.
Note that you need to install a hypervisor too. For the macOS, I find VirtualBox the most reliable. You may prefer another hypervisor, such as HyperKit. There will be more detailed instructions later when you get to play with Minikube.
- The code for the chapter is available here: https://github.com/PacktPublishing/Hands-On-Microservices-with-Kubernetes/tree/master/Chapter01
- There is another Git repository for the Delinkcious sample application that we will build together: https://github.com/the-gigi/delinkcious
In this section, you'll get a sense of what Kubernetes is all about, its history, and how it became so popular.
The primary function of Kubernetes is deploying and managing a large number of container-based workloads on a fleet of machines (physical or virtual). This means that Kubernetes provides the means to deploy containers to the cluster. It makes sure to comply with various scheduling constraints and pack the containers efficiently into the cluster nodes. In addition, Kubernetes automatically watches your containers and restarts them if they fail. Kubernetes will also relocate workloads off problematic nodes to other nodes. Kubernetes is an extremely flexible platform. It relies on a provisioned infrastructure layer of compute, memory, storage, and networking, and, with these resources, it works its magic.
Kubernetes and the entire cloud-native scene is moving at breakneck speed, but let's take a moment to reflect on how we got here. It will be a very short journey because Kubernetes came out of Google in June 2014, just a few years ago. When Docker became popular, it changed how people package, distribute, and deploy software. But, it soon became apparent that Docker doesn't scale on its own for large distributed systems. A few orchestration solutions became available, such as Apache Mesos, and later, Docker's own swarm. But, they never measured up to Kubernetes. Kubernetes was conceptually based on Google's Borg system. It brought together the design and technical excellence of a decade of Google engineering, but it was a new open source project. At OSCON 2015, Kubernetes 1.0 was released and the floodgates opened. The growth of Kubernetes, its ecosystem, and the community behind it, was as impressive as its technical excellence.
Kubernetes means helmsman in Greek. You'll notice many nautical terms in the names of Kubernetes-related projects.
Kubernetes is now a household name. The DevOps world pretty much equates container orchestration with Kubernetes. All major cloud providers offer managed Kubernetes solutions. It is ubiquitous in enterprise and in startup companies. While Kubernetes is still young and innovation keeps happening, it is all happening in a very healthy way. The core is rock solid, battle tested, and used in production across lots and lots of companies. There are very big players collaborating and pushing Kubernetes forward, such as Google (obviously), Microsoft, Amazon, IBM, and VMware.
The Cloud Native Computing Foundation (CNCF) open source organization offers certification. Every 3 months, a new Kubernetes release comes out, which is the result of a collaboration between hundreds of volunteers and paid engineers. There is a large ecosystem surrounding the main project of both commercial and open source projects. You will see later how Kubernetes' flexible and extensible design encourages this ecosystem and helps in integrating Kubernetes into any cloud platform.
Kubernetes is a marvel of software engineering. The architecture and design of Kubernetes are a big part in its success. Each cluster has a control plane and data plane. The control plane consists of several components, such as an API server, a metadata store for keeping the state of a cluster, and multiple controllers that are responsible for managing the nodes in the data plane and providing access to users. The control plane in production will be distributed across multiple machines for high availability and robustness. The data plane consists of multiple nodes, or workers. The control plane will deploy and run your pods (groups of containers) on these nodes, and then watch for changes and respond.
Here is a diagram that illustrates the overall architecture:
Let's review in detail the control plane and the data plane, as well as kubectl, which is the command-line tool you use to interact with the Kubernetes cluster.
The control plane consists of several components:
- API server
- The etcd metadata store
- Controller manager
- Cloud controller manager
Let's examine the role of each component.
The kube-api-server is a massive REST server that exposes the Kubernetes API to the world. You can have multiple instances of the API server in your control plane for high-availability. The API server keeps the cluster state in etcd.
The complete cluster is stored in etcd (https://coreos.com/etcd/), a consistent and reliable, distributed key-value store. The etcd store is an open source project (developed by CoreOS, originally).
It is common to have three or five instances of etcd for redundancy. If you lose the data in your etcd store, you lose your cluster.
The kube-scheduler is responsible for scheduling pods to worker nodes. It implements a sophisticated scheduling algorithm that takes a lot of information into account, such as resource availability on each node, various constraints specified by the user, types of available nodes, resource limits and quotas, and other factors, such as affinity, anti-affinity, tolerations, and taints.
The kube-controller manager is a single process that contains multiple controllers for simplicity. These controllers watch for events and changes to the cluster and respond accordingly:
- Node controller: Responsible for noticing and responding when nodes go down.
- Replication controller: This makes sure that there is the correct number of pods for each replica set or replication controller object.
- Endpoints controller: This assigns for each service an endpoints object that lists the service's pods.
- Service account and token controllers: These initialize new namespaces with default service accounts and corresponding API access tokens.
The data plane is the collection of the nodes in the cluster that run your containerized workloads as pods. The data plane and control plane can share physical or virtual machines. This happens, of course, when you run a single node cluster, such as Minikube. But, typically, in a production-ready deployment, the data plane will have its own nodes. There are several components that Kubernetes installs on each node in order to communicate, watch, and schedule pods: kubelet, kube-proxy, and the container runtime (for example, the Docker daemon).
The kubelet is a Kubernetes agent. It's responsible for talking to the API server and for running and managing the pods on the node. Here are some of the responsibilities of the kubelet:
- Downloading pod secrets from the API server
- Mounting volumes
- Running the pod container via the Container Runtime Interface (CRI)
- Reporting the status of the node and each pod
- Probe container liveness
The kube proxy is responsible for the networking aspects of the node. It operates as a local front for services and can forward TCP and UDP packets. It discovers the IP addresses of services via DNS or environment variables.
Kubernetes eventually runs containers, even if they are organized in pods. Kubernetes supports different container runtimes. Originally, only Docker was supported. Now, Kubernetes runs containers through an interface called CRI, which is based on gRPC.
Each container runtime that implements CRI can be used on a node controlled by the kubelet, as shown in the preceding diagram.
Kubectl is a tool you should get very comfortable with. It is your command-line interface (CLI) to your Kubernetes cluster. We will use kubectl extensively throughout the book to manage and operate Kubernetes. Here is a short list of the capabilities kubectl puts literally at your fingertips:
- Cluster management
- Troubleshooting and debugging
- Resource management (Kubernetes objects)
- Configuration and metadata
Just type kubectl to get a complete list of all the commands and kubectl <command> --help for more detailed info on specific commands.
Kubernetes is a fantastic platform with amazing capabilities and a wonderful ecosystem. How does it help you with your system? As you'll see, there is a very good alignment between Kubernetes and microservices. The building blocks of Kubernetes, such as namespaces, pods, deployments, and services, map directly to important microservices concepts and an agile software development life cycle (SDLC). Let's dive in.
When you employ a microservice-based architecture, you'll have lots of microservices. Those microservices, in general, may be developed independently, and deployed independently. The packaging mechanism is simply containers. Every microservice you develop will have a Dockerfile. The resulting image represents the deployment unit for that microservice. In Kubernetes, your microservice image will run inside a pod (possibly alongside other containers). But an isolated pod, running on a node, is not very resilient. The kubelet on the node will restart the pod's container if it crashes, but if something happens to the node itself, the pod is gone. Kubernetes has abstractions and resources that build on the pod.
ReplicaSets are sets of pods with a certain number of replicas. When you create a ReplicaSet, Kubernetes will make sure that the correct number of pods you specify always run in the cluster. The deployment resource takes it a step further and provides an abstraction that exactly aligns with the way you consider and think about microservices. When you have a new version of a microservice ready, you will want to deploy it. Here is a Kubernetes deployment manifest:
- name: nginx
- containerPort: 80
This is a YAML file (https://yaml.org/) that has some fields that are common to all Kubernetes resources, and some fields that are specific to deployments. Let's break this down piece by piece. Almost everything you learn here will apply to other resources:
- The apiVersion field marks the Kubernetes resources version. A specific version of the Kubernetes API server (for example, V1.13.0) can work with different versions of different resources. Resource versions have two parts: an API group (in this case, apps) and a version number (v1). The version number may include alpha or beta designations:
- The kind field specifies what resource or API object we are dealing with. You will meet many kinds of resources in this chapter and later:
- The metadata section contains the name of the resource (nginx) and a set of labels, which are just key-value string pairs. The name is used to refer to this particular resource. The labels allow for operating on a set of resources that share the same label. Labels are very useful and flexible. In this case, there is just one label (app: nginx):
- Next, we have a spec field. This is a ReplicaSet spec. You could create a ReplicaSet directly, but it would be static. The whole purpose of deployments is to manage its set of replicas. What's in a ReplicaSet spec? Obviously, it contains the number of replicas (3). It has a selector with a set of matchLabels (also app: nginx), and it has a pod template. The ReplicaSet will manage pods that have labels that match matchLabels:
- Let's have a look at the pod template. The template has two parts: metadata and a spec. The metadata is where you specify the labels. The spec describes the containers in the pod. There may be one or more containers in a pod. In this case, there is just one container. The key field for a container is the image (often a Docker image), where you packaged your microservice. That's the code we want to run. There is also a name (nginx) and a set of ports:
- name: nginx
- containerPort: 80
There are more fields that are optional. If you want to dive in deeper, check out the API reference for the deployment resource at https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#deployment-v1-apps.
We deployed our microservice with a deployment. Now, we need to expose it, so that it can be used by other services in the cluster and possibly also make it visible outside the cluster. Kubernetes provides the Service resource for that purpose. Kubernetes services are backed up by pods, identified by labels:
- port: 80
Services discover each other inside the cluster, using DNS or environment variables. This is the default behavior. But, if you want to make a service accessible to the world, you will normally set an ingress object or a load balancer. We will explore this topic in detail later.
Kubernetes was designed for running large-scale critical systems, where security is of paramount concern. Microservices are often more challenging to secure than monolithic systems because there is so much internal communication across many boundaries. Also, microservices encourage agile development, which leads to a constantly changing system. There is no steady state you can secure once and be done with it. You must constantly adapt the security of the system to the changes. Kubernetes comes pre-packed with several concepts and mechanisms for secure development, deployment, and operation of your microservices. You still need to employ best practices, such as principle of least privilege, security in depth, and minimizing blast radius. Here are some of the security features of Kubernetes.
Namespaces let you isolate different parts of your cluster from each other. You can create as many namespaces as you want and scope many resources and operations to their namespace, including limits, and quotas. Pods running in a namespace can only access directly their own namespace. To access other namespaces, they must go through public APIs.
Service accounts provide identity to your microservices. Each service account will have certain privileges and access rights associated with its account. Service accounts are pretty simple:
You can associate service accounts with a pod (for example, in the pod spec of a deployment) and the microservices that run inside the pod will have that identity and all the privileges and restrictions associated with that account. If you don't assign a service account, then the pod will get the default service account of its namespace. Each service account is associated with a secret used to authenticate it.
Kubernetes provides secret management capabilities to all microservices. The secrets can be encrypted at rest on etcd (since Kubernetes 1.7), and are always encrypted on the wire (over HTTPS). Secrets are managed per namespace. Secrets are mounted in pods as either files (secret volumes) or environment variables. There are multiple ways to create secrets. Secrets can contain two maps: data and stringData. The type of values in the data map can be arbitrary, but must be base64-encoded. Refer to the following, for example:
Here is how a pod can load secrets as a volume:
- name: mypod
- name: db_creds
- name: foo
The end result is that the DB credentials secrets that are managed outside the pod by Kubernetes show up as a regular file inside the pod accessible through the path /etc/db_creds.
Kubernetes utilizes client-side certificates to fully authenticate both sides of any external communication (for example, kubectl). All communication to the Kubernetes API from outside should be over HTTP. Internal cluster communication between the API server and the kubelet on the node is over HTTPS too (the kubelet endpoint). But, it doesn't use a client certificate by default (you can enable it).
Communication between the API server and nodes, pods, and services is, by default, over HTTP and is not authenticated. You can upgrade them to HTTPS, but note that the client certificate is checked, so don't run your worker nodes on public networks.
In a distributed system, beyond securing each container, pod, and node, it is critical to also control communication over the network. Kubernetes supports network policies, which give you full flexibility to define and shape the traffic and access across the cluster.
Authentication and authorization are also related to security, by limiting access to trusted users and to limited aspects of Kubernetes. Organizations have a variety of ways to authenticate their users. Kubernetes supports many of the common authentication schemes, such as X.509 certificates, and HTTP basic authentication (not very secure), as well as an external authentication server via webhook that gives you ultimate control over the authentication process. The authentication process just matches the credentials of a request with an identity (either the original or an impersonated user). What that user is allowed to do is controlled by the authorization process. Enter RBAC.
Deploying and securing microservices is just the beginning. As you develop and evolve your system, you'll need to upgrade your microservices. There are many important considerations regarding how to go about it that we will discuss later (versioning, rolling updates, blue-green, and canary). Kubernetes provides direct support for many of these concepts out of the box and the ecosystem built on top of it to provide many flavors and opinionated solutions.
The goal is often zero downtime and safe rollback if a problem occurs. Kubernetes deployments provide the primitives, such as updating a deployment, pausing a roll-out, and rolling back a deployment. Specific workflows are built on these solid foundations.
The mechanics of upgrading a service typically involve upgrading its image to a new version and sometimes changes to its support resources and access: volumes, roles, quotas, limits, and so on.
There are two aspects to scaling a microservice with Kubernetes. The first aspect is scaling the number of pods backing up a particular microservice. The second aspect is the total capacity of the cluster. You can easily scale a microservice explicitly by updating the number of replicas of a deployment, but that requires constant vigilance on your part. For services that have large variations in the volume of requests they handle over long periods (for example, business hours versus off hours or week days versus weekends), it might take a lot of effort. Kubernetes provides horizontal pod autoscaling, which is based on CPU, memory, or custom metrics, and can scale your service up and down automatically.
Here is how to scale our nginx deployment that is currently fixed at three replicas to go between 2 and 5, depending on the average CPU usage across all instances:
The outcome is that Kubernetes will watch CPU utilization of the pods that belong to the nginx deployment. When the average CPU over a certain period of time (5 minutes, by default) exceeds 90%, it will add more replicas until the maximum of 5, or until utilization drops below 90%. The HPA can scale down too, but will always maintain a minimum of two replicas, even if the CPU utilization is zero.
Your microservices are deployed and running on Kubernetes. You can update the version of your microservices whenever it is needed. Kubernetes takes care of healing and scaling automatically. However, you still need to monitor your system and keep track of errors and performance. This is important for addressing problems, but also for informing you on potential improvements, optimizations, and cost cutting.
There are several categories of information that are relevant and that you should monitor:
- Third-party logs
- Application logs
- Application errors
- Kubernetes events
When considering a system composed of multiple microservices and multiple supporting components, the number of logs will be substantial. The solution is central logging, where all the logs go to a single place where you can slice and dice at your will. Errors can be logged, of course, but often it is useful to report errors with additional metadata, such as stack trace, and review them in their own dedicated environment (for example, sentry or rollbar). Metrics are useful for detecting performance and system health problems or trends over time.
Kubernetes provides several mechanisms and abstractions for monitoring your microservices. The ecosystem provides a number of useful projects too.
There are several ways to implement central logging with Kubernetes:
- Have a logging agent that runs on every node
- Inject a logging sidecar container to every application pod
- Have your application send its logs directly to a central logging service
There are pros and cons to each approach. But, the main thing is that Kubernetes supports all approaches and makes container and pod logs available for consumption.
Kubernetes comes with cAdvisor (https://github.com/google/cadvisor), which is a tool for collecting container metrics integrated into the kubelet binary. Kubernetes used to provide a metrics server called heapster that required additional backends and a UI. But, these days, the best in class metrics server is the open source Prometheus project. If you run Kubernetes on Google's GKE, then Google Cloud Monitoring is a great option that doesn't require additional components to be installed in your cluster. Other cloud providers also have integration with their monitoring solutions (for example, CloudWatch on EKS).
One of the strengths of Kubernetes as a deployment platform is that you can create a local cluster and, with relatively little effort, have a realistic environment that is very close to your production environment. The main benefit is that developers can test their microservices locally and collaborate with the rest of the services in the cluster. When your system is comprised of many microservices, the more significant tests are often integration tests and even configuration and infrastructure tests, as opposed to unit tests. Kubernetes makes that kind of testing much easier and requires much less brittle mocking.
In this section, you will install a local Kubernetes cluster and some additional projects, and then have some fun exploring it using the invaluable kubectl command-line tool.
Minikube is a single node Kubernetes cluster that you can install anywhere. I used macOS here, but, in the past, I used it successfully on Windows too. Before installing Minikube itself, you must install a hypervisor. I prefer HyperKit:
$ curl -LO https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-hyperkit \
&& chmod +x docker-machine-driver-hyperkit \
&& sudo mv docker-machine-driver-hyperkit /usr/local/bin/ \
&& sudo chown root:wheel /usr/local/bin/docker-machine-driver-hyperkit \
&& sudo chmod u+s /usr/local/bin/docker-machine-driver-hyperkit
But, I've run into trouble with HyperKit from time to time. If you can't overcome the issues, I suggest using VirtualBox as the hypervisor instead. Run the following command to install VirtualBox via Homebrew:
$ brew cask install virtualbox
Now, you can install Minikube itself. Homebrew is the best way to go again:
brew cask install minikube
If you're not on macOS, follow the official instructions here: https://kubernetes.io/docs/tasks/tools/install-minikube/.
Minikube supports multiple versions of Kubernetes. At the moment, the default version is 1.10.0, but 1.13.0 is already out and supported, so let's use that version:
$ minikube start --vm-driver=hyperkit --kubernetes-version=v1.13.0
If you're using VirtualBox as your hypervisor, you don't need to specify --vm-driver:
$ minikube start --kubernetes-version=v1.13.0
You should see the following:
$ minikube start --kubernetes-version=v1.13.0
Starting local Kubernetes v1.13.0 cluster...
Downloading Minikube ISO
178.88 MB / 178.88 MB [============================================] 100.00% 0s
Getting VM IP address...
E0111 07:47:46.013804 18969 start.go:211] Error parsing version semver: Version string empty
Moving files into cluster...
Downloading kubeadm v1.13.0
Downloading kubelet v1.13.0
Finished Downloading kubeadm v1.13.0
Finished Downloading kubelet v1.13.0
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Stopping extra container runtimes...
Starting cluster components...
Verifying kubelet health ...
Verifying apiserver health ...Kubectl is now configured to use the cluster.
Loading cached images from config file.
Everything looks great. Please enjoy minikube!
At this point, your Minikube cluster is ready to go.
If you run into some trouble (for example, if you forgot to turn off your VPN), try to delete your Minikube installation and restart it with verbose logging:
$ minikube delete
$ rm -rf ~/.minikube
$ minikube start --vm-driver=hyperkit --kubernetes-version=v1.13.0 --logtostderr --v=3
If your Minikube installation just hangs (maybe waiting for SSH), you might have to reboot to unstick it. If that doesn't help, try the following:
sudo mv /var/db/dhcpd_leases /var/db/dhcpd_leases.old
sudo touch /var/db/dhcpd_leases
Then, reboot again.
If everything is OK, you can check your Minikube version:
$ minikube version
minikube version: v0.31.0
Minikube has many other useful commands. Just type minikube to see the list of commands and flags.
Minikube is running, so let's have some fun. Your kubectl is going to serve you well in this section. Let's start by examining our node:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready master 4m v1.13.0
Your cluster already has some pods and services running. It turns out that Kubernetes is dogfooding and many of its own services are plain services and pods. But, those pods and services run in namespaces. Here are all the namespaces:
$ kubectl get ns
NAME STATUS AGE
default Active 18m
kube-public Active 18m
kube-system Active 18m
To see all the services in all the namespaces, you can use the --all-namespaces flag:
$ kubectl get svc --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 19m
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 19m
kube-system kubernetes-dashboard ClusterIP 10.111.39.46 <none> 80/TCP 18m
The Kubernetes API server, itself, is running as a service in the default namespace and then we have kube-dns and the kubernetes-dashboard running in the kube-system namespace.
To explore the dashboard, you can run the dedicated Minikube command, minikube dashboard. You can also use kubectl, which is more universal and will work on any Kubernetes cluster:
$ kubectl port-forward deployment/kubernetes-dashboard 9090
Then, browse to http://localhost:9090 and you will see the following dashboard:
Helm is the Kubernetes package manager. It doesn't come with Kubernetes, so you have to install it. Helm has two components: a server-side component called tiller, and a CLI called helm.
Let's install helm locally first, using Homebrew:
$ brew install kubernetes-helm
Then, properly initialize both the server and client type:
$ helm init
$HELM_HOME has been configured at /Users/gigi.sayfan/.helm.
Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
With Helm in place, you can easily install all kinds of goodies in your Kubernetes cluster. There are currently 275 chars (the Helm term for a package) in the stable chart repository:
$ helm search | wc -l
For example, check out all the releases tagged with the db type:
$ helm search db
NAME CHART VERSION APP VERSION DESCRIPTION
stable/cockroachdb 2.0.6 2.1.1 CockroachDB is a scalable, survivable, strongly-consisten...
stable/hlf-couchdb 1.0.5 0.4.9 CouchDB instance for Hyperledger Fabric (these charts are...
stable/influxdb 1.0.0 1.7 Scalable datastore for metrics, events, and real-time ana...
stable/kubedb 0.1.3 0.8.0-beta.2 DEPRECATED KubeDB by AppsCode - Making running production...
stable/mariadb 5.2.3 10.1.37 Fast, reliable, scalable, and easy to use open-source rel...
stable/mongodb 4.9.1 4.0.3 NoSQL document-oriented database that stores JSON-like do...
stable/mongodb-replicaset 3.8.0 3.6 NoSQL document-oriented database that stores JSON-like do...
stable/percona-xtradb-cluster 0.6.0 5.7.19 free, fully compatible, enhanced, open source drop-in rep...
stable/prometheus-couchdb-exporter 0.1.0 1.0 A Helm chart to export the metrics from couchdb in Promet...
stable/rethinkdb 0.2.0 0.1.0 The open-source database for the realtime web
jenkins-x/cb-app-slack 0.0.1 A Slack App for CloudBees Core
stable/kapacitor 1.1.0 1.5.1 InfluxDB's native data processing engine. It can process ...
stable/lamp 0.1.5 5.7 Modular and transparent LAMP stack chart supporting PHP-F...
stable/postgresql 2.7.6 10.6.0 Chart for PostgreSQL, an object-relational database manag...
stable/phpmyadmin 2.0.0 4.8.3 phpMyAdmin is an mysql administration frontend
stable/unifi 0.2.1 5.9.29 Ubiquiti Network's Unifi Controller
We will use Helm a lot throughout the book.
In this chapter, you received a whirlwind tour of Kubernetes and got an idea of how well it aligns with microservices. The extensible architecture of Kubernetes empowers a large community of enterprise organizations, startup companies, and open source organizations to collaborate and create an ecosystem around Kubernetes that multiplies its benefits and ensures its staying power. The concepts and abstractions built into Kubernetes are very well suited for microservice-based systems. They support every phase of the SDLC, from development, through testing, and deployments, and all the way to monitoring and troubleshooting. The Minikube project lets every developer run a local Kubernetes cluster, which is great for experimenting with Kubernetes itself, as well as testing locally in an environment that is very similar to the production environment. The Helm project is a fantastic addition to Kubernetes and provides great value as the de facto package management solution. In the next chapter, we will dive into the world of microservices and learn why they are the best approach for developing complex and fast-moving distributed systems that run in the cloud.
- If you want to learn more about Kubernetes, I recommend my book, Mastering Kubernetes – Second Edition, published by Packt: https://www.packtpub.com/application-development/mastering-kubernetes-second-edition