Note: This document outlines a comprehensive 30-section learning path for Kubernetes, focusing on commands and practical usage. Each section introduces a new concept or command, building on the previous ones. By the end of this journey, you'll be well-versed in Kubernetes and ready to tackle advanced projects.
What is Kubernetes?
Kubernetes is an open-source platform for automating the deployment, scaling, and management of containerized applications. It groups containers that make up an application into logical units for easy management and discovery.
+-------------------+
| Master Node |
|-------------------|
| API Server |
| Scheduler |
| Controller Manager|
| etcd |
+-------------------+
+-------------------+ +-------------------+
| Worker Node 1 | | Worker Node 2 |
|-------------------| |-------------------|
| kubelet | | kubelet |
| kube-proxy | | kube-proxy |
| Container runtime | | Container runtime |
|-------------------| |-------------------|
| +-------------+ | | +-------------+ |
| | Pod 1 | | | | Pod 2 | |
| | +---------+ | | | | +---------+ | |
| | |Container| | | | | |Container| | |
| | +---------+ | | | | +---------+ | |
| +-------------+ | | +-------------+ |
+-------------------+ +-------------------+
+-------------------+
| Service |
|-------------------|
| Connects to Pods |
+-------------------+
How to set up Kubernetes on Docker Desktop?
- Install Docker Desktop: Download and install Docker Desktop from the official website.
- Enable Kubernetes: Go to Docker Desktop settings, navigate to the Kubernetes tab, and check the "Enable Kubernetes" option.
- Verify Installation: Open a terminal and run the following command to verify the installation:
$ kubectl version
What are the main components of Kubernetes?
Kubernetes architecture includes:
- Master Node: Manages the cluster and includes components like API Server, Scheduler, Controller Manager, and etcd.
- Worker Nodes: Run the containerized applications and include components like kubelet, kube-proxy, and container runtime.
How to interact with Kubernetes using kubectl?
kubectl
is the command-line tool used to interact with Kubernetes clusters. Here are some basic commands:
-
List Nodes:
kubectl get nodes
- Example:
$ kubectl get nodes NAME STATUS ROLES AGE VERSION node-1 Ready <none> 7d v1.21.3 node-2 Ready <none> 7d v1.21.3
- Example:
-
List Pods:
kubectl get pods
- Example:
$ kubectl get pods NAME READY STATUS RESTARTS AGE mypod 1/1 Running 0 1h
- Example:
-
Describe Node:
kubectl describe node <node-name>
- Example:
$ kubectl describe node node-1
- Example:
How to create a local Kubernetes cluster with Minikube?
Minikube is a tool that lets you run Kubernetes locally. Here are the steps to create a cluster:
- Install Minikube: Follow the installation instructions for your operating system from the Minikube documentation.
- Start a Cluster: Use the
minikube start
command to start a local Kubernetes cluster.- Example:
$ minikube start
- Example:
- Verify the Cluster: Check the status of the cluster with
kubectl
.- Example:
$ kubectl get nodes NAME STATUS ROLES AGE VERSION minikube Ready master 1m v1.21.3
- Example:
How to deploy a simple application?
Deploying an application in Kubernetes involves creating a deployment and exposing it as a service:
-
Create a Deployment: Use
kubectl create deployment
to create a deployment.- Example:
$ kubectl create deployment nginx --image=nginx
- Example:
-
Expose the Deployment: Use
kubectl expose deployment
to expose the deployment as a service.- Example:
$ kubectl expose deployment nginx --port=80 --type=NodePort
- Example:
-
Verify the Deployment: Check the status of the deployment and service.
- Example:
$ kubectl get deployments $ kubectl get services
- Example:
What is a Pod?
A Pod is the smallest deployable unit in Kubernetes, representing a single instance of a running process in your cluster. Pods can contain one or more containers, which share the same network namespace and storage.
How to manage Pods?
Pods are the smallest deployable units in Kubernetes. Here are some commands to manage them:
-
Create a Pod: Use
kubectl run
to create a pod.- Example:
$ kubectl run mypod --image=nginx
- Example:
-
Delete a Pod: Use
kubectl delete pod
to delete a pod.- Example:
$ kubectl delete pod mypod
- Example:
-
Get Pod Details: Use
kubectl describe pod
to get detailed information about a pod.- Example:
$ kubectl describe pod mypod
- Example:
What are Namespaces?
Namespaces are a way to divide cluster resources between multiple users. They provide a mechanism for isolating groups of resources within a single cluster.
How to create and use Namespaces?
-
Create a Namespace: Use
kubectl create namespace
.- Example:
$ kubectl create namespace mynamespace
- Example:
-
Use a Namespace: Set the current namespace for
kubectl
commands.- Example:
$ kubectl config set-context --current --namespace=mynamespace
- Example:
What is a Deployment?
A Deployment provides declarative updates to applications, managing ReplicaSets to ensure the desired number of Pods are running. It allows you to define the desired state of your application and Kubernetes will manage the rest.
How to create and manage Deployments?
Deployments manage the deployment and scaling of a set of Pods. Here are some commands:
-
Create a Deployment: Use
kubectl create deployment
.- Example:
$ kubectl create deployment myapp --image=myimage
- Example:
-
Scale a Deployment: Use
kubectl scale
to change the number of replicas.- Example:
$ kubectl scale deployment myapp --replicas=3
- Example:
-
Update a Deployment: Use
kubectl set image
to update the image of a deployment.- Example:
$ kubectl set image deployment/myapp myapp=myimage:v2
- Example:
What is a Service?
A Service is an abstraction that defines a logical set of Pods and a policy to access them. Services enable network access to a set of Pods.
How to create a Service?
Services expose your application to the network. Here are some commands:
-
Expose a Deployment: Use
kubectl expose deployment
.- Example:
$ kubectl expose deployment myapp --type=LoadBalancer --port=80
- Example:
-
Create a Service: Use
kubectl create service
.- Example:
$ kubectl create service clusterip myapp --tcp=5678:8080
- Example:
-
Get Service Details: Use
kubectl get services
to list services.- Example:
$ kubectl get services
- Example:
What are ConfigMaps and Secrets?
ConfigMaps and Secrets are used to manage configuration data and sensitive information, respectively. ConfigMaps store non-confidential data in key-value pairs, while Secrets store sensitive data.
How to create and use ConfigMaps and Secrets?
-
Create a ConfigMap: Use
kubectl create configmap
.- Example:
$ kubectl create configmap myconfig --from-literal=key1=value1
- Example:
-
Create a Secret: Use
kubectl create secret
.- Example:
$ kubectl create secret generic mysecret --from-literal=password=mysecretpassword
- Example:
-
Use in Pods: Reference ConfigMaps and Secrets in Pod specifications.
- Example:
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mycontainer image: nginx envFrom: - configMapRef: name: myconfig - secretRef: name: mysecret
- Example:
What is Persistent Storage in Kubernetes?
Persistent Volumes (PVs) and Persistent Volume Claims (PVCs) provide storage resources in a Kubernetes cluster. PVs are a piece of storage in the cluster that has been provisioned by an administrator, while PVCs are a request for storage by a user.
How to create and use Persistent Volumes?
-
Create a PV: Define a PV in a YAML file and apply it.
- Example:
apiVersion: v1 kind: PersistentVolume metadata: name: mypv spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce hostPath: path: /mnt/data
$ kubectl apply -f pv.yaml
- Example:
-
Create a PVC: Define a PVC in a YAML file and apply it.
- Example:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
$ kubectl apply -f pvc.yaml
- Example:
-
Use in Pods: Reference the PVC in Pod specifications.
- Example:
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mycontainer image: nginx volumeMounts: - mountPath: "/mnt/data" name: myvolume volumes: - name: myvolume persistentVolumeClaim: claimName: mypvc
- Example:
What is a StatefulSet?
StatefulSets manage the deployment and scaling of a set of Pods, providing guarantees about the ordering and uniqueness of these Pods. They are used for stateful applications that require stable, unique network identifiers and persistent storage.
How to create a StatefulSet?
- Create a StatefulSet: Define a StatefulSet in a YAML file and apply it.
- Example:
apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: "nginx" replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: k8s.gcr.io/nginx-slim:0.8 ports: - containerPort: 80 name: web volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi
$ kubectl apply -f statefulset.yaml
- Example:
What is an Ingress Controller?
An Ingress Controller manages external access to the services in a cluster, typically HTTP. It provides load balancing, SSL termination, and name-based virtual hosting.
How to set up an Ingress?
-
Create an Ingress Resource: Define an Ingress in a YAML file and apply it.
- Example:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress spec: rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: example-service port: number: 80
$ kubectl apply -f ingress.yaml
- Example:
-
Verify Ingress: Check the status of the Ingress.
- Example:
$ kubectl get ingress
- Example:
How to monitor and log in Kubernetes?
Monitoring and logging are essential for managing Kubernetes clusters. Tools like Prometheus and Fluentd are commonly used.
-
Install Prometheus: Use Helm to install Prometheus.
- Example:
$ helm install prometheus stable/prometheus
- Example:
-
Install Fluentd: Use Helm to install Fluentd.
- Example:
$ helm install fluentd stable/fluentd
- Example:
-
Check Metrics: Use
kubectl top
to check resource usage.- Example:
$ kubectl top nodes $ kubectl top pods
- Example:
What is Helm?
Helm is a package manager for Kubernetes, simplifying the deployment of applications. It uses charts, which are packages of pre-configured Kubernetes resources.
How to install and use Helm?
-
Install Helm: Follow the installation instructions from the Helm documentation.
-
Add a Repository: Add a Helm chart repository.
- Example:
$ helm repo add stable https://charts.helm.sh/stable
- Example:
-
Install a Chart: Use
helm install
to deploy an application.- Example:
$ helm install myapp stable/nginx
- Example:
-
List Releases: Use
helm list
to list installed releases.- Example:
$ helm list
- Example:
What is RBAC?
RBAC is a method of regulating access to resources based on the roles of individual users. It allows you to define roles and assign them to users or groups.
How to set up RBAC?
-
Create a Role: Define a Role in a YAML file and apply it.
- Example:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]
$ kubectl apply -f role.yaml
- Example:
-
Bind the Role: Define a RoleBinding in a YAML file and apply it.
- Example:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-pods namespace: default subjects: - kind: User name: jane apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io
$ kubectl apply -f rolebinding.yaml
- Example:
What is Autoscaling?
Autoscaling automatically adjusts the number of Pods in a deployment based on resource usage. Kubernetes supports Horizontal Pod Autoscaling (HPA) to scale the number of pods.
How to implement Autoscaling?
-
Enable Autoscaling: Use
kubectl autoscale
to set up autoscaling.- Example:
$ kubectl autoscale deployment myapp --cpu-percent=50 --min=1 --max=10
- Example:
-
Check Autoscaler: Use
kubectl get hpa
to check the status of the Horizontal Pod Autoscaler.- Example:
$ kubectl get hpa
- Example:
How to perform rolling updates and rollbacks?
-
Update a Deployment: Use
kubectl set image
to update the image of a deployment.- Example:
$ kubectl set image deployment/myapp myapp=myimage:v2
- Example:
-
Check Rollout Status: Use
kubectl rollout status
to check the status of the rollout.- Example:
$ kubectl rollout status deployment/myapp
- Example:
-
Rollback a Deployment: Use
kubectl rollout undo
to rollback to a previous version.- Example:
$ kubectl rollout undo deployment/myapp
- Example:
Citations: [1] https://blog.stackademic.com/blue-green-deployment-using-kubernetes-4fbd023a19c5?gi=36542b52b934 [2] https://dev.to/pavanbelagatti/kubernetes-deployments-rolling-vs-canary-vs-blue-green-4k9p [3] https://codefresh.io/learn/software-deployment/what-is-blue-green-deployment/ [4] https://kubernetes.io/blog/2018/04/30/zero-downtime-deployment-kubernetes-jenkins/ [5] https://semaphoreci.com/blog/continuous-blue-green-deployments-with-kubernetes [6] https://github.com/ianlewis/kubernetes-bluegreen-deployment-tutorial [7] https://www.youtube.com/watch?v=er0JTGnryZ4 [8] https://www.geeksforgeeks.org/what-is-kubernetes-blue-green-deployment/
# Kubernetes Final Projects
## Project 1: Blue-Green Deployment
**Objective**: Implement a blue-green deployment strategy to minimize downtime and reduce risk.
1. **Create a Namespace**:
```bash
$ kubectl create namespace blue-green-deployment
-
Create Blue Deployment: Deploy the initial version of the application.
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-blue namespace: blue-green-deployment labels: app: myapp version: blue spec: replicas: 2 selector: matchLabels: app: myapp version: blue template: metadata: labels: app: myapp version: blue spec: containers: - name: myapp image: myapp:v1 ports: - containerPort: 80
$ kubectl apply -f blue-deployment.yaml
-
Expose Blue Deployment: Expose the blue deployment as a service.
apiVersion: v1 kind: Service metadata: name: myapp-service namespace: blue-green-deployment spec: selector: app: myapp version: blue ports: - protocol: TCP port: 80 targetPort: 80
$ kubectl apply -f blue-service.yaml
-
Create Green Deployment: Deploy the new version of the application.
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-green namespace: blue-green-deployment labels: app: myapp version: green spec: replicas: 2 selector: matchLabels: app: myapp version: green template: metadata: labels: app: myapp version: green spec: containers: - name: myapp image: myapp:v2 ports: - containerPort: 80
$ kubectl apply -f green-deployment.yaml
-
Switch Traffic to Green Deployment: Update the service to point to the green deployment.
$ kubectl patch service myapp-service -n blue-green-deployment -p '{"spec":{"selector":{"app":"myapp","version":"green"}}}'
-
Verify Deployment: Ensure the service is now pointing to the green deployment.
$ kubectl get services -n blue-green-deployment $ kubectl get pods -n blue-green-deployment -l app=myapp,version=green
-
Clean Up: Optionally, delete the blue deployment if everything is working fine.
$ kubectl delete deployment myapp-blue -n blue-green-deployment
Objective: Deploy a small web application using Python and Flask.
-
Create a Flask Application:
-
app.py
:from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, World!' if __name__ == '__main__': app.run(host='0.0.0.0')
-
requirements.txt
:Flask==2.0.1
-
-
Create a Dockerfile:
FROM python:3.8-slim WORKDIR /app COPY requirements.txt requirements.txt RUN pip install -r requirements.txt COPY . . CMD ["python", "app.py"]
-
Build Docker Image:
$ docker build -t myflaskapp .
-
Push Docker Image to a Registry (Optional):
$ docker tag myflaskapp <your-dockerhub-username>/myflaskapp $ docker push <your-dockerhub-username>/myflaskapp
-
Create Kubernetes Deployment:
apiVersion: apps/v1 kind: Deployment metadata: name: myflaskapp spec: replicas: 2 selector: matchLabels: app: myflaskapp template: metadata: labels: app: myflaskapp spec: containers: - name: myflaskapp image: <your-dockerhub-username>/myflaskapp ports: - containerPort: 80
$ kubectl apply -f flask-deployment.yaml
-
Expose Deployment:
apiVersion: v1 kind: Service metadata: name: myflaskapp-service spec: selector: app: myflaskapp ports: - protocol: TCP port: 80 targetPort: 80 type: LoadBalancer
$ kubectl apply -f flask-service.yaml
-
Verify Deployment:
$ kubectl get services $ kubectl get pods
Objective: Deploy a large application with multiple containers, including a monitoring container to monitor the cluster.
-
Create Dockerfiles for Each Service:
-
Example for a web service (Node.js):
FROM node:14 WORKDIR /app COPY package*.json ./ RUN npm install COPY . . CMD ["node", "web.js"]
-
Example for a database service (MySQL):
FROM mysql:5.7 ENV MYSQL_ROOT_PASSWORD=rootpassword ENV MYSQL_DATABASE=mydatabase
-
Example for a monitoring service (Prometheus):
FROM prom/prometheus COPY prometheus.yml /etc/prometheus/
-
-
Build Docker Images:
$ docker build -t mywebapp -f Dockerfile.web . $ docker build -t mydb -f Dockerfile.db . $ docker build -t mymonitoring -f Dockerfile.monitoring .
-
Push Docker Images to a Registry (Optional):
$ docker tag mywebapp <your-dockerhub-username>/mywebapp $ docker tag mydb <your-dockerhub-username>/mydb $ docker tag mymonitoring <your-dockerhub-username>/mymonitoring $ docker push <your-dockerhub-username>/mywebapp $ docker push <your-dockerhub-username>/mydb $ docker push <your-dockerhub-username>/mymonitoring
-
Create Kubernetes Deployments:
apiVersion: apps/v1 kind: Deployment metadata: name: webapp spec: replicas: 2 selector: matchLabels: app: webapp template: metadata: labels: app: webapp spec: containers: - name: webapp image: <your-dockerhub-username>/mywebapp ports: - containerPort: 80
$ kubectl apply -f webapp-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: db spec: replicas: 1 selector: matchLabels: app: db template: metadata: labels: app: db spec: containers: - name: db image: <your-dockerhub-username>/mydb ports: - containerPort: 3306
$ kubectl apply -f db-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: monitoring spec: replicas: 1 selector: matchLabels: app: monitoring template: metadata: labels: app: monitoring spec: containers: - name: prometheus image: <your-dockerhub-username>/mymonitoring volumeMounts: - name: config-volume mountPath: /etc/prometheus volumes: - name: config-volume configMap: name: prometheus-config
$ kubectl apply -f monitoring-deployment.yaml
-
Expose Services:
apiVersion: v1 kind: Service metadata: name: webapp-service spec: selector: app: webapp ports: - protocol: TCP port: 80 targetPort: 80 type: LoadBalancer
$ kubectl apply -f webapp-service.yaml
apiVersion: v1 kind: Service metadata: name: db-service spec: selector: app: db ports: - protocol: TCP port: 3306 targetPort: 3306
$ kubectl apply -f db-service.yaml
apiVersion: v1 kind: Service metadata: name: monitoring-service spec: selector: app: monitoring ports: - protocol: TCP port: 9090 targetPort: 9090 type: LoadBalancer
$ kubectl apply -f monitoring-service.yaml
-
Verify Deployments:
$ kubectl get services $ kubectl get pods
-
Create a ConfigMap for Prometheus:
apiVersion: v1 kind: ConfigMap metadata: name: prometheus-config data: prometheus.yml: | global: scrape_interval: 15s scrape_configs: - job_name: 'kubernetes' kubernetes_sd_configs: - role: pod
$ kubectl apply -f prometheus-config.yaml
-
Update Monitoring Deployment to Use ConfigMap:
apiVersion: apps/v1 kind: Deployment metadata: name: monitoring spec: replicas: 1 selector: matchLabels: app: monitoring template: metadata: labels: app: monitoring spec: containers: - name: prometheus image: prom/prometheus volumeMounts: - name: config-volume mountPath: /etc/prometheus volumes: - name: config-volume configMap: name: prometheus-config
$ kubectl apply -f monitoring-deployment.yaml
Share whats on your mind: pooyan.azadparvar@gmail.com