Skip to main content

Kubernetes Manifests

Introduction

Kubernetes manifests are YAML or JSON files that describe the desired state of resources in a Kubernetes cluster. They are the backbone of Kubernetes configuration, allowing you to define, create, and manage Kubernetes objects declaratively. In this guide, we'll explore what manifests are, their structure, and how to use them effectively.

Think of manifests as blueprints for your Kubernetes resources - they tell Kubernetes what you want to build and how you want it to look.

What Are Kubernetes Manifests?

Kubernetes manifests are declarative configuration files that define:

  • What resources you want to create (Pods, Services, Deployments, etc.)
  • What properties and configurations these resources should have
  • How these resources should behave

Instead of telling Kubernetes how to create resources through a series of commands, manifests tell Kubernetes what resources should exist and their desired state. Kubernetes then works to ensure the actual state matches this desired state.

Manifest Structure

Most Kubernetes manifests are written in YAML format (though JSON is also supported). A basic manifest contains four required top-level fields:

yaml
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
containers:
- name: nginx
image: nginx:1.17.3

Let's break down these core fields:

  1. apiVersion: Specifies which version of the Kubernetes API to use
  2. kind: Defines what type of resource you're creating
  3. metadata: Contains data that identifies the resource (name, labels, etc.)
  4. spec: Contains the desired state for the resource

Common Kubernetes Resource Types

Here are some of the most common resource types you'll define in manifests:

ResourceDescription
PodThe smallest deployable unit in Kubernetes
DeploymentManages a set of replicated Pods
ServiceExposes Pods to network traffic
ConfigMapStores configuration data
SecretStores sensitive data (encrypted)
PersistentVolumeClaimRequests storage resources
NamespaceVirtual cluster within a physical cluster

Creating Your First Manifest

Let's create a simple manifest for a Deployment that runs an NGINX web server:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.17.3
ports:
- containerPort: 80

This manifest:

  • Creates a Deployment resource named "nginx-deployment"
  • Tells Kubernetes to create and maintain 3 replicas of the Pod
  • Labels the Pods with app: nginx
  • Defines that each Pod should run the NGINX 1.17.3 container
  • Specifies that the container listens on port 80

Applying Manifests

Once you've created a manifest file (e.g., deployment.yaml), you can apply it to your cluster using the kubectl apply command:

bash
kubectl apply -f deployment.yaml

The output will look something like:

deployment.apps/nginx-deployment created

You can verify the deployment was created:

bash
kubectl get deployments

Output:

NAME              READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment 3/3 3 3 45s

Understanding More Complex Manifests

In real-world scenarios, you'll often create more complex manifests. Let's look at a more comprehensive example that includes a Deployment and a Service to expose it:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web-container
image: nginx:latest
ports:
- containerPort: 80
resources:
limits:
cpu: "0.5"
memory: "256Mi"
requests:
cpu: "0.2"
memory: "128Mi"
---
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
type: ClusterIP

Key points about this example:

  1. The --- separates different resources in the same file
  2. We've added resource constraints for the container
  3. We've created a Service to expose the Deployment internally
  4. The Service targets Pods with the label app: web

Manifest Validation

Before applying manifests, it's a good practice to validate them. You can use:

bash
kubectl apply --dry-run=client -f your-manifest.yaml

This checks for syntax errors without actually creating resources.

For more detailed validation, you can use:

bash
kubectl apply --server-side --dry-run=server -f your-manifest.yaml

This sends the manifest to the API server for validation without creating resources.

Working with Multiple Manifests

As your application grows, you'll have multiple manifests. There are several ways to organize them:

  1. Multiple files: Create separate files for each resource type

    bash
    kubectl apply -f deployment.yaml -f service.yaml
  2. Directory: Organize manifests in a directory structure

    bash
    kubectl apply -f ./my-app/
  3. Kustomize: Use Kubernetes' built-in configuration customization tool

    bash
    kubectl apply -k ./overlay/development/

Common Manifest Patterns

Environment Variables

yaml
apiVersion: v1
kind: Pod
metadata:
name: env-example
spec:
containers:
- name: nginx
image: nginx
env:
- name: DATABASE_URL
value: "postgres://user:password@localhost:5432/db"
- name: LOG_LEVEL
value: "info"

Using ConfigMaps

yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database.url: "postgres://localhost:5432/db"
log.level: "debug"
---
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- configMapRef:
name: app-config

Secret References

yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
containers:
- name: app
image: myapp:1.0
env:
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: password

Best Practices for Manifests

  1. Use version control: Store manifests in Git or another version control system
  2. Use namespaces: Organize resources into namespaces for better isolation
  3. Add labels and annotations: These help with resource organization and selection
  4. Keep manifests modular: Separate concerns into different files
  5. Use resource limits: Always specify CPU and memory limits
  6. Follow naming conventions: Use consistent naming for resources
  7. Document your manifests: Add comments to explain complex configurations

Visualizing Manifest Relationships

Troubleshooting Manifests

When applying manifests, you might encounter errors. Here are some common issues and solutions:

  1. YAML formatting: Ensure indentation is correct (YAML is whitespace-sensitive)
  2. API version mismatch: Verify the apiVersion is correct for your Kubernetes version
  3. Missing required fields: Check that all required fields are included
  4. Resource not found: Ensure the specified resource exists (for references)
  5. Permission issues: Verify you have the necessary permissions

Using Helm for Template-Based Manifests

While basic manifests are powerful, as applications grow more complex, consider using Helm, a package manager for Kubernetes that allows you to create reusable manifest templates.

bash
# Install a Helm chart (template-based manifests)
helm install myapp ./mychart

Summary

Kubernetes manifests are the declarative way to define and manage Kubernetes resources. They allow you to:

  • Define resources in a human-readable format (YAML or JSON)
  • Describe the desired state rather than imperative commands
  • Version control your infrastructure configuration
  • Apply consistent configurations across environments

As you continue your Kubernetes journey, you'll create increasingly sophisticated manifests that define complex applications. The declarative approach used in manifests represents the true power of Kubernetes - letting you define what you want, not how to get there.

Exercises

  1. Create a manifest for a Pod running the busybox image that executes a command to print "Hello, Kubernetes!"
  2. Build a manifest file that contains both a Deployment and a Service for a simple web application
  3. Create a ConfigMap with several key-value pairs and reference it in a Pod manifest
  4. Modify an existing manifest to add resource limits and requests
  5. Create a manifest that deploys an application with two different container images in the same Pod

Additional Resources



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)