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:
httpGet
specifies that the kubelet should try a HTTP request on the root of the web server on port 80.periodSeconds
specifies how often the kubelet should perform a liveness probe.initialDelaySeconds
specifies 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.affinity
field 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-elasticsearch
spec.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-class
storage 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