How to Create a Kubernetes Deployment using YAML (2024)

Ready for more about YAML? This webinar helps you get started and shows how YAML is used in defining basic Kubernetes deployments.

In previous articles, we’ve been talking about how to use Kubernetes to spin up resources. So far, we’ve been working exclusively with the CLI, but there’s an easier and more useful way to do it: creating configuration files using kubernetes YAML. In this article, we’ll look at how Kubernetes YAML works and use it to define first a Kubernetes Pod, and then a Kubernetes Deployment.

Kubernetes YAML Basics

It’s difficult to escape YAML if you’re doing anything related to many software fields — particularly Kubernetes, SDN, and OpenStack. YAML, which stands for Yet Another Markup Language, or YAML Ain’t Markup Language (depending who you ask) is a human-readable text-based format for specifying configuration-type information. For example, in this article, we’ll pick apart the Kuberenetes YAML definitions for creating first a Pod, and then a Deployment.

Defining a Kubernetes Manifest

When defining a Kubernetes manifest, YAML gives you a number of advantages, including:

Convenience: You’ll no longer have to add all of your parameters to the command line

Maintenance: YAML files can be added to source control, such as a Github repository so you can track changes

Flexibility: You’ll be able to create much more complex structures using YAML than you can on the command line

YAML is a superset of JSON, which means that any valid JSON file is also a valid YAML file. So on the one hand, if you know JSON and you’re only ever going to write your own YAML (as opposed to reading other people’s) you’re all set. On the other hand, that’s not very likely, unfortunately. Even if you’re only trying to find examples on the web, they’re most likely in (non-JSON) YAML, so we might as well get used to it. Still, there may be situations where the JSON format is more convenient, so it’s good to know that it’s available to you.

Fortunately, YAML is relatively easy to learn. There are only two types of structures you need to know about in YAML:

  • Lists

  • Maps

That’s it. You might have maps of lists and lists of maps, and so on, but if you’ve got those two structures down, you’re all set. That’s not to say there aren’t more complex things you can do, but in general, this is all you need to get started.

YAML Maps

Let’s start by looking at YAML maps. Maps let you associate name-value pairs, which of course is convenient when you’re trying to set up configuration information. For example, you might have a config file that starts like this:

---apiVersion: v1kind: Pod

The first line is a separator, and is optional unless you’re trying to define multiple structures in a single file. From there, as you can see, we have two values, v1 and Pod, mapped to two keys, apiVersion, and kind.

This kind of thing is pretty simple, of course, and you can think of it in terms of its JSON equivalent:

{ "apiVersion": "v1", "kind": "Pod"}

Notice that in our YAML version, the quotation marks are optional; the processor can tell that you’re looking at a string based on the formatting.

You can also specify more complicated structures by creating a key that maps to another map, rather than a string, as in:

---apiVersion: v1kind: Podmetadata: name: rss-site labels: app: web

In this case, we have a key, metadata, that has as its value a map with 2 more keys, name and labels. The labels key itself has a map as its value. You can nest these as far as you want to.

The YAML processor knows how all of these pieces relate to each other because we’ve indented the lines. In this example I’ve used 2 spaces for readability, but the number of spaces doesn’t matter — as long as it’s at least 1, and as long as you’re CONSISTENT. For example, name and labels are at the same indentation level, so the processor knows they’re both part of the same map; it knows that app is a value for labels because it’s indented further.

Quick note: NEVER use tabs in a YAML file.

So if we were to translate this to JSON, it would look like this:

