What is Kubernetes Deployment YAML?
YAML (which stands for YAML Ain’t Markup Language) is a language used to provide configuration for software, and is the main type of input for Kubernetes configurations. It is human-readable and can be authored in any text editor.
A Kubernetes user or administrator specifies data in a YAML file, typically to define a Kubernetes object. The YAML configuration is called a “manifest”, and when it is “applied” to a Kubernetes cluster, Kubernetes creates an object based on the configuration.
A Kubernetes Deployment YAML specifies the configuration for a Deployment object—this is a Kubernetes object that can create and update a set of identical pods. Each pod runs specific containers, which are defined in the spec.template field of the YAML configuration.
The Deployment object not only creates the pods but also ensures the correct number of pods is always running in the cluster, handles scalability, and takes care of updates to the pods on an ongoing basis. All these activities can be configured through fields in the Deployment YAML.
Below we’ll show several examples that will walk you through the most common options in a Kubernetes Deployment YAML manifest.
Related content: Read our guide to Kubernetes deployment strategies
Kubernetes Deployment YAML Examples
Example 1 – With Multiple Replicas
The following YAML configuration creates a Deployment object that runs 5 replicas of an NGINX container.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: web
spec:
selector:
matchLabels:
app: web
replicas: 5
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: web
spec:
containers:
—name: nginx
image: nginx
ports:
—containerPort: 80
Important points in this configuration:
spec.replicas—specifies how many pods to runstrategy.type—specifies which deployment strategy should be used. In this case and in the following examples we select RollingUpdate, which means new versions are rolled out gradually to pods to avoid downtime.spec.template.spec.containers—specifies which container image to run in each of the pods and ports to expose.
Example 2 – With Resource Limits
The following YAML configuration creates a Deployment object similar to the above, but with resource limits.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: web
spec:
selector:
matchLabels:
app: web
replicas: 5
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: web
spec:
containers:
—name: nginx
image: nginx
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
ports:
—containerPort: 80
The spec.containers.resources field specifies:
limits—each container should not be allowed to consume more than 200Mi of memory.requests—each container requires 100m of CPU resources and 200Mi of memory on the node
Example 3 – With Health Checks
The following YAML configuration creates a Deployment object that performs a health check on containers by checking for an HTTP response on the root directory.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: web
spec:
selector:
matchLabels:
app: web
replicas: 5
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: web
spec:
containers:
—name: nginx
image: nginx
ports:
—containerPort: 80
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
The template.spec.containers.livenessProbe field defines what the kubelet should check to ensure that the pod is alive:
httpGetspecifies that the kubelet should try a HTTP request on the root of the web server on port 80.periodSecondsspecifies how often the kubelet should perform a liveness probe.initialDelaySecondsspecifies how long the kubelet should wait after the pod starts, before performing the first probe.
You can also define readiness probes and startup probes—learn more in the Kubernetes documentation.
Example 4 – With Persistent Volumes
The following YAML configuration creates a Deployment object that creates containers that request a PersistentVolume (PV) using a PersistentVolumeClaim (PVC), and mount it on a path within the container.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: web
spec:
selector:
matchLabels:
app: web
replicas: 5
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: web
spec:
volumes:
—name: my-pv-storage
persistentVolumeClaim:
claimName: my-pv-claim
containers:
—name: nginx
image: nginx
ports:
—containerPort: 80
volumeMounts:
—mountPath: "/usr/share/nginx/html"
name: my-pv-storage
Important points in this configuration:
template.spec.volumes—defines a name for the volume, which is referenced below in containers.volumeMountstemplate.spec.volumes.persistVolumeClaim—references a PVC. For this to work, you must have some PVs in your cluster and create a PVC object that matches those PVs. You can then reference the existing PVC object here and the pod will attempt to bind to a matching PV.
Learn more about PVs and PVCs in the documentation.
Example 5 – With Affinity Settings
The following YAML configuration creates a Deployment object with affinity criteria that can encourage a pod to schedule on certain types of nodes.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: web
spec:
selector:
matchLabels:
app: web
replicas: 5
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: web
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
—matchExpressions:
—key: disktype
operator: In
values:
—ssd
containers:
—name: nginx
image: nginx
ports:
—containerPort: 80
The spec.affinityfield defines criteria that can affect whether the pod schedules on a certain node or not:
spec.affinity.nodeAffinity—specifies desired criteria of a node which will cause the pod to be scheduled on itspec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution—specifies that affinity is relevant when scheduling a new pod, but is ignored when the pod is already running.nodeSelectorTerms—specifies, in this case, that the node needs to have a disk of type SSD for the pod to be scheduled.
There are many other options, including preferred node affinity, and pod affinity, which means the pod is scheduled based on the criteria of other pods running on the same node. Learn more in the documentation.
Alternatives to the Deployment Object
Two common alternatives to the Kubernetes Deployment object are:
- DaemonSet—deploys a pod on all cluster nodes or a certain subset of nodes
- StatefulSet—used for stateful applications. Similar to a Deployment, but each pod is unique and has a persistent identifier.
Let’s see examples of YAML configurations for these two objects. The code is taken from the Kubernetes documentation.
Example 1 – Kubernetes DaemonSet Example YAML
A DaemonSet runs copies of a pod on all cluster nodes, or a selection of nodes within a cluster. Whenever a node is added to the cluster, the DaemonSet controller checks if it is eligible, and if so, runs the pod on it. When a node is removed from the cluster, the pods are moved to garbage collection. Deleting a DaemonSet also results in removal of the pods it created.
The following YAML file shows how to run a DaemonSet that runs fluentd-elasticsearch for logging purposes.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
# this toleration is to have the daemonset runnable on
# master nodes
—key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
—name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
—name: varlog
mountPath: /var/log
—name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
—name: varlog
hostPath:
path: /var/log
—name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
The important fields of this configuration are:
selector—specifies which nodes the pod should run on. In this case we assume that all pods that need the logging component will have the labelfluentd-elasticsearchspec.tolerations—tolerations are applied to pods, and allow the pods to schedule on nodes with matching characteristics. In this case we allow the pod to run on a node even if it is a master node.containers, volumes—specifies what pod and storage volumes the DaemonSet should run on each node.
Example 2 – Kubernetes Statefulset Example YAML
A StatefulSet manages a group of pods while maintaining a sticky identity for each pod, with a persistent identifier that remains even if the pod is shut down and restarted. Pods also have PersistentVolumes that can store data that outlines the lifecycle of each individual pod.
The following example shows a YAML configuration for a headless Service that controls the network domain, and a StatefulSet that runs 3 instances of an NGINX web server.
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
—port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # by default is 1
minReadySeconds: 10 # by default is 0
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
—name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
—containerPort: 80
name: web
volumeMounts:
—name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
—metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "my-storage-class"
resources:
requests:
storage: 1Gi
The important fields of this configuration are:
metadata.name—must be a valid DNS subdomain name..spec.selector.matchLabels and .spec.template.metadata.labels—both of these must match and are referenced by the headless Service to route requests to the application.spec.selector.replicas—specifies that the StatefulSet should run three replicas of the container, each with a unique persistent identifier.spec.template.spec.containers—specifies what NGINX image to run and how it should mount the PersistentVolumes.volumeClaimTemplates—provides persistent storage using themy-storage-classstorage class. In a real environment, your cluster will have one or more storage classes defined by the cluster administrator, which provide different types of persistent storage.
Learn more in our detailed guide to Kubernetes in production
Kubernetes Deployment with Codefresh
The Codefresh Software Delivery Platform, powered by Argo, lets you answer many important questions within your organization, whether you’re a developer or a product manager. For example:
- What features are deployed right now in any of your environments?
- What features are waiting in Staging?
- What features were deployed last Thursday?
- Where is feature #53.6 in our environment chain?
What’s great is that you can answer all of these questions by viewing one single dashboard. Our applications dashboard shows:
- Services affected by each deployment
- The current state of Kubernetes components
- Deployment history and log of who deployed what and when and the pull request or Jira ticket associated with each deployment