
We'll try to answer the biggest question: "What is Kubernetes"? From its brief history to how it came to be the popular choice for container orchestration, you'll have a good understanding of what led to its success.
It’s important to understand the Kubernetes architecture foundations. From a high-level overview of its Master and Worker components, from Pods to Controllers that run them, we will start exploring the Kubernetes architecture.
After familiarizing ourselves with the architectural fundamentals of Kubernetes, it's now time to understand its core concepts. These are the foundational elements upon which we build, deploy, and manage our applications within Kubernetes
Kubernetes Installation Steps on Linux (Debian):
1. Install Docker
Let's update the packages first:
sudo apt-get update
And install the necessary packages:
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
Adding Docker's official GPG key to be able to install Docker:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Let's now add the stable repository of Docker:
echo "deb [arch=arm64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list
Now let's install Docker community edition:
sudo apt-get update && sudo apt-get install docker-ce
And finally, let's add our user to the Docker group so we can manage Docker as a non-root user:
sudo usermod -aG docker $USER && newgrp docker
2. Install Minikube
Download the binary suitable for your CPU architecture (ARM in this case):
wget https://storage.googleapis.com/minikube/releases/latest/minikube-linux-arm64
Make it executable and move:
chmod +x minikube-linux-arm64 && sudo mv minikube-linux-arm64 /usr/local/bin/minikube
Check your installation:
minikube version
This should display Minikube's version.
3. Installing Kubectl
Download the latest release for ARM64:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl"
Make it executable and move:
chmod +x kubectl && sudo mv kubectl /usr/local/bin/
Verify:
kubectl version
This should display kubectl's version.
4. Verifying the Installation
Starting Minikube:
minikube start
After a while, your cluster should be ready, you can then validate by running:
kubectl get nodes
This should return your minikube node.
If you have issues/questions regarding installation, feel free to go over to Q&A!
Kubernetes Installation Steps on MacOS:
1. Install Docker
Download and install the dmg for your Mac: https://docs.docker.com/desktop/install/mac-install/
2. Install Minikube
You can either use Homebrew:
brew install minikube
or run the commands provided in Minikube documentation:
https://minikube.sigs.k8s.io/docs/start/
3. Install Kubectl
There are various ways we can use `kubectl`. Minikube already comes with a builtin `kubectl` command we can use by running:
minikube kubectl
and rest of the command and arguments after that. Or the way I recommend is to install it using homebrew. This way, you can use `kubectl` for any Kubernetes cluster, not just the ones based on Minikube. The command we need is:
brew install kubectl
Verify the installation with `kubectl version` command:
kubectl version
4. Start Minikube and Verify
minikube start
This should create and start the cluster. You can verify by running a kubectl command:
kubectl get nodes
Kubernetes Installation Steps on Windows:
Easiest way to set Kubernetes up in Windows is by using Chocolatey package manager. You can install here if you don't have it already:
https://chocolatey.org/install
1. Install Docker
Install Docker using Chocolatey:
https://community.chocolatey.org/packages/docker-desktop
2. Install Minikube
Install Minikube using Chocolatey:
https://community.chocolatey.org/packages/Minikube
3. Install Kubectl
Install Kubectl using Chocolatey:
https://community.chocolatey.org/packages/kubernetes-cli
4. Start Minikube and Verify
Start Minikube using the following command:
minikube start
This should create and start the cluster. You can then verify by running a kubectl command:
kubectl get nodes
There's always more ways to install Kubernetes; be it locally on your machine or using a cloud provider, there's a Kubernetes flavor for every need. Let's explore the most popular options available.
Starting with this lecture, we'll get started on an important journey within the Kubernetes ecosystem—mastering the concept of Pods.
In Kubernetes, a Pod is the smallest deployable unit that you can create and manage. It can hold one or more closely related containers that are necessary for your main application to operate.
Code and the commands used in the lecture:
You can download my-first-pod.yaml form lecture resources and follow along the lecture.
Deploying the pod:
kubectl apply -f my-first-pod.yaml
Listing pods:
kubectl get pods
Describing the pod:
kubectl describe pod my-first-pod
Before we deeper into the world of Kubernetes, let’s make sure we understand an important concept; YAML manifests in Kubernetes.
In this lecture, we'll dive into one of the most powerful concepts in Kubernetes—Deployments.
Deployments are at the core of modern application management, enabling you to update and scale your applications with ease and resilience.
Code and commands used in the lecture:
You can download the nginx-deployment.yaml from resources.
Deploy the nginx deployment:
kubectl apply -f nginx-deployment.yaml
Check the rollout status of deployment:
kubectl rollout status deployment/nginx-deployment
Describe the deployment:
kubectl describe deployment/nginx-deployment
Updating and rolling back changes if necessary are important concepts to understand in Kubernetes. Let's see how deployments work with updates and rollbacks.
Commands used in the lecture:
Update an existing deployment with kubectl (set a new image):
kubectl set image deployment/nginx-deployment nginx-container=nginx:1.25.3
Describe the deployment to verify changes:
kubectl describe deployment/nginx-deployment
Rollback a deployment to the previous:
kubectl rollout undo deployment/nginx-deployment
Applications and services are usually designed to interact with other applications and services.
In this lecture, we will learn how to expose applications inside the cluster to other applications.
Code and commands used in the lecture:
You can download nginx-clusterip.yaml from resources.
Create the ClusterIP service for existing nginx deployment:
kubectl apply -f nginx-clusterip.yaml
Exposing services outside the cluster is a crucial part of service management in Kubernetes, especially when you're working with applications that need to be accessible from outside the cluster.
Now we will start looking into ways of exposing services outside the Kubernetes cluster and the first approach we will see is NodePort.
Code and commands used in the lecture:
You can download nginx-nodeport.yaml.zip from resources.
Deploy the NodePort service:
kubectl apply -f nginx-nodeport.yaml
Get the service:
kubectl get service nginx-nodeport
Get Minikube IP to access the service:
minikube ip
Now we're going to explore how to expose your services externally using the LoadBalancer service type in Kubernetes.
This is particularly relevant when you're working in a cloud environment, but today, we'll see how we can simulate this on a local Minikube cluster.
Commands used in the lecture:
Create an nginx deployment with kubectl:
kubectl create deployment nginx --image=nginx
Expose the deployment with LoadBalancer type:
kubectl expose deployment nginx --type=LoadBalancer --port=80
Get the URL for accessing the service with Minikube:
minikube service nginx --url
In this lecture, we're going to focus on path-based routing, a powerful feature that allows you to direct traffic to different services within your Kubernetes cluster based on the request path. This is an essential concept for managing web traffic, especially when you're running multiple web applications within the same cluster.
Code and commands used in the lecture:
You can download web-ingress.yaml from resources.
Enable Ingress add-on in Minikube:
minikube addons enable ingress
Confirm ingress controller is running:
kubectl get pods -n ingress-nginx
Deploy webapp1:
kubectl create deployment webapp1 --image=erdoganiyazi/webapp1:latest
Deploy webapp2:
kubectl create deployment webapp2 --image=erdoganiyazi/webapp2:latest
Expose web applications:
kubectl expose deployment webapp1 --type=ClusterIP --port=8080
kubectl expose deployment webapp2 --type=ClusterIP --port=8080
Create ingress resource with web-ingress,yaml:
kubectl apply -f web-ingress.yaml
Get the ingress:
kubectl get ingress
Grab the ingress address and open up a browser to access both webapps at:
INGRESS_ADDRESS/webapp1
INGRESS_ADDRESS/webapp2
ConfigMaps are a key feature in Kubernetes that allow you to manage configuration data separately from your application code.
By the end of this lecture, you'll understand what ConfigMaps are, how to create and use them, and some of the best practices
Code and commands used in the lecture:
You can download app.properties and app-configmap.yaml from resources (5.1-source_code.zip).
Create configmap from app.properties file:
kubectl create configmap app-config --from-file=app.properties
Describe the configmap:
kubectl describe configmap/app-config
Create a configmap from YAML manifest:
kubectl apply -f app-configmap.yaml
In this lecture, we're going to dive into the world of Kubernetes Secrets.
Secrets are essential for securely managing sensitive data such as passwords, tokens, and keys within your Kubernetes environment.
Code and commands used in the lecture:
You can download app-with-db-secret.yaml from resources.
Create a database password secret from literal:
kubectl create secret generic db-secret --from-literal=password='myDbPassword123!'
Create a Pod that uses the secret:
kubectl apply -f app-with-db-secret.yaml
Create an API key secret from literal:
kubectl create secret generic api-key-secret --from-literal=api_key='12345-my-api-key-67890'
Create a Pod that uses the secret:
kubectl apply -f pod-with-api-secret.yaml
Kubectl is the command-line interface for Kubernetes.
Kubectl is essential for interacting with your Kubernetes cluster and managing its resources. We’ve been using kubectl along the way so far in our previous lectures and now, we'll cover some of the basics, some advanced commands, and best practices to help you become proficient with kubectl.
Code and commands used in the lecture:
You can download nginx-deployment.yaml from resources.
Browse your local Kubeconfig file:
cat ~/.kube/config
Get pods with kubectl:
kubectl get pods
Get and watch pods interactively with kubectl:
kubectl get pods --watch
Describe a pod with kubectl:
kubectl describe pod <pod-name>
Get the logs of a pod with kubectl:
kubectl logs <pod-name>
or follow them with -f flag:
kubectl logs -f <pod-name>
Execute a command in a pod or run an interactive shell:
kubectl exec -it <pod-name> -- /bin/bash
Deploy nginx-deployment.yaml:
kubectl apply -f nginx-deployment.yaml
Delete the deployment:
kubectl delete -f nginx-deployment.yaml
Delete a pod:
kubectl delete pod <pod-name>
Create a pod directly with kubectl:
kubectl run nginx --image=nginx
Use port-forwarding to access a service:
kubectl port-forward pod/<pod-name> 8080:80
Copy files to a pod:
kubectl cp <local-file> <pod-name>:/path/in/pod
Copy files from a pod:
kubectl cp <pod-name>:/path/in/pod <local-file>
Create an alias as "k" for kubectl:
alias k=kubectl
Run commands with the alias:
k get pods
Enable auto-completion for kubectl commands:
source <(kubectl completion bash)
Switch between different cluster context using kubectl:
kubectl config use-context my-cluster-context
Helm is the package manager for Kubernetes.
Helm simplifies the process of defining, installing, and upgrading even the most complex Kubernetes applications. In this lecture, we'll explore what Helm is, how to use it, and I'll walk you through some hands-on examples.
Code and commands used in the lecture:
You can download my-nginx-values.yaml from resources.
Get GPG key for Helm on Debian:
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
Install necessary packages:
sudo apt-get install apt-transport-https --yes
Add Helm repository to Debian package sources list:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
Update packages:
sudo apt-get update
Install Helm:
sudo apt-get install helm
Verify Helm installation with help command:
helm help
Add a chart repository for Helm:
helm repo add stable https://charts.helm.sh/stable
Update repository index for Helm:
helm repo update
Search for a Helm chart:
helm search repo nginx
Install a Helm chart from a repository:
helm install nginx-ingress stable/nginx-ingress
Uninstall a Helm chart:
helm uninstall nginx-ingress
Install a Helm chart with custom values from a YAML manifest:
helm install nginx-ingress stable/nginx-ingress -f my-nginx-values.yaml
Rollback a Helm release:
helm rollback nginx-ingress 1
Create your own Helm chart:
helm create my-chart
Kustomize introduces a new approach to customizing Kubernetes resources.
It's a tool that lets you create an entire setup based on Kubernetes manifests without altering the original configuration files. In this lecture, we'll explore how to use Kustomize to manage your Kubernetes resources effectively.
Code and commands used in the lecture:
You can download the kustomize-example.zip from resources.
Download kustomize binary with curl:
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
Move kustomize binary to an appropriate directory:
mv kustomize /usr/local/bin/
Confirm kustomize installation:
kustomize version
After downloading and extracting the source, follow along below:
Build kustomizations from the base directory:
kustomize build kustomize-example/base/
Build apply the kustomization with piping to kubectl:
kustomize build kustomize-example/base/ | kubectl apply -f -
Check the deployments after apply:
kubectl get deployment/nginx-deployment
Build development overlay kustomizations:
kustomize build kustomize-example/overlays/development/
Build apply the development overlay kustomizations with piping to kubectl:
kustomize build kustomize-example/overlays/development | kubectl apply -f -
Get deployments again to confirm 2 replicas:
kubectl get deployment/nginx-deployment
GitOps or git-based operations concepts have been very popular in recent years. Chances are that you might have heard FluxCD.
In this lecture, we will see a great tool to manage and automate Kubernetes deployments, and that is Flux CD. We will take advantage of FluxCD to see how we can manage our manifests that are in a git repository, and see how easy it is to configure and set up a GitOps-driven workflow that leverages the combined power of Flux CD and Helm for streamlined application deployment.
Code and commands used in the lecture:
You can download fluxcd-example-demo.zip from resources.
To configure Github with FluxCD, create a personal access token as shown in the video or by following the below guide:
https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic
Export your Github credentials:
export GITHUB_TOKEN=YOUR_GITHUB_TOKEN
export GITHUB_USER=YOUR_GITHUB_USER
Install FluxCD:
curl -s https://fluxcd.io/install.sh | sudo bash
Bootstrap the cluster with FluxCD:
flux bootstrap github \
--owner="${GITHUB_USER}" \
--repository=fluxcd-example-demo \
--branch=main \
--path=./clusters/my-cluster \
--personal \
--token-auth \
--token="${GITHUB_TOKEN}"
Clone your Git repository:
git clone git@github.com:YOUR_GITHUB_USER/fluxcd-example-demo.git
Change directory to clusters/my-clusters directory:
cd fluxcd-example-demo/clusters/my-cluster/flux-system/
Create a Helm repository using the manifest from source code:
Add helm-repository.yaml to fluxcd-example-demo/clusters/my-cluster/flux-system/ directory
Create an nginx Helm release using the manifest from source code:
Add nginx-helmrelease.yaml to fluxcd-example-demo/clusters/my-cluster/flux-system/ directory
Edit the kustomization.yaml file to add the new Helm repository and release:
vi clusters/my-cluster/flux-system/kustomization.yaml
kustomization.yaml after changes:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gotk-components.yaml
- gotk-sync.yaml
- helm-repository.yaml
- nginx-helmrelease.yaml
Commit and push your changes to Github remote repository:
git add .
git commit -m "Add Flux configuration for Bitnami Helm repository and Nginx Helm release"
git push origin main
Watch your FluxCD resources come alive in the cluster:
flux get sources helm --watch
flux get helmreleases --watch
Check the nginx deployment:
kubectl get deployments -n flux-system
ArgoCD is a tool that embodies the principles of GitOps to manage Kubernetes deployments. In principle, it's similar to FluxCD in many ways but offers some extra features such as a nice user interface for managing GitOps repositories, applications, deployments and more.
In this lecture, we'll explore how Argo CD can streamline your deployment process, ensuring that your cluster state matches the configuration stored in your Git repositories.
Commands used in the lecture:
You can download guestbook-application.yaml.zip from resources.
Create a namespace for ArgoCD:
kubectl create namespace argocd
Install ArgoCD with its manifest:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Watch ArgoCD deployments progressing:
kubectl get deployments -n argocd -w
Once deployments are ready, read the ArgoCD UI default password:
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d; echo
Port-forward to argocd-server to access ArgoCD UI:
kubectl port-forward svc/argocd-server -n argocd 8080:443
Note: You can use admin as the user while logging in.
Create a namespace for guestbook-application:
kubectl create namespace guestbook
Deploy guestbook-application:
kubectl apply -f guestbook-application.yaml
In this section overall and lecture, we're going to explore two fundamental concepts that are essential for securing your Kubernetes cluster: Namespaces and Role-Based Access Control, or RBAC.
By the end of this lecture, you'll understand how these features work individually and in tandem to enhance your cluster's security.
In this lecture, we're going to dive deeper into Namespaces and explore how they enable multi-tenancy in Kubernetes.
By the end of this lecture, you'll understand how to use Namespaces to create isolated environments for different teams or projects.
Commands used in the lecture:
Namespaces
Get all namespaces
kubectl get namespaces
Get all pods in a given namespace:
kubectl get pods --namespace flux-system
Or use the shorter form instead:
kubectl get pods -n flux-system
You can also use --all-namespaces flag on any resource:
kubectl get pods --all-namespaces
Create a new namespace:
kubectl create namespace dev
Or create with yaml manifest:
vi prod-namespace.yaml
Add the manifest for namespace:
apiVersion: v1
kind: Namespace
metadata:
name: prod
Delete a namespace:
kubectl delete namespace dev
Resource Quotas
Create a new namespace:
kubectl create namespace quota-demo
Create a resource quota:
vi resourcequota.yaml
Add manifest:
apiVersion: v1
kind: ResourceQuota
metadata:
name: quota-demo-quota
namespace: quota-demo
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
Finally create it:
kubectl apply -f resourcequota.yaml
Describe the quota:
kubectl describe resourcequota quota-demo-quota --namespace quota-demo
Test the quota:
vi high-cpu-pod.yaml
Add manifest:
apiVersion: v1
kind: Pod
metadata:
name: high-cpu-pod
namespace: quota-demo
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
memory: "500Mi"
cpu: "1500m"
limits:
memory: "1Gi"
cpu: "2"
Apply it:
kubectl apply -f high-cpu-pod.yaml
Note: Once you apply, you should receive and error as expected with resource quota.
In our previous lectures, we've laid the groundwork by exploring Namespaces and Multi-Tenancy.
Now, we're going to merge two critical concepts into one comprehensive lecture: Roles and RoleBindings.
These are the building blocks of access control in Kubernetes, and by the end of this session, you'll know how to create and manage them to secure your cluster effectively.
Code and commands used in the lecture:
You can download the 7.3-source_code.zip from resources
Create a role with manifest:
kubectl apply -f role.yaml
Create the role binding with manifest:
kubectl apply -f role-binding.yaml
Building on our understanding of Roles and RoleBindings, now we're going to elevate our discussion to the cluster level with ClusterRoles and ClusterRoleBindings.
These are key components in Kubernetes RBAC for granting permissions across the entire cluster.
By the end of this lecture, you'll know when and how to use these tools effectively.
Code and commands used in the lecture:
You can download 7.4-source_code.zip from resources.
Create a cluster role with manifest:
kubectl apply -f cluster-role.yaml
Create a cluster role binding with manifest:
kubectl apply -f cluster-role-binding.yaml
In this lecture, we’re going to dive into the world of Service Accounts, User Access, and Authentication in Kubernetes, with a focus on Role-Based Access Control or RBAC.
I want to give you practical insights into managing access and permissions within your Kubernetes clusters.
Code and commands used in the lecture:
You can download 7.5-source_code.zip from resources.
Create a service account with manifest:
kubectl apply -f example-service-account.yaml
Now, let’s verify that our Service Account has been created:
kubectl get serviceaccounts
Create a role with manifest to read pods (get, list, watch):
kubectl apply -f role-pod-reader.yaml
Create the role binding with manifest:
kubectl apply -f rolebinding-read-pods.yaml
Create a pod with manifest to use the service account:
kubectl apply -f access-test-pod.yaml
Describe the pod to check if service account volume is mounted:
kubectl describe pod/access-test-pod
Execute into the pod shell:
kubectl exec -it access-test-pod -- /bin/bash
Read the service account token inside pod:
cat /var/run/secrets/kubernetes.io/serviceaccount/token
Run a kubectl command inside pod to verify:
kubectl get pods
Create a service account token directly with kubectl:
kubectl create token example-service-account
With our previous lecture on Service Accounts, we now know how we can access Kubernetes API using a Pod or essentially a deployment in Kubernetes.
With service accounts, we can obtain programmatic access to Kubernetes API for our applications and services.
How about when we want to connect to Kubernetes as a user? How do we authenticate? Let's take a look at that.
When it comes to user authentication, Kubernetes relies on external sources, as it doesn't manage user accounts natively.
When we look at user access and authentication, we have to look at how cloud providers like AWS, Azure and GCP does it, as these are most popular Kubernetes providers in the cloud.
In this lecture, we will take a look at how AWS, Azure and GCP handles authentication with Kubernetes.
Networking in Kubernetes is important to understand and we'll explore how to deny or allow traffic between specific pods and services.
At it's core, networking is possible within Kubernetes by a concept called Container Network Interfaces or CNI for short.
Code and commands used in the lecture:
You can download 7.8-source_code.zip from resources.
Stop, delete and recreate your Minikube cluster with Calico CNI:
minikube stop
minikube delete
minikube start --network-plugin=cni --cni=calico
Create a deny-all policy with manifest to deny all traffic between pods:
kubectl apply -f deny-all-policy.yaml
Create a backend deployment with manifest:
kubectl apply -f backend-deployment.yaml
Create a frontend deployment with manifest:
kubectl apply -f frontend-deployment.yaml
Confirm deployments are ready:
kubectl get deployments
Get the IP address of backend pods:
kubectl get pods -l app=backend -o wide
Execute into frontend pod:
kubectl exec -it $(kubectl get pods -l app=frontend -o jsonpath='{.items[0].metadata.name}') -- /bin/sh
Try to access backend (will fail):
wget -qO- <backend-pod-ip> -T 5
Create a network policy with manifest to allow traffic from frontend to backend:
kubectl apply -f network-policy.yaml
Execute into frontend pod again and verify you can access backend this time:
kubectl exec -it $(kubectl get pods -l app=frontend -o jsonpath='{.items[0].metadata.name}') -- /bin/sh
wget -qO- <backend-pod-ip> -T 5
Thank you for taking the time to take this course with me! Let's wrap up the course by going over the topics we've covered in this course and what comes next.
Welcome to "Hands-on Kubernetes: Mastering the Fundamentals," your personal guide to the vast and vibrant world of Kubernetes!
This course is tailor-made to walk you through the essentials of managing and deploying applications using one of today's most influential tools, all presented in a friendly and approachable manner.
Starting from the very beginning, I'll help you understand what Kubernetes is and why it's a game-changer for developers and system administrators. You'll get familiar with its architecture and the key components that power Kubernetes. Whether you're using Linux, MacOS, or Windows, I've prepared step-by-step instructions for setting up Kubernetes with Minikube and Kubectl, ensuring you're equipped to tackle any environment.
But we won't just stop at the basics. I'll guide you through deploying your first application, teaching you how to use YAML manifests to define your app's needs clearly and concisely. Learn how to scale your applications effortlessly, preparing them to handle growing traffic with ease.
Then, I'll show you how to make your applications available to your team or the whole world, using different methods to manage access both internally and externally. Through straightforward explanations and hands-on examples, you'll become proficient in networking, managing external access, and ensuring your services are reachable whenever needed.
Configuring your apps and keeping their secrets safe is crucial. I'll walk you through managing application settings and protecting sensitive information with configuration and secrets management, all without overwhelming you with complex terminology.
Kubernetes isn't just a standalone tool; it's part of a larger ecosystem. You'll discover how tools like Helm can simplify adding features to your applications, and how GitOps practices with FluxCD and ArgoCD can make application deployment and updates straightforward and secure.
Security is paramount, and I'll take you through setting up role-based access control (RBAC), securing your applications, and ensuring your network is fortified against threats, all explained in a friendly, understandable way.
By the end of this course, you'll have a solid understanding of Kubernetes, capable of deploying, managing, and securing your applications confidently. Whether you're beginning your journey or looking to enhance your existing skills, I'm here to lead you through each step with clarity and a touch of fun, making this comprehensive journey into Kubernetes as enjoyable as it is informative!
Looking forward to seeing you in the course!