{ "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "rss-site", "labels": { "app": "web" } }}

Now let’s look at lists.

YAML lists

YAML lists are literally a sequence of objects. For example:

args: - sleep - "1000" - message - "Bring back Firefly!"

As you can see here, you can have virtually any number of items in a list, which is defined as items that start with a dash (-) indented from the parent. So in JSON, this would be:

{ "args": ["sleep", "1000", "message", "Bring back Firefly!"]}

And of course, members of the list can also be maps:

---apiVersion: v1kind: Podmetadata: name: rss-site labels: app: webspec: containers: - name: front-end image: nginx ports: - containerPort: 80 - name: rss-reader image: nickchase/rss-php-nginx:v1 ports: - containerPort: 88

So as you can see here, we have a list of container “objects”, each of which consists of a name, an image, and a list of ports (It might also include network information). Each list item under ports is itself a map that lists the containerPort and its value.

For completeness, let’s quickly look at the JSON equivalent:

{ "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "rss-site", "labels": { "app": "web" } }, "spec": { "containers": [ { "name": "front-end", "image": "nginx", "ports": [ { "containerPort": "80" } ] }, { "name": "rss-reader", "image": "nickchase/rss-php-nginx:v1", "ports": [ { "containerPort": "88" } ] } ] }}

As you can see, we’re starting to get pretty complex, and we haven’t even gotten into anything particularly complicated! No wonder YAML is replacing JSON so fast.

So let’s review. We have:

  • maps, which are groups of name-value pairs

  • lists, which are individual items

  • maps of maps

  • maps of lists

  • lists of lists

  • lists of maps

Basically, whatever structure you want to put together, you can do it with those two structures.

Mirantis simplifies Kubernetes.

From the world’s most popular Kubernetes IDE to fully managed services and training, we can help you at every step of your K8s journey.

Connect with a Mirantis expert to learn how we can help you.

Contact Us

How to Create a Kubernetes Deployment using YAML (1)

Creating a Kubernetes Pod using YAML

OK, so now that we’ve got the basics out of the way, let’s look at putting this to use. We’re going to first create a Pod, then a Deployment, using YAML.

If you haven’t set up your cluster and kubectl, go ahead and check out this article series on setting up Kubernetes on your server before you go on. It’s OK, we’ll wait….

Back already? Great! Let’s start with a Pod.

Creating the Kubernetes Pod YAML deployment file

In our previous example, we described a simple Pod using YAML which we can save locally. Open that file:

---apiVersion: v1kind: Podmetadata: name: rss-site labels: app: webspec: containers: - name: front-end image: nginx ports: - containerPort: 80 - name: rss-reader image: nickchase/rss-php-nginx:v1 ports: - containerPort: 88

Taking it apart one piece at a time, we start with the API version; here it’s just v1. (When we get to deployments, we’ll have to specify a different version because Deployments don’t exist in v1.)

Next, we’re specifying that we want to create a Pod to hold your application or cloud service; we might specify instead a Deployment, Job, Service, and so on, depending on what we’re trying to achieve.

Next, we specify the metadata. Here we’re specifying the name of the Pod, as well as the label we’ll use to identify the pod to Kubernetes.

Finally, we’ll configure the actual objects that make up the pod. The spec property includes any containers, memory requirements, storage volumes, network or other details that Kubernetes needs to know about, as well as properties such as whether to restart the container if it fails. You can find a complete list of Kubernetes Pod properties in the Kubernetes API specification, but let’s take a closer look at a typical container definition:

... spec: containers: - name: front-end image: nginx ports: - containerPort: 80 - name: rss-reader ...

In this case, we have a simple, fairly minimal definition: a name (front-end), the image on which it’s based (nginx), and one port on which the container will listen internally (80). Of these, only the name is really required, but in general, if you want it to do anything useful, you’ll need more information.

You can also specify more complex properties, such as a command to run when the container starts, arguments it should use, a working directory, or whether to pull a new copy of the image every time it’s instantiated. You can also specify even deeper information, such as the location of the container’s exit log. Here are the properties you can set for a container, which you can find in the Kubernetes YAML Reference:

  • name

  • image

  • command

  • args

  • workingDir

  • ports

  • env

  • resources

  • volumeMounts

  • livenessProbe

  • readinessProbe

  • lifecycle

  • terminationMessagePath

  • imagePullPolicy

  • securityContext

  • stdin

  • stdinOnce

  • tty

Now let’s go ahead and actually create the pod.

Creating the pod using the YAML file

The first step, of course, is to go ahead and create a text file locally. Call it pod.yaml and add the following text, just as we specified earlier:

--- apiVersion: v1 kind: Pod metadata: name: rss-site labels: app: web spec: containers: - name: front-end image: nginx ports: - containerPort: 80 - name: rss-reader image: nickchase/rss-php-nginx:v1 ports: - containerPort: 88

Save the file. Now we need to deploy the manifests.

Kubernetes YAML Deployment Example

Tell Kubernetes to rollout the YAML file’s manifests using the CLI:

> kubectl create -f pod.yamlpod "rss-site" created

As you can see, K8s references the name we gave the Pod. You can see that if you ask for a list of the pods in the default namespace:

> kubectl get pods NAME READY STATUS RESTARTS AGE rss-site 0/2 ContainerCreating 0 6s

If you check early enough, while K8s is still deploying, you can see that the workload is still being created. After a few seconds, you should see the pods running:

> kubectl get podsNAME READY STATUS RESTARTS AGErss-site 2/2 Running 0 14s

From here, you can test out the Pod (just as we did in the previous article), but ultimately we want to create a Kubernetes Deployment example, so let’s go ahead and delete it so there aren’t any name conflicts:

> kubectl delete pod rss-sitepod "rss-site" deleted

Troubleshooting pod creation

Sometimes, of course, things don’t go as you expect. Maybe you’ve got a networking issue, or you’ve mistyped something in your YAML file. You might see an error like this:

> kubectl get podsNAME READY STATUS RESTARTS AGErss-site 1/2 ErrImagePull 0 9s

In this case, we can see that one of our containers started up just fine, but there was a problem with the other. To track down the problem, we can ask Kubernetes for more information on the Pod:

> kubectl describe pod rss-siteName: rss-siteNamespace: defaultNode: 10.0.10.7/10.0.10.7Start Time: Sun, 08 Jan 2017 08:36:47 +0000Labels: app=webStatus: PendingIP: 10.200.18.2Controllers: Containers: front-end: Container ID: docker://a42edaa6dfbfdf161f3df5bc6af05e740b97fd9ac3d35317a6dcda77b0310759 Image: nginx Image ID: docker://sha256:01f818af747d88b4ebca7cdabd0c581e406e0e790be72678d257735fad84a15f Port: 80/TCP State: Running Started: Sun, 08 Jan 2017 08:36:49 +0000 Ready: True Restart Count: 0 Environment Variables: rss-reader: Container ID: Image: nickchase/rss-php-nginx Image ID: Port: 88/TCP State: Waiting Reason: ErrImagePull Ready: False Restart Count: 0 Environment Variables: Conditions: Type Status Initialized True Ready False PodScheduled TrueNo volumes.QoS Tier: BestEffortEvents: FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 45s 45s 1 {default-scheduler } Normal Scheduled Successfully assigned rss-site to 10.0.10.7 44s 44s 1 {kubelet 10.0.10.7} spec.containers{front-end} Normal Pulling pulling image "nginx" 45s 43s 2 {kubelet 10.0.10.7} Warning MissingClusterDNS kubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. Falling back to DNSDefault policy. 43s 43s 1 {kubelet 10.0.10.7} spec.containers{front-end} Normal Pulled Successfully pulled image "nginx" 43s 43s 1 {kubelet 10.0.10.7} spec.containers{front-end} Normal Created Created container with docker id a42edaa6dfbf 43s 43s 1 {kubelet 10.0.10.7} spec.containers{front-end} Normal Started Started container with docker id a42edaa6dfbf 43s 29s 2 {kubelet 10.0.10.7} spec.containers{rss-reader} Normal Pulling pulling image "nickchase/rss-php-nginx" 42s 26s 2 {kubelet 10.0.10.7} spec.containers{rss-reader} Warning Failed Failed to pull image "nickchase/rss-php-nginx": Tag latest not found in repository docker.io/nickchase/rss-php-nginx 42s 26s 2 {kubelet 10.0.10.7} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "rss-reader" with ErrImagePull: "Tag latest not found in repository docker.io/nickchase/rss-php-nginx" 41s 12s 2 {kubelet 10.0.10.7} spec.containers{rss-reader} Normal BackOff Back-off pulling image "nickchase/rss-php-nginx" 41s 12s 2 {kubelet 10.0.10.7} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "rss-reader" with ImagePullBackOff: "Back-off pulling image \"nickchase/rss-php-nginx\""

As you can see, there’s a lot of information here, but we’re most interested in the Events — specifically, once the warnings and errors start showing up. From here I was able to quickly see that I’d forgotten to add the :v1 tag to my image, so by default it was looking for the :latest tag, which didn’t exist.

To fix the problem, I first deleted the Pod, then fixed the YAML file and started again. Instead, I could have fixed the repo so that Kubernetes could find what it was looking for, and it would have continued on as though nothing had happened.

Now that we’ve successfully gotten a Pod running, let’s look at doing the same for a Deployment.

Creating a Kubernetes Deployment using YAML

Finally, we’re down to creating the actual Kubernetes Deployment. Before we do that, though, it’s worth understanding what it is we’re actually doing.

Kubernetes, remember, manages container-based applications and services. In the case of a K8s Deployment, you’re creating a set of resources to be managed. For example, where we previously created a single instance of the Pod, we might create a Kubernetes Deployment YAML example to tell Kubernetes to manage a set of replicas of that Pod — literally, a ReplicaSet — to make sure that a certain number of them are always available.

Kubernetes Deployment Use Cases

It’s important to understand why you’d want to use a Kuberenetes Deployment in the first place. Some of these use cases include:

  • Ensuring availability of a workload: Deployments specify how many copies of a particular workload should always be running, so if a workload dies, Kubernetes will automatically restart it, ensuring that the workload is always available.

  • Scaling workloads: Kubernetes makes it easy to change how many replicas a Deployment should maintain, making it straightforward to increase or decrease the number of copies running at any given time. It even offers autoscaling!

  • Managing the state of an application: Deployments can be paused, edited, and rolled back, so you can make changes with a minimum of fuss.

  • Easily exposing a workload outside the cluster: It might not sound like much, but being able to create a service that connects your application with the outside world with a single command is more than a little convenient.

Now let’s look at actually building Deployments.

Writing a DeploymentSpec

So we might start our Kubernetes Deployment manifest definition YAML like this:

--- apiVersion: apps/v1 kind: Deployment metadata: name: rss-site spec: replicas: 2

Here we’re specifying the apiVersion and that we want a Deployment. Next we specify the name. We can also specify any other metadata we want, but let’s keep things simple for now.

Finally, we get into the spec. In the Pod spec, we gave information about what actually went into the Pod; we’ll do the same thing here with the Deployment. We’ll start, in this case, by saying that whatever Pods we deploy, we always want to have 2 replicas. You can set this number however you like, of course, and you can also set properties such as the selector that defines the Pods affected by this Deployment, or the minimum number of seconds a pod must be up without any errors before it’s considered “ready”. You can find a full list of the Deployment specification properties in the Kuberenetes v1beta1 API reference.

OK, so now that we know we want 2 replicas, we need to answer the question: “Replicas of what?” They’re defined by templates:

---apiVersion: apps/v1kind: Deploymentmetadata: name: rss-site labels: app: webspec: replicas: 2 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: front-end image: nginx ports: - containerPort: 80 - name: rss-reader image: nickchase/rss-php-nginx:v1 ports: - containerPort: 88

Look familiar? It should; this Kubernetes template is virtually identical to the Pod definition in the previous section, and that’s by design. Templates are simply definitions of objects to be replicated — objects that might, in other circ*mstances, be created on their own.

The difference here is that we’re specifying how we know what objects are part of this deployment; notice that the Deployment and the template both specify labels of app: web, and that the selector specifies that as the matchLabels.

Now let’s go ahead and rollout the deployment. Add the YAML to a file called deployment.yaml and point Kubernetes at it:

> kubectl create -f deployment.yamldeployment "rss-site" created

To see how it’s doing, we can check on the deployments list:

> kubectl get deploymentsNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGErss-site 2 2 2 1 7s

As you can see, Kubernetes has started both replicas, but only one is available. You can check the event log by describing the Deployment, as before:

> kubectl describe deployment rss-siteName: rss-siteNamespace: defaultCreationTimestamp: Mon, 09 Jan 2017 17:42:14 +0000=Labels: app=webSelector: app=webReplicas: 2 updated | 2 total | 1 available | 1 unavailableStrategyType: RollingUpdateMinReadySeconds: 0RollingUpdateStrategy: 1 max unavailable, 1 max surgeOldReplicaSets: yEvents: FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 46s 46s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set rss-site-4056856218 to 2

As you can see here, there’s no problem, it just hasn’t finished scaling up yet. Another few seconds, and we can see that both Pods are running:

> kubectl get deploymentsNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGErss-site 2 2 2 2 1m

Updating a deployment

Updating a Deployment

The simplest ways of updating the properties of a deployment involve editing the YAML used to create it. To do that, you’ll want to use apply rather than create when creating the Deployment in the first place, as in:

kubectl apply -f deployment.yaml

You can then make changes to the YAML file itself and re-run kubectl apply to, well, apply them.

The other option is to use the kubectl edit command to edit a specific object, as in:

kubectl edit deployment.v1.apps/rss-site

You’ll then see an editor that enables you to edit the actual YAML that defines the Deployment. When you save your changes, they’ll be applied to the live object. For example, you can change the number of replicas, and when you save the definition, Kubernetes will ensure that the proper number of replicas is running.

Other ways for scaling a deployment

You can also scale a deployment directly using kubectl, as in:

kubectl scale deployment.v1.apps/rss-site --replicas=5

You can even tell Kubernetes to scale the Deployment automatically. For example, you can ensure that your pods are never using more than 60% of their available CPU capacity:

kubectl autoscale deployment.v1.apps/rss-site --min=3 --max=20 --cpu-percent=60

Kubernetes provides you with a number of other alternatives for automatically managing Deployments, which we will cover in future updates, so watch this space!

What we’ve seen so far

OK, so let’s review. We’ve basically covered these topics:

YAML is a human-readable text-based format that lets you easily specify configuration-type information by using a combination of maps of name-value pairs and lists of items (and nested versions of each).

YAML is the most convenient way to work with Kubernetes objects, and in this article we looked at creating Pods and Deployments.

You can get more information on running (or should-be-running) objects by asking Kubernetes to describe them.

That’s our basic YAML tutorial, with a focus on Deployments. We’re going to be tackling a great deal of Kubernetes-related content and documentation in the coming months, so if there’s something specific you want to hear about, let us know in the comments, or tweet us at @MirantisIT.

Check out Part 2 of this series to learn more about YAML for Kubernetes services, ingress, and more—and watch a recording of author Nick Chase in a webinar on Kubernetes Deployments using YAML.

How to Create a Kubernetes Deployment using YAML (2024)

References

Top Articles
Titre: Garmin Forerunner 55 : La Montre Connectée pour les Amateurs de Course
Comment activer Microsoft Office sur Windows 10 et 11 (Support Technique Dell Officiel)
Spasa Parish
Rentals for rent in Maastricht
159R Bus Schedule Pdf
Sallisaw Bin Store
Black Adam Showtimes Near Maya Cinemas Delano
Espn Transfer Portal Basketball
Pollen Levels Richmond
11 Best Sites Like The Chive For Funny Pictures and Memes
Things to do in Wichita Falls on weekends 12-15 September
Craigslist Pets Huntsville Alabama
Paulette Goddard | American Actress, Modern Times, Charlie Chaplin
Red Dead Redemption 2 Legendary Fish Locations Guide (“A Fisher of Fish”)
What's the Difference Between Halal and Haram Meat & Food?
Tyreek Hill admits some regrets but calls for officer who restrained him to be fired | CNN
Haverhill, MA Obituaries | Driscoll Funeral Home and Cremation Service
Rogers Breece Obituaries
Ems Isd Skyward Family Access
Elektrische Arbeit W (Kilowattstunden kWh Strompreis Berechnen Berechnung)
Omni Id Portal Waconia
Kellifans.com
Banned in NYC: Airbnb One Year Later
Four-Legged Friday: Meet Tuscaloosa's Adoptable All-Stars Cub & Pickle
Model Center Jasmin
Ice Dodo Unblocked 76
Is Slatt Offensive
Labcorp Locations Near Me
Storm Prediction Center Convective Outlook
Experience the Convenience of Po Box 790010 St Louis Mo
Fungal Symbiote Terraria
modelo julia - PLAYBOARD
Poker News Views Gossip
Abby's Caribbean Cafe
Joanna Gaines Reveals Who Bought the 'Fixer Upper' Lake House and Her Favorite Features of the Milestone Project
Tri-State Dog Racing Results
Navy Qrs Supervisor Answers
Trade Chart Dave Richard
Lincoln Financial Field Section 110
Free Stuff Craigslist Roanoke Va
Wi Dept Of Regulation & Licensing
Pick N Pull Near Me [Locator Map + Guide + FAQ]
Crystal Westbrooks Nipple
Ice Hockey Dboard
Über 60 Prozent Rabatt auf E-Bikes: Aldi reduziert sämtliche Pedelecs stark im Preis - nur noch für kurze Zeit
Wie blocke ich einen Bot aus Boardman/USA - sellerforum.de
Infinity Pool Showtimes Near Maya Cinemas Bakersfield
Dermpathdiagnostics Com Pay Invoice
How To Use Price Chopper Points At Quiktrip
Maria Butina Bikini
Busted Newspaper Zapata Tx
Latest Posts
Article information

Author: Corie Satterfield

Last Updated:

Views: 6778

Rating: 4.1 / 5 (62 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Corie Satterfield

Birthday: 1992-08-19

Address: 850 Benjamin Bridge, Dickinsonchester, CO 68572-0542

Phone: +26813599986666

Job: Sales Manager

Hobby: Table tennis, Soapmaking, Flower arranging, amateur radio, Rock climbing, scrapbook, Horseback riding

Introduction: My name is Corie Satterfield, I am a fancy, perfect, spotless, quaint, fantastic, funny, lucky person who loves writing and wants to share my knowledge and understanding with you.