Kubernetes 08 - Declarative Management with Kubernetes
When managing a Kubernetes cluster, you have several options to interact with your resources. Common imperative commands like kubectl create
, kubectl replace
, and kubectl edit
might seem straightforward, but they lack the structural integrity needed for handling production environments effectively. These commands often lead to inconsistencies and are prone to human error, making them less desirable for a solid DevOps structure.
Problems of Imperative Commands
-
kubectl create
: While useful for quickly spinning up resources, it doesn’t provide an easy way to track and manage changes over time. -
kubectl replace
: This command overwrites existing configurations, potentially leading to unintended disruptions. -
kubectl edit
: Directly editing live configurations can be risky and might result in unexpected downtime.
Instead of these imperative methods, opting for a declarative approach allows for better version control, easier auditing, and simplified management.
Using kubectl apply
The command kubectl apply -f filename.yml
is your pathway into the declarative world of Kubernetes. It allows you to create and update resources using YAML files, providing a clear and concise way to define your infrastructure. Here’s how you can harness its potential.
Applying Configurations
-
Create/Update a Single Resource: To apply a configuration defined in a YAML file, use the command:
kubectl apply -f filename.yml
-
Create/Update Multiple Resources: You can also manage a whole directory of YAML files, applying configurations for various resources simultaneously:
kubectl apply -f directory/
-
Apply Configurations from a URL: For resources hosted externally, you can directly apply them using a URL:
kubectl apply -f https://example.com/filename.yml
It’s crucial to inspect the content of the file before applying it. Ensure the commands within align with your infrastructure needs, as follows:
curl -L https://example.com/filename.yml | less
By using kubectl apply
, you embrace a practice that fosters consistency by ensuring your infrastructure’s desired state matches its current state—automatically handling updates and maintaining control over your Kubernetes environment.
Kubernetes Configuration YAML
Kubernetes configuration files are typically written in YAML or JSON format. These files are the blueprint for your Kubernetes resources, telling the system what to create and how to manage it. Each file can contain one or more manifests, with each manifest describing a specific API object such as a deployment, job, or secret.
The Four Essential Components of a Kubernetes YAML File
Every manifest in a Kubernetes configuration file needs four key components:
- kind: Specifies the type of resource you’re creating.
- apiVersion: Indicates which version of the Kubernetes API you’re using.
- metadata: Provides information about the resource, such as its name.
- spec: Defines the desired state and characteristics of the resource.
Let’s explore each of these in more detail.
Understanding kind
The kind
field tells Kubernetes what type of resource you want to create. Kubernetes supports a wide variety of resources, and you can view a list of them using the command:
kubectl api-resources
This command will display a table showing the resource name, short names (if any), API version, whether it’s namespaced, and the kind. For example, you might see entries like:
NAME SHORTNAMES APIVERSION NAMESPACED KIND
pods po v1 true Pod
services svc v1 true Service
deployments deploy apps/v1 true Deployment
Specifying apiVersion
Different resources might be supported by different API versions. To see which API versions your cluster supports, use:
kubectl api-versions
This will list all available API versions, such as:
v1
apps/v1
batch/v1
networking.k8s.io/v1
When creating your configuration file, make sure to use an apiVersion that’s compatible with the resource kind you’re using.
Adding metadata
The metadata section is where you provide information about your resource. At a minimum, you need to specify a name for your resource. You can also include other metadata like labels or annotations.
Defining the spec
The spec
section is where you define the desired state of your resource. This is where most of the configuration happens, and the exact fields will depend on the kind of resource you’re creating.
Putting It All Together
Here’s a simple example of how these four parts come together in a YAML file for a basic Pod:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx:latest
In this example, we’re creating a Pod (kind) using the v1 API version. We’ve named it “my-pod” in the metadata, and in the spec, we’ve defined that it should run a single container using the latest nginx image.
Understanding these basics will help you start creating your own Kubernetes configurations. As you become more familiar with Kubernetes, you’ll learn about more complex resources and configurations, but these four parts will always form the foundation of your YAML files.
Leveraging kubectl explain
One of the most powerful tools at your disposal is the kubectl explain
command. This command allows you to explore the structure and available fields for different Kubernetes resources right from your terminal.
Getting an Overview
To get a comprehensive view of all the keys a particular resource supports, you can use the --recursive
flag. For example, to see all possible fields for a Service resource:
kubectl explain services --recursive
This command will output a detailed tree-like structure of all available fields, giving you a bird’s-eye view of the resource’s capabilities.
Drilling Down
If you want to focus on a specific part of the resource, you can narrow down your query. For instance, to learn more about the spec
field of a Service:
kubectl explain services.spec
This will provide you with information about the spec
field and its immediate sub-fields.
Understanding Specific Fields
You can drill down even further to get details about individual fields. For example, if you want to know more about the type
field within a Service’s spec:
kubectl explain services.spec.type
This command will give you a description of the type
field, including its purpose and possible values.
Navigating Complex Structures
Kubernetes resources can have deeply nested structures. The kubectl explain
command allows you to navigate these structures easily. For example, if you need information about the server
field of an NFS volume in a Deployment’s pod template:
kubectl explain deployment.spec.template.spec.volumes.nfs.server
This command demonstrates how you can traverse the resource hierarchy to find information about very specific fields.
Complementing with Official Documentation
While kubectl explain
is useful, it’s always a good idea to complement it with the official Kubernetes documentation. The Kubernetes docs website offers comprehensive guides, tutorials, and reference materials that can provide additional context and examples.
Dry Runs with Apply YAML
Dry runs are a way to test your Kubernetes configurations without actually making changes to your cluster. This feature allows you to validate your YAML files and catch potential issues before applying them.
- Client-side dry run:
kubectl apply -f app.yml --dry-run=client
This command simulates the creation of resources defined in your YAML file on the client-side only. It’s useful for quick syntax checks and validation.
- Server-side dry run:
kubectl apply -f app.yml --dry-run=server
This command goes a step further by sending the request to the Kubernetes API server, allowing for more thorough validation, including admission control checks.
To visualize the differences between your current cluster state and the proposed changes, you can use:
kubectl diff -f app.yml
This command provides a clear, git-style diff output, making it easy to spot changes.
Labels and Annotations
Labels are key-value pairs that help you organize and select Kubernetes objects. They are defined under the metadata:
section in your YAML files.
Labels serve several purposes:
- Identifying resources
- Grouping related objects
- Filtering and selecting objects for operations
Common label examples include:
tier: frontend
app: api
env: prod
customer: acme.co
It’s important to note that labels should be simple and used for identification purposes. For more complex or non-identifying information, use annotations instead.
You can use labels to filter your kubectl commands:
kubectl get pods -l app=api
This command retrieves only the pods labeled with app=nginx
. You can also apply changes to resources matching specific labels:
kubectl apply -f myfile.yml -l app=nginx
This command applies the configuration in myfile.yml
only to resources labeled with app=nginx
.
Label Selectors
Label selectors are the “glue” that connects different Kubernetes resources. They play a crucial role in how Services and Deployments identify which Pods belong to them.
Key points about label selectors:
- They create relationships between resources based on labels
- You’ll find them in Service and Deployment YAML files
- They can be used to control which Pods are scheduled on which nodes
- Work in conjunction with Taints and Tolerations for fine-grained control over Pod placement
Cleanup
After working with Kubernetes resources, it’s good practice to clean up any unnecessary objects. You can do this by first listing all resources:
kubectl get all
Then, delete specific resources using:
kubectl delete <resource type>/<resource name>
Replace <resource type>
with the type of resource (e.g., pod, deployment, service) and <resource name>
with the specific resource name you want to delete.
Using dry runs, labels, and selectors in Kubernetes can significantly improve your ability to manage and organize your cluster effectively. These features provide powerful tools for testing configurations, organizing resources, and creating relationships between different Kubernetes objects.
Enjoy Reading This Article?
Here are some more articles you might like to read next: