> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Solution Lightning Lab 1

> This guide provides step-by-step solutions for completing tasks in Lightning Lab 1, including creating persistent volumes, claims, and troubleshooting network connectivity.

In this guide, we walk through the solutions for Lightning Lab 1 step by step. Each task includes detailed configuration files and commands to accomplish the requirements effectively.

***

## Task 1: Create a Persistent Volume

The first task is to create a persistent volume named **log-volume** with the following specifications:

* **Storage Class:** manual
* **Access Mode:** ReadWriteMany (RWX)
* **Capacity:** 1Gi
* **Host Path:** /opt/volume/nginx

A common starting point is referencing the Kubernetes documentation. Here’s an example snippet that you might have encountered:

```yaml theme={null}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: foo-pvc
  namespace: foo
spec:
  storageClassName: "" # Empty string must be explicitly set otherwise default StorageClass will be set
  volumeName: foo-pv
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: foo-pv
spec:
  storageClassName: ""
  claimRef:
    name: foo-pvc
    namespace: foo
```

Adjust this example to match our requirements. The complete persistent volume configuration becomes:

```yaml theme={null}
apiVersion: v1
kind: PersistentVolume
metadata:
  name: log-volume
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  hostPath:
    path: /opt/volume/nginx
```

Apply the configuration:

```bash theme={null}
kubectl apply -f log-volume.yaml
```

Then verify the persistent volume is created:

```bash theme={null}
kubectl get pv
```

***

## Task 2: Create a Persistent Volume Claim

Next, create a persistent volume claim (PVC) named **log-claim** with these requirements:

* **Access Mode:** ReadWriteMany
* **Storage Request:** 8Gi of storage
* **Storage Class:** manual

Use the following YAML configuration:

```yaml theme={null}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: log-claim
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 8Gi
  storageClassName: manual
```

Save this as `log-claim.yaml` and apply it:

```bash theme={null}
kubectl apply -f log-claim.yaml
```

After applying, check the PVC status:

```bash theme={null}
kubectl get pvc
```

***

## Task 3: Mount the Volume in a Pod

Now, mount the PVC into a pod named **logger** at the mount path **/var/www/nginx**. This pod will run a container using the `nginx:alpine` image.

### Step 1: Generate the Initial Pod YAML

Create the pod configuration using a dry-run:

```bash theme={null}
kubectl run logger --image=nginx:alpine --dry-run=client -o yaml > logger.yaml
```

### Step 2: Edit the YAML to Add Volumes and Volume Mounts

Modify `logger.yaml` to include:

* A **volumes** section to reference the PVC.
* A **volumeMounts** section under the container to specify the mount path.

Place the following snippet under the `spec`:

```yaml theme={null}
volumes:
  - name: log
    persistentVolumeClaim:
      claimName: log-claim
```

And under the container definition, add:

```yaml theme={null}
volumeMounts:
  - name: log
    mountPath: /var/www/nginx
```

After ensuring the field name is correctly spelled (`persistentVolumeClaim` with an "s"), apply the updated configuration:

```bash theme={null}
kubectl apply -f logger.yaml
```

If you encounter an error like:

<Callout icon="triangle-alert" color="#FF6B6B">
  Ensure that the field name `persistentVolumeClaim` is spelled correctly and that you have saved the file appropriately before re-applying.
</Callout>

Verify the pod creation:

```bash theme={null}
kubectl get pod
```

***

## Task 4: Troubleshoot Network Connectivity for Secure Pod

A pod named **secure-pod** and a service named **secure-service** are deployed. However, incoming and outgoing connections to the secure pod are currently failing, and traffic from the **webapp-color** pod using **secure-service** is not working.

### Step 1: Verify Pods and Service

Check the pods:

```bash theme={null}
kubectl get pod
```

Expected output:

```text theme={null}
NAME           READY   STATUS    RESTARTS   AGE
logger         1/1     Running   0          98s
secure-pod     1/1     Running   0          88s
webapp-color   1/1     Running   0          8m7s
```

Check the service:

```bash theme={null}
kubectl get svc
```

Expected output:

```text theme={null}
NAME             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
kubernetes       ClusterIP   10.96.0.1      <none>        443/TCP    61m
secure-service   ClusterIP   10.102.116.150 <none>        80/TCP     96s
```

### Step 2: Test Connectivity from the webapp-color Pod

Enter the pod shell:

```bash theme={null}
kubectl exec -it webapp-color -- sh
```

Inside the pod, test connectivity with netcat:

```bash theme={null}
nc -v -z -w 2 secure-service 80
```

A timeout error confirms the issue.

### Step 3: Check the Existing Network Policy

Run:

```bash theme={null}
kubectl get netpol
kubectl describe netpol default-deny
```

The output will reveal that a default deny policy is in effect.

### Step 4: Identify Pod Labels

Determine the pod labels with:

```bash theme={null}
kubectl get pod --show-labels
```

Example output:

```text theme={null}
NAME          READY   STATUS    RESTARTS   AGE     LABELS
logger        1/1     Running   0          3m31s   run=logger
secure-pod    1/1     Running   0          3m21s   run=secure-pod
webapp-color  1/1     Running   0          10m     name=webapp-color
```

### Step 5: Create a Network Policy

Create a network policy YAML (`netpol.yaml`) to allow ingress traffic from pods labeled `name=webapp-color` to the pod labeled `run=secure-pod` on port 80:

```yaml theme={null}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      run: secure-pod
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              name: webapp-color
      ports:
        - protocol: TCP
          port: 80
```

Apply the policy:

```bash theme={null}
kubectl apply -f netpol.yaml
```

### Step 6: Retest Connectivity

From the **webapp-color** pod, execute:

```bash theme={null}
nc -v -z -w 2 secure-service 80
```

A successful connection message confirms that the issue has been resolved.

***

## Task 5: Create a Time-Check Pod Using a ConfigMap

In this task, we create a pod that periodically checks the system time. This pod is deployed in a new namespace (for example, `dv11987`).

### Step 1: Create the Namespace

If the namespace doesn’t already exist, create it:

```bash theme={null}
kubectl create ns dv11987
```

### Step 2: Create the ConfigMap

Create a ConfigMap named **time-config** with the key-value pair `TIME_FREQ=10`:

```bash theme={null}
kubectl create cm time-config -n dv11987 --from-literal=TIME_FREQ=10
```

Verify the ConfigMap:

```bash theme={null}
kubectl get cm -n dv11987
```

### Step 3: Generate the Pod YAML

Generate a pod configuration for **time-check** using the `busybox` image:

```bash theme={null}
kubectl run time-check --image=busybox --dry-run=client -o yaml > time-check.yaml
```

### Step 4: Edit the Pod Configuration

Update `time-check.yaml` to include the environment variable from the ConfigMap, a command that logs the current date, and a volume mounted at `/opt/time` using `emptyDir`:

```yaml theme={null}
apiVersion: v1
kind: Pod
metadata:
  name: time-check
  namespace: dv11987
  labels:
    run: time-check
spec:
  containers:
    - name: time-check
      image: busybox
      env:
        - name: TIME_FREQ
          valueFrom:
            configMapKeyRef:
              name: time-config
              key: TIME_FREQ
      command: ["/bin/sh", "-c"]
      args:
        - while true; do date >> /opt/time/time-check.log; sleep $TIME_FREQ; done
      volumeMounts:
        - name: time-volume
          mountPath: /opt/time
  volumes:
    - name: time-volume
      emptyDir: {}
  restartPolicy: Always
```

Apply the configuration:

```bash theme={null}
kubectl apply -f time-check.yaml
```

Verify the pod is running in the `dv11987` namespace:

```bash theme={null}
kubectl get pod -n dv11987
```

If you have any pods with conflicting names in the default namespace, delete them before applying the new configuration.

***

## Task 6: Create and Upgrade an Nginx Deployment

Create a deployment named **nginx-deploy** with the following requirements:

* **Image:** nginx:1.16 initially
* **Replicas:** 4
* **Rolling Update Strategy:**
  * maxSurge: 1
  * maxUnavailable: 2

### Step 1: Generate the Deployment YAML

Generate the deployment using a dry-run:

```bash theme={null}
kubectl create deploy nginx-deploy --image=nginx:1.16 --replicas=4 --dry-run=client -o yaml > nginx-deploy.yaml
```

### Step 2: Edit the Deployment for Rolling Updates

Modify `nginx-deploy.yaml` to add the rolling update strategy:

```yaml theme={null}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  labels:
    app: nginx-deploy
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx-deploy
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 2
  template:
    metadata:
      labels:
        app: nginx-deploy
    spec:
      containers:
        - name: nginx
          image: nginx:1.16
          resources: {}
```

Apply the deployment:

```bash theme={null}
kubectl apply -f nginx-deploy.yaml
```

### Step 3: Upgrade the Deployment

Upgrade the deployment to use `nginx:1.17`:

```bash theme={null}
kubectl set image deployment/nginx-deploy nginx=nginx:1.17
```

Monitor the rollout:

```bash theme={null}
kubectl get deploy
```

### Step 4: Rollback the Deployment

After the upgrade, rollback to the previous version if needed:

```bash theme={null}
kubectl rollout undo deployment/nginx-deploy
```

***

## Task 7: Create a Redis Deployment with Resource Limits and Volume Mounts

Finally, create a deployment named **redis** with these parameters:

* **Image:** redis:alpine
* **Replicas:** 1
* **Resource Request:** 0.2 CPU
* **Label:** app=redis
* **Volumes:**
  * **data:** Use `emptyDir` mounted at `/redis-master-data`
  * **redis-config:** Use a ConfigMap (named redis-config) mounted at `/redis-master`
* **Exposed Port:** 6379

### Step 1: Generate the Deployment YAML

Generate the initial deployment:

```bash theme={null}
kubectl create deploy redis --image=redis:alpine --replicas=1 --dry-run=client -o yaml > redis.yaml
```

### Step 2: Edit the Deployment File

Update `redis.yaml` with the correct resource requests, volumes, and volume mounts:

```yaml theme={null}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  labels:
    app: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      volumes:
        - name: data
          emptyDir: {}
        - name: redis-config
          configMap:
            name: redis-config
      containers:
        - name: redis
          image: redis:alpine
          resources:
            requests:
              cpu: "0.2"
          volumeMounts:
            - name: data
              mountPath: /redis-master-data
            - name: redis-config
              mountPath: /redis-master
          ports:
            - containerPort: 6379
```

Apply the deployment:

```bash theme={null}
kubectl apply -f redis.yaml
```

***

After completing all the tasks, validate your configurations with the appropriate `kubectl get` commands to ensure that all pods, deployments, and services are running as expected.

Happy deploying!

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/certified-kubernetes-application-developer-ckad/module/82805f4b-784c-4364-82ab-dfc139d96dda/lesson/55fde3a8-dcc4-401a-a11c-35dd08b25690" />

  <Card title="Practice Lab" icon="installation" cta="Learn more" href="https://learn.kodekloud.com/user/courses/certified-kubernetes-application-developer-ckad/module/82805f4b-784c-4364-82ab-dfc139d96dda/lesson/f8f8cefc-83f9-4126-8d93-d99fa91682f8" />
</CardGroup>
