Apply the YAML Manifest
In this step, you will explore the kubectl apply
command in more detail and learn different ways to apply Kubernetes manifests. Building upon the YAML files from the previous step, we will demonstrate various techniques for applying manifests.
First, make sure you are in the correct directory:
cd ~/project/k8s-manifests
Let's create a new subdirectory to organize our manifests further. Create a directory named manifests
and navigate into it:
mkdir -p manifests
cd manifests
Now, let's create a manifest for a simple web application that includes both a Deployment and a Service in a single file. Create a new file named web-app.yaml
using nano
:
nano web-app.yaml
Add the following content to web-app.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
type: ClusterIP
ports:
- port: 80
targetPort: 80
This manifest defines two Kubernetes resources in a single file, separated by ---
. This is a common way to group related resources together. Let's break down what's new:
- Multiple Resources in One File: The
web-app.yaml
file now contains two separate Kubernetes resource definitions: a Deployment and a Service. The ---
separator is used to distinguish between them.
kind: Service
: This defines a Service resource.
spec.selector.app: web
: This Service will target pods that have the label app: web
. This matches the labels we set for the pods created by the web-app
Deployment.
spec.type: ClusterIP
: Specifies the service type as ClusterIP
. This means the service will be exposed on an internal IP address within the cluster and is typically used for communication between services within the cluster.
spec.ports
: Defines how the service maps ports to the target pods.
port: 80
: The port on the Service itself that you will access.
targetPort: 80
: The port on the target pods that the service will forward traffic to.
Now, let's apply this manifest using different methods.
Method 1: Apply the entire file
This is the most common way to apply a manifest. Use kubectl apply -f
followed by the filename:
kubectl apply -f web-app.yaml
This command will create both the Deployment and the Service defined in web-app.yaml
. You should see output like:
deployment.apps/web-app created
service/web-service created
Method 2: Apply from a directory
You can apply all manifests in a directory at once. If you have multiple manifest files in the manifests
directory, you can apply them all by specifying the directory instead of a specific file:
kubectl apply -f .
The .
represents the current directory. kubectl
will look for YAML files in this directory and apply all of them. This is useful when you have organized your manifests into multiple files within a directory.
Method 3: Apply from a URL (Optional)
kubectl apply
can also apply manifests directly from a URL. This is useful for quickly deploying example applications or configurations hosted online. For example, you can deploy the Redis master deployment from the Kubernetes examples repository:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook/redis-master-deployment.yaml
This will download the manifest from the URL and apply it to your cluster. Note: Be cautious when applying manifests from untrusted URLs as they can potentially modify your cluster.
Let's explore some additional options for kubectl apply
.
Dry Run
You can use the --dry-run=client
flag to simulate applying a manifest without actually making changes to the cluster. This is useful for checking if your manifest is valid and for seeing what resources would be created or modified:
kubectl apply -f web-app.yaml --dry-run=client
This command will output what would be created or changed, but it won't actually apply the changes to your cluster.
Verbose Output
For more detailed output from kubectl apply
, you can use the -v
flag followed by a verbosity level (e.g., -v=7
). Higher verbosity levels provide more detailed information, which can be helpful for debugging:
kubectl apply -f web-app.yaml -v=7
This will print a lot more information about the API requests being made and the processing of the manifest.
Verify the resources created by applying web-app.yaml
. Use kubectl get deployments
and kubectl get services
to list the Deployments and Services in your cluster:
## List deployments
kubectl get deployments
## List services
kubectl get services
## Describe the deployment to see more details
kubectl describe deployment web-app
Example output for kubectl get deployments
:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 3m33s
redis-master 0/1 1 0 23s
web-app 2/2 2 2 42s
Example output for kubectl get services
:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8m28s
web-service ClusterIP 10.106.220.33 <none> 80/TCP 46s
Notice that now you have a web-app
Deployment with 2/2 READY
replicas and a web-service
of type ClusterIP
.
Let's briefly discuss the difference between declarative and imperative management in Kubernetes, especially in the context of kubectl apply
and kubectl create
.
kubectl apply
: Uses a declarative approach. You define the desired state in your manifest files, and kubectl apply
attempts to achieve that state. If you run kubectl apply
multiple times with the same manifest, Kubernetes will only make changes if there are differences between the desired state in the manifest and the current state in the cluster. kubectl apply
is generally recommended for managing Kubernetes resources because it is more robust and easier to manage changes over time. It tracks the configuration of your resources and allows for incremental updates.
kubectl create
: Uses an imperative approach. You directly instruct Kubernetes to create a resource. If you try to run kubectl create
for a resource that already exists, it will typically result in an error. kubectl create
is less flexible for managing updates and changes compared to kubectl apply
.
In most cases, especially for managing application deployments, kubectl apply
is the preferred and recommended method due to its declarative nature and better handling of updates and configuration management.