Now that your company has decided to embrace Cloud-native and microservices software architecture, you’ve suddenly been thrust into the whimsical, and somewhat confusing, world of Kubernetes.
Put on your learning Monokle and let’s dive into Kubernetes Manifest files!
A Kubernetes manifest file is your personal guide through a Kubernetes cluster: A configuration file written in a format called YAML or JSON, that describes the resources you want in your cluster. These resources can be a myriad of things: pods (that run your applications), services (that help your applications communicate), and deployments (that manage your applications).
You can also think of a manifest file as a Kubernetes wish list! It communicates what resources you want, and how you want them configured.
- `apiVersion`: This is where you specify the version of the Kubernetes API you're using. Think of it as telling Kubernetes which edition of the rulebook you're playing by.
- `kind`: This tells Kubernetes what type of resource you want to create. It could be a `Pod`, `Service`, `Deployment`, `StatefulSet`, and so much more.
- `metadata`: This is the section where you give your resource a name, and also assign it labels and annotations. It's like giving your resource a name tag and some fun stickers!
- `spec`: This is the big one! This is where you define what you want for your resource. What is placed here depends on the type of resource you're creating.
For example, if you're creating a `Pod`, you'll need to specify things like which containers to run, and which Docker image to use for each.
Here's a simple example of a Kubernetes manifest file that creates a Pod:
To bring your wish list to life, use the `kubectl` command-line tool with the `apply` command:
The `-f my-manifest.yaml` bit tells `kubectl` to read your wish list from the file `my-manifest.yaml`. The `apply` command then works its magic, creating or updating resources in your cluster to match your wishes!
Alright, let's move on to another important piece of the Manifest puzzle: the `metadata` field in our manifest file.
You can think of `metadata` as the ID card for your Kubernetes resource. It has all the crucial details that help us uniquely ID our resources and understand where it fits in the big picture. Here's what you'll typically find in the `metadata`:
- `name`: Every hero has a name, andevery resource in Kubernetes has a name too! The `name` is the unique identifier of the resource within its own namespace.
- 'namespace': If Kubernetes were a house, namespaces would be the individual rooms. The `namespace` field tells us which room (or namespace) our resource is in. If we don't specify this, Kubernetes assumes it's in the `default` room, somewhere down the hall or deep in the basement where no one will find it...
- `labels`: Labels are the fun, colorful stickers we put on our resources (like the lisa-frank ones we were sticking on composition notebooks in middle-school). They're key-value pairs that help us categorize and find our resources quickly. For example, we might slap on the label `app=frontend` on all pods that make up the frontend of our application.
- `annotations`: Annotations are the notes we stick on our resources (I might be running out of fun analogies). They're also key-value pairs, but these are meant for storing extra details that help us understand our resources better. These could be added by us, by other tools working with Kubernetes, or a helpful friend!
- `uid`: This is the unique ID card number for our resource, and is automatically given.
- `creationTimestamp`: This is the birth certificate of our resource. Kubernetes automatically notes down when our resource was created.
- `resourceVersion`: A super handy field that helps systems to know if a resource has been updated or not. Think a history book, a ledger.
Here's how all of this might look like in a manifest file:
In this example, I've got a Pod named `my-pod` in the namespace `my-namespace`. It's got a label `app=my-app` and an annotation that tells us a bit about the application. Just like that, our Pod has its own ID card!
Remember, getting your `metadata` correct is vital in Kubernetes. It's the key to keeping things organized and running smoothly.
So go ahead, bust out that label-maker and start labeling!
Just like `metadata`, the `spec` field in your Kubernetes manifest file is equally important, despite serving a different purpose.
The `spec` field (short for specifications) is where we define the desired state of our resources.
With this, you're telling Kubernetes, "Hey! This is what I want my resources to look like, and here's how they should behave!"
It's essentially a blueprint for your Kubernetes resource.
What you put inside `spec` depends largely on the `kind` of resource you're creating:
- If you're creating a `Pod`, specify the containers that should run in the Pod, along with the Docker image to use for each container and the ports that should be open.
- If you're creating a `Service`, specify the type of the service (`ClusterIP`, `NodePort`, `LoadBalancer`, or `ExternalName`) and what ports to expose.
- If you're creating a `Deployment`, specify things like the number of replicas, the strategy for updating and rolling back to a previous version, and a Pod template to describe the Pods' contents.
Here's an example of a `spec` for a Deployment:
In this example, we're saying we want a Deployment named `my-deployment` with 3 replicas. We're also specifying that we want each Pod in the Deployment to run a single container using `my-image:1.0` Docker image, and that the container needs to expose port 80.
Remember, `spec` is where you communicate what you want your resources to be. Getting it right is imperative to ensuring the application runs the way you want.
Now, go ahead and start crafting your blueprint for success!
So, what exactly does an error in a Kubernetes Manifest look like?
Well, the most common errors are YAML formatting errors, property names with simple typos, invalid values and JSON syntax errors (insert links to related articles).
But, in my experience, the most common error is similar to what I do with my keys: forgetting. Specifically, forgetting to include required properties for your objects like image names for containers.
Fortunately, Monokle has an easy solution if you happen to leave your specified properties behind on the counter.
But, enough about my chaotic morning, let’s take a closer look at some of the most common hiccups when dealing with Kubernetes Manifests:
Incorrect Indentation: Kubernetes manifests are written in YAML, which is a whitespace and indentation sensitive language. Incorrect indentation is a common source of errors. Make sure each nested field is properly indented.
Misspelled or Incorrect Fields: Typos or using incorrect field names can lead to errors. Always double-check your spelling and ensure you're using the correct field names as defined in the Kubernetes API documentation.
Missing Required Fields: Every Kubernetes resource requires certain fields to be set. For example, a `Pod` needs the `spec.containers[].name` and `spec.containers[].image` fields. If a required field is missing, you'll encounter an error.
Incorrect Data Types: Kubernetes expects certain fields to be of a certain data type. For example, `spec.replicas` in a `Deployment` should be an integer. Providing a string will result in an error.
Invalid Resource References: If you're referring to other resources in your manifest (like a ConfigMap or Secret), and these resources don't exist or are misspelled, you'll encounter errors.
Invalid or Incompatible Values: Some fields only accept certain values, or the values have to be compatible. For example, if you're creating a `Service` of type `LoadBalancer`, but your cluster doesn't support LoadBalancer services, you'll see an error.
If you encounter an error in your Kubernetes manifests, don't be disheartened.
Look at the error message, understand what it's saying, and use it as a stepping stone to improve your Kubernetes skills.