There are a fair few abstractions in Kubernetes and today, we’ll run through an overview of three flavors of compute resources available in Kubernetes – Pods, ReplicaSets, and Deployments. We’ll break them out in terms of relative complexity and why you might choose one over the others for a given use case.
Pods
Pods are the most fundamental compute resource that you can stand up in Kubernetes. Put simply, if you use Kubernetes, you will be using pods. Contrary to popular belief among those just starting out with Kubernetes, pods are not the Kubernetes equivalent to Docker containers. Instead, pods are responsible for running a container engine that can then, in turn, run one or more containers inside of the pod. It is worth noting that Docker isn’t the only compatible container engine, but it is by far the most popular choice.
Pods are defined in YAML files, which are called from the command line with the kubectl CLI, like so:
kubectl apply -f pod_example.yml
A sample pod definition would look something like this:
apiVersion: v1
kind: Pod
metadata:
name: chef-server
spec:
containers:
- name: chef-server
image: chef/chefdk
command: ["/bin/sh"]
args: ["-c", "echo Hello from the Ubuntu container; sleep 1000"]
Key pieces in the above YAML file include the name of our container and the Docker hub image that we want Kubernetes to pull when the pod starts up.
When to use pods
Using standalone pods is generally frowned upon except for quick testing, as there is nothing in place to monitor the health of the pod. This means that if a pod (or its host node) should fail for some reason, there won’t be any mechanism in place to stand it back up, which is really where the power of Kubernetes lies.
ReplicaSets
ReplicaSets are higher-level abstractions that are responsible for ensuring that a specified number of exact copies of a given pod are running. This system of parallelization is the foundation of Kubernetes' power. If for some reason, one or more copies of chef-server that we mentioned above should fail, our server will still be available for two reasons: (1) there are multiple, identical pods running, and (2) the ReplicaSet will create a new pod in place of the one that failed. Moreover, we can be guaranteed that we will end up with the exact number of pods we’ve requested, as any extras will be torn down.
Like pods, ReplicaSets are defined in a YAML file that can be executed from the command line, like so:
kubectl apply -f replica_set_example.yml
And, an example of that YAML file might look like the following:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: chef-server
labels:
app: chef-server
tier: chef-server
spec:
replicas: 3 # We'll get three identical pods
selector:
matchLabels:
tier: chef-server
template:
metadata:
labels:
tier: chef-server
spec:
containers:
- name: chef-server
image: chef/chefdk
command: ["/bin/sh"]
args: ["-c", "echo Hello from the Ubuntu container; sleep 1000"]
A couple of critical points in the above YAML file include our replicas count – i.e., the number of copies of this pod that we want it to maintain, as well as the alignment of our labels, which will allow the Kubernetes controller to keep track of the pods in the ReplicaSet.
When to use ReplicaSets
Interestingly, ReplicaSets are considered more of a building block in Kubernetes than an end unto themselves. The Kubernetes docs are pretty explicit about this, “...you may never need to manipulate ReplicaSet objects: use a Deployment instead, and define your application in the spec section.”
Deployments
One step higher in the abstraction hierarchy, deployments control both ReplicaSets and pods in a declarative manner. This means that you define what you want your collection of pods to be, and the deployment makes use of several other Kubernetes objects to ensure that things are as you’ve declared in your YAML file.
This is different than a ReplicaSet in that you can roll out changes to the desired state of the system by changing the pod template in your deployment YAML, and the deployment will take care of the rest. You can also revert to a previous state if things go awry. This contrasts with a ReplicaSet in that if you were to change the ReplicaSet’s YAML and then run <kubectl apply -f <replicaset.yml> your original ReplicaSet will persist. And with that, you’ll be creating a second ReplicaSet. </replicaset.yml>
In the sample file below, you’ll see that we’ve essentially “layered in” pods and a ReplicaSet, as deployments are working with these objects, so you don’t have to.
kubectl apply -f deployment_example.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: chef-server
spec:
replicas: 3
selector:
matchLabels:
app: chef-server
template:
metadata:
labels:
app: chef-server
spec:
containers:
- name: chef-server
image: chef/chefdk
ports:
- containerPort: 8080
command: ["/bin/sh"]
args: ["-c", "echo Hello from the Chef container; sleep 1000"]
- name: ubuntu
image: ubuntu:18.04
ports:
- containerPort: 8080
command: ["/bin/sh"]
args: ["-c", "echo Hello from the Ubuntu container; sleep 1000"]
securityContext:
runAsUser: 1
When to use Deployments
The Kubernetes docs explicitly suggest using a deployment rather than a ReplicaSet directly. As such, a deployment is generally the best option for any service that needs to maintain high availability, as it intelligently tears down services in the event of a change to the desired state of the system so that it doesn’t interrupt any service running therein.
TL;DR
We’ve discussed three “tiers” of complexity above – namely Pods, ReplicaSets, and Deployments. The first building block is a pod, which is, in turn, used in ReplicaSets. Further, both pods and ReplicaSets are used by deployments. Pods are best used for testing only. ReplicaSets are generally considered a “bridge” to deployments – the use of which is generally considered a best practice when using Kubernetes.
Share this article
Orka, Orka Workspace and Orka Pulse are trademarks of MacStadium, Inc. Apple, Mac, Mac mini, Mac Pro, Mac Studio, and macOS are trademarks of Apple Inc. The names and logos of third-party products and companies shown on the website are the property of their respective owners and may also be trademarked.
©2024 MacStadium, Inc. is a U.S. corporation headquartered at 3340 Peachtree Rd NE, Suite 2330, Atlanta, GA 30326. MacStadium, Ltd. is registered in Ireland, company no. 562354.