├── Domain 1 - Core Concepts ├── Readme.md ├── Readme.old.md ├── basic-pods.md ├── cli-doc.md ├── cmd-args-clarity.md ├── cmd-args-overview.md ├── cmd-args-practical.md ├── cmd-args.md ├── expose-pods.md ├── install-kubectl.md ├── kubectl-to-k8s.md ├── manifest-structure.md ├── minikube-install.md ├── multi-container-pod.md ├── pod-manifest-cli.md └── pod-manifest.md ├── Domain 2 - Application Design and Build ├── Readme.md ├── activeDeadlineSeconds.md ├── cronjob.md ├── daemonset.md ├── deployment.md ├── imp-dep-commands.md ├── jobs-backofflimit.md ├── jobs-history-limit.md ├── jobs.md ├── labels.md ├── maxSurge-maxUnavailable.md ├── replicaset.md ├── rs-challenges.md └── service-manifest-cli.md ├── Domain 3 - Services and Networking ├── Readme.md ├── cluster-ip.md ├── first-helm-chart.md ├── helm-practical.md ├── ingress-controller.md ├── ingress.md ├── install-helm.md ├── loadbalancer.md ├── namespace.md ├── netpol-01.md ├── netpol-02.md ├── netpol-practical.md ├── netpol-structure.md ├── nodeport.md ├── nodeport.yaml ├── sa-pointers.md ├── sa-practical.md ├── service-account.md ├── service-endpoints.md ├── service-manifest-cli.md └── service-selector.md ├── Domain 4 - Configuration ├── Readme.md ├── limit-ranges.md ├── mounting-secrets.md ├── pod-env-variables.md ├── pod-phases.md ├── requests-limits.md ├── resource-quota.md ├── restartPolicy.md └── secret-data.md ├── Domain 5 - Application Observability and Maintenance ├── Readme.md ├── events.md ├── field-selector.md ├── install-metric-server.md ├── livenessprobe.yaml └── readinessprobe.yaml ├── Domain 6 - State Persistence ├── Readme.md ├── configmap-01.md ├── configmap-02.md ├── emptydir.md ├── hostPath.md ├── pod-configmap.yaml ├── pod-securitycontext.yaml ├── pod-volume.yaml ├── privileged-pod.md ├── pv-pvc.md ├── pvandpvc.md └── security-context.md ├── Domain 7 - Multi-Container PODS ├── Readme.md ├── adapter.yaml ├── ambassador.yaml └── init-containers.md ├── Domain 8 - New Exam Updates ├── Readme.md ├── blue-green.md ├── crds.md ├── exercise-canary.md ├── role-rolebinding.md └── user-rbac.md ├── README.md └── practice-tests ├── Readme.md ├── cronjob.md ├── dep-upgrade.md ├── exercise-canary.md ├── limit-ranges.md ├── probes.md ├── request-limits.md ├── sa.yaml ├── secrets.md ├── security-context.md ├── surge.md └── troubleshoot-01.md /Domain 1 - Core Concepts/Readme.md: -------------------------------------------------------------------------------- 1 | # Domain - Core Concepts 2 | 3 | The code mentioned in this document are used in the Certified Kubernetes Application Developer 2025 course. 4 | 5 | https://www.udemy.com/course/certified-kubernetes-administrator/?referralCode=700DA06BF8A30E27AC7E 6 | 7 | # Video-Document Mapper 8 | 9 | 10 | | Sr No | Document Link | 11 | | ------ | ------ | 12 | | 1 | [Installing Kubectl][PlDa] | 13 | | 2 | [Connecting kubectl to Kubernetes Cluster][PlDb] | 14 | | 3 | [Configuring Kubernetes Using Minikube][PlDc] | 15 | | 4 | [Basics of Pods][PlDd] | 16 | | 5 | [Multiple Ways to Create Kubernetes Objects][PlDe] | 17 | | 6 | [Basic Structure of a Manifest File][PlDf] | 18 | | 7 | [Generating Manifest File through CLI Command][PlDg] | 19 | | 8 | [Creating Multi-Container Pods][PlDh] | 20 | | 8 | [Overview of Command And Arguments][PlDi] | 21 | | 8 | [Practical - Commands and Arguments][PlDj] | 22 | | 8 | [More Clarity - Command and Arguments][PlDk] | 23 | | 9 | [CLI Documentation of Kubernetes Resources][PlDl] | 24 | | 10 | [Exposing Ports for PODS][PlDm] | 25 | 26 | [PlDa]: <./install-kubectl.md> 27 | [PlDb]: <./kubectl-to-k8s.md> 28 | [PlDc]: <./minikube-install.md> 29 | [PlDd]: <./basic-pods.md> 30 | [PlDe]: <./pod-manifest.md> 31 | [PlDf]: <./manifest-structure.md> 32 | [PlDg]: <./pod-manifest-cli.md> 33 | [PlDh]: <./multi-container-pod.md> 34 | [PlDi]: <./cmd-args-overview.md> 35 | [PlDj]: <./cmd-args-practical.md> 36 | [PlDk]: <./cmd-args-clarity.md> 37 | [PlDl]: <./cli-doc.md> 38 | [PlDm]: <./expose-pods.md> 39 | -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/Readme.old.md: -------------------------------------------------------------------------------- 1 | # Domain 1 - Core Concepts 2 | 3 | The code mentioned in this document are used in the Certified Kubernetes Administrator 2022 course. 4 | 5 | https://www.udemy.com/course/mastering-certified-kubernetes-application-developer/?referralCode=3A549BA24AC8ED6597DF 6 | 7 | 8 | # Video-Document Mapper 9 | 10 | | Sr No | Document Link | 11 | | ------ | ------ | 12 | | 1 | [Installing & Configuring kubectl for Linux][PlDa] | 13 | | 2 | [Configuring Kubernetes in Minikube in Windows][PlDb] | 14 | | 3 | [Configuring Kubernetes in Minikube in Linux][PlDc] 15 | | 4 | [Understanding PODS][PlDd] | 16 | | 5 | [Creating First POD Configuration in YAML][PlDe] | 17 | | 6 | [Understanding Commands and Arguments in Kubernetes][PlDf] | 18 | | 7 | [Exposing Ports for PODS][PlDg] | 19 | | 8 | [Generating Pod Manifests via CLI][PlDh] | 20 | 21 | [PlDa]: <./install-kubectl.md> 22 | [PlDb]: <./minikube-install-linux.md> 23 | [PlDc]: <./minikube-install-windows.md> 24 | [PlDd]: <./basic-pods.md> 25 | [PlDe]: <./first-pod-yaml.md> 26 | [PlDf]: <./cmd-args.md> 27 | [PlDg]: <./expose-pods.md> 28 | [PlDh]: <./pod-manifest-cli.md> -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/basic-pods.md: -------------------------------------------------------------------------------- 1 | 2 | #### Create a new POD from Nginx Image 3 | ```sh 4 | kubectl run nginx --image=nginx 5 | ``` 6 | 7 | #### List the PODS that are currently running. 8 | ```sh 9 | kubectl get pods 10 | ``` 11 | #### View Logs of a Specific Pod 12 | ```sh 13 | kubectl logs nginx 14 | ``` 15 | 16 | #### Describe Pod Information in Detail 17 | ```sh 18 | kubectl describe pod nginx 19 | ``` 20 | #### Connect inside the POD 21 | ```sh 22 | kubectl exec -it nginx -- bash 23 | ``` 24 | 25 | #### Delete the POD 26 | ```sh 27 | kubectl delete pod nginx 28 | ``` 29 | 30 | #### View Node Information 31 | ```sh 32 | kubectl get nodes 33 | 34 | kubectl describe node 35 | ``` 36 | 37 | #### Create 2 Pods as shown in video 38 | 39 | ```sh 40 | kubectl run nginx-01 --image=nginx 41 | kubectl run nginx-02 --image=nginx 42 | ``` 43 | 44 | #### View Pods with Output of Wide 45 | ```sh 46 | kubectl get pods -o wide 47 | ``` 48 | 49 | #### Delete the Pods Created 50 | ```sh 51 | kubectl delete pod nginx-01 52 | kubectl delete pod nginx-02 53 | ``` -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/cli-doc.md: -------------------------------------------------------------------------------- 1 | 2 | ### API Documentation Referenced in the Video: 3 | 4 | https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/ 5 | 6 | ### CLI Commands 7 | ```sh 8 | kubectl explain pod 9 | kubectl explain pod.spec 10 | kubectl explain pod.spec.containers 11 | ``` 12 | -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/cmd-args-clarity.md: -------------------------------------------------------------------------------- 1 | 2 | ### Base File Used in the Video 3 | ```sh 4 | apiVersion: v1 5 | kind: Pod 6 | metadata: 7 | name: new-ping-pod 8 | spec: 9 | containers: 10 | - name: ping-container 11 | image: busybox:latest 12 | command: ["ping"] 13 | args: ["-c","60","google.com"] 14 | ``` 15 | 16 | ### Example 1 - Using Only Command without Args (cmd-clarity.yaml) 17 | ```sh 18 | apiVersion: v1 19 | kind: Pod 20 | metadata: 21 | name: new-ping-pod 22 | spec: 23 | containers: 24 | - name: ping-container 25 | image: busybox:latest 26 | command: ["ping","-c","60","google.com"] 27 | args: [] 28 | ``` 29 | ```sh 30 | kubectl apply -f cmd-clarity.yaml 31 | kubectl get pods 32 | kubectl logs new-ping-pod 33 | kubectl delete pod new-ping-pod 34 | ``` 35 | ### Example 2 - Specifying Command in a List Format 36 | ```sh 37 | apiVersion: v1 38 | kind: Pod 39 | metadata: 40 | name: new-ping-pod 41 | spec: 42 | containers: 43 | - name: ping-container 44 | image: busybox:latest 45 | command: 46 | - "ping" 47 | - "-c" 48 | - "60" 49 | - "google.com" 50 | ``` 51 | ```sh 52 | kubectl apply -f cmd-clarity.yaml 53 | kubectl get pods 54 | kubectl logs new-ping-pod 55 | kubectl delete pod new-ping-pod 56 | ``` -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/cmd-args-overview.md: -------------------------------------------------------------------------------- 1 | 2 | ## Note: 3 | 4 | This is primarily a Demo video to revise concepts related to Docker. To test the commands we have used in the video, you will need a system with Docker installed.Kubernetes installation is not required. 5 | 6 | ### Documentation Referenced: 7 | 8 | https://hub.docker.com/_/nginx 9 | 10 | ### Docker File - Example 1 11 | 12 | ```sh 13 | FROM busybox:latest 14 | CMD ["ping","-c","3","google.com"] 15 | ``` 16 | ```sh 17 | docker build -t busybox:ping . 18 | 19 | docker images 20 | 21 | docker run busybox:ping 22 | 23 | docker ps 24 | 25 | docker ps -a 26 | ``` 27 | ### Docker File - Example 2 28 | 29 | ```sh 30 | FROM ubuntu 31 | ENTRYPOINT ["/bin/echo"] 32 | CMD ["hello", "world"] 33 | ``` 34 | 35 | ```sh 36 | docker build -t ubuntu:custom . 37 | 38 | docker images 39 | 40 | docker run ubuntu:custom 41 | ``` 42 | ### Overriding the Default CMD in Docker 43 | ```sh 44 | docker run ubuntu:custom how are you 45 | ``` -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/cmd-args-practical.md: -------------------------------------------------------------------------------- 1 | 2 | ### Example 1 - Echo Pod 3 | ```sh 4 | kubectl run echo-pod --image=busybox:latest --command -- "Hello World!" 5 | 6 | kubectl logs echo-pod 7 | 8 | kubectl delete pod echo-pod 9 | ``` 10 | 11 | ### Example 2 - Ping Pod 12 | ```sh 13 | kubectl run ping-pod --image=busybox:latest --command -- ping "-c" "30" "google.com 14 | 15 | kubectl logs ping-pod 16 | 17 | kubectl delete pod ping-pod 18 | ``` 19 | ### Example 3 - Manifest File 20 | 21 | #### 1 - Base Pod Manifest File Used as Reference 22 | ```sh 23 | apiVersion: v1 24 | kind: Pod 25 | metadata: 26 | name: nginx 27 | spec: 28 | containers: 29 | - name: nginx-container 30 | image: nginx 31 | ``` 32 | 33 | #### 2 - Final Pod Manifest with CMD and Args (cmd-args.yaml) 34 | 35 | ```sh 36 | apiVersion: v1 37 | kind: Pod 38 | metadata: 39 | name: new-ping-pod 40 | spec: 41 | containers: 42 | - name: ping-container 43 | image: busybox:latest 44 | command: ["ping"] 45 | args: ["-c","60","google.com"] 46 | ``` 47 | 48 | ```sh 49 | kubectl apply -f cmd-args.yaml 50 | kubectl get pods 51 | kubectl logs new-ping-pod 52 | ``` 53 | 54 | -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/cmd-args.md: -------------------------------------------------------------------------------- 1 | #### Documentation Referenced in Video 2 | 3 | https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/ 4 | 5 | #### Create POD without any commands or arguments. 6 | 7 | ##### newpod.yaml 8 | 9 | ```sh 10 | apiVersion: v1 11 | kind: Pod 12 | metadata: 13 | name: command 14 | spec: 15 | containers: 16 | - image: count 17 | name: busybox 18 | ``` 19 | ```sh 20 | kubectl apply -f commands.yaml 21 | ``` 22 | ```sh 23 | kubectl get pods 24 | kubectl exec -it command -- bash 25 | ``` 26 | 27 | #### Create POD with Command 28 | 29 | Modify the POD contents to the following one. 30 | 31 | ```sh 32 | apiVersion: v1 33 | kind: Pod 34 | metadata: 35 | name: command2 36 | spec: 37 | containers: 38 | - image: count 39 | name: busybox 40 | command: ["sleep","3600"] 41 | ``` 42 | ```sh 43 | kubectl apply -f commands.yaml 44 | ``` 45 | ```sh 46 | kubectl get pods 47 | kubectl exec -it command2 -- sh 48 | ``` 49 | 50 | #### Create POD with Command and Arguments 51 | 52 | Modify the YAML file contents to the following one. 53 | 54 | ```sh 55 | apiVersion: v1 56 | kind: Pod 57 | metadata: 58 | name: command3 59 | spec: 60 | containers: 61 | - image: count 62 | name: busybox 63 | command: ["sleep"] 64 | args: ["3600"] 65 | ``` 66 | ```sh 67 | kubectl apply -f commands.yaml 68 | ``` 69 | ```sh 70 | kubectl get pods 71 | ``` 72 | 73 | #### Create POD with Arguments 74 | 75 | Modify the YAML file contents to the following one. 76 | 77 | ```sh 78 | apiVersion: v1 79 | kind: Pod 80 | metadata: 81 | name: command4 82 | spec: 83 | containers: 84 | - image: count 85 | name: busybox 86 | args: ["sleep","3600"] 87 | ``` 88 | ```sh 89 | kubectl apply -f commands.yaml 90 | ``` 91 | ```sh 92 | kubectl get pods 93 | kubectl exec -it command4 -- sh 94 | ``` -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/expose-pods.md: -------------------------------------------------------------------------------- 1 | #### Documentation Referred: 2 | 3 | https://kubernetes.io/docs/tutorials/stateless-application/expose-external-ip-address/#creating-a-service-for-an-application-running-in-five-pods 4 | 5 | 6 | 7 | ##### pod-expose-port.yaml 8 | 9 | ```sh 10 | apiVersion: v1 11 | kind: Pod 12 | metadata: 13 | name: nginx-pod 14 | spec: 15 | containers: 16 | - image: nginx 17 | name: democontainer 18 | ports: 19 | - containerPort: 8080 20 | ``` 21 | ```sh 22 | kubectl apply -f pod-expose-port.yaml 23 | ``` 24 | ```sh 25 | kubectl get pods 26 | 27 | kubectl describe pod nginx-pod 28 | 29 | kubectl explain pod.spec.containers.ports 30 | ``` 31 | -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/install-kubectl.md: -------------------------------------------------------------------------------- 1 | # Installing and Configuring Kubectl for Linux 2 | 3 | 4 | ### Documentation Link for kubectl 5 | 6 | https://kubernetes.io/docs/tasks/tools/install-kubectl/ 7 | 8 | 9 | ### Installing Kubectl in Linux: 10 | ```sh 11 | curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" 12 | 13 | chmod +x kubectl 14 | mv kubectl /usr/local/bin 15 | ``` 16 | 17 | ### Verification 18 | ```sh 19 | kubectl 20 | ``` 21 | 22 | -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/kubectl-to-k8s.md: -------------------------------------------------------------------------------- 1 | 2 | ### Configuring Kubectl for Linux: 3 | 4 | ```sh 5 | mkdir ~/.kube 6 | cd ~/.kube 7 | nano config 8 | ``` 9 | 10 | Add the config file which you have downloaded inside the config file in ~/kube directory. 11 | 12 | ### Verification: 13 | ```sh 14 | kubectl get nodes 15 | ``` 16 | 17 | ### Reference to Custom Kubeconfig file in non-default Path 18 | ```sh 19 | kubectl get nodes --kubeconfig "config" 20 | ``` -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/manifest-structure.md: -------------------------------------------------------------------------------- 1 | 2 | ### API Documentation Referenced in the Video 3 | 4 | https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/ 5 | 6 | ### Command Used 7 | 8 | ```sh 9 | kubectl api-resources 10 | ``` 11 | 12 | ### pod.yaml 13 | ```sh 14 | apiVersion: v1 15 | kind: Pod 16 | metadata: 17 | name: nginx 18 | spec: 19 | containers: 20 | - name: nginx-container 21 | image: nginx 22 | ``` -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/minikube-install.md: -------------------------------------------------------------------------------- 1 | ### Documentation Referenced in Video 2 | 3 | https://minikube.sigs.k8s.io/docs/start/?arch=%2Fwindows%2Fx86-64%2Fstable%2F.exe+download 4 | 5 | ### Step 1 Install Docker 6 | 7 | ```sh 8 | sudo apt-get update 9 | sudo apt-get -y install ca-certificates curl 10 | sudo install -m 0755 -d /etc/apt/keyrings 11 | sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc 12 | sudo chmod a+r /etc/apt/keyrings/docker.asc 13 | 14 | 15 | echo \ 16 | "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ 17 | $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ 18 | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 19 | sudo apt-get update 20 | ``` 21 | 22 | ```sh 23 | sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 24 | ``` 25 | 26 | ### Step 2: Install Kubectl 27 | ```sh 28 | curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" 29 | 30 | chmod +x kubectl 31 | 32 | mv kubectl /usr/local/bin 33 | 34 | kubectl 35 | ``` 36 | 37 | 38 | ### Step 2: Install Minikube 39 | ```sh 40 | curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 41 | 42 | sudo install minikube-linux-amd64 /usr/local/bin/minikube && rm minikube-linux-amd64 43 | ``` 44 | 45 | ### Step 3: Start Minikube 46 | 47 | ```sh 48 | minikube start --force 49 | ``` 50 | 51 | ### Step 4: Verification 52 | ```sh 53 | minikube status 54 | 55 | kubectl get nodes 56 | ``` 57 | -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/multi-container-pod.md: -------------------------------------------------------------------------------- 1 | 2 | ### Base Pod Manifest File Used 3 | 4 | ```sh 5 | apiVersion: v1 6 | kind: Pod 7 | metadata: 8 | name: nginx 9 | spec: 10 | containers: 11 | - name: nginx-container 12 | image: nginx 13 | ``` 14 | 15 | ### Multi-Container Pod Manifest (multi-container-pod.yaml) 16 | 17 | ```sh 18 | apiVersion: v1 19 | kind: Pod 20 | metadata: 21 | name: multi-container-pod 22 | spec: 23 | containers: 24 | - name: nginx-container 25 | image: nginx 26 | - name: redis-container 27 | image: redis 28 | ``` 29 | 30 | ### Base Commands Used in Video 31 | ```sh 32 | kubectl apply -f pod.yaml 33 | kubectl apply -f multi-container-pod.yaml 34 | kubectl get pods 35 | kubectl describe pod multi-container-pod 36 | ``` 37 | 38 | ### Exec into Multi Container Pod 39 | ```sh 40 | kubectl exec -it multi-container-pod -- bash 41 | 42 | kubectl exec -it multi-container-pod -c redis-container -- bash 43 | ``` 44 | 45 | ### Delete the Resource Created in this Video 46 | 47 | ```sh 48 | kubectl delete -f pod.yaml 49 | 50 | kubectl delete -f multi-container-pod.yaml 51 | ``` 52 | -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/pod-manifest-cli.md: -------------------------------------------------------------------------------- 1 | #### 1. Create a Pod from Nginx Image 2 | 3 | ```sh 4 | kubectl run nginx --image=nginx 5 | 6 | kubectl get pods 7 | ``` 8 | 9 | #### 2. Create a Pod from Nginx Image with Dry Run 10 | 11 | ```sh 12 | kubectl run nginx2 --image=nginx --dry-run=client 13 | 14 | kubectl get pods 15 | ``` 16 | #### 3. Create a Pod from Nginx Image with Output of YAML 17 | 18 | ```sh 19 | kubectl run nginx2 --image=nginx -o yaml 20 | ``` 21 | #### 4. Main Command of this Video to Create Manifest File 22 | 23 | ```sh 24 | kubectl run nginx4 --image=nginx --dry-run=client -o yaml 25 | 26 | kubectl run nginx4 --image=nginx --dry-run=client -o yaml > pod-custom.yaml 27 | ``` 28 | 29 | #### 4. Delete All Pods 30 | ```sh 31 | kubectl delete pod --all 32 | ``` -------------------------------------------------------------------------------- /Domain 1 - Core Concepts/pod-manifest.md: -------------------------------------------------------------------------------- 1 | 2 | ### pod.yaml 3 | ```sh 4 | apiVersion: v1 5 | kind: Pod 6 | metadata: 7 | name: nginx 8 | spec: 9 | containers: 10 | - name: nginx-container 11 | image: nginx 12 | ``` 13 | 14 | ### Create Pod Using Manifest File 15 | ```sh 16 | kubectl apply -f pod.yaml 17 | ``` 18 | 19 | #### List the Running Pods 20 | ```sh 21 | kubectl get pods 22 | ``` 23 | #### Delete the Resources Created via pod.yaml file 24 | ```sh 25 | kubectl delete -f pod.yaml 26 | ``` 27 | -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/Readme.md: -------------------------------------------------------------------------------- 1 | # Domain 2 - Application Design and Build 2 | 3 | The code mentioned in this document are used in the Certified Kubernetes Application Developer 2025 course. 4 | 5 | https://www.udemy.com/course/mastering-certified-kubernetes-application-developer/?referralCode=3A549BA24AC8ED6597DF 6 | 7 | 8 | # Video-Document Mapper 9 | 10 | | Sr No | Document Link | 11 | | ------ | ------ | 12 | | 1 | [Implementing Labels and Selectors][PlDa] | 13 | | 2 | [ReplicaSet - Practical][PlDb] | 14 | | 3 | [Challenges with ReplicaSets][PlDc] | 15 | | 4 | [Deployments - Practical][PlDd] 16 | | 5 | [maxSurge and maxUnavailable][PlDe] 17 | | 6 | [DaemonSet - Practical][PlDf] 18 | | 7 | [Practical - Jobs][PlDg] 19 | | 8 | [Jobs Field - ActiveDeadLineSeconds][PlDh] 20 | | 9 | [Jobs - backoffLimit][PlDi] 21 | | 10 | [Practical - CronJob][PlDj] 22 | | 11 | [Job History Limits][PlDk] 23 | 24 | 25 | [PlDa]: <./labels.md> 26 | [PlDb]: <./replicaset.md> 27 | [PlDc]: <./rs-challenges.md> 28 | [PlDd]: <./deployment.md> 29 | [PlDe]: <./maxSurge-maxUnavailable.md> 30 | [PlDf]: <./daemonset.md> 31 | [PlDg]: <./jobs.md> 32 | [PlDh]: <./activeDeadlineSeconds.md> 33 | [PlDi]: <./jobs-backofflimit.md> 34 | [PlDj]: <./cronjob.md> 35 | [PlDk]: <./jobs-history-limit.md> -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/activeDeadlineSeconds.md: -------------------------------------------------------------------------------- 1 | ### Base Manifest File Used 2 | 3 | ```sh 4 | apiVersion: batch/v1 5 | kind: Job 6 | metadata: 7 | name: ping-job-manifest 8 | spec: 9 | template: 10 | metadata: 11 | spec: 12 | containers: 13 | - command: 14 | - ping 15 | - -c 16 | - "100" 17 | - google.com 18 | image: busybox:latest 19 | name: ping-job 20 | restartPolicy: Never 21 | ``` 22 | 23 | 24 | ### Final Manifest File 25 | 26 | jobs.yaml 27 | 28 | ```sh 29 | apiVersion: batch/v1 30 | kind: Job 31 | metadata: 32 | name: ping-job-manifest 33 | spec: 34 | activeDeadlineSeconds: 30 35 | template: 36 | metadata: 37 | spec: 38 | containers: 39 | - command: 40 | - ping 41 | - -c 42 | - "100" 43 | - google.com 44 | image: busybox:latest 45 | name: ping-job 46 | restartPolicy: Never 47 | ``` 48 | 49 | ```sh 50 | kubectl apply -f jobs.yaml 51 | 52 | kubectl get pods 53 | ``` 54 | -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/cronjob.md: -------------------------------------------------------------------------------- 1 | 2 | ### Commands Used 3 | ```sh 4 | kubectl create cronjob --help 5 | 6 | kubectl create cronjob demo-cronjob --image=busybox:latest --schedule="* * * * *" -- ping "-c" "5" "google.com" 7 | 8 | kubectl get pods 9 | ``` 10 | ### Create Manfiest File for CronJob 11 | ```sh 12 | kubectl create cronjob demo-cronjob --image=busybox:latest --dry-run=client -o yaml --schedule="* * * * *" -- ping "-c" "5" "google.com" 13 | ``` 14 | 15 | ### Delete the Resources after Practical 16 | ```sh 17 | kubectl delete cronjob demo-cronjob 18 | ``` -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/daemonset.md: -------------------------------------------------------------------------------- 1 | 2 | ### Documentation Referenced: 3 | 4 | https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/ 5 | 6 | ### Daemonset Manifest File (daemonset-custom.yaml) 7 | 8 | ```sh 9 | apiVersion: apps/v1 10 | kind: DaemonSet 11 | metadata: 12 | name: anti-virus 13 | spec: 14 | selector: 15 | matchLabels: 16 | app: nginx 17 | template: 18 | metadata: 19 | labels: 20 | app: nginx 21 | spec: 22 | containers: 23 | - name: nginx 24 | image: nginx 25 | ``` 26 | 27 | ```sh 28 | kubectl apply -f daemonset-custom.yaml 29 | 30 | kubectl get pods 31 | 32 | kubectl get nodes 33 | 34 | kubectl delete -f daemonset-custom.yaml 35 | ``` -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/deployment.md: -------------------------------------------------------------------------------- 1 | 2 | ### Create Deployment through CLI Command 3 | ```sh 4 | kubectl create deployment nginx-deployment --image=nginx 5 | ``` 6 | ```sh 7 | kubectl get deployment 8 | kubectl get pods 9 | kubectl get rs 10 | ``` 11 | ### Generate Deployment Manifest File 12 | ```sh 13 | kubectl create deployment nginx-deployment --image=nginx --dry-run=client -o yaml > deployment.yaml 14 | ``` 15 | 16 | ### Update Image of Deployment 17 | ```sh 18 | kubectl set image --help 19 | 20 | kubectl set image deployment/nginx-deployment nginx=httpd:latest 21 | 22 | kubectl get pods 23 | ``` 24 | ### Rollout Undo (Revert the Changes) 25 | ```sh 26 | kubectl rollout history deployment/nginx-deployment 27 | 28 | kubectl get rs 29 | 30 | kubectl rollout undo deployment nginx-deployment 31 | 32 | kubectl get rs 33 | ``` 34 | ```sh 35 | kubectl rollout undo --help 36 | 37 | kubectl rollout undo deployment nginx-deployment --to-revision=2 38 | ``` 39 | ### Scale Deployment 40 | ```sh 41 | kubectl scale --replicas=3 deployment nginx-deployment 42 | ``` 43 | ### Delete the Deployment 44 | ```sh 45 | kubectl delete deployment nginx-deployment 46 | 47 | kubectl get rs 48 | ``` 49 | 50 | -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/imp-dep-commands.md: -------------------------------------------------------------------------------- 1 | #### Documentation Referred: 2 | 3 | https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ 4 | 5 | #### Create a new Deployment 6 | ```sh 7 | kubectl create deployment kplabs-deployment --image=nginx 8 | ``` 9 | ```sh 10 | kubectl get pods 11 | ``` 12 | #### Set a New Image to Existing Deployment 13 | ```sh 14 | kubectl set image deployment/kplabs-deployment nginx=apache 15 | ``` 16 | ```sh 17 | kubectl get pods 18 | ``` 19 | #### Rolling Back changes 20 | ```sh 21 | kubectl rollout history deployment kplabs-deployment 22 | ``` 23 | ```sh 24 | kubectl rollout undo deployment/kplabs-deployment 25 | ``` 26 | #### Adding a Record Instruction 27 | ```sh 28 | kubectl set image deployment/kplabs-deployment nginx=httpd 29 | ``` 30 | ```sh 31 | kubectl rollout history deployment kplabs-deployment 32 | ``` 33 | #### Scaling Deployment 34 | 35 | ```sh 36 | kubectl scale deployment/kplabs-deployment --replicas=10 37 | ``` 38 | ```sh 39 | kubectl get deployments 40 | kubectl get pods 41 | ``` 42 | 43 | #### Delete the resources created in this lecture 44 | ```sh 45 | kubectl delete deployment kplabs-deployment 46 | ``` -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/jobs-backofflimit.md: -------------------------------------------------------------------------------- 1 | ### Documentation Referenced: 2 | 3 | https://kubernetes.io/docs/concepts/workloads/controllers/job/ 4 | 5 | ### Create Job with backoffLimit of 3 6 | 7 | `backoffLimit.yaml` 8 | 9 | ```sh 10 | apiVersion: batch/v1 11 | kind: Job 12 | metadata: 13 | name: failing-job 14 | spec: 15 | template: 16 | spec: 17 | containers: 18 | - name: always-fail 19 | image: busybox 20 | command: ["sh", "-c", "exit 1"] 21 | restartPolicy: Never 22 | backoffLimit: 3 23 | ``` 24 | 25 | ```sh 26 | kubectl create -f backoff-limit.yaml 27 | ``` 28 | 29 | ### Verification 30 | Wait for a minute or two, there should be a total of 4 failed pods. 31 | 32 | ```sh 33 | kubectl get pods 34 | ``` 35 | 36 | ### Delete the Resources Created 37 | ```sh 38 | kubectl delete -f backoffLimit.yaml 39 | ``` -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/jobs-history-limit.md: -------------------------------------------------------------------------------- 1 | ### Documentation Referenced: 2 | 3 | https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#jobs-history-limits 4 | 5 | ### Example 1 - Create CronJob with successfulJobsHistoryLimit as 3 6 | 7 | `cronjob-success-history-3.yaml` 8 | ```sh 9 | apiVersion: batch/v1 10 | kind: CronJob 11 | metadata: 12 | name: success-custom 13 | spec: 14 | schedule: "*/1 * * * *" 15 | successfulJobsHistoryLimit: 3 16 | jobTemplate: 17 | spec: 18 | template: 19 | spec: 20 | containers: 21 | - name: pass 22 | image: busybox 23 | args: 24 | - ping 25 | - -c2 26 | - "google.com" 27 | restartPolicy: Never 28 | ``` 29 | ```sh 30 | kubectl create -f cronjob-success-history-3.yaml 31 | ``` 32 | 33 | Wait for a 3-4 minutes 34 | ```sh 35 | kubectl get jobs 36 | 37 | kubectl get pods 38 | 39 | kubectl delete -f cronjob-history-3.yaml 40 | ``` 41 | 42 | 43 | ### Example 1 - Create CronJob with failedJobsHistoryLimit as 3 44 | 45 | `cronjob-fail-history-3.yaml` 46 | ```sh 47 | apiVersion: batch/v1 48 | kind: CronJob 49 | metadata: 50 | name: failjob-default 51 | spec: 52 | schedule: "*/1 * * * *" 53 | failedJobsHistoryLimit: 2 54 | jobTemplate: 55 | spec: 56 | backoffLimit: 0 57 | template: 58 | spec: 59 | containers: 60 | - name: fail 61 | image: busybox 62 | args: 63 | - /bin/sh 64 | - -c 65 | - "exit 1" 66 | restartPolicy: Never 67 | ``` 68 | 69 | ```sh 70 | kubectl create -f cronjob-fail-history-3.yaml 71 | ``` 72 | 73 | Wait for a 3-4 minutes 74 | ```sh 75 | kubectl get jobs 76 | 77 | kubectl get pods 78 | 79 | kubectl delete -f cronjob-fail-history-3.yaml 80 | ``` -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/jobs.md: -------------------------------------------------------------------------------- 1 | 2 | ### Command Used in Video 3 | 4 | ```sh 5 | kubectl create job --help 6 | 7 | kubectl create job ping-job --image=busybox:latest -- ping "-c" "5" "google.com" 8 | ``` 9 | 10 | ### Verification of Job and Pods 11 | ```sh 12 | kubectl get pods 13 | kubectl logs 14 | kubectl describe job ping-job 15 | ``` 16 | 17 | ### Testing Use-Case of Deletion of Pod 18 | ```sh 19 | kubectl delete job ping-job 20 | 21 | kubectl create job ping-job --image=busybox:latest -- ping "-c" "100" "google.com" 22 | 23 | kubectl get pods 24 | 25 | kubectl delete pod 26 | 27 | kubectl get pods 28 | ``` 29 | ### Generate Manifest File For Job 30 | ```sh 31 | kubectl create job ping-job --image=busybox:latest --dry-run=client -o yaml -- ping "-c" "100" "google.com" > jobs.yaml 32 | ``` 33 | 34 | ### Delete the Resources Created 35 | ```sh 36 | kubectl delete job ping-job 37 | ``` -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/labels.md: -------------------------------------------------------------------------------- 1 | 2 | #### Step 1: Create 3 PODS 3 | ```sh 4 | kubectl run pod-1 --image=nginx 5 | kubectl run pod-2 --image=nginx 6 | kubectl run pod-3 --image=nginx 7 | ``` 8 | 9 | #### Step 2: Show Labels of POD 10 | ```sh 11 | kubectl get pods --show-labels 12 | ``` 13 | 14 | #### Step 3: Label PODS 15 | ```sh 16 | kubectl label pod pod-1 env=dev 17 | kubectl label pod pod-2 env=stage 18 | kubectl label pod pod-3 env=prod 19 | ``` 20 | ```sh 21 | kubectl get pods --show-labels 22 | ``` 23 | 24 | #### Step 4: Use Selectors to Filter PODS 25 | ```sh 26 | kubectl get pods -l env=dev 27 | kubectl get pods -l env=dev 28 | kubectl get pods -l env!=dev 29 | ``` 30 | #### Step 5: Check Available Example using Help command 31 | ```sh 32 | kubectl label --help 33 | ``` 34 | 35 | #### Step 6: Remove Label of POD from DEV environement 36 | ```sh 37 | kubectl label pod pod-1 env- 38 | ``` 39 | 40 | ```sh 41 | kubectl get pods --show-labels 42 | ``` 43 | 44 | #### Step 7: Generate POD Manifest to See Location of Labels 45 | ```sh 46 | kubectl run nginx --image=nginx --dry-run=client -o yaml 47 | ``` 48 | #### Step 8: Add a new Label in POD Manifest 49 | ```sh 50 | kubectl run nginx --image=nginx --dry-run=client -o yaml > label-pod.yaml 51 | ``` 52 | Add a new label of "env=dev" in metadata.labels. 53 | 54 | Final output of file 55 | 56 | ```sh 57 | apiVersion: v1 58 | kind: Pod 59 | metadata: 60 | creationTimestamp: null 61 | labels: 62 | run: nginx 63 | env: dev 64 | name: nginx 65 | spec: 66 | containers: 67 | - image: nginx 68 | name: nginx 69 | resources: {} 70 | dnsPolicy: ClusterFirst 71 | restartPolicy: Always 72 | status: {} 73 | ``` 74 | ```sh 75 | kubectl apply -f label-pod.yaml 76 | ``` 77 | ```sh 78 | kubectl get pods --show-labels 79 | ``` 80 | #### Step 9: Add Label to ALL PODS 81 | ```sh 82 | kubectl label pods --all status=running 83 | ``` 84 | ```sh 85 | kubectl get pods --show-labels 86 | ``` 87 | #### Step 10: Delete All the PODS 88 | ```sh 89 | kubectl delete pods --all 90 | ``` -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/maxSurge-maxUnavailable.md: -------------------------------------------------------------------------------- 1 | 2 | #### Create a new deployment 3 | ```sh 4 | kubectl create deployment demo-deployment --image=nginx 5 | ``` 6 | ```sh 7 | kubectl get deployment demo-deployment -o yaml 8 | ``` 9 | #### Set a new image to Deployment 10 | ```sh 11 | kubectl set image deployment demo-deployment nginx=httpd 12 | ``` 13 | #### Edit Deployment 14 | ```sh 15 | kubectl edit deployment demo-deployment 16 | ``` 17 | Set the maxSurge=0 18 | 19 | #### Verify the Result 20 | ```sh 21 | kubectl set image deployment demo-deployment nginx=httpd 22 | ``` 23 | ```sh 24 | kubectl get pods 25 | ``` -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/replicaset.md: -------------------------------------------------------------------------------- 1 | #### Documentation Referred: 2 | 3 | https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ 4 | 5 | #### Step 1: Create a ReplicaSet Manifest File (replicaset.yaml) 6 | 7 | ```sh 8 | apiVersion: apps/v1 9 | kind: ReplicaSet 10 | metadata: 11 | name: frontend-replicaset 12 | spec: 13 | replicas: 3 14 | selector: 15 | matchLabels: 16 | tier: frontend 17 | template: 18 | metadata: 19 | labels: 20 | tier: frontend 21 | spec: 22 | containers: 23 | - name: php-redis 24 | image: us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5 25 | ``` 26 | 27 | ```sh 28 | kubectl apply -f replicaset.yaml 29 | ``` 30 | #### Step 2: Verify Replicaset Creation 31 | ```sh 32 | kubectl get replicaset 33 | 34 | kubectl get pods 35 | 36 | kubectl get pods --show-labels 37 | ``` 38 | #### Step 3: Scaling ReplicaSet 39 | ```sh 40 | kubectl scale --replicas=5 rs/frontend-replicaset 41 | kubectl scale --replicas=1 rs/frontend-replicaset 42 | ``` 43 | 44 | #### Step 4: Delete Replica Set 45 | ```sh 46 | kubectl delete -f replicaset.yaml 47 | ``` -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/rs-challenges.md: -------------------------------------------------------------------------------- 1 | 2 | ### Base ReplicaSet Manifest File Used (rs.yaml) 3 | 4 | ```sh 5 | apiVersion: apps/v1 6 | kind: ReplicaSet 7 | metadata: 8 | name: webserver-replicaset 9 | spec: 10 | replicas: 3 11 | selector: 12 | matchLabels: 13 | app: webserver 14 | template: 15 | metadata: 16 | labels: 17 | app: webserver 18 | spec: 19 | containers: 20 | - name: nginx-container 21 | image: nginx:latest 22 | ``` 23 | ```sh 24 | kubectl apply -f rs.yaml 25 | ``` 26 | 27 | ### Commands Used in Video 28 | 29 | ```sh 30 | kubectl get rs 31 | kubectl get pods 32 | ``` 33 | 34 | ### Changing the Image of ReplicaSet to Observe Effects 35 | 36 | ```sh 37 | apiVersion: apps/v1 38 | kind: ReplicaSet 39 | metadata: 40 | name: webserver-replicaset 41 | spec: 42 | replicas: 3 43 | selector: 44 | matchLabels: 45 | app: webserver 46 | template: 47 | metadata: 48 | labels: 49 | app: webserver 50 | spec: 51 | containers: 52 | - name: nginx-container 53 | image: httpd:latest 54 | ``` 55 | ```sh 56 | kubectl apply -f rs.yaml 57 | ``` 58 | 59 | ```sh 60 | kubectl get pods 61 | 62 | kubectl describe rs webserver-replicaset 63 | 64 | kubetl describe pod 65 | 66 | kubectl delete pod 67 | 68 | kubectl get pods 69 | 70 | kubectl scale rs/webserver-replicaset --replicas=0 71 | kubectl scale rs/webserver-replicaset --replicas=3 72 | ``` 73 | 74 | ### Label Collision Use-Case 75 | ```sh 76 | kubectl delete -f rs.yaml 77 | 78 | kubectl run pod external-pod --image=nginx 79 | kubectl label pod external-pod app=webserver 80 | kubectl get pods --show-labels 81 | 82 | kubectl apply -f rs.yaml 83 | kubectl get pods 84 | 85 | kubectl delete -f rs.yaml 86 | kubectl get pods 87 | ``` 88 | 89 | ### Multiple Labels and Selector Use-Case 90 | 91 | ```sh 92 | kubectl run pod external-pod --image=nginx 93 | kubectl label pod external-pod app=webserver 94 | ``` 95 | Adding one more label in the selector and template. 96 | 97 | ```sh 98 | apiVersion: apps/v1 99 | kind: ReplicaSet 100 | metadata: 101 | name: webserver-replicaset 102 | spec: 103 | replicas: 1 104 | selector: 105 | matchLabels: 106 | app: webserver 107 | env: prod 108 | template: 109 | metadata: 110 | labels: 111 | app: webserver 112 | env: prod 113 | spec: 114 | containers: 115 | - name: nginx-container 116 | image: httpd:latest 117 | ``` 118 | ```sh 119 | kubectl apply -f rs.yaml 120 | 121 | kubectl get pods --show-labels 122 | 123 | kubectl delete -f rs.yaml 124 | ``` -------------------------------------------------------------------------------- /Domain 2 - Application Design and Build/service-manifest-cli.md: -------------------------------------------------------------------------------- 1 | 2 | #### Pre-Requisite Step 1: Create a new POD with name nginx 3 | ```sh 4 | kubectl run nginx --image=nginx 5 | ``` 6 | #### Pre-Requisite Step 2: Create a New Deployment 7 | ```sh 8 | nano service-deployment.yaml 9 | ``` 10 | ```sh 11 | apiVersion: apps/v1 12 | kind: Deployment 13 | metadata: 14 | name: kplabs-deployment 15 | spec: 16 | replicas: 3 17 | selector: 18 | matchLabels: 19 | tier: frontend 20 | template: 21 | metadata: 22 | labels: 23 | tier: frontend 24 | spec: 25 | containers: 26 | - name: nginx 27 | image: nginx 28 | ``` 29 | ```sh 30 | kubectl apply -f service-deployment.yaml 31 | ``` 32 | #### Step 1: Generate Service Manifest - POD 33 | ```sh 34 | kubectl expose pod nginx --name nginx-service --port=80 --target-port=80 --dry-run=client -o yaml 35 | 36 | kubectl expose pod nginx --name nginx-service --port=80 --target-port=80 --dry-run=client -o yaml > service-01.yaml 37 | 38 | kubectl describe service nginx-svc 39 | ``` 40 | #### Step 2: Generate NodePort Service Manifest - POD 41 | ```sh 42 | kubectl expose pod nginx --name nginx-nodeport-service --port=80 --target-port=80 --type=NodePort --dry-run=client -o yaml 43 | 44 | kubectl get service 45 | ``` 46 | 47 | #### Step 3: Generate Service Manifest - Deployment 48 | ```sh 49 | kubectl expose deployment kplabs-deployment --name nginx-deployment-service --port=80 --target-port=8000 50 | 51 | kubectl describe service nginx-deployment-service 52 | ``` 53 | 54 | ### Step 4: Delete Resources 55 | ```sh 56 | kubectl delete pod nginx 57 | kubectl delete deployment kplabs-deployment 58 | kubectl delete service nginx-service 59 | kubectl delete service nginx-nodeport-service 60 | kubectl delete service nginx-deployment-service 61 | ``` 62 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/Readme.md: -------------------------------------------------------------------------------- 1 | # Domain 3 - Services and Networking 2 | 3 | The code mentioned in this document are used in the Certified Kubernetes Application Developer 2025 course. 4 | 5 | https://www.udemy.com/course/mastering-certified-kubernetes-application-developer/?referralCode=3A549BA24AC8ED6597DF 6 | 7 | # Video-Document Mapper 8 | 9 | | Sr No | Document Link | 10 | | ------ | ------ | 11 | | 1 | [Practical - Service and Endpoints][PlDa] | 12 | | 2 | [Using Selectors in Service][PlDb] | 13 | | 3 | [Service Type: ClusterIP][PlDc] | 14 | | 4 | [Practical - NodePort][PlDd] | 15 | | 5 | [Practical - Load Balancer][PlDe] 16 | | 6 | [Practical - Ingress Resource][PlDf] | 17 | | 7 | [Practical - Ingress Controller][PlDg] | 18 | | 8 | [Installing Helm][PlDh] | 19 | | 9 | [Helm Practical][PlDi] | 20 | | 10 | [Kubernetes Namespace][PlDj] | 21 | | 11 | [Overview of Service Accounts][PlDk] | 22 | | 12 | [Service Accounts - Points to Note][PlDl] | 23 | | 13 | [Service Accounts- Practical Scenerios][PlDm] | 24 | | 14 | [Structure of Network Policy][PlDn] | 25 | | 15 | [Practical - Network Policies][PlDo] | 26 | | 16 | [Network Policies - Except, Port and Protocol][PlDp] | 27 | 28 | 29 | [PlDa]: <./service-endpoints.md> 30 | [PlDb]: <./service-selector.md> 31 | [PlDc]: <./cluster-ip.md> 32 | [PlDd]: <./nodeport.md> 33 | [PlDe]: <./loadbalancer.md> 34 | [PlDf]: <./ingress.md> 35 | [PlDg]: <./ingress-controller.md> 36 | [PlDh]: <./install-helm.md> 37 | [PlDi]: <./helm-practical.md> 38 | [PlDj]: <./namespace.md> 39 | [PlDk]: <./service-account.md> 40 | [PlDl]: <./sa-pointers.md> 41 | [PlDm]: <./sa-practical.md> 42 | [PlDn]: <./netpol-01.md> 43 | [PlDo]: <./netpol-practical.md> 44 | [PlDp]: <./netpol-02.md> -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/cluster-ip.md: -------------------------------------------------------------------------------- 1 | 2 | ### Base Service Manifest File Used in Practical 3 | 4 | service.yaml 5 | 6 | ```sh 7 | apiVersion: v1 8 | kind: Service 9 | metadata: 10 | name: simple-service 11 | spec: 12 | ports: 13 | - port: 80 14 | targetPort: 80 15 | ``` 16 | ```sh 17 | kubectl create -f service.yaml 18 | 19 | kubectl get service 20 | ``` 21 | 22 | ### Create Cluster IP Service through CLI Command 23 | ```sh 24 | kubectl create service --help 25 | 26 | kubectl create service clusterip --help 27 | 28 | kubectl create service clusterip test-service --tcp=80:80 29 | 30 | kubectl get service 31 | 32 | kubectl create service clusterip test-service --tcp=80:80 --dry-run=client -o yaml 33 | ``` -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/first-helm-chart.md: -------------------------------------------------------------------------------- 1 | ### Artifact Hub Page: 2 | 3 | https://artifacthub.io/ 4 | 5 | 6 | ## Deploying Jenkins Helm Chart 7 | 8 | https://artifacthub.io/packages/helm/jenkinsci/jenkins 9 | 10 | ##### Step 1. Configure and Install Jenkins Helm Chart 11 | 12 | ```sh 13 | helm repo add jenkins https://charts.jenkins.io 14 | helm repo update 15 | helm install my-jenkins jenkins/jenkins 16 | ``` 17 | ##### Step 2. Verify the List of Releases 18 | 19 | ```sh 20 | helm list 21 | ``` 22 | ##### Step 3. Uninstall Jenkins Helm Chart 23 | 24 | ```sh 25 | helm uninstall my-jenkins 26 | ``` 27 | 28 | ## Deploying WordPress Helm Chart (Run this in Big Node) 29 | 30 | https://artifacthub.io/packages/helm/bitnami/wordpress 31 | 32 | ##### Step 1. Configure and Install Wordpress Helm Chart 33 | 34 | ```sh 35 | helm repo add bitnami https://charts.bitnami.com/bitnami 36 | helm install my-release bitnami/wordpress 37 | ``` 38 | 39 | ##### Step 2. Uninstall Wordpress Helm Chart 40 | 41 | ```sh 42 | helm uninstall my-release 43 | ``` 44 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/helm-practical.md: -------------------------------------------------------------------------------- 1 | ### External Website Referenced 2 | 3 | https://artifacthub.io/ 4 | 5 | https://artifacthub.io/packages/helm/bitnami/nginx 6 | 7 | ### Install Nginx Chart 8 | 9 | ```sh 10 | helm repo add bitnami https://charts.bitnami.com/bitnami 11 | 12 | helm install my-nginx bitnami/nginx --version 19.0.4 13 | ``` 14 | 15 | ### Other Helm Commands 16 | ```sh 17 | helm list 18 | 19 | helm repo list 20 | 21 | helm search repo bitnami 22 | 23 | helm search hub nginx 24 | 25 | helm template bitnami/nginx 26 | 27 | helm template bitnami/nginx > nginx.yaml 28 | 29 | helm template bitnami/nginx -n custom-ns > nginx.yaml 30 | 31 | helm uninstall my-nginx 32 | ``` 33 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/ingress-controller.md: -------------------------------------------------------------------------------- 1 | #### Documentation Referred: 2 | 3 | https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/ 4 | 5 | https://kubernetes.github.io/ingress-nginx/deploy/ 6 | 7 | ### Step 1 - Create 2 Pods for Example Service and Kplabs Service 8 | ```sh 9 | kubectl run example-pod --image=nginx 10 | kubectl run kplabs-pod --image=httpd 11 | ``` 12 | ### Step 2 - Create Service for Both the pods 13 | ```sh 14 | kubectl expose pod example-pod --name example-service --port=80 --target-port=80 15 | 16 | kubectl expose pod kplabs-pod --name kplabs-service --port=80 --target-port=80 17 | 18 | kubectl get service 19 | ``` 20 | ### Step 3 - Create Ingress Resource with 2 Rules 21 | ```sh 22 | kubectl create ingress main-ingress --class=nginx --rule="example.internal/*=example-service:80" --rule="kplabs.internal/*=kplabs-service:80" 23 | 24 | kubectl describe ingress main-ingress 25 | ``` 26 | #### Step 4: Install Nginx Ingress Controller: 27 | ```sh 28 | kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.12.0/deploy/static/provider/cloud/deploy.yaml 29 | ``` 30 | 31 | #### Step 5: Verify the Ingress Controller Resource 32 | ```sh 33 | kubectl get pods -n ingress-nginx 34 | kubectl get service -n ingress-nginx 35 | ``` 36 | Verify if a new load balancer is created in Digital Ocean. 37 | 38 | 39 | #### Step 6: Verify the Setup 40 | ```sh 41 | curl -H "Host: example.internal" 42 | curl -H "Host: kplabs.internal" 43 | ``` 44 | 45 | #### Step 7: Delete All Resource 46 | 47 | ```sh 48 | kubectl delete -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.12.0/deploy/static/provider/cloud/deploy.yaml 49 | 50 | kubectl delete ingress main-ingress 51 | 52 | kubectl delete service example-service 53 | kubectl delete service kplabs-service 54 | kubectl delete pod example-pod 55 | kubectl delete pod kplabs-pod 56 | ``` 57 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/ingress.md: -------------------------------------------------------------------------------- 1 | #### Documentation Referred: 2 | 3 | https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting 4 | 5 | ### Ingress Resource - Rule 1 6 | ```sh 7 | kubectl create ingress --help 8 | 9 | kubectl first ingress first-ingress --rule="example.internal/*=example-service:80" 10 | 11 | kubectl describe ingress first-ingress 12 | ``` 13 | ### Ingress Resource - Rule 2 14 | ```sh 15 | kubectl create ingress second-ingress --rule="example.internal/*=example-service:80" --rule="kplabs.internal/*=kplabs-service:80" 16 | ``` 17 | 18 | ### Generating Manifest File for Ingress Resource 19 | 20 | ```sh 21 | kubectl create ingress second-ingress --rule="example.internal/*=example-service:80" --rule="kplabs.internal/*=kplabs-service:80" --dry-run=client -o yaml 22 | ``` 23 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/install-helm.md: -------------------------------------------------------------------------------- 1 | #### Documentation Referred: 2 | 3 | https://helm.sh/docs/intro/install/ 4 | 5 | #### 2.Installing Helm in Ubuntu: 6 | 7 | ```sh 8 | curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null 9 | sudo apt-get install apt-transport-https --yes 10 | 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 11 | sudo apt-get update 12 | sudo apt-get install helm 13 | ``` 14 | 15 | ##### Step 2: Verify if Helm Command is working 16 | 17 | ```sh 18 | helm 19 | ``` 20 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/loadbalancer.md: -------------------------------------------------------------------------------- 1 | ### Base Service Manifest File Used 2 | 3 | lb-service.yaml 4 | 5 | ```sh 6 | apiVersion: v1 7 | kind: Service 8 | metadata: 9 | name: simple-service 10 | spec: 11 | selector: 12 | app: backend 13 | ports: 14 | - port: 80 15 | targetPort: 80 16 | ``` 17 | 18 | ### Create Load Balancer Service 19 | 20 | lb-service.yaml 21 | 22 | ```sh 23 | apiVersion: v1 24 | kind: Service 25 | metadata: 26 | name: simple-service 27 | spec: 28 | selector: 29 | app: backend 30 | type: LoadBalancer 31 | ports: 32 | - port: 80 33 | targetPort: 80 34 | ``` 35 | ```sh 36 | kubectl create -f lb-service.yaml 37 | 38 | kubectl get service 39 | ``` 40 | 41 | #### Create Pod with Label Matching Service Selector 42 | ```sh 43 | kubectl run backend-pod --image=nginx 44 | 45 | kubectl label pod backend-pod app=backend 46 | ``` 47 | 48 | Fetch the External IP and verify if the Nginx webpage loads. 49 | 50 | #### Delete the Resources 51 | ```sh 52 | kubectl delete pod backend-pod 53 | kubectl delete -f lb-service.yaml 54 | ``` 55 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/namespace.md: -------------------------------------------------------------------------------- 1 | 2 | ### Fetch Pod Details 3 | ```sh 4 | kubectl get pods 5 | 6 | kubectl get pods --all-namespaces 7 | ``` 8 | ### Running Pod in Default Namespace 9 | ```sh 10 | kubectl run test-pod --image=nginx 11 | ``` 12 | 13 | #### List PODS in a specific namespace: 14 | ```sh 15 | kubectl get pods -n kube-system 16 | ``` 17 | 18 | #### Create a new Namespace 19 | ```sh 20 | kubectl create namespace development 21 | kubectl create namespace qa 22 | kubectl get namespace 23 | ``` 24 | 25 | #### Create a new POD in specific namespace: 26 | ```sh 27 | kubectl run development-pod --image=nginx -n development 28 | kubectl run qa-pod --image=nginx -n qa 29 | 30 | kubectl get pods - development 31 | 32 | kubectl run test-pod --image=nginx --dry-run=client -o yaml 33 | ``` 34 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/netpol-01.md: -------------------------------------------------------------------------------- 1 | #### Create base setup: 2 | ```sh 3 | kubectl create ns external 4 | ``` 5 | ```sh 6 | kubectl run pod-1 --image=praqma/network-multitool 7 | kubectl run pod-2 --image=praqma/network-multitool 8 | kubectl run pod-3 --image=praqma/network-multitool -n external 9 | ``` 10 | ```sh 11 | kubectl get pods -o wide 12 | kubectl get pods -o wide -n external 13 | ``` 14 | Check connectivity from POD-1 to POD2 and POD-3 and Internet: 15 | ```sh 16 | kubectl exec -it pod-1 -- ping [pod-2-ip] 17 | kubectl exec -it pod-1 -- ping [pod-3-ip] 18 | kubectl exec -it pod-1 -- ping google.com 19 | ``` 20 | ### Rule 1: Deny Ingress 21 | ```sh 22 | nano netpol.yaml 23 | ``` 24 | ```sh 25 | --- 26 | apiVersion: networking.k8s.io/v1 27 | kind: NetworkPolicy 28 | metadata: 29 | name: default-deny-ingress 30 | spec: 31 | podSelector: {} 32 | ingress: 33 | - {} 34 | policyTypes: 35 | - Ingress 36 | ``` 37 | ```sh 38 | kubectl apply -f netpol.yaml 39 | ``` 40 | ```sh 41 | kubectl get netpol 42 | ``` 43 | ```sh 44 | kubectl exec -it pod-1 -- ping [pod2-ip] 45 | kubectl exec -it pod-1 -- ping [pod3-ip] 46 | kubectl exec -it pod-1 -- ping google.com 47 | 48 | kubectl exec -it pod-3 -- ping [pod1-ip] 49 | kubectl exec -it pod-3 -- ping [pod2-ip] 50 | ``` 51 | ```sh 52 | kubectl delete -f netpol.yaml 53 | ``` 54 | [Remove the contents of netpol.yaml file] 55 | 56 | ### Rule 2: Allow Ingress 57 | ```sh 58 | nano netpol.yaml 59 | ``` 60 | ```sh 61 | --- 62 | apiVersion: networking.k8s.io/v1 63 | kind: NetworkPolicy 64 | metadata: 65 | name: default-deny-ingress 66 | spec: 67 | podSelector: {} 68 | ingress: 69 | - {} 70 | policyTypes: 71 | - Ingress 72 | ``` 73 | ```sh 74 | kubectl apply -f netpol.yaml 75 | ``` 76 | ```sh 77 | kubectl exec -it pod-3 -- ping [pod1-ip] 78 | kubectl exec -it pod-3 -- ping [pod2-ip] 79 | ``` 80 | ```sh 81 | kubectl delete -f netpol.yaml 82 | ``` 83 | [Remove the contents of netpol.yaml file] 84 | 85 | ### Rule 3: Deny All Egress: 86 | 87 | ```sh 88 | nano netpol.yaml 89 | ``` 90 | ```sh 91 | --- 92 | apiVersion: networking.k8s.io/v1 93 | kind: NetworkPolicy 94 | metadata: 95 | name: default-deny-egress 96 | spec: 97 | podSelector: {} 98 | policyTypes: 99 | - Egress 100 | ``` 101 | ```sh 102 | kubectl apply -f netpol.yaml 103 | ``` 104 | ```sh 105 | kubectl exec -it pod-2 -- ping google.com 106 | kubectl exec -n external -it pod-3 -- ping [pod1] 107 | kubectl exec -n external -it pod-3 -- ping [pod2] 108 | ``` 109 | ```sh 110 | kubectl delete -f netpol.yaml 111 | ``` 112 | ### Rule 4 - PodSelector: 113 | 114 | ```sh 115 | nano netpol.yaml 116 | ``` 117 | ```sh 118 | --- 119 | apiVersion: networking.k8s.io/v1 120 | kind: NetworkPolicy 121 | metadata: 122 | name: podselector-suspicous 123 | spec: 124 | podSelector: 125 | matchLabels: 126 | role: suspicious 127 | policyTypes: 128 | - Ingress 129 | - Egress 130 | ``` 131 | ```sh 132 | kubectl apply -f netpol.yaml 133 | ``` 134 | ```sh 135 | kubectl label pod pod-1 role=suspicious 136 | kubectl get pods --show-labels 137 | kubectl exec -it pod-2 -- ping [pod-1] 138 | kubectl exec -it pod-1 -- ping google.com 139 | ``` 140 | Remove the label and verify: 141 | 142 | ```sh 143 | kubectl label pod pod-1 role- 144 | kubectl exec -it pod-1 -- ping google.com 145 | ``` 146 | ```sh 147 | kubectl delete -f netpol.yaml 148 | ``` 149 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/netpol-02.md: -------------------------------------------------------------------------------- 1 | 2 | ### Example 1 - Except Field 3 | 4 | ```sh 5 | apiVersion: networking.k8s.io/v1 6 | kind: NetworkPolicy 7 | metadata: 8 | name: except 9 | spec: 10 | podSelector: 11 | matchLabels: 12 | role: database 13 | ingress: 14 | - from: 15 | - ipBlock: 16 | cidr: 172.17.0.0/16 17 | except: 18 | - 172.17.1.0/24 19 | policyTypes: 20 | - Ingress 21 | ``` 22 | ```sh 23 | kubectl create -f except.yaml 24 | ``` 25 | 26 | 27 | ### Example 2 - Port and Protocol 28 | ```sh 29 | apiVersion: networking.k8s.io/v1 30 | kind: NetworkPolicy 31 | metadata: 32 | name: multi-port-egress 33 | namespace: default 34 | spec: 35 | podSelector: 36 | matchLabels: 37 | role: db 38 | policyTypes: 39 | - Egress 40 | egress: 41 | - to: 42 | - ipBlock: 43 | cidr: 10.0.0.0/24 44 | ports: 45 | - protocol: TCP 46 | port: 32000 47 | endPort: 32768 48 | ``` 49 | ```sh 50 | kubectl create -f port-proto.yaml 51 | ``` -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/netpol-practical.md: -------------------------------------------------------------------------------- 1 | 2 | ### Base Network Policy 3 | 4 | `base-netpol.yaml` 5 | 6 | ```sh 7 | apiVersion: networking.k8s.io/v1 8 | kind: NetworkPolicy 9 | metadata: 10 | name: base-network-policy 11 | ``` 12 | 13 | ### Example 1 14 | `example-1.yaml` 15 | 16 | ```sh 17 | apiVersion: networking.k8s.io/v1 18 | kind: NetworkPolicy 19 | metadata: 20 | name: example-1 21 | spec: 22 | podSelector: {} 23 | policyTypes: 24 | - Ingress 25 | - Egress 26 | ``` 27 | 28 | Create Pod for Testing 29 | 30 | ```sh 31 | kubectl run test-pod --image=alpine/curl -- sleep 36000 32 | kubectl get pods 33 | kubectl exec -it test-pod --sh 34 | ping 35 | curl 36 | ping google.com 37 | ``` 38 | ```sh 39 | kubectl create -f example-1.yaml 40 | kubectl get netpol 41 | kubectl describe netpol base-network-policy 42 | ``` 43 | 44 | Testing the setup 45 | ```sh 46 | kubectl exec -it test-pod --sh 47 | ping google.com 48 | ``` 49 | 50 | ```sh 51 | kubectl delete -f example-1.yaml 52 | ``` 53 | ### Example 2 54 | `example-2.yaml` 55 | ```sh 56 | apiVersion: networking.k8s.io/v1 57 | kind: NetworkPolicy 58 | metadata: 59 | name: example-2 60 | spec: 61 | podSelector: {} 62 | ingress: 63 | - {} 64 | policyTypes: 65 | - Ingress 66 | - Egress 67 | ``` 68 | ```sh 69 | kubectl create -f example-2.yaml 70 | kubectl describe netpol base-network-policy 71 | ``` 72 | Testing the Setup 73 | ```sh 74 | kubectl run random-pod --image=alpine/curl -- sleep 36000 75 | kubectl get pods -o wide 76 | kubectl exec -it random-pod --sh 77 | ping 78 | ``` 79 | ```sh 80 | kubectl create ns testing 81 | kubectl run random-pod -n testing --image=alpine/curl -- sleep 36000 82 | kubectl get pods -n testing 83 | kubectl exec -it random-pod -n testing --sh 84 | ping 85 | ``` 86 | 87 | ### Example 3 88 | `example-3.yaml` 89 | ```sh 90 | apiVersion: networking.k8s.io/v1 91 | kind: NetworkPolicy 92 | metadata: 93 | name: example-3 94 | spec: 95 | podSelector: 96 | matchLabels: 97 | role: suspicious 98 | policyTypes: 99 | - Ingress 100 | - Egress 101 | ``` 102 | ```sh 103 | kubectl create -f example-3.yaml 104 | ``` 105 | 106 | Testing the Setup 107 | ```sh 108 | kubectl run suspicious-pod --image=alpine/curl -- sleep 36000 109 | kubectl label pod suspicious-pod role=suspicious 110 | kubectl exec -it suspicious-pod --sh 111 | ping google.com 112 | ``` 113 | ### Example 4 114 | `example-4.yaml` 115 | ```sh 116 | apiVersion: networking.k8s.io/v1 117 | kind: NetworkPolicy 118 | metadata: 119 | name: example-4 120 | spec: 121 | podSelector: 122 | matchLabels: 123 | role: database 124 | ingress: 125 | - from: 126 | - podSelector: 127 | matchLabels: 128 | role: app 129 | policyTypes: 130 | - Ingress 131 | ``` 132 | ```sh 133 | kubectl create -f example-4.yaml 134 | ``` 135 | Testing the Setup 136 | ```sh 137 | kubectl run app-pod --image=alpine/curl -- sleep 36000 138 | kubectl run database-pod --image=alpine/curl -- sleep 36000 139 | kubectl get pods -o wide 140 | 141 | kubectl exec -it test-pod --sh 142 | ping 143 | 144 | kubectl label pod app-pod role=app 145 | kubectl exec -it app-pod --sh 146 | ping 147 | ``` 148 | ```sh 149 | kubectl delete -f example-4.yaml 150 | ``` 151 | 152 | ### Example 5 153 | `example-5.yaml` 154 | ```sh 155 | apiVersion: networking.k8s.io/v1 156 | kind: NetworkPolicy 157 | metadata: 158 | name: example-5 159 | namespace: production 160 | spec: 161 | podSelector: {} 162 | ingress: 163 | - from: 164 | - namespaceSelector: 165 | matchLabels: 166 | kubernetes.io/metadata.name: security 167 | policyTypes: 168 | - Ingress 169 | ``` 170 | ```sh 171 | kubectl create -f example-5.yaml 172 | ``` 173 | 174 | ```sh 175 | kubectl create ns production 176 | kubectl create ns security 177 | 178 | kubectl get ns --show-labels 179 | 180 | kubectl run prod-pod -n production --image=alpine/curl -- sleep 36000 181 | kubectl run security-pod -n security --image=alpine/curl -- sleep 36000 182 | 183 | kubectl exec -it security-pod -n security --sh 184 | ping 185 | ``` 186 | ```sh 187 | kubectl delete -f example-5.yaml 188 | ``` 189 | ### Example 6 190 | `example-6.yaml` 191 | ```sh 192 | apiVersion: networking.k8s.io/v1 193 | kind: NetworkPolicy 194 | metadata: 195 | name: example-6 196 | namespace: production 197 | spec: 198 | podSelector: {} 199 | egress: 200 | - to: 201 | - ipBlock: 202 | cidr: 8.8.8.8/32 203 | policyTypes: 204 | - Egress 205 | ``` 206 | ```sh 207 | kubectl create -f example-6.yaml 208 | `` 209 | ```sh 210 | kubectl exec -it prod-pod -n production -- sh 211 | ping 8.8.8.8 212 | ``` 213 | ```sh 214 | kubectl delete -f example-6.yaml 215 | ``` 216 | ### Remove the Created Resources 217 | ```sh 218 | kubectl delete pods --all 219 | kubectl delete pod security-pod -n security 220 | kubectl delete pod prod-pod -n production 221 | kubectl delete pods --all -n testing 222 | 223 | kubectl delete ns testing 224 | kubectl delete ns production 225 | kubectl delete ns security 226 | ``` 227 | 228 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/netpol-structure.md: -------------------------------------------------------------------------------- 1 | 2 | ### Manifest File Used in Video 3 | 4 | first-netpol.yaml 5 | 6 | ```sh 7 | apiVersion: networking.k8s.io/v1 8 | kind: NetworkPolicy 9 | metadata: 10 | name: demo-network-policy 11 | spec: 12 | podSelector: 13 | matchLabels: 14 | env: production 15 | policyTypes: 16 | - Ingress 17 | - Egress 18 | ingress: 19 | - from: 20 | - podSelector: 21 | matchLabels: 22 | env: security 23 | egress: 24 | - to: 25 | - ipBlock: 26 | cidr: 8.8.8.8/32 27 | ``` 28 | ```sh 29 | kubectl create -f first-netpol.yaml 30 | 31 | kubectl describe netpol demo-network-policy 32 | ``` 33 | ### Delete the Resource created 34 | ```sh 35 | kubectl delete -f first-netpol.yaml 36 | ``` -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/nodeport.md: -------------------------------------------------------------------------------- 1 | ### Base Service Manifest File Used 2 | 3 | service.yaml 4 | 5 | ```sh 6 | apiVersion: v1 7 | kind: Service 8 | metadata: 9 | name: nodeport-service 10 | spec: 11 | selector: 12 | app: backend 13 | ports: 14 | - port: 80 15 | targetPort: 80 16 | ``` 17 | 18 | ### Creating NodePort Service Type 19 | 20 | ```sh 21 | apiVersion: v1 22 | kind: Service 23 | metadata: 24 | name: nodeport-service 25 | spec: 26 | selector: 27 | app: backend 28 | type: NodePort 29 | ports: 30 | - port: 80 31 | targetPort: 80 32 | ``` 33 | ```sh 34 | kubectl create -f service.yaml 35 | ``` 36 | ### Create Necessary Pods to Match Service Selector 37 | ```sh 38 | kubectl run backend-pod --image=nginx 39 | 40 | kubectl label pod backend-pod app=backend 41 | 42 | kubectl describe service nodeport-service 43 | ``` 44 | ### Fetch the Worker Node IP to make a request 45 | ```sh 46 | kubectl get nodes -o wide 47 | 48 | curl 49 | ``` 50 | ### Create NodePort Manifest from CLI 51 | ```sh 52 | kubectl create service nodeport --help 53 | 54 | kubectl create service nodeport test-nodeport --tcp=80:80 --dry-run=client -o ya```ml 55 | ``` 56 | 57 | ### Manually Define NodePort in Manifest 58 | 59 | ```sh 60 | apiVersion: v1 61 | kind: Service 62 | metadata: 63 | name: nodeport-service 64 | spec: 65 | type: NodePort 66 | ports: 67 | - port: 80 68 | targetPort: 80 69 | nodePort: 30556 70 | ``` 71 | ```sh 72 | kubectl delete service nodeport-service 73 | 74 | kubectl create -f service.yaml 75 | ``` 76 | 77 | #### Step 5: Delete All the Resources 78 | ```sh 79 | kubectl delete pod backend-pod 80 | kubectl delete -f service.yaml 81 | ``` 82 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/nodeport.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: kplabs-nodeport 5 | spec: 6 | selector: 7 | run: nginx 8 | type: NodePort 9 | ports: 10 | - port: 80 11 | targetPort: 80 12 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/sa-pointers.md: -------------------------------------------------------------------------------- 1 | #### Verify Default Service Account In Namespace 2 | ```sh 3 | kubectl get serviceaccount 4 | kubectl get sa 5 | kubectl get sa -n kube-system 6 | ``` 7 | #### Create New Namespace 8 | ```sh 9 | kubectl create namespace kplabs-test 10 | ``` 11 | #### Verify if Default Service Account Gets Created in Namespace 12 | ```sh 13 | kubectl get sa -n kplabs-test 14 | ``` 15 | #### Create New Pod in Newly Created Namespace 16 | ```sh 17 | kubectl run nginx-pod -n kplabs-test --image=nginx 18 | kubectl get pods -n kplabs-test 19 | kubectl describe pod nginx-pod -n kplabs-test 20 | ``` 21 | #### Verify if Mounted Token is Available inside Pod 22 | ```sh 23 | kubectl exec -it nginx-pod -n kplabs-test -- bash 24 | cd /var/run/secrets/kubernetes.io/serviceaccount/ 25 | ls 26 | cat token 27 | ``` 28 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/sa-practical.md: -------------------------------------------------------------------------------- 1 | ### Documentation Referred: 2 | 3 | https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ 4 | 5 | 6 | #### Create New Service Account 7 | ```sh 8 | kubectl create serviceaccount custom-sa 9 | ``` 10 | 11 | #### Generate Base Pod Manifest 12 | ```sh 13 | kubectl run custom-pod --image=nginx --dry-run=client -o yaml > custom-pod-sa.yaml 14 | ``` 15 | #### Final Edited Manifest 16 | ```sh 17 | apiVersion: v1 18 | kind: Pod 19 | metadata: 20 | name: custom-pod 21 | spec: 22 | serviceAccountName: custom-sa 23 | containers: 24 | - image: nginx 25 | name: custom-pod 26 | ``` 27 | ```sh 28 | kubectl apply -f custom-pod-sa.yaml 29 | `````` -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/service-account.md: -------------------------------------------------------------------------------- 1 | #### List service account in all namespaces 2 | ```sh 3 | kubectl get serviceaccount --all-namespaces 4 | ``` 5 | 6 | #### Create a Test App Pod 7 | ```sh 8 | kubectl run app-pod --image=nginx 9 | kubectl get pods 10 | ``` 11 | #### Verify Namespace associated with Pod 12 | ```sh 13 | kubectl describe pod app-pod 14 | ``` 15 | #### Verify Mounted Token in Pod 16 | ```sh 17 | kubectl exec -it app-pod -- bash 18 | 19 | cd /var/run/secrets/kubernetes.io/serviceaccount/ 20 | 21 | ls 22 | 23 | cat token 24 | ``` 25 | #### Connect to Kubernetes Cluster using Token 26 | ```sh 27 | token=$(cat token) 28 | echo $token 29 | 30 | kubectl cluster-info (from outside of Pod) 31 | 32 | curl -k -H "Authorization: Bearer $token" https://control-plane-url-here/api/v1 33 | ``` 34 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/service-endpoints.md: -------------------------------------------------------------------------------- 1 | 2 | #### Step 1: Create Backend Pod 3 | ```sh 4 | kubectl run backend-pod --image=nginx 5 | ``` 6 | #### Step 2: Create Frontend Pod 7 | ```sh 8 | kubectl run frontend-pod --image=ubuntu --command -- sleep 36000 9 | ``` 10 | #### Step 3: Test the Connection between Frontend and Backend PODs 11 | ```sh 12 | kubectl get pods -o wide 13 | kubectl exec -it frontend-pod -- bash 14 | apt-get update && apt-get -y install curl 15 | curl 16 | ``` 17 | #### Step 4: Create a new Service 18 | 19 | ```sh 20 | service.yaml file 21 | ``` 22 | ```sh 23 | apiVersion: v1 24 | kind: Service 25 | metadata: 26 | name: simple-service 27 | spec: 28 | ports: 29 | - port: 80 30 | targetPort: 80 31 | ``` 32 | ``` 33 | kubectl create -f service.yaml 34 | kubectl get service 35 | kubectl describe service simple-service 36 | ``` 37 | #### Step 5: Create Endpoint for Service 38 | ```sh 39 | endpoint.yaml 40 | ``` 41 | Make sure to change the IP address to `backend-pod` ip. 42 | 43 | ```sh 44 | apiVersion: v1 45 | kind: Endpoints 46 | metadata: 47 | name: simple-service 48 | subsets: 49 | - addresses: 50 | - ip: 10.244.0.23 51 | ports: 52 | - port: 80 53 | ``` 54 | ```sh 55 | kubectl create -f endpoint.yaml 56 | 57 | kubectl describe service simple-service 58 | ``` 59 | #### Step 6: Test the Connection 60 | ```sh 61 | kubectl exec -it frontend-pod -- bash 62 | curl 63 | ``` 64 | 65 | ### Step 7: Testing Port vs TargetPort 66 | 67 | Modify the `service.yaml` file to change Port to 8080 68 | ```sh 69 | apiVersion: v1 70 | kind: Service 71 | metadata: 72 | name: simple-service 73 | spec: 74 | ports: 75 | - port: 8080 76 | targetPort: 80 77 | ``` 78 | ``` 79 | kubectl delete -f service.yaml 80 | 81 | kubectl create -f service.yaml 82 | kubectl create -f endpoint.yaml 83 | kubectl describe service simple-service 84 | ``` 85 | 86 | #### Step 8: Test the Connectivity 87 | ```sh 88 | kubectl exec -it frontend-pod -- bash 89 | curl :8080 90 | ``` 91 | 92 | #### Step 9: Delete the Created Resources 93 | ```sh 94 | kubectl delete -f service.yaml 95 | 96 | kubectl delete pod backend-pod 97 | 98 | kubectl delete pod frontend-pod 99 | ``` 100 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/service-manifest-cli.md: -------------------------------------------------------------------------------- 1 | 2 | #### Pre-Requisite Step 1: Create a new POD with name nginx 3 | ```sh 4 | kubectl run nginx --image=nginx 5 | ``` 6 | #### Pre-Requisite Step 2: Create a New Deployment 7 | ```sh 8 | nano service-deployment.yaml 9 | ``` 10 | ```sh 11 | apiVersion: apps/v1 12 | kind: Deployment 13 | metadata: 14 | name: kplabs-deployment 15 | spec: 16 | replicas: 3 17 | selector: 18 | matchLabels: 19 | tier: frontend 20 | template: 21 | metadata: 22 | labels: 23 | tier: frontend 24 | spec: 25 | containers: 26 | - name: nginx 27 | image: nginx 28 | ``` 29 | ```sh 30 | kubectl apply -f service-deployment.yaml 31 | ``` 32 | #### Step 1: Generate Service Manifest - POD 33 | ```sh 34 | kubectl expose pod nginx --name nginx-service --port=80 --target-port=80 --dry-run=client -o yaml 35 | 36 | kubectl expose pod nginx --name nginx-service --port=80 --target-port=80 --dry-run=client -o yaml > service-01.yaml 37 | 38 | kubectl describe service nginx-svc 39 | ``` 40 | #### Step 2: Generate NodePort Service Manifest - POD 41 | ```sh 42 | kubectl expose pod nginx --name nginx-nodeport-service --port=80 --target-port=80 --type=NodePort --dry-run=client -o yaml 43 | 44 | kubectl get service 45 | ``` 46 | 47 | #### Step 3: Generate Service Manifest - Deployment 48 | ```sh 49 | kubectl expose deployment kplabs-deployment --name nginx-deployment-service --port=80 --target-port=8000 50 | 51 | kubectl describe service nginx-deployment-service 52 | ``` 53 | 54 | ### Step 4: Delete Resources 55 | ```sh 56 | kubectl delete pod nginx 57 | kubectl delete deployment kplabs-deployment 58 | kubectl delete service nginx-service 59 | kubectl delete service nginx-nodeport-service 60 | kubectl delete service nginx-deployment-service 61 | ``` 62 | -------------------------------------------------------------------------------- /Domain 3 - Services and Networking/service-selector.md: -------------------------------------------------------------------------------- 1 | 2 | #### Step 1: Creating Deployments 3 | ```sh 4 | nano demo-deployment.yaml 5 | ``` 6 | ```sh 7 | apiVersion: apps/v1 8 | kind: Deployment 9 | metadata: 10 | name: nginx-deployment 11 | labels: 12 | app: nginx 13 | spec: 14 | replicas: 3 15 | selector: 16 | matchLabels: 17 | app: nginx 18 | template: 19 | metadata: 20 | labels: 21 | app: nginx 22 | spec: 23 | containers: 24 | - name: nginx 25 | image: nginx:1.14.2 26 | ports: 27 | - containerPort: 80 28 | ``` 29 | ```sh 30 | kubectl apply -f demo-deployment.yaml 31 | ``` 32 | 33 | #### Step 2: Creating Service 34 | ```sh 35 | nano service-selector.yaml 36 | ``` 37 | ```sh 38 | apiVersion: v1 39 | kind: Service 40 | metadata: 41 | name: kplabs-service-selector 42 | spec: 43 | selector: 44 | app: nginx 45 | ports: 46 | - port: 80 47 | targetPort: 80 48 | ``` 49 | ```sh 50 | kubectl apply -f service-selector.yaml 51 | ``` 52 | 53 | #### Step 3: Verify Endpoints in Service 54 | ```sh 55 | kubectl describe service kplabs-service-selector 56 | ``` 57 | 58 | #### Step 4: Scale Deployments 59 | ```sh 60 | kubectl scale deployment/nginx-deployment --replicas=10 61 | ``` 62 | 63 | #### Step 5: Verify Endpoints in Service 64 | ```sh 65 | kubectl describe service kplabs-service-selector 66 | ``` 67 | 68 | #### Step 6: Create a New Manual POD and Add a Label 69 | ```sh 70 | kubectl run manual-pod --image=nginx 71 | kubectl label pods manual-pod app=nginx 72 | ``` 73 | 74 | #### Step 7: Verify Endpoints in Service 75 | ```sh 76 | kubectl describe service kplabs-service-selector 77 | kubectl describe endpoints kplabs-service-selector 78 | ``` 79 | 80 | #### Step 8: Delete Created Resources 81 | ```sh 82 | kubectl delete service kplabs-service-selector 83 | kubectl delete -f demo-deployment.yaml 84 | kubectl delete pod manual-pod 85 | ``` 86 | -------------------------------------------------------------------------------- /Domain 4 - Configuration/Readme.md: -------------------------------------------------------------------------------- 1 | # Domain 4 - Configuration 2 | 3 | The code mentioned in this document are used in the Certified Kubernetes Application Developer 2025 course. 4 | 5 | https://www.udemy.com/course/mastering-certified-kubernetes-application-developer/?referralCode=3A549BA24AC8ED6597DF 6 | 7 | 8 | # Video-Document Mapper 9 | 10 | | Sr No | Document Link | 11 | | ------ | ------ | 12 | | 1 | [Kubernetes Secrets][PlDa] | 13 | | 2 | [Mounting Secrets Inside Pods][PlDb] | 14 | | 3 | [Requests and Limits][PlDc] 15 | | 4 | [Limit Ranges][PlDd] 16 | | 5 | [Practical - Resource Quota][PlDe] 17 | | 6 | [Pod Lifecycle Phases][PlDf] 18 | | 7 | [Container Restart Policy][PlDg] 19 | | 8 | [Pod and Environment Variables][PlDh] 20 | 21 | [PlDa]: <./secret-data.md> 22 | [PlDb]: <./mounting-secrets.md> 23 | [PlDc]: <./requests-limits.md> 24 | [PlDd]: <./limit-ranges.md> 25 | [PlDe]: <./resource-quota.md> 26 | [PlDf]: <./pod-phases.md> 27 | [PlDg]: <./restartPolicy.md> 28 | [PlDh]: <./pod-env-variables.md> -------------------------------------------------------------------------------- /Domain 4 - Configuration/limit-ranges.md: -------------------------------------------------------------------------------- 1 | ### Documentation Referenced: 2 | 3 | https://kubernetes.io/docs/concepts/policy/limit-range/ 4 | 5 | ## Use-Case 1 - Set Default Request/Limits for a Container 6 | ```sh 7 | kubectl create namespace lr-demo 8 | ``` 9 | ```sh 10 | nano limitranges-eg1.yaml 11 | ``` 12 | ```sh 13 | apiVersion: v1 14 | kind: LimitRange 15 | metadata: 16 | name: resource-limits 17 | namespace: lr-demo 18 | spec: 19 | limits: 20 | - default: 21 | cpu: "100m" 22 | memory: "128Mi" 23 | defaultRequest: 24 | cpu: "50m" 25 | memory: "64Mi" 26 | type: Container 27 | ``` 28 | ```sh 29 | kubectl create -f limitranges-eg1.yaml 30 | ``` 31 | ```sh 32 | kubectl get limitrange resource-limits -n lr-demo 33 | 34 | kubectl describe limitrange resource-limits -n lr-demo 35 | 36 | ``` 37 | ### Test 1 - Deploy a Pod Without Resource Requests/Limits 38 | ```sh 39 | nano test-pod-1.yaml 40 | ``` 41 | ```sh 42 | apiVersion: v1 43 | kind: Pod 44 | metadata: 45 | name: test-pod-1 46 | namespace: lr-demo 47 | spec: 48 | containers: 49 | - name: busybox 50 | image: busybox 51 | command: ["sleep", "3600"] 52 | ``` 53 | ```sh 54 | kubectl apply -f test-pod-1.yaml 55 | ``` 56 | ```sh 57 | kubectl get pod test-pod-1 -o yaml -n lr-demo 58 | 59 | kubectl delete -f test-pod-1.yaml 60 | ``` 61 | 62 | ### Test 2 - Deploy a Pod Over the Limit 63 | ```sh 64 | nano test-pod-2.yaml 65 | ``` 66 | ```sh 67 | apiVersion: v1 68 | kind: Pod 69 | metadata: 70 | name: test-pod-2 71 | namespace: lr-demo 72 | spec: 73 | containers: 74 | - name: busybox 75 | image: busybox 76 | command: ["sleep", "3600"] 77 | resources: 78 | limits: 79 | cpu: "102m" 80 | memory: "130Mi" 81 | ``` 82 | ```sh 83 | kubectl apply -f test-pod-2.yaml 84 | ``` 85 | ```sh 86 | kubectl delete -f test-pod-2.yaml 87 | 88 | kubectl delete -f limitranges-eg1.yaml 89 | ``` 90 | ## Use-Case 2 - Set Minimum/Maximum for a Container 91 | ```sh 92 | nano limitranges-eg2.yaml 93 | ``` 94 | ```sh 95 | apiVersion: v1 96 | kind: LimitRange 97 | metadata: 98 | name: stricter-limits 99 | namespace: lr-demo 100 | spec: 101 | limits: 102 | - type: Container 103 | max: 104 | cpu: "100m" 105 | memory: "128Mi" 106 | min: 107 | cpu: "30m" 108 | memory: "50Mi" 109 | ``` 110 | 111 | ```sh 112 | kubectl create -f limitranges-eg2.yaml 113 | ``` 114 | ```sh 115 | kubectl describe limitrange stricter-limits -n lr-demo 116 | 117 | ``` 118 | 119 | ### Test Case 1: Below Minimum Limit 120 | ```sh 121 | nano test-pod-3.yaml 122 | ``` 123 | ```sh 124 | apiVersion: v1 125 | kind: Pod 126 | metadata: 127 | name: pod-below-min 128 | namespace: lr-demo 129 | spec: 130 | containers: 131 | - name: busybox 132 | image: busybox 133 | command: ["sleep", "3600"] 134 | resources: 135 | limits: 136 | cpu: "20m" 137 | memory: "64Mi" 138 | requests: 139 | cpu: "20m" 140 | memory: "64Mi" 141 | ``` 142 | 143 | ```sh 144 | kubectl create -f test-pod-3.yaml 145 | ``` 146 | 147 | ### Test Case 2: Above Maximum Limit 148 | ```sh 149 | nano test-pod-4.yaml 150 | ``` 151 | ```sh 152 | apiVersion: v1 153 | kind: Pod 154 | metadata: 155 | name: pod-above-max 156 | namespace: lr-demo 157 | spec: 158 | containers: 159 | - name: busybox 160 | image: busybox 161 | command: ["sleep", "3600"] 162 | resources: 163 | requests: 164 | cpu: "90m" 165 | memory: "256Mi" 166 | ``` 167 | 168 | ```sh 169 | kubectl create -f test-pod-4.yaml 170 | ``` 171 | 172 | ```sh 173 | kubectl delete -f limitranges-eg2.yaml 174 | 175 | kubectl delete namespace lr-demo 176 | ``` 177 | -------------------------------------------------------------------------------- /Domain 4 - Configuration/mounting-secrets.md: -------------------------------------------------------------------------------- 1 | ##### secretpod.yaml 2 | 3 | ```sh 4 | apiVersion: v1 5 | kind: Pod 6 | metadata: 7 | name: secretmount 8 | spec: 9 | containers: 10 | - name: secretmount 11 | image: nginx 12 | volumeMounts: 13 | - name: foo 14 | mountPath: "/etc/foo" 15 | readOnly: true 16 | volumes: 17 | - name: foo 18 | secret: 19 | secretName: firstsecret 20 | ``` 21 | 22 | ##### secret-env.yaml 23 | 24 | ```sh 25 | apiVersion: v1 26 | kind: Pod 27 | metadata: 28 | name: secret-env 29 | spec: 30 | containers: 31 | - name: secret-env 32 | image: nginx 33 | env: 34 | - name: SECRET_USERNAME 35 | valueFrom: 36 | secretKeyRef: 37 | name: firstsecret 38 | key: dbpass 39 | restartPolicy: Never 40 | ``` 41 | -------------------------------------------------------------------------------- /Domain 4 - Configuration/pod-env-variables.md: -------------------------------------------------------------------------------- 1 | 2 | ### Documentation Referenced: 3 | 4 | https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/ 5 | 6 | ### Create Pod with Env Variable 7 | 8 | `pod-env.yaml` 9 | ```sh 10 | apiVersion: v1 11 | kind: Pod 12 | metadata: 13 | name: env-pod 14 | spec: 15 | containers: 16 | - name: busybox 17 | image: busybox:latest 18 | command: ["sleep","3600"] 19 | env: 20 | - name: DB_HOST 21 | value: "prod-db.kplabs.internal" 22 | - name: DB_PASS 23 | value: "notsosecretpassword" 24 | ``` 25 | ```sh 26 | kubectl create -f pod-env.yaml 27 | ``` 28 | ### Verification 29 | ```sh 30 | kubectl exec -it env-pod -- sh 31 | 32 | echo $DB_HOSt 33 | 34 | echo $DB_PASS 35 | ``` 36 | 37 | ### Delete the Resource Created 38 | 39 | ```sh 40 | kubectl delete -f pod-env.yaml 41 | ``` 42 | -------------------------------------------------------------------------------- /Domain 4 - Configuration/pod-phases.md: -------------------------------------------------------------------------------- 1 | 2 | ### Pending Phase Example 3 | ```sh 4 | nano pending-pod.yaml 5 | ``` 6 | ```sh 7 | apiVersion: v1 8 | kind: Pod 9 | metadata: 10 | name: app-pod 11 | spec: 12 | containers: 13 | - name: myapp-container 14 | image: nginx 15 | resources: 16 | requests: 17 | memory: "100Gi" 18 | cpu: "100" 19 | ``` 20 | ```sh 21 | kubectl create -f pending-pod.yaml 22 | ``` 23 | ```sh 24 | kubectl get pods 25 | ``` 26 | ### Succeeded Phase Example 27 | ```sh 28 | nano pod-succeded.yaml 29 | ``` 30 | ```sh 31 | apiVersion: v1 32 | kind: Pod 33 | metadata: 34 | name: test-pod 35 | spec: 36 | restartPolicy: Never 37 | containers: 38 | - name: busybox 39 | image: busybox 40 | command: ["echo", "Hello, Kubernetes!"] 41 | ``` 42 | 43 | ```sh 44 | kubectl create -f pod-succeded.yaml 45 | ``` 46 | ```sh 47 | kubectl get pods 48 | ``` 49 | 50 | ### Failed Phase Example 51 | ```sh 52 | kubectl run failpod --image=busybox --restart=Never -- /bin/sh -c "exit 1" 53 | ``` 54 | 55 | ### Additional Testing 56 | ```sh 57 | kubectl run nginx-pod --image=nginx:notexistent 58 | 59 | kubectl run curl-pod --image=alpine/curl 60 | ``` 61 | -------------------------------------------------------------------------------- /Domain 4 - Configuration/requests-limits.md: -------------------------------------------------------------------------------- 1 | 2 | ### Documentation Referenced: 3 | 4 | https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ 5 | 6 | ### Base Pod Manifest File (request-limit.yaml) 7 | 8 | ```sh 9 | apiVersion: v1 10 | kind: Pod 11 | metadata: 12 | name: kplabs-pod 13 | spec: 14 | containers: 15 | - name: kplabs-container 16 | image: nginx 17 | ``` 18 | 19 | ### Final Pod Manifest File with Request and Limits 20 | 21 | ```sh 22 | apiVersion: v1 23 | kind: Pod 24 | metadata: 25 | name: kplabs-pod 26 | spec: 27 | containers: 28 | - name: kplabs-container 29 | image: nginx 30 | resources: 31 | requests: 32 | memory: "128Mi" 33 | cpu: "0.1" 34 | limits: 35 | memory: "500Mi" 36 | cpu: "1" 37 | ``` 38 | 39 | ### Commands Used in Video 40 | ```sh 41 | kubectl describe node 42 | 43 | kubectl apply -f request-limit.yaml 44 | 45 | kubectl delete -f request-limit.yaml 46 | ``` -------------------------------------------------------------------------------- /Domain 4 - Configuration/resource-quota.md: -------------------------------------------------------------------------------- 1 | ### Documentation Referenced: 2 | 3 | https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/ 4 | 5 | https://kubernetes.io/docs/concepts/policy/resource-quotas/ 6 | 7 | ### Create Namespace for today's practical 8 | ```sh 9 | kubectl create namespace quota-demo 10 | ``` 11 | ### Setting Compute Quota 12 | ```sh 13 | nano compute-quota.yaml 14 | ``` 15 | ```sh 16 | apiVersion: v1 17 | kind: ResourceQuota 18 | metadata: 19 | name: mem-cpu-demo 20 | namespace: quota-demo 21 | spec: 22 | hard: 23 | requests.cpu: "100m" 24 | requests.memory: "128Mi" 25 | limits.cpu: "200m" 26 | limits.memory: "256Mi" 27 | ``` 28 | 29 | ```sh 30 | kubectl create -f compute-quota.yaml 31 | ``` 32 | 33 | #### Test 1 - Pod with Exceeded Quota 34 | ```sh 35 | nano test-pod-1.yaml 36 | ``` 37 | ```sh 38 | apiVersion: v1 39 | kind: Pod 40 | metadata: 41 | name: test-pod-fail 42 | namespace: quota-demo 43 | spec: 44 | containers: 45 | - name: demo 46 | image: busybox 47 | command: ["sleep", "3600"] 48 | resources: 49 | requests: 50 | cpu: "101m" 51 | memory: "128Mi" 52 | limits: 53 | cpu: "101m" 54 | memory: "128Mi" 55 | ``` 56 | ```sh 57 | kubectl create -f test-pod-1.yaml 58 | ``` 59 | #### Test 2 - Pod without Request/Limits 60 | ```sh 61 | kubectl run nginx-pod --image=nginx -n quota-demo 62 | ``` 63 | ```sh 64 | kubectl delete -f compute-quota.yaml 65 | 66 | ``` 67 | 68 | ### Setting Object Quota 69 | 70 | ```sh 71 | nano object-quota.yaml 72 | ``` 73 | 74 | ```sh 75 | apiVersion: v1 76 | kind: ResourceQuota 77 | metadata: 78 | name: object-count-quota 79 | namespace: quota-demo 80 | spec: 81 | hard: 82 | pods: "1" 83 | secrets: "3" 84 | services: "10" 85 | services.loadbalancers: "2" 86 | ``` 87 | 88 | ```sh 89 | kubectl create -f object-quota.yaml 90 | ``` 91 | 92 | #### Test 2 - Launch two Pods 93 | 94 | ```sh 95 | kubectl run test-pod-1 --image=nginx -n quota-demo 96 | 97 | kubectl run test-pod-2 --image=nginx -n quota-demo 98 | ``` 99 | 100 | ### Delete Resources Created 101 | ```sh 102 | kubectl delete pods --all -n quota-demo --force 103 | 104 | kubectl delete namespace quota-demo 105 | ``` 106 | -------------------------------------------------------------------------------- /Domain 4 - Configuration/restartPolicy.md: -------------------------------------------------------------------------------- 1 | 2 | ### 1 - Always Restart Policy 3 | ```sh 4 | kubectl run test-pod --image=busybox -- nonexistentcommand 5 | ``` 6 | ```sh 7 | kubectl get pods -w 8 | ``` 9 | 10 | ### 2- Never Restart Policy 11 | ```sh 12 | kubectl run test-pod-2 --restart=Never --image=busybox -- nonexistentcommand 13 | 14 | kubectl get pods 15 | ``` 16 | 17 | ### 3- OnFailure Restart Policy 18 | 19 | ```sh 20 | kubectl run test-pod-3 --restart=OnFailure --image=busybox -- nonexistentcommand 21 | 22 | kubectl run test-pod-4 --restart=OnFailure --image=busybox -- echo "Hello Kubernetes" 23 | ``` 24 | 25 | ### Manifest File with Restart Policy 26 | ```sh 27 | kubectl run test-pod-5 --restart=OnFailure --dry-run=client -o yaml --image=busybox -- echo "Hello Kubernetes" 28 | ``` 29 | Rererence Manifest File: 30 | ```sh 31 | apiVersion: v1 32 | kind: Pod 33 | metadata: 34 | labels: 35 | run: test-pod-5 36 | name: test-pod-5 37 | spec: 38 | containers: 39 | - args: 40 | - echo 41 | - Hello Kubernetes 42 | image: busybox 43 | name: test-pod-5 44 | restartPolicy: OnFailure 45 | ``` -------------------------------------------------------------------------------- /Domain 4 - Configuration/secret-data.md: -------------------------------------------------------------------------------- 1 | ##### secret-data.yaml 2 | 3 | ```sh 4 | apiVersion: v1 5 | kind: Secret 6 | metadata: 7 | name: thirdsecret 8 | type: Opaque 9 | data: 10 | username: ZGJhZG1pbg== 11 | password: bXlwYXNzd29yZDEyMw== 12 | ``` 13 | 14 | ##### secret-stringdata.yaml 15 | 16 | ```sh 17 | apiVersion: v1 18 | kind: Secret 19 | metadata: 20 | name: thirdsecret 21 | type: Opaque 22 | data: 23 | username: ZGJhZG1pbg== 24 | password: bXlwYXNzd29yZDEyMw== 25 | 26 | ``` 27 | -------------------------------------------------------------------------------- /Domain 5 - Application Observability and Maintenance/Readme.md: -------------------------------------------------------------------------------- 1 | # Domain 4 - Observability 2 | 3 | The code mentioned in this document are used in the Certified Kubernetes Application Developer 2025 course. 4 | 5 | https://www.udemy.com/course/mastering-certified-kubernetes-application-developer/ 6 | 7 | 8 | # Video-Document Mapper 9 | 10 | | Sr No | Document Link | 11 | | ------ | ------ | 12 | | 1 | [Liveness Probe][PlDa] | 13 | | 2 | [Readiness Probe][PlDb] | 14 | | 3 | [Practical - Metrics Server][PlDc] | 15 | | 4 | [Kubernetes Events][PlDd] | 16 | | 5 | [Field selectors][PlDe] | 17 | 18 | 19 | 20 | [PlDa]: <./livenessprobe.yaml> 21 | [PlDb]: <./readinessprobe.yaml> 22 | [PlDc]: <./install-metric-server.md> 23 | [PlDd]: <./events.md> 24 | [PlDe]: <./field-selector.md> -------------------------------------------------------------------------------- /Domain 5 - Application Observability and Maintenance/events.md: -------------------------------------------------------------------------------- 1 | #### Documentation Referred: 2 | 3 | https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/ 4 | 5 | #### Get the Events 6 | ```sh 7 | kubectl get events 8 | ``` 9 | #### Create POD 10 | ```sh 11 | kubectl run event-pod --image=nginx 12 | ``` 13 | #### Check for Evetns 14 | ```sh 15 | kubectl get events 16 | ``` 17 | #### Check for Events based on Namespace 18 | ```sh 19 | kubectl get events -n kube-system 20 | kubectl get events -n default 21 | ``` -------------------------------------------------------------------------------- /Domain 5 - Application Observability and Maintenance/field-selector.md: -------------------------------------------------------------------------------- 1 | 2 | #### List all the PODS from All Namespaces 3 | ```sh 4 | kubectl get pods --all-namespaces 5 | ``` 6 | #### List all PODS from ALL namespaces except default namespace 7 | ```sh 8 | kubectl get pods --field-selector metadata.namespace!=default 9 | ``` 10 | #### List all Pods from ALL namespace except a specific POD 11 | ```sh 12 | kubectl get pods --field-selector metadata.name!= 13 | ``` 14 | #### Create New Deployment 15 | ```sh 16 | kubectl create deployment test-deployment --replicas 3 --image=nginx 17 | ``` 18 | #### Get Events with Output JSON 19 | ```sh 20 | kubectl get events -o json 21 | ``` 22 | #### Get Events Associated with a Specific POD 23 | ```sh 24 | kubectl get events --field-selector involvedObject.name=event-pod 25 | ``` 26 | #### Default Configuration 27 | ```sh 28 | kubectl get pods --field-selector "" 29 | ``` -------------------------------------------------------------------------------- /Domain 5 - Application Observability and Maintenance/install-metric-server.md: -------------------------------------------------------------------------------- 1 | #### Documentation Referred: 2 | 3 | https://github.com/kubernetes-sigs/metrics-server 4 | 5 | #### Install Metric Server 6 | ```sh 7 | kubectl apply -f https://raw.githubusercontent.com/zealvora/certified-kubernetes-administrator/refs/heads/master/Domain%203%20-%20Services%20and%20Networking/metric-server.yaml 8 | ``` 9 | #### Verify 10 | ```sh 11 | kubectl top pods 12 | 13 | kubectl top pods -A 14 | 15 | kubectl top nodes 16 | ``` 17 | -------------------------------------------------------------------------------- /Domain 5 - Application Observability and Maintenance/livenessprobe.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: liveness 5 | spec: 6 | containers: 7 | - name: liveness 8 | image: ubuntu 9 | tty: true 10 | livenessProbe: 11 | exec: 12 | command: 13 | - service 14 | - nginx 15 | - status 16 | initialDelaySeconds: 20 17 | periodSeconds: 5 18 | -------------------------------------------------------------------------------- /Domain 5 - Application Observability and Maintenance/readinessprobe.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: readiness 5 | spec: 6 | containers: 7 | - name: readiness 8 | image: ubuntu 9 | tty: true 10 | readinessProbe: 11 | exec: 12 | command: 13 | - cat 14 | - /tmp/healthy 15 | initialDelaySeconds: 5 16 | periodSeconds: 5 17 | -------------------------------------------------------------------------------- /Domain 6 - State Persistence/Readme.md: -------------------------------------------------------------------------------- 1 | # Domain 6 - State Persistence 2 | 3 | The code mentioned in this document are used in the Certified Kubernetes Application Developer 2025 course. 4 | 5 | https://www.udemy.com/course/mastering-certified-kubernetes-application-developer/?referralCode=3A549BA24AC8ED6597DF 6 | 7 | 8 | # Video-Document Mapper 9 | 10 | | Sr No | Document Link | 11 | | ------ | ------ | 12 | | 1 | [emptyDir Volume][PlDa] | 13 | | 2 | [hostPath Volume][PlDb] | 14 | | 3 | [Practical - PV and PVC][PlDc] | 15 | | 4 | [Practical 1 - ConfigMaps (Creation)][PlDd] 16 | | 5 | [Practical 2 - ConfigMaps (Mounting to Pods)][PlDe] 17 | | 6 | [Security Contexts][PlDf] 18 | | 7 | [Privileged Pods][PlDg] 19 | 20 | [PlDa]: <./emptydir.md> 21 | [PlDb]: <./hostPath.md> 22 | [PlDc]: <./pv-pvc.md> 23 | [PlDd]: <./configmap-01.md> 24 | [PlDe]: <./configmap-02.md> 25 | [PlDf]: <./security-context.md> 26 | [PlDg]: <./privileged-pod.md> 27 | -------------------------------------------------------------------------------- /Domain 6 - State Persistence/configmap-01.md: -------------------------------------------------------------------------------- 1 | 2 | ### Creating ConfigMap From Literal 3 | 4 | ```sh 5 | kubectl create configmap --help 6 | 7 | kubectl create configmap first-configmap --from-literal=key1=value1 --from-literal=key2=value2 8 | 9 | kubectl describe configmap first-configmap 10 | 11 | kubectl get configmap first-configmap -o yaml 12 | ``` 13 | 14 | ### Creating ConfigMap From File 15 | 16 | large-file.txt 17 | ```sh 18 | key1=value1 19 | key2=value2 20 | key3=value3 21 | ``` 22 | 23 | ```sh 24 | kubectl create configmap second-configmap --from-file=large-file.txt 25 | 26 | kubectl get configmap second-configmap -o yaml 27 | ``` 28 | ### Creating ConfigMap From Directory 29 | 30 | Contents of Big Folder 31 | 32 | first-file.txt 33 | ```sh 34 | key1=value1 35 | key2=value2 36 | key3=value3 37 | ``` 38 | second-file.txt 39 | ```sh 40 | key4=value4 41 | key5=value5 42 | key6=value6 43 | ``` 44 | ```sh 45 | kubectl create configmap second-configmap --from-file=big-folder 46 | 47 | kubectl get configmap third-configmap -o yaml 48 | ``` 49 | 50 | ### ConfigMap Manifest File (configmap.yaml) 51 | 52 | ```sh 53 | apiVersion: v1 54 | kind: ConfigMap 55 | metadata: 56 | name: manifest-configmap 57 | data: 58 | key1: "value1" 59 | key2: "value2" 60 | 61 | big-data: | 62 | This is Line 1 63 | This is Line 2 64 | This is Line 3 65 | ``` 66 | ```sh 67 | kubectl create -f configmap.yaml 68 | 69 | kubectl get configmap manifest-configmap -o yaml 70 | ``` 71 | 72 | ### Delete All the Resource After Practical 73 | 74 | ```sh 75 | 76 | kubectl delete -f configmap.yaml 77 | 78 | kubectl delete configmap first-configmap 79 | kubectl delete configmap second-configmap 80 | kubectl delete configmap third-configmap 81 | ``` -------------------------------------------------------------------------------- /Domain 6 - State Persistence/configmap-02.md: -------------------------------------------------------------------------------- 1 | ### Base ConfigMap Manifest File Used (configmap.yaml) 2 | 3 | ```sh 4 | apiVersion: v1 5 | kind: ConfigMap 6 | metadata: 7 | name: demo-configmap 8 | data: 9 | DB_HOST: "172.31.10.30:3306" 10 | DB_USER: "dbadmin" 11 | DB_PASS: "db!2312$#" 12 | APP_MODE: "production" 13 | APP_CAPACITY: "100%" 14 | 15 | large-data: | 16 | This is Line 1 17 | This is Line 2 18 | This is Line 3 19 | ``` 20 | ```sh 21 | kubectl create -f configmap.yaml 22 | ``` 23 | 24 | ### Base Pod Manifest File 25 | 26 | ```sh 27 | apiVersion: v1 28 | kind: Pod 29 | metadata: 30 | name: configmap-pod 31 | spec: 32 | containers: 33 | - name: test-container 34 | image: nginx 35 | ``` 36 | 37 | 38 | ### Part 1 - Mount ConfigMap using Volumes 39 | 40 | Documentation Referenced: 41 | 42 | https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#add-configmap-data-to-a-volume 43 | 44 | ```sh 45 | apiVersion: v1 46 | kind: Pod 47 | metadata: 48 | name: configmap-volume-pod 49 | spec: 50 | containers: 51 | - name: nginx-container 52 | image: nginx 53 | volumeMounts: 54 | - name: config-volume 55 | mountPath: /etc/config 56 | volumes: 57 | - name: config-volume 58 | configMap: 59 | name: demo-configmap 60 | ``` 61 | ```sh 62 | kubectl apply -f pod.yaml 63 | ``` 64 | ### Part 2 - Fetching ConfigMap data as Env Variables 65 | 66 | ```sh 67 | apiVersion: v1 68 | kind: Pod 69 | metadata: 70 | name: configmap-env-pod 71 | spec: 72 | containers: 73 | - name: nginx-container 74 | image: nginx 75 | env: 76 | - name: MODE_APP 77 | valueFrom: 78 | configMapKeyRef: 79 | name: demo-configmap 80 | key: APP_MODE 81 | ``` 82 | ```sh 83 | kubectl apply -f pod-env.yaml 84 | ``` 85 | 86 | ### Delete all the Resources After Completing Practical 87 | 88 | ```sh 89 | kubectl delete -f configmap.yaml 90 | kubectl delete -f pod.yaml 91 | kubectl delete -f pod-env.yaml 92 | ``` -------------------------------------------------------------------------------- /Domain 6 - State Persistence/emptydir.md: -------------------------------------------------------------------------------- 1 | ### Documentation Referenced: 2 | 3 | https://kubernetes.io/docs/concepts/storage/volumes/#emptydir 4 | 5 | ### Base Manifest for Multi-Container Pod 6 | ```sh 7 | nano multi-container.yaml 8 | ``` 9 | ```sh 10 | apiVersion: v1 11 | kind: Pod 12 | metadata: 13 | name: multi-container-pod 14 | spec: 15 | containers: 16 | - name: busybox-container-1 17 | image: busybox 18 | command: ["sleep", "36000"] 19 | 20 | - name: busybox-container-2 21 | image: busybox 22 | command: ["sleep", "36000"] 23 | ``` 24 | 25 | ### Final Manifest with emptyDir volume 26 | 27 | ```sh 28 | apiVersion: v1 29 | kind: Pod 30 | metadata: 31 | name: multi-container-pod 32 | spec: 33 | volumes: 34 | - name: kplabs-emptydir 35 | emptyDir: {} 36 | 37 | containers: 38 | - name: busybox-container-1 39 | image: busybox 40 | command: ["sleep", "36000"] 41 | volumeMounts: 42 | - name: kplabs-emptydir 43 | mountPath: /shared-folder 44 | 45 | - name: busybox-container-2 46 | image: busybox 47 | command: ["sleep", "36000"] 48 | volumeMounts: 49 | - name: kplabs-emptydir 50 | mountPath: /shared-folder 51 | ``` 52 | ```sh 53 | kubectl create -f multi-container.yaml 54 | 55 | kubectl get pods 56 | ``` 57 | ### Verification 58 | ```sh 59 | kubectl exec -it multi-container-pod -c busybox-container-1 -- sh 60 | 61 | ls -l / 62 | 63 | cd /shared-folder 64 | 65 | touch container-1-file.txt 66 | ``` 67 | ```sh 68 | kubectl exec -it multi-container-pod -c busybox-container-2 -- sh 69 | 70 | cd /shared-folder 71 | 72 | ls 73 | ``` 74 | 75 | ### Delete the Resources 76 | ```sh 77 | kubectl delete -f multi-container.yaml 78 | ``` -------------------------------------------------------------------------------- /Domain 6 - State Persistence/hostPath.md: -------------------------------------------------------------------------------- 1 | ### Documentation Referenced: 2 | 3 | https://kubernetes.io/docs/concepts/storage/volumes/#hostpath 4 | 5 | ### Create Pod with hostPath Volume 6 | 7 | ```sh 8 | nano hostPath.yaml 9 | ``` 10 | ```sh 11 | apiVersion: v1 12 | kind: Pod 13 | metadata: 14 | name: test-pod 15 | spec: 16 | containers: 17 | - name: test-container 18 | image: busybox 19 | command: ["sleep", "3600"] 20 | volumeMounts: 21 | - name: host-volume 22 | mountPath: /worker-node-data 23 | volumes: 24 | - name: host-volume 25 | hostPath: 26 | path: / 27 | ``` 28 | 29 | ```sh 30 | kubectl create -f hostPath.yaml 31 | ``` 32 | 33 | ### Verification 34 | ```sh 35 | kubectl get pods 36 | 37 | ls -l / 38 | 39 | cd /worker-node-data 40 | 41 | ls -l / 42 | ``` 43 | 44 | ### Delete the Resources 45 | ```sh 46 | kubectl delete -f hostPath.yaml 47 | ``` -------------------------------------------------------------------------------- /Domain 6 - State Persistence/pod-configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: configmap-pod 5 | spec: 6 | containers: 7 | - name: test-container 8 | image: nginx 9 | volumeMounts: 10 | - name: config-volume 11 | mountPath: /etc/config 12 | volumes: 13 | - name: config-volume 14 | configMap: 15 | name: dev-properties 16 | restartPolicy: Never 17 | -------------------------------------------------------------------------------- /Domain 6 - State Persistence/pod-securitycontext.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: pod-context 5 | spec: 6 | securityContext: 7 | runAsUser: 1000 8 | runAsGroup: 3000 9 | containers: 10 | - name: sec-ctx-demo 11 | image: busybox 12 | command: [ "sh", "-c", "sleep 1h" ] 13 | 14 | --- 15 | 16 | apiVersion: v1 17 | kind: Pod 18 | metadata: 19 | name: security-context-demo 20 | spec: 21 | securityContext: 22 | runAsUser: root 23 | runAsGroup: 3000 24 | fsGroup: 2000 25 | volumes: 26 | - name: sec-ctx-vol 27 | emptyDir: {} 28 | containers: 29 | - name: sec-ctx-demo 30 | image: busybox 31 | command: [ "sh", "-c", "sleep 1h" ] 32 | volumeMounts: 33 | - name: sec-ctx-vol 34 | mountPath: /data/demo 35 | -------------------------------------------------------------------------------- /Domain 6 - State Persistence/pod-volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: demopod-volume 5 | spec: 6 | containers: 7 | - image: nginx 8 | name: test-container 9 | volumeMounts: 10 | - mountPath: /data 11 | name: first-volume 12 | volumes: 13 | - name: first-volume 14 | hostPath: 15 | path: /mydata 16 | type: Directory 17 | -------------------------------------------------------------------------------- /Domain 6 - State Persistence/privileged-pod.md: -------------------------------------------------------------------------------- 1 | ### Documentation Referenced: 2 | 3 | https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ 4 | 5 | #### Create Non-Privileged Pod 6 | ```sh 7 | kubectl run non-privileged --image=busybox -- sleep 36000 8 | ``` 9 | #### Create Privileged Pod 10 | ```sh 11 | kubectl run privileged-pod --image=busybox --privileged -- sleep 36000 12 | ``` 13 | 14 | ### Connect to Both the Pods in Two Separate Terminal Tabs 15 | ```sh 16 | kubectl exec -it non-privileged -- sh 17 | 18 | kubectl exec -it privileged-pod -- sh 19 | ``` 20 | 21 | ### Run Commands in Both Pods to See Difference 22 | ```sh 23 | cd /dev 24 | ls 25 | 26 | dmesg 27 | 28 | fdisk -l 29 | ``` 30 | 31 | #### Verify Manifest File Associated with Privileged Pod 32 | 33 | ```sh 34 | kubectl run privileged-pod --image=busybox --dry-run=client -o yaml --privileged -- sleep 36000 35 | ``` 36 | -------------------------------------------------------------------------------- /Domain 6 - State Persistence/pv-pvc.md: -------------------------------------------------------------------------------- 1 | 2 | ### Step 1 - Create Two Persistent Volumes 3 | ```sh 4 | nano pv-1.yaml 5 | ``` 6 | ```sh 7 | apiVersion: v1 8 | kind: PersistentVolume 9 | metadata: 10 | name: manual-pv-1gb 11 | spec: 12 | storageClassName: manual 13 | capacity: 14 | storage: 1Gi 15 | accessModes: 16 | - ReadWriteOnce 17 | hostPath: 18 | path: /mnt/data/1gb 19 | ``` 20 | ```sh 21 | kubectl create -f pv-1.yaml 22 | ``` 23 | 24 | ```sh 25 | nano pv-2.yaml 26 | ``` 27 | ```sh 28 | apiVersion: v1 29 | kind: PersistentVolume 30 | metadata: 31 | name: manual-pv-3gb 32 | spec: 33 | storageClassName: manual 34 | capacity: 35 | storage: 3Gi 36 | accessModes: 37 | - ReadWriteOnce 38 | hostPath: 39 | path: /mnt/data/2gb 40 | ``` 41 | 42 | ```sh 43 | kubectl create -f pv-1.yaml 44 | ``` 45 | 46 | ```sh 47 | kubectl get pv 48 | ``` 49 | 50 | ### Step 2 - Create Persistent Volume Claim 51 | ```sh 52 | nano pvc.yaml 53 | ``` 54 | ```sh 55 | apiVersion: v1 56 | kind: PersistentVolumeClaim 57 | metadata: 58 | name: manual-pvc-2gb 59 | spec: 60 | accessModes: 61 | - ReadWriteOnce 62 | resources: 63 | requests: 64 | storage: 2Gi 65 | storageClassName: manual 66 | ``` 67 | ```sh 68 | kubectl get pvc 69 | ``` 70 | 71 | ### Step 3 - Create Pod 72 | ```sh 73 | nano pod-pvc.yaml 74 | ``` 75 | ```sh 76 | apiVersion: v1 77 | kind: Pod 78 | metadata: 79 | name: test-pod 80 | spec: 81 | containers: 82 | - name: app 83 | image: busybox 84 | command: ["sleep", "3600"] 85 | volumeMounts: 86 | - mountPath: "/data" 87 | name: mydata 88 | volumes: 89 | - name: mydata 90 | persistentVolumeClaim: 91 | claimName: manual-pvc-2gb 92 | ``` 93 | ```sh 94 | kubectl create -f pod-pvc.yaml 95 | ``` 96 | ```sh 97 | kubectl exec -it busybox -- sh 98 | 99 | ls -l / 100 | ``` 101 | 102 | ### Delete the Resources 103 | ```sh 104 | kubectl delete -f pod-pvc.yaml 105 | kubectl delete -f pvc.yaml 106 | kubectl delete -f pv-1.yaml 107 | kubectl delete -f pv.yaml 108 | ``` -------------------------------------------------------------------------------- /Domain 6 - State Persistence/pvandpvc.md: -------------------------------------------------------------------------------- 1 | ##### pv.yaml 2 | 3 | ```sh 4 | apiVersion: v1 5 | kind: PersistentVolume 6 | metadata: 7 | name: block-pv 8 | spec: 9 | storageClassName: manual 10 | capacity: 11 | storage: 10Gi 12 | accessModes: 13 | - ReadWriteOnce 14 | hostPath: 15 | path: /tmp/data 16 | ``` 17 | 18 | ##### pvc.yaml 19 | 20 | ```sh 21 | apiVersion: v1 22 | kind: PersistentVolumeClaim 23 | metadata: 24 | name: pvc 25 | spec: 26 | storageClassName: manual 27 | accessModes: 28 | - ReadWriteOnce 29 | resources: 30 | requests: 31 | storage: 10Gi 32 | ``` 33 | ##### pod-pvc.yaml 34 | ```sh 35 | kind: Pod 36 | apiVersion: v1 37 | metadata: 38 | name: kplabs-pvc 39 | spec: 40 | containers: 41 | - name: my-frontend 42 | image: nginx 43 | volumeMounts: 44 | - mountPath: "/data" 45 | name: my-volume 46 | volumes: 47 | - name: my-volume 48 | persistentVolumeClaim: 49 | claimName: pvc 50 | 51 | ``` 52 | -------------------------------------------------------------------------------- /Domain 6 - State Persistence/security-context.md: -------------------------------------------------------------------------------- 1 | ### Base Insecure Pod Manifest File Used (pod.yaml) 2 | 3 | ```sh 4 | apiVersion: v1 5 | kind: Pod 6 | metadata: 7 | name: insecure-pod 8 | spec: 9 | containers: 10 | - name: demo-container 11 | image: busybox:latest 12 | command: ["sleep", "36000"] 13 | volumeMounts: 14 | - name: host-root 15 | mountPath: /host 16 | volumes: 17 | - name: host-root 18 | hostPath: 19 | path: / 20 | ``` 21 | 22 | ```sh 23 | kubectl apply -f pod.yaml 24 | ``` 25 | 26 | ```sh 27 | kubectl exec -it insecure-pod -- sh 28 | id 29 | cd /hosts 30 | ls 31 | ``` 32 | 33 | ### Documentation Referenced for Security Context: 34 | 35 | https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ 36 | 37 | ### Adding Security Context to Pod Manifest with HostPath Volume Mount 38 | 39 | pod-controlled.yaml 40 | 41 | ```sh 42 | apiVersion: v1 43 | kind: Pod 44 | metadata: 45 | name: controlled-pod 46 | spec: 47 | securityContext: 48 | runAsUser: 1000 49 | runAsGroup: 2000 50 | fsGroup: 3000 51 | containers: 52 | - name: demo-container 53 | image: busybox:latest 54 | command: ["sleep", "36000"] 55 | volumeMounts: 56 | - name: host-root 57 | mountPath: /host 58 | volumes: 59 | - name: host-root 60 | hostPath: 61 | path: / 62 | ``` 63 | 64 | ```sh 65 | kubectl apply -f pod-controlled.yaml 66 | kubectl exec -it controlled-pod -- sh 67 | id 68 | 69 | cd /host/tmp 70 | touch test.txt 71 | ls -l 72 | ``` 73 | ### Security Context with EmptyDir Volume (pod-fs.yaml) 74 | 75 | ```sh 76 | apiVersion: v1 77 | kind: Pod 78 | metadata: 79 | name: fsgroup-pod 80 | spec: 81 | securityContext: 82 | runAsUser: 1000 83 | runAsGroup: 2000 84 | fsGroup: 3000 85 | volumes: 86 | - name: host-root 87 | emptyDir: {} 88 | containers: 89 | - name: demo-container 90 | image: busybox:latest 91 | command: ["sleep", "36000"] 92 | volumeMounts: 93 | - name: host-root 94 | mountPath: /host 95 | ``` 96 | 97 | ```sh 98 | kubectl apply -f pod-fs.yaml 99 | 100 | kubectl exec -it fsgroup-pod -- sh 101 | id 102 | cd /host/tmp 103 | touch test.txt 104 | ls -l 105 | ``` 106 | 107 | -------------------------------------------------------------------------------- /Domain 7 - Multi-Container PODS/Readme.md: -------------------------------------------------------------------------------- 1 | # Domain 7 - Multi-Container PODS 2 | 3 | The code mentioned in this document are used in the Certified Kubernetes Application Developer 2025 course. 4 | 5 | https://www.udemy.com/course/mastering-certified-kubernetes-application-developer/?referralCode=3A549BA24AC8ED6597DF 6 | 7 | 8 | # Video-Document Mapper 9 | 10 | | Sr No | Document Link | 11 | | ------ | ------ | 12 | | 1 | [Adapter Container][PlDa] | 13 | | 2 | [Ambssador Container][PlDb] | 14 | | 3 | [Init Containers][PlDc] | 15 | 16 | 17 | 18 | [PlDa]: <./adapter.yaml> 19 | [PlDb]: <./ambassador.yaml> 20 | [PlDc]: <./init-containers.md> 21 | -------------------------------------------------------------------------------- /Domain 7 - Multi-Container PODS/adapter.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: fluentd-config 5 | data: 6 | fluentd.conf: | 7 | 8 | type tail 9 | format none 10 | path /var/log/1.log 11 | pos_file /var/log/1.log.pos 12 | tag PHP 13 | 14 | 15 | 16 | type tail 17 | format none 18 | path /var/log/2.log 19 | pos_file /var/log/2.log.pos 20 | tag JAVA 21 | 22 | 23 | 24 | @type file 25 | path /var/log/fluent/access 26 | 27 | 28 | --- 29 | apiVersion: v1 30 | kind: Pod 31 | metadata: 32 | name: counter 33 | spec: 34 | containers: 35 | - name: count 36 | image: busybox 37 | args: 38 | - /bin/sh 39 | - -c 40 | - > 41 | i=0; 42 | while true; 43 | do 44 | echo "$i: $(date)" >> /var/log/1.log; 45 | echo "$(date) INFO $i" >> /var/log/2.log; 46 | i=$((i+1)); 47 | sleep 1; 48 | done 49 | volumeMounts: 50 | - name: varlog 51 | mountPath: /var/log 52 | - name: count-agent 53 | image: k8s.gcr.io/fluentd-gcp:1.30 54 | env: 55 | - name: FLUENTD_ARGS 56 | value: -c /etc/fluentd-config/fluentd.conf 57 | volumeMounts: 58 | - name: varlog 59 | mountPath: /var/log 60 | - name: config-volume 61 | mountPath: /etc/fluentd-config 62 | volumes: 63 | - name: varlog 64 | emptyDir: {} 65 | - name: config-volume 66 | configMap: 67 | name: fluentd-config 68 | -------------------------------------------------------------------------------- /Domain 7 - Multi-Container PODS/ambassador.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: kplabs-ambassador-config 5 | data: 6 | haproxy.cfg: |- 7 | global 8 | daemon 9 | maxconn 256 10 | 11 | defaults 12 | mode http 13 | timeout connect 5000ms 14 | timeout client 50000ms 15 | timeout server 50000ms 16 | 17 | listen http-in 18 | bind *:80 19 | server server1 127.0.0.1:9080 maxconn 32 20 | 21 | --- 22 | 23 | apiVersion: v1 24 | kind: Pod 25 | metadata: 26 | name: ambassador 27 | spec: 28 | containers: 29 | - name: haproxy-container 30 | image: haproxy:1.7 31 | volumeMounts: 32 | - name: config-volume 33 | mountPath: /usr/local/etc/haproxy 34 | - name: kplabs-nginx 35 | image: mykplabs/kubernetes:nginx 36 | volumes: 37 | - name: config-volume 38 | configMap: 39 | name: kplabs-ambassador-config 40 | 41 | --- 42 | 43 | apiVersion: v1 44 | kind: Pod 45 | metadata: 46 | name: busybox 47 | spec: 48 | containers: 49 | - name: curl-container 50 | image: yauritux/busybox-curl 51 | command: ['sh', '-c', 'while true; do sleep 3600; done'] 52 | -------------------------------------------------------------------------------- /Domain 7 - Multi-Container PODS/init-containers.md: -------------------------------------------------------------------------------- 1 | ### Documentation Referenced: 2 | 3 | https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ 4 | 5 | ### Init Container Manifest 6 | ```sh 7 | nano init.yaml 8 | ``` 9 | ```sh 10 | apiVersion: v1 11 | kind: Pod 12 | metadata: 13 | name: myapp-pod 14 | spec: 15 | containers: 16 | - name: app-container 17 | image: nginx 18 | initContainers: 19 | - name: check-google 20 | image: alpine/curl 21 | command: ["ping", "-c", "10", "google.com"] 22 | - name: check-kubernetes 23 | image: alpine/curl 24 | command: ["curl", "kubernetes.io"] 25 | ``` 26 | 27 | ```sh 28 | kubectl create -f init.yaml 29 | 30 | kubectl get pods -w 31 | ``` -------------------------------------------------------------------------------- /Domain 8 - New Exam Updates/Readme.md: -------------------------------------------------------------------------------- 1 | # Domain 7 - Multi-Container PODS 2 | 3 | The code mentioned in this document are used in the Certified Kubernetes Application Developer 2025 course. 4 | 5 | https://www.udemy.com/course/mastering-certified-kubernetes-application-developer/?referralCode=3A549BA24AC8ED6597DF 6 | 7 | 8 | # Video-Document Mapper 9 | 10 | | Sr No | Document Link | 11 | | ------ | ------ | 12 | | 1 | [Implementing Blue-Green Deployments][PlDa] | 13 | | 2 | [Exercise - Canary Deployment][PlDb] | 14 | | 3 | [Custom Resource Definition (CRDs)][PlDc] | 15 | | 4 | [Creating Token for RBAC Practicals][PlDd] | 16 | | 5 | [Practical - Role and RoleBinding][PlDe] | 17 | 18 | 19 | [PlDa]: <./blue-green.md> 20 | [PlDb]: <./exercise-canary.md> 21 | [PlDc]: <./crds.md> 22 | [PlDd]: <./user-rbac.md> 23 | [PlDe]: <./role-rolebinding.md> -------------------------------------------------------------------------------- /Domain 8 - New Exam Updates/blue-green.md: -------------------------------------------------------------------------------- 1 | #### 1. Create 2 Pods 2 | ```sh 3 | kubectl run blue-pod --image=nginx 4 | kubectl run green-pod --image=httpd 5 | ``` 6 | #### 2. Add Labels to both the Pods 7 | ```sh 8 | kubectl label pod blue-pod app=demo-app-v1 9 | kubectl label pod green-pod app=demo-app-v2 10 | ``` 11 | #### 3. Verify POD labels 12 | ```sh 13 | kubectl get pods --show-labels 14 | ``` 15 | #### 4. Create Service 16 | 17 | blue-green.yaml 18 | ```sh 19 | apiVersion: v1 20 | kind: Service 21 | metadata: 22 | name: application-service 23 | spec: 24 | type: NodePort 25 | ports: 26 | - name: http 27 | port: 80 28 | targetPort: 80 29 | selector: 30 | app: demo-app-v1 31 | ``` 32 | ```sh 33 | kubectl apply blue-green.yaml 34 | ``` 35 | #### 5. Verify Service: 36 | ```sh 37 | kubectl get service 38 | kubectl describe service application-service 39 | ``` 40 | #### 6. Fetch the Public Endpoint IP of the nodes 41 | ```sh 42 | kubectl get nodes 43 | kubectl describe node 44 | ``` 45 | #### 7. Change from Blue to Green Environment: 46 | 47 | Modify the selector to demo-app-v2 in the service manifest file and re-deploy it. 48 | ```sh 49 | kubectl apply blue-green.yaml 50 | ``` 51 | Second Way to Edit Service (Optional) 52 | ```sh 53 | kubectl edit service application-service 54 | ``` 55 | Modify the selector to demo-app-v2 -------------------------------------------------------------------------------- /Domain 8 - New Exam Updates/crds.md: -------------------------------------------------------------------------------- 1 | ### Documentation Referenced: 2 | 3 | https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/ 4 | 5 | ### Create a CustomResourceDefinition 6 | ```sh 7 | nano crd.yaml 8 | ``` 9 | ```sh 10 | apiVersion: apiextensions.k8s.io/v1 11 | kind: CustomResourceDefinition 12 | metadata: 13 | name: databases.kplabs.internal 14 | spec: 15 | group: kplabs.internal 16 | names: 17 | kind: Database 18 | listKind: DatabaseList 19 | plural: databases 20 | singular: database 21 | scope: Namespaced 22 | versions: 23 | - name: v1 24 | served: true 25 | storage: true 26 | schema: 27 | openAPIV3Schema: 28 | type: object 29 | properties: 30 | spec: 31 | type: object 32 | properties: 33 | name: 34 | type: string 35 | replicas: 36 | type: integer 37 | ``` 38 | ```sh 39 | kubectl create -f crd.yaml 40 | 41 | kubectl get crd 42 | ``` 43 | ### Create custom objects 44 | ```sh 45 | nano db.yaml 46 | ``` 47 | ```sh 48 | apiVersion: kplabs.internal/v1 49 | kind: Database 50 | metadata: 51 | name: my-database 52 | spec: 53 | name: test-db 54 | replicas: 3 55 | ``` 56 | 57 | ```sh 58 | kubectl create -f db.yaml 59 | kubectl get database 60 | ``` 61 | 62 | ### Delete CRD 63 | 64 | ```sh 65 | kubectl delete -f crd.yaml 66 | ``` 67 | -------------------------------------------------------------------------------- /Domain 8 - New Exam Updates/exercise-canary.md: -------------------------------------------------------------------------------- 1 | 2 | ### Step 1 - Calculate Total Canary Pods 3 | 4 | Total Pods Needed = `5` 5 | 6 | Canary Percentage = `20%` 7 | 8 | Canary Pods = `round(Total Pods × (Desired Percentage / 100))` 9 | 10 | Final Result = `round(5 x (20/100) = 1` 11 | 12 | ### Step 2 - Create Deployments 13 | ```sh 14 | kubectl create deployment v1-app --image=nginx --replicas=4 --dry-run=client -o yaml > v1-app.yaml 15 | ``` 16 | 17 | Add a label of `env: payments-app` in the manifest file. 18 | 19 | ```sh 20 | kubectl create deployment v2-app --image=httpd --replicas=1 --dry-run=client -o yaml > v2-canary.yaml 21 | ``` 22 | Add a label of `env: payments-app` in the manifest file. 23 | ```sh 24 | kubectl create -f v1-app.yaml 25 | kubectl create -f v2-canary.yaml 26 | ``` 27 | 28 | ### Step 3 - Create Service 29 | ```sh 30 | app-service.yaml 31 | ``` 32 | ```sh 33 | apiVersion: v1 34 | kind: Service 35 | metadata: 36 | name: app-service 37 | spec: 38 | ports: 39 | - name: http 40 | port: 80 41 | targetPort: 80 42 | selector: 43 | env: payments-app 44 | ``` 45 | ```sh 46 | kubectl create -f app-service.yaml 47 | ``` 48 | ```sh 49 | kubectl describe service app-service 50 | 51 | kubectl get endpoints app-service -o yaml 52 | ``` 53 | 54 | ### Step 4 - Testing the Setup 55 | ```sh 56 | kubectl run curl-pod --image=alpine/curl -- sleep 36000 57 | 58 | kubectl exec -it curl-pod -- sh 59 | 60 | for i in $(seq 1 10); do curl -s app-service:80 | grep -E 'works'; done 61 | ``` 62 | 63 | ### Step 5 - Delete the Setup 64 | ```sh 65 | kubectl delete -f v1-app.yaml 66 | 67 | kubectl delete -f v2-canary.yaml 68 | 69 | kubectl delete -f app-service.yaml 70 | 71 | kubectl delete pod curl-pod 72 | ``` 73 | -------------------------------------------------------------------------------- /Domain 8 - New Exam Updates/role-rolebinding.md: -------------------------------------------------------------------------------- 1 | ### Documentation / Websites Referenced: 2 | 3 | https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/ 4 | 5 | #### Check Resources as part of specific API Group 6 | ```sh 7 | kubectl api-resources --api-group="apps" 8 | kubectl api-resources --api-group="" 9 | ``` 10 | #### Create Role 11 | ```sh 12 | kubectl create role --help 13 | 14 | kubectl create role pod-reader --verb=list --resource=pods 15 | 16 | kubectl get roles 17 | 18 | kubectl describe role pod-reader 19 | ``` 20 | #### Test the Permissions 21 | ```sh 22 | kubectl cluster-info 23 | ``` 24 | 25 | Replace the `K8S-DETAILS-HERE` with the output you get in previous command 26 | ```sh 27 | curl -k https://K8S-DETAILS-HERE/api/v1/namespaces/default/pods --header "Authorization: Bearer $TOKEN" 28 | ``` 29 | 30 | #### Create RoleBinding 31 | ```sh 32 | kubectl create rolebinding --help 33 | 34 | kubectl create rolebinding test-rolebinding --role=pod-reader --user=system:serviceaccount:default:test-sa 35 | 36 | kubectl get rolebinding 37 | 38 | kubectl describe rolebinding test-rolebinding 39 | ``` 40 | #### Test the Permissions 41 | ```sh 42 | kubectl run test-pod --image=nginx 43 | ``` 44 | Replace the URL in below command to your K8s URL. If using macOS or Linux, use `$TOKEN` instead of `%TOKEN%` 45 | ```sh 46 | curl -k https://38140ecd-e8d7-4fff-be52-24629c40cdac.k8s.ondigitalocean.com/api/v1/namespaces/default/pods --header "Authorization: Bearer %TOKEN%" 47 | ``` 48 | #### Generate Manifest Files for Role and Role Binding 49 | ```sh 50 | kubectl create role test-role --verb=list --resource=pods --dry-run=client -o yaml 51 | 52 | kubectl create rolebinding test-rolebinding --role=pod-reader --user=system:serviceaccount:default:test-sa --dry-run=client -o yaml 53 | ``` 54 | #### Delete Role and RoleBinding 55 | ```sh 56 | kubectl delete role pod-reader 57 | 58 | kubectl delete rolebinding test-rolebinding 59 | ``` -------------------------------------------------------------------------------- /Domain 8 - New Exam Updates/user-rbac.md: -------------------------------------------------------------------------------- 1 | ### Websites Referred in Video: 2 | 3 | https://fusionauth.io/dev-tools/jwt-decoder 4 | 5 | https://www.unixtimestamp.com/ 6 | 7 | ### Generate Token 8 | ```sh 9 | kubectl create token --duration=100h 10 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Certified Kubernetes Application Developer - KPLABS 2 | 3 | This is a central document which contains all the commands and code files used throughout the video course. 4 | 5 | https://www.udemy.com/course/mastering-certified-kubernetes-application-developer/?referralCode=3A549BA24AC8ED6597DF 6 | 7 | We also have a new Discord community for any support related discussion as well as to connect to other students doing the same course. Feel free to join the community. 8 | 9 | ```sh 10 | http://kplabs.in/chat 11 | ``` 12 | Welcome to the community again and we look forward to see you certified! :) 13 | 14 |

15 | 16 |

17 | 18 | 19 | -------------------------------------------------------------------------------- /practice-tests/Readme.md: -------------------------------------------------------------------------------- 1 | # Practice Tests - Challenges 2 | 3 | The challenges mentioned in this document are used in the Certified Kubernetes Application Developer 2025 course by Zeal Vora. 4 | 5 | https://www.udemy.com/course/mastering-certified-kubernetes-application-developer/?referralCode=3A549BA24AC8ED6597DF 6 | 7 | 8 | 9 | | Sr No | Document Link | 10 | | ------ | ------ | 11 | | 1 | [Challenge 1 - Secrets and Pod Environment Variables][PlDa] | 12 | | 2 | [Challenge 2 - Deployment Manifest Upgrade][PlDb] | 13 | | 3 | [Challenge 3 - Request and Limits][PlDc] | 14 | | 4 | [Challenge 4 - Troubleshooting][PlDd] | 15 | | 5 | [Challenge 5 - Canary Deployment][PlDe] | 16 | | 6 | [Challenge 6 - Security Context][PlDf] | 17 | | 7 | [Challenge 7 - CronJob][PlDg] | 18 | | 8 | [Challenge 8 - Deployment Updates][PlDh] | 19 | | 9 | [Challenge 9 - Limit Ranges and NodePort Service][PlDi] | 20 | 21 | [PlDa]: <./secrets.md> 22 | [PlDb]: <./dep-upgrade.md> 23 | [PlDc]: <./request-limits.md> 24 | [PlDd]: <./troubleshoot-01.md> 25 | [PlDe]: <./exercise-canary.md> 26 | [PlDf]: <./security-context.md> 27 | [PlDg]: <./cronjob.md> 28 | [PlDh]: <./surge.md> 29 | [PlDi]: <./limit-ranges.md> 30 | -------------------------------------------------------------------------------- /practice-tests/cronjob.md: -------------------------------------------------------------------------------- 1 | ## Challenge: CronJob 2 | 3 | ### Context 4 | You’re a Kubernetes engineer and need to implement a recurring maintenance task in the `default` namespace. Write a complete YAML manifest named `kplabs-cronjob.yaml` that meets **all** of the below requirements. 5 | 6 | ### Requirements 7 | 8 | 1. **Schedule** 9 | - Run every 2 minutes. 10 | 11 | 2. **Job Configuration** 12 | - Image: `busybox` 13 | - Command / Args: 14 | ```shell 15 | echo "Hello from Kubernetes CronJob!" 16 | ``` 17 | 18 | 3. **History Limits** 19 | Prevent old Jobs/Pods from accumulating in your cluster. 20 | - Retain only the most recent `3` successful Job records. 21 | - Retain only the most recent `5` failed Job records. 22 | 23 | 4. **Timeout** 24 | - Terminate any Pod that runs longer than `25` seconds 25 | 5. **Delay** 26 | - If the CronJob controller is down or the cluster is unavailable at the exact schedule time, allow missing runs to be started for up to `30` seconds after their original schedule 27 | 5. **Restart Policy** 28 | - Pods should restart **only on failure** 29 | 30 | 31 | -------------------------------------------------------------------------------- /practice-tests/dep-upgrade.md: -------------------------------------------------------------------------------- 1 | ### Challenge - Deployment Manifest Upgrade 2 | 3 | ### Background 4 | 5 | You are a Kubernetes administrator responsible for maintaining applications on a Kubernetes cluster that has recently been upgraded to the latest version. You've discovered an old deployment manifest file, `old-deployment.yaml`, which was used to deploy an Nginx application on a much older Kubernetes version (1.15). 6 | 7 | This manifest file is no longer compatible with the current Kubernetes API versions and will fail if applied directly. 8 | 9 | ### Your Task 10 | 11 | Your goal is to update the `old-deployment.yaml` manifest to make it compatible with your current Kubernetes environment. In case if any container errors, save the error logs to error-container.txt 12 | 13 | `old-deployment.yaml` 14 | ```sh 15 | apiVersion: extensions/v1beta1 16 | kind: Deployment 17 | metadata: 18 | name: nginx-deployment 19 | spec: 20 | replicas: 3 21 | template: 22 | metadata: 23 | labels: 24 | run: nginx 25 | spec: 26 | containers: 27 | - name: nginx 28 | image: nginx:latest 29 | ports: 30 | - containerPort: 80 31 | - name: apache 32 | image: httpd:latest 33 | ports: 34 | - containerPort: 8080 35 | ``` 36 | 37 | 38 | -------------------------------------------------------------------------------- /practice-tests/exercise-canary.md: -------------------------------------------------------------------------------- 1 | ### Challenge - Canary Deployment 2 | 3 | #### Tasks: (Complete each step sequentially) 4 | 5 | 1. Create a deploymet named `app-v1` that has 5 replicas and uses image of `nginx:latest ` 6 | 7 | 2. Create canary deployment named `app-v2` in a way that 40% traffic goes to `app-v2` and 60% traffic goes to `app-v1`. The canary deployment should image of `httpd:latest`. Total number of Pods in the namespace should only be `5`. 8 | 9 | 3. Create a service named `app-service`. This service should redirect traffic to the Pods associated with both the deployments. 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /practice-tests/limit-ranges.md: -------------------------------------------------------------------------------- 1 | 2 | ## Challenge - Limit Ranges and NodePort Service 3 | 4 | 1. Create a LimitRange object in the `test` namespace that enforces maximum memory of `500Mi` per container. The default cpu request should be `25m`. 5 | 6 | 2. Create a Pod named `half-mem-pod` in the `test` namespace with a single container based on following specification. 7 | 8 | | Key | Value | 9 | |:-------------:|:-----------------------------------------:| 10 | | Container name| nginx | 11 | | Image | nginx:latest | 12 | | Memory Limit | Half of the test namespace memory limit | 13 | 14 | 3. Make sure that the Pod restarts only in-case of Failure. 15 | 16 | 4. Create a service named `nodeport-service` that has NodePort of `32000` and sends request to the `half-mem-pod` on Port `80`. 17 | 18 | -------------------------------------------------------------------------------- /practice-tests/probes.md: -------------------------------------------------------------------------------- 1 | ## Challenge: Probes 2 | 3 | ### Context 4 | You need to create a Deployment that runs your web application and configure both liveness and readiness probes so that Kubernetes can verify the health and readiness of your Pods before routing traffic. 5 | 6 | ### Requirement 7 | 8 | 1. Create a Deployment named `kplabs-probes` that uses `2` replicas. 9 | 2. Container image should be `nginx:latest` 10 | 3. Expose container port `8081`. 11 | 12 | Make sure deployment is created before proceeding with the next steps. 13 | 14 | 4. Configure a readiness probe that: 15 | - Performs an `HTTP GET` on path `/healthz` 16 | - Port should be same as the Container Port. 17 | - Has initialDelaySeconds: `15` 18 | - Has failureThreshold: `3` 19 | 20 | 5. Configure a livenessProbe that 21 | - Performs an `HTTP GET` on path `/healthz` 22 | - Port should be same as the Container Port. 23 | - Has initialDelaySeconds: `15` 24 | - Has periodSeconds: `10` 25 | - Has failureThreshold: `5` 26 | -------------------------------------------------------------------------------- /practice-tests/request-limits.md: -------------------------------------------------------------------------------- 1 | ### Challenge - Requests and Limits 2 | 3 | Create a Pod named `cpu-mem-limits` in the namespace of `limits` that has a single container based on the following specifications 4 | 5 | | Key | Value | 6 | |:-------------:|:-----------------------------------------:| 7 | | Container name| nginx | 8 | | Image | busybox:latest | 9 | | Command / Args | sleep for 100 seconds | 10 | | CPU Request | 20m | 11 | | CPU Limit | 80m | 12 | | Memory Request | 50Mi | 13 | | Memory Limit | 256Mi | 14 | 15 | 16 | 17 | 18 | This container must NOT be restarted after the main command has completed it's operations. 19 | 20 | 21 | -------------------------------------------------------------------------------- /practice-tests/sa.yaml: -------------------------------------------------------------------------------- 1 | # namespace.yaml 2 | --- 3 | apiVersion: v1 4 | kind: Namespace 5 | metadata: 6 | name: dev-namespace 7 | 8 | # role.yaml 9 | --- 10 | apiVersion: rbac.authorization.k8s.io/v1 11 | kind: Role 12 | metadata: 13 | name: pod-reader 14 | namespace: dev-namespace 15 | rules: 16 | - apiGroups: [""] 17 | resources: ["pods"] 18 | verbs: ["get", "watch", "list"] 19 | 20 | --- 21 | 22 | # sa.yaml 23 | apiVersion: v1 24 | kind: ServiceAccount 25 | metadata: 26 | name: pod-reader-sa 27 | namespace: default 28 | 29 | --- 30 | 31 | # deployment.yaml 32 | apiVersion: apps/v1 33 | kind: Deployment 34 | metadata: 35 | name: mypod-lister 36 | namespace: default 37 | spec: 38 | replicas: 1 39 | selector: 40 | matchLabels: 41 | app: mypod-lister 42 | template: 43 | metadata: 44 | labels: 45 | app: mypod-lister 46 | spec: 47 | containers: 48 | - name: pod-lister 49 | image: curlimages/curl:7.85.0 50 | command: 51 | - sh 52 | - -c 53 | - | 54 | # wait for SA → token secret to mount 55 | sleep 5 56 | echo "=== Attempting to list pods via Kubernetes API ===" 57 | curl -s --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ 58 | -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ 59 | https://kubernetes.default.svc/api/v1/namespaces/default/pods 60 | echo "=== Done ===" 61 | # keep pod alive so you can inspect logs 62 | sleep 3600 -------------------------------------------------------------------------------- /practice-tests/secrets.md: -------------------------------------------------------------------------------- 1 | ## Challenge - Secrets and Pod Environment Variables 2 | 3 | ### Question 4 | You are tasked with deploying a new application that requires sensitive configuration data to be securely managed. This data should be made available to the application container as environment variables. 5 | 6 | ### Tasks: 7 | 8 | 1. Create a new Kubernetes Secret named `app-secret` in the default namespace. 9 | 10 | 2. The Secret should contain the following key-value pairs: 11 | ```sh 12 | DB_USERNAME: admin 13 | DB_PASSWORD: supersecret 14 | ``` 15 | 16 | 3. Create a new Pod named `my-app-pod` in the default namespace. 17 | 18 | 4. The Pod should use the `nginx:latest` image. 19 | 20 | 5. Configure the Pod to expose the `DB_USERNAME` and `DB_PASSWORD` values from the `app-secret` Secret as environment variables named `APP_DB_USER` and `APP_DB_PASS` respectively, within the container. 21 | 22 | 6. Ensure the Pod is running and verify that the environment variables are correctly set inside the container. -------------------------------------------------------------------------------- /practice-tests/security-context.md: -------------------------------------------------------------------------------- 1 | ### Challenge - Security Context 2 | 3 | Deploy a Pod from the `busybox:latest` image. Pod should be named `security-pod` and it must be created in the default namespace. The container should run `sleep` command for `3600` seconds.The Pod must also meet the following security requirements: 4 | 5 | 1. Run all containers with UID of `1001` 6 | 7 | 2. Run all containers with GID of `2002` 8 | 9 | 3. Pods should not allow any privilege escalation. 10 | -------------------------------------------------------------------------------- /practice-tests/surge.md: -------------------------------------------------------------------------------- 1 | ## Challenge: Deployment Updates 2 | 3 | ### Context 4 | You are managing a Kubernetes Deployment for a web application with `3` replicas. Your application is critical, and you want to minimize downtime during a `rolling update`, but you also want the update to finish quickly. 5 | 6 | ### Requirement 7 | 8 | 1. At least `2` Pods must be available at all times during the rolling update. 9 | 10 | 2. You want to allow `1` extra Pod to be created above the desired replica count during the update for faster rollout. 11 | 12 | ### Task: 13 | 14 | Create a deployment named `kplabs-deployment` using image of `nginx:latest` that satisfies the requirements. 15 | 16 | Once the deployment is running based on the above requirement, update the image of the deployment from `nginx:latest` to `httpd:latest` 17 | -------------------------------------------------------------------------------- /practice-tests/troubleshoot-01.md: -------------------------------------------------------------------------------- 1 | ## Challenge - Troubleshooting 2 | 3 | ### 1 - Pre-Requisite: 4 | 5 | Run the following command to setup the environement 6 | 7 | ```sh 8 | kubectl create -f https://raw.githubusercontent.com/zealvora/certified-kubernetes-application-developer/refs/heads/master/practice-tests/sa.yaml 9 | ``` 10 | ### 2 - Question: 11 | 12 | Application in the Pods that are part of the deployment named `mypod-lister` are failing. Application in the pods managed by this deployment are trying to list other pods in the same namespace as part of their startup routine, but they are encountering permission errors. 13 | 14 | 15 | #### Task: 16 | 17 | Fix the issue preventing the application within the `mypod-lister` deployment's pods from listing other pods in the namespace. Validate the fix by inspecting the pod logs. 18 | 19 | 20 | #### Hints: 21 | 22 | A ServiceAccount named `pod-lister-sa` exists. Use this service account for the application Pods. 23 | 24 | A Role named `pod-reader` exists in the `dev-namespace` which grants permission to get, watch, and list pods. 25 | --------------------------------------------------------------------------------