<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thu Kha Kyawe</title>
    <description>The latest articles on DEV Community by Thu Kha Kyawe (@thukhakyawe_cloud).</description>
    <link>https://dev.to/thukhakyawe_cloud</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3601335%2Fd44a63a0-36bb-4c80-a1f0-1d55fd8ccc1c.png</url>
      <title>DEV Community: Thu Kha Kyawe</title>
      <link>https://dev.to/thukhakyawe_cloud</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thukhakyawe_cloud"/>
    <language>en</language>
    <item>
      <title>10.Fix Python App Deployed on Kubernetes Cluster</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Thu, 20 Aug 2026 16:10:22 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/10fix-python-app-deployed-on-kubernetes-cluster-ief</link>
      <guid>https://dev.to/thukhakyawe_cloud/10fix-python-app-deployed-on-kubernetes-cluster-ief</guid>
      <description>&lt;h1&gt;
  
  
  Step 1: Check Current Deployment Status
&lt;/h1&gt;

&lt;p&gt;First, let's see what's currently deployed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Check all deployments
kubectl get deployments

# Check the specific deployment
kubectl get deployment python-deployment-datacenter

# Check pods status
kubectl get pods

# Check services
kubectl get services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fukhc6dq6v8yc5cj3l6yu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fukhc6dq6v8yc5cj3l6yu.png" alt=" " width="756" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Examine Detailed Information
&lt;/h1&gt;

&lt;p&gt;Let's look at the deployment and service configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Get detailed deployment information
kubectl describe deployment python-deployment-datacenter

# Get pod details (look for any error messages)
kubectl describe pods python-deployment-datacenter-6fdb496d59-df826 

# Get service details
kubectl describe service python-service-datacenter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thor@jumphost ~$ kubectl describe deployment python-deployment-datacenter
Name:                   python-deployment-datacenter
Namespace:              default
CreationTimestamp:      Sat, 08 Nov 2025 03:56:27 +0000
Labels:                 &amp;lt;none&amp;gt;
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=python_app
Replicas:               1 desired | 1 updated | 1 total | 0 available | 1 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=python_app
  Containers:
   python-container-datacenter:
    Image:         poroko/flask-app-demo
    Port:          5000/TCP
    Host Port:     0/TCP
    Environment:   &amp;lt;none&amp;gt;
    Mounts:        &amp;lt;none&amp;gt;
  Volumes:         &amp;lt;none&amp;gt;
  Node-Selectors:  &amp;lt;none&amp;gt;
  Tolerations:     &amp;lt;none&amp;gt;
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      False   MinimumReplicasUnavailable
  Progressing    False   ProgressDeadlineExceeded
OldReplicaSets:  &amp;lt;none&amp;gt;
NewReplicaSet:   python-deployment-datacenter-6fdb496d59 (1/1 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  20m   deployment-controller  Scaled up replica set python-deployment-datacenter-6fdb496d59 to 1

thor@jumphost ~$ kubectl describe pods python-deployment-datacenter-6fdb496d59-df826 
Name:             python-deployment-datacenter-6fdb496d59-df826
Namespace:        default
Priority:         0
Service Account:  default
Node:             kodekloud-control-plane/172.17.0.2
Start Time:       Sat, 08 Nov 2025 03:56:27 +0000
Labels:           app=python_app
                  pod-template-hash=6fdb496d59
Annotations:      &amp;lt;none&amp;gt;
Status:           Pending
IP:               10.244.0.5
IPs:
  IP:           10.244.0.5
Controlled By:  ReplicaSet/python-deployment-datacenter-6fdb496d59
Containers:
  python-container-datacenter:
    Container ID:   
    Image:          poroko/flask-app-demo
    Image ID:       
    Port:           5000/TCP
    Host Port:      0/TCP
    State:          Waiting
      Reason:       ImagePullBackOff
    Ready:          False
    Restart Count:  0
    Environment:    &amp;lt;none&amp;gt;
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-gfps4 (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             False 
  ContainersReady   False 
  PodScheduled      True 
Volumes:
  kube-api-access-gfps4:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       &amp;lt;nil&amp;gt;
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              &amp;lt;none&amp;gt;
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason     Age                   From               Message
  ----     ------     ----                  ----               -------
  Normal   Scheduled  22m                   default-scheduler  Successfully assigned default/python-deployment-datacenter-6fdb496d59-df826 to kodekloud-control-plane
  Normal   Pulling    20m (x4 over 22m)     kubelet            Pulling image "poroko/flask-app-demo"
  Warning  Failed     20m (x4 over 22m)     kubelet            Failed to pull image "poroko/flask-app-demo": rpc error: code = Unknown desc = failed to pull and unpack image "docker.io/poroko/flask-app-demo:latest": failed to resolve reference "docker.io/poroko/flask-app-demo:latest": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
  Warning  Failed     20m (x4 over 22m)     kubelet            Error: ErrImagePull
  Warning  Failed     20m (x6 over 22m)     kubelet            Error: ImagePullBackOff
  Normal   BackOff    2m25s (x86 over 22m)  kubelet            Back-off pulling image "poroko/flask-app-demo"

thor@jumphost ~$ kubectl describe service python-service-datacenter 
Name:                     python-service-datacenter
Namespace:                default
Labels:                   &amp;lt;none&amp;gt;
Annotations:              &amp;lt;none&amp;gt;
Selector:                 app=python_app
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.96.237.132
IPs:                      10.96.237.132
Port:                     &amp;lt;unset&amp;gt;  8080/TCP
TargetPort:               8080/TCP
NodePort:                 &amp;lt;unset&amp;gt;  32345/TCP
Endpoints:                
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   &amp;lt;none&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Issues Identified:&lt;/p&gt;

&lt;p&gt;Wrong image name: The deployment is using poroko/flask-app-demo but it should be poroko/flask-demo-app&lt;/p&gt;

&lt;p&gt;Port mismatch: The service has targetPort 8080 but the Flask app runs on port 5000&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Fix the Image Name
&lt;/h1&gt;

&lt;p&gt;Let's correct the image name in the deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl set image deployment/python-deployment-datacenter python-container-datacenter=poroko/flask-demo-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 4: Fix the Service Port Configuration
&lt;/h1&gt;

&lt;p&gt;The service needs to target port 5000 (Flask default) instead of 8080:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl patch service python-service-datacenter -p '{"spec":{"ports":[{"port":8080,"targetPort":5000,"nodePort":32345}]}}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7bhshkgwe78joaybo3ob.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7bhshkgwe78joaybo3ob.png" alt=" " width="797" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Verify the Fixes
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Check pod status
kubectl get pods

# Check deployment status
kubectl get deployment python-deployment-datacenter

# Check service endpoints (should now show the pod IP)
kubectl describe service python-service-datacenter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3rafjo1vfatyh31344am.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3rafjo1vfatyh31344am.png" alt=" " width="677" height="459"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>9.Deploy Iron Gallery App on Kubernetes</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Thu, 20 Aug 2026 16:05:45 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/9deploy-iron-gallery-app-on-kubernetes-cg7</link>
      <guid>https://dev.to/thukhakyawe_cloud/9deploy-iron-gallery-app-on-kubernetes-cg7</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;There is an iron gallery app that the Nautilus DevOps team was developing. They have recently customized the app and are going to deploy the same on the Kubernetes cluster. Below you can find more details:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a namespace iron-namespace-nautilus

Create a deployment iron-gallery-deployment-nautilus for iron gallery under the same namespace you created.

:- Labels run should be iron-gallery.

:- Replicas count should be 1.

:- Selector's matchLabels run should be iron-gallery.

:- Template labels run should be iron-gallery under metadata.

:- The container should be named as iron-gallery-container-nautilus, use kodekloud/irongallery:2.0 image ( use exact image name / tag ).

:- Resources limits for memory should be 100Mi and for CPU should be 50m.

:- First volumeMount name should be config, its mountPath should be /usr/share/nginx/html/data.

:- Second volumeMount name should be images, its mountPath should be /usr/share/nginx/html/uploads.

:- First volume name should be config and give it emptyDir and second volume name should be images, also give it emptyDir.

Create a deployment iron-db-deployment-nautilus for iron db under the same namespace.

:- Labels db should be mariadb.

:- Replicas count should be 1.

:- Selector's matchLabels db should be mariadb.

:- Template labels db should be mariadb under metadata.

:- The container name should be iron-db-container-nautilus, use kodekloud/irondb:2.0 image ( use exact image name / tag ).

:- Define environment, set MYSQL_DATABASE its value should be database_apache, set MYSQL_ROOT_PASSWORD and MYSQL_PASSWORD value should be with some complex passwords for DB connections, and MYSQL_USER value should be any custom user ( except root ).

:- Volume mount name should be db and its mountPath should be /var/lib/mysql. Volume name should be db and give it an emptyDir.

Create a service for iron db which should be named iron-db-service-nautilus under the same namespace. Configure spec as selector's db should be mariadb. Protocol should be TCP, port and targetPort should be 3306 and its type should be ClusterIP.

Create a service for iron gallery which should be named iron-gallery-service-nautilus under the same namespace. Configure spec as selector's run should be iron-gallery. Protocol should be TCP, port and targetPort should be 80, nodePort should be 32678 and its type should be NodePort.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;We don't need to make connection b/w database and front-end now, if the installation page is coming up it should be enough for now.

The kubectl on jump_host has been configured to work with the kubernetes cluster.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;
&lt;h1&gt;
  
  
  Step 1: Create the Namespace
&lt;/h1&gt;

&lt;p&gt;vi iron-namespace.yaml&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Namespace
metadata:
  name: iron-namespace-nautilus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the namespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f iron-namespace.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnlh8cwvxc443fynvnzz9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnlh8cwvxc443fynvnzz9.png" alt=" " width="467" height="62"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Create the Iron Gallery Deployment
&lt;/h1&gt;

&lt;p&gt;vi iron-gallery-deployment.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: iron-gallery-deployment-nautilus
  namespace: iron-namespace-nautilus
spec:
  replicas: 1
  selector:
    matchLabels:
      run: iron-gallery
  template:
    metadata:
      labels:
        run: iron-gallery
    spec:
      containers:
      - name: iron-gallery-container-nautilus
        image: kodekloud/irongallery:2.0
        resources:
          limits:
            memory: "100Mi"
            cpu: "50m"
        volumeMounts:
        - name: config
          mountPath: /usr/share/nginx/html/data
        - name: images
          mountPath: /usr/share/nginx/html/uploads
      volumes:
      - name: config
        emptyDir: {}
      - name: images
        emptyDir: {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 3: Create the Iron DB Deployment
&lt;/h1&gt;

&lt;p&gt;vi iron-db-deployment.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: iron-db-deployment-nautilus
  namespace: iron-namespace-nautilus
spec:
  replicas: 1
  selector:
    matchLabels:
      db: mariadb
  template:
    metadata:
      labels:
        db: mariadb
    spec:
      containers:
      - name: iron-db-container-nautilus
        image: kodekloud/irondb:2.0
        env:
        - name: MYSQL_DATABASE
          value: "database_apache"
        - name: MYSQL_ROOT_PASSWORD
          value: "RootPassword123!"
        - name: MYSQL_PASSWORD
          value: "UserPassword123!"
        - name: MYSQL_USER
          value: "ironuser"
        volumeMounts:
        - name: db
          mountPath: /var/lib/mysql
      volumes:
      - name: db
        emptyDir: {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 4: Create the Services
&lt;/h1&gt;

&lt;p&gt;vi iron-services.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Service
metadata:
  name: iron-db-service-nautilus
  namespace: iron-namespace-nautilus
spec:
  selector:
    db: mariadb
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  name: iron-gallery-service-nautilus
  namespace: iron-namespace-nautilus
spec:
  type: NodePort
  selector:
    run: iron-gallery
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 32678
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 5: Apply All Resources
&lt;/h1&gt;

&lt;p&gt;Now let's apply all the YAML files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Apply namespace
kubectl apply -f iron-namespace.yaml

# Apply deployments
kubectl apply -f iron-gallery-deployment.yaml
kubectl apply -f iron-db-deployment.yaml

# Apply services
kubectl apply -f iron-services.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzpjtwxr0dy94uc2q52ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzpjtwxr0dy94uc2q52ln.png" alt=" " width="510" height="138"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Verification
&lt;/h1&gt;

&lt;p&gt;Let's verify that all resources are created correctly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Check namespace
kubectl get namespace iron-namespace-nautilus

# Check all resources in the namespace
kubectl get all -n iron-namespace-nautilus

# Check deployments
kubectl get deployments -n iron-namespace-nautilus

# Check pods
kubectl get pods -n iron-namespace-nautilus

# Check services
kubectl get services -n iron-namespace-nautilus

# Check pod details to ensure everything is running correctly
kubectl describe pod -n iron-namespace-nautilus -l run=iron-gallery
kubectl describe pod -n iron-namespace-nautilus -l db=mariadb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2y7tvmfduqq0vz9hc3jm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2y7tvmfduqq0vz9hc3jm.png" alt=" " width="510" height="138"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb0jrw47cjum4kjkr707h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb0jrw47cjum4kjkr707h.png" alt=" " width="800" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9rwzbhbqrgqu720a3jan.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9rwzbhbqrgqu720a3jan.png" alt=" " width="590" height="77"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi6raq5gqpvsr6iz6efb9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi6raq5gqpvsr6iz6efb9.png" alt=" " width="688" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg0jtjblasuu8tbbsakcq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg0jtjblasuu8tbbsakcq.png" alt=" " width="758" height="79"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thor@jumphost ~$ kubectl describe pod -n iron-namespace-nautilus -l run=iron-gallery
Name:             iron-gallery-deployment-nautilus-7cf86c44d7-6qzkt
Namespace:        iron-namespace-nautilus
Priority:         0
Service Account:  default
Node:             kodekloud-control-plane/172.17.0.2
Start Time:       Fri, 07 Nov 2025 11:27:42 +0000
Labels:           pod-template-hash=7cf86c44d7
                  run=iron-gallery
Annotations:      &amp;lt;none&amp;gt;
Status:           Running
IP:               10.244.0.5
IPs:
  IP:           10.244.0.5
Controlled By:  ReplicaSet/iron-gallery-deployment-nautilus-7cf86c44d7
Containers:
  iron-gallery-container-nautilus:
    Container ID:   containerd://6983760721d6b4cdf17c22e001b61596ff1e4e406d58cf8b66fb6487cc3a9fde
    Image:          kodekloud/irongallery:2.0
    Image ID:       docker.io/kodekloud/irongallery@sha256:677aded1f2397f8168bf7061646630e153a68187a6026587c881feb79436d468
    Port:           &amp;lt;none&amp;gt;
    Host Port:      &amp;lt;none&amp;gt;
    State:          Running
      Started:      Fri, 07 Nov 2025 11:27:54 +0000
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     50m
      memory:  100Mi
    Requests:
      cpu:        50m
      memory:     100Mi
    Environment:  &amp;lt;none&amp;gt;
    Mounts:
      /usr/share/nginx/html/data from config (rw)
      /usr/share/nginx/html/uploads from images (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-4n2v4 (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  config:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     
    SizeLimit:  &amp;lt;unset&amp;gt;
  images:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     
    SizeLimit:  &amp;lt;unset&amp;gt;
  kube-api-access-4n2v4:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       &amp;lt;nil&amp;gt;
    DownwardAPI:             true
QoS Class:                   Guaranteed
Node-Selectors:              &amp;lt;none&amp;gt;
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m12s  default-scheduler  Successfully assigned iron-namespace-nautilus/iron-gallery-deployment-nautilus-7cf86c44d7-6qzkt to kodekloud-control-plane
  Normal  Pulling    2m10s  kubelet            Pulling image "kodekloud/irongallery:2.0"
  Normal  Pulled     2m1s   kubelet            Successfully pulled image "kodekloud/irongallery:2.0" in 9.671382144s (9.671467974s including waiting)
  Normal  Created    2m1s   kubelet            Created container iron-gallery-container-nautilus
  Normal  Started    2m     kubelet            Started container iron-gallery-container-nautilus


thor@jumphost ~$ kubectl describe pod -n iron-namespace-nautilus -l db=mariadb
Name:             iron-db-deployment-nautilus-765f55859c-fc9dw
Namespace:        iron-namespace-nautilus
Priority:         0
Service Account:  default
Node:             kodekloud-control-plane/172.17.0.2
Start Time:       Fri, 07 Nov 2025 11:27:50 +0000
Labels:           db=mariadb
                  pod-template-hash=765f55859c
Annotations:      &amp;lt;none&amp;gt;
Status:           Running
IP:               10.244.0.6
IPs:
  IP:           10.244.0.6
Controlled By:  ReplicaSet/iron-db-deployment-nautilus-765f55859c
Containers:
  iron-db-container-nautilus:
    Container ID:   containerd://3e78fa187d014e0db5b56c452951576b3d83b189aae97e231183d0b0f244f6cf
    Image:          kodekloud/irondb:2.0
    Image ID:       docker.io/kodekloud/irondb@sha256:fa72f29b927307e2a678a2f5056ee5be1f50ae249dbdbd4e47e4abb88e0e5953
    Port:           &amp;lt;none&amp;gt;
    Host Port:      &amp;lt;none&amp;gt;
    State:          Running
      Started:      Fri, 07 Nov 2025 11:28:07 +0000
    Ready:          True
    Restart Count:  0
    Environment:
      MYSQL_DATABASE:       database_apache
      MYSQL_ROOT_PASSWORD:  RootPassword123!
      MYSQL_PASSWORD:       UserPassword123!
      MYSQL_USER:           ironuser
    Mounts:
      /var/lib/mysql from db (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-qclp4 (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  db:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     
    SizeLimit:  &amp;lt;unset&amp;gt;
  kube-api-access-qclp4:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       &amp;lt;nil&amp;gt;
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              &amp;lt;none&amp;gt;
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m25s  default-scheduler  Successfully assigned iron-namespace-nautilus/iron-db-deployment-nautilus-765f55859c-fc9dw to kodekloud-control-plane
  Normal  Pulling    2m23s  kubelet            Pulling image "kodekloud/irondb:2.0"
  Normal  Pulled     2m9s   kubelet            Successfully pulled image "kodekloud/irondb:2.0" in 12.973625003s (14.740476439s including waiting)
  Normal  Created    2m9s   kubelet            Created container iron-db-container-nautilus
  Normal  Started    2m8s   kubelet            Started container iron-db-container-nautilus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Testing the Application
&lt;/h1&gt;

&lt;p&gt;Once deployed, you should be able to access the Iron Gallery application using button from console. &lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>8.Kubernetes Troubleshooting</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Thu, 20 Aug 2026 16:01:40 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/8kubernetes-troubleshooting-5ak9</link>
      <guid>https://dev.to/thukhakyawe_cloud/8kubernetes-troubleshooting-5ak9</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;One of the Nautilus DevOps team members was working on to update an existing Kubernetes template. Somehow, he made some mistakes in the template and it is failing while applying. We need to fix this as soon as possible, so take a look into it and make sure you are able to apply it without any issues. Also, do not remove any component from the template like pods/deployments/volumes etc.&lt;/p&gt;

&lt;p&gt;/home/thor/mysql_deployment.yml is the template that needs to be fixed.&lt;/p&gt;

&lt;p&gt;Note: The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;

&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Step 1. Check yaml file
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat mysql_deployment.yml 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thor@jumphost ~$ cat mysql_deployment.yml 
apiVersion: apps/v1 
kind: PersistentVolume            
metadata:
  name: mysql-pv
  labels: 
  type: local 
spec:
  storageClassName: standard      
  capacity:
    storage: 250Mi
  accessModes: 
    - ReadWriteOnce
  hostPath:                       
  path: "/mnt/data" 
  persistentVolumeReclaimPolicy:  
  -  Retain  
---    
apiVersion: apps/v1 
kind: PersistentVolumeClaim 
metadata:                          
  name: mysql-pv-claim
  labels:
  app: mysql-app 
spec:                              
  storageClassName: standard       
  accessModes:
    - ReadWriteOnce                
  resources:
    requests: 
      storage: 250MB 
---
apiVersion: v1                    
kind: Service                      
metadata:
  name: mysql         
  labels:             
    app: mysql-app
spec:
  type: NodePort
  ports:
    - targetPort: 3306
      port: 3306
      nodePort: 30011
  selector:    
    app: mysql-app
  tier: mysql
---
apiVersion: v1 
kind: Deployment            
metadata:
  name: mysql-deployment       
  labels:                       
    app: mysql-app 
spec:
  selector:
    matchLabels:
      app: mysql-app
    tier: mysql 
  strategy:
    type: Recreate
  template:                    
    metadata:
      labels:                  
        app: mysql-app
      tier: mysql 
    spec:                       
      containers: 
      - images: mysql:5.6 
        name: mysql
        env:                        
        - name: MYSQL_ROOT_PASSWORD 
          valueFrom:                
          secretKeyRef: 
            name: mysql-root-pass 
              key: password 
        - name: MYSQL_DATABASE
          valueFrom:
          secretKeyRef: 
            name: mysql-db-url 
              key: database 
        - name: MYSQL_USER
          valueFrom:
            secretKeyRef:
              name: mysql-user-pass
              key: username
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-user-pass
              key: password
        ports:
        - containerPort: 3306        
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage 
          mountPath: /var/lib/mysql
      volumes:                       
      - name: mysql-persistent-storage
          persistentVolumeClaim:
          claimName: mysql-pv-claim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 2: Errors in the Original YAML
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;mysql_deployment.yml&lt;/code&gt; contains the following errors, which need to be corrected:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wrong apiVersion for PersistentVolume:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: PersistentVolume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Issue: PersistentVolume is a core API resource and must use apiVersion: v1. Fix: Change to apiVersion: v1.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Misplaced labels in PersistentVolume:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;labels:
type: local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Issue: Indentation is incorrect. Fix: Ensure proper indentation under metadata.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;hostPath indentation error:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hostPath:
path: "/mnt/data"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Issue: The path field are not indented correctly under hostPath. Fix: Properly indent path under hostPath.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wrong format for persistentVolumeReclaimPolicy:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;persistentVolumeReclaimPolicy:
  - Retain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Issue: This field takes a string, not a list. Fix: Use persistentVolumeReclaimPolicy: Retain.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;PVC storage unit typo:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;storage: 250MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Issue: Kubernetes uses binary SI units (e.g., Mi, Gi), not MB. Fix: Change to storage: 250Mi.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wrong apiVersion for Deployment:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Deployment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Issue: Deployments are under apps/v1, not v1. Fix: Change to apiVersion: apps/v1.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Misplaced tier labels in selector:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;selector:
  matchLabels:
    app: mysql-app
  tier: mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Issue: tier is incorrectly placed outside matchLabels. Fix: Move tier: mysql under matchLabels.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wrong field name in Deployment container:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- images: mysql:5.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Issue: The field must be image, not images. Fix: Change to image: mysql:5.6.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Indentation of secretKeyRef in env:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: MYSQL_ROOT_PASSWORD
  valueFrom:
  secretKeyRef:
    name: mysql-root-pass
      key: password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Issue: secretKeyRef is not properly indented under valueFrom, and key is indented too far. Fix: Correct indentation for secretKeyRef and its subfields.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Volumes section mis-indented:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;volumes:
- name: mysql-persistent-storage
    persistentVolumeClaim:
    claimName: mysql-pv-claim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Issue: persistentVolumeClaim is not properly indented under the volume. Fix: Correct indentation for persistentVolumeClaim.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Update With Correct Configuration
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
  labels:
    type: local
spec:
  storageClassName: standard
  capacity:
    storage: 250Mi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
  persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
  labels:
    app: mysql-app
spec:
  storageClassName: standard
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 250Mi
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql-app
spec:
  type: NodePort
  ports:
    - targetPort: 3306
      port: 3306
      nodePort: 30011
  selector:
    app: mysql-app
    tier: mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
  labels:
    app: mysql-app
spec:
  selector:
    matchLabels:
      app: mysql-app
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql-app
        tier: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-root-pass
              key: password
        - name: MYSQL_DATABASE
          valueFrom:
            secretKeyRef:
              name: mysql-db-url
              key: database
        - name: MYSQL_USER
          valueFrom:
            secretKeyRef:
              name: mysql-user-pass
              key: username
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-user-pass
              key: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 3: Apply Configuration
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f /home/thor/mysql_deployment.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 4: Verify Resources
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pv,pvc
kubectl get svc mysql
kubectl get deploy mysql-deployment
kubectl get pod -l app=mysql-app
kubectl get secrets
echo "Username:"
kubectl get secret mysql-user-pass -o jsonpath='{.data.username}' | base64 --decode &amp;amp;&amp;amp; echo
echo "Password:"
kubectl get secret mysql-user-pass -o jsonpath='{.data.password}' | base64 --decode &amp;amp;&amp;amp; echo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhdgjaec3g5fw8o7m1iep.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhdgjaec3g5fw8o7m1iep.png" alt=" " width="800" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fromet2de4c15ux23wfic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fromet2de4c15ux23wfic.png" alt=" " width="579" height="66"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ydk51fy9ohz6vu3mbsl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ydk51fy9ohz6vu3mbsl.png" alt=" " width="464" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F20n0q9frrqirihdhyhuj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F20n0q9frrqirihdhyhuj.png" alt=" " width="562" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzy0wxz565ufa7gdks8x5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzy0wxz565ufa7gdks8x5.png" alt=" " width="323" height="94"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F678886fj1locgg7nbyl8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F678886fj1locgg7nbyl8.png" alt=" " width="323" height="94"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Verify MySQL Accessibility
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POD=$(kubectl get pod -l app=mysql-app -o jsonpath='{.items[0].metadata.name}')
kubectl exec $POD -- mysqladmin -u kodekloud_pop -pRc5C9EyvbU status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi53oqa98apbetu7pbpci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi53oqa98apbetu7pbpci.png" alt=" " width="800" height="57"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>7.Kubernetes LEMP Setup</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Fri, 24 Jul 2026 15:14:35 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/7kubernetes-lemp-setup-41g3</link>
      <guid>https://dev.to/thukhakyawe_cloud/7kubernetes-lemp-setup-41g3</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;The Nautilus DevOps team want to deploy a static website on Kubernetes cluster. They are going to use Nginx, phpfpm and MySQL for the database. The team had already gathered the requirements and now they want to make this website live. Below you can find more details:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create some secrets for MySQL.

Create a secret named mysql-root-pass wih key/value pairs as below:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;name: password&lt;br&gt;
value: R00t&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a secret named mysql-user-pass with key/value pairs as below:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;name: username&lt;br&gt;
value: kodekloud_cap&lt;/p&gt;

&lt;p&gt;name: password&lt;br&gt;
value: Rc5C9EyvbU&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a secret named mysql-db-url with key/value pairs as below:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;name: database&lt;br&gt;
value: kodekloud_db8&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a secret named mysql-host with key/value pairs as below:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;name: host&lt;br&gt;
value: mysql-service&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a config map php-config for php.ini with variables_order = "EGPCS" data.

Create a deployment named lemp-wp.

Create two containers under it. First container must be nginx-php-container using image webdevops/php-nginx:alpine-3-php7 and second container must be mysql-container from image mysql:5.6. Mount php-config configmap in nginx container at /opt/docker/etc/php/php.ini location.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;5) Add some environment variables for both containers:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD and MYSQL_HOST. Take their values from the secrets you created. Please make sure to use env field (do not use envFrom) to define the name-value pair of environment variables.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;6) Create a node port type service lemp-service to expose the web application, nodePort must be 30008.&lt;/p&gt;

&lt;p&gt;7) Create a service for mysql named mysql-service and its port must be 3306.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;We already have a /tmp/index.php file on jump_host server.

    Copy this file into the nginx container under document root i.e /app and replace the dummy values for mysql related variables with the environment variables you have set for mysql related parameters. Please make sure you do not hard code the mysql related details in this file, you must use the environment variables to fetch those values.

    Once done, you must be able to access this website using Website button on the top bar, please note that you should see Connected successfully message while accessing this page.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Note: The kubectl on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;


&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;
&lt;h1&gt;
  
  
  Step 1: Create Secrets using YAML files
&lt;/h1&gt;
&lt;h3&gt;
  
  
  Create yaml file by using &lt;code&gt;vi&lt;/code&gt; commands
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;mysql-root-pass-secret.yaml
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: mysql-root-pass
type: Opaque
data:
  password: UjAwdA==  # R00t base64 encoded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;mysql-user-pass-secret.yaml
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: mysql-user-pass
type: Opaque
data:
  username: a29kZWtsb3VkX2NhcA==  # kodekloud_cap base64 encoded
  password: UmM1QzlFeXZiVQ==       # Rc5C9EyvbU base64 encoded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;mysql-db-url-secret.yaml
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: mysql-db-url
type: Opaque
data:
  database: a29kZWtsb3VkX2RiOA==  # kodekloud_db8 base64 encoded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;mysql-host-secret.yaml
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: mysql-host
type: Opaque
data:
  host: bXlzcWwtc2VydmljZQ==  # mysql-service base64 encoded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Apply the secrets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f mysql-root-pass-secret.yaml
kubectl apply -f mysql-user-pass-secret.yaml
kubectl apply -f mysql-db-url-secret.yaml
kubectl apply -f mysql-host-secret.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frzkggun9eui4gnzwrdzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frzkggun9eui4gnzwrdzg.png" alt=" " width="509" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Create ConfigMap using YAML file
&lt;/h1&gt;

&lt;p&gt;php-config-configmap.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: ConfigMap
metadata:
  name: php-config
data:
  php.ini: |
    variables_order = "EGPCS"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the configmap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f php-config-configmap.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F838x8titd1qsfi0pplhi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F838x8titd1qsfi0pplhi.png" alt=" " width="497" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Create the Deployment
&lt;/h1&gt;

&lt;p&gt;lemp-wp-deployment.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: lemp-wp
spec:
  selector:
    matchLabels:
      app: lemp-wp
  template:
    metadata:
      labels:
        app: lemp-wp
    spec:
      containers:
      # Nginx-PHP container
      - name: nginx-php-container
        image: webdevops/php-nginx:alpine-3-php7
        volumeMounts:
        - name: php-config
          mountPath: /opt/docker/etc/php/php.ini
          subPath: php.ini
        - name: app-volume
          mountPath: /app
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-root-pass
              key: password
        - name: MYSQL_DATABASE
          valueFrom:
            secretKeyRef:
              name: mysql-db-url
              key: database
        - name: MYSQL_USER
          valueFrom:
            secretKeyRef:
              name: mysql-user-pass
              key: username
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-user-pass
              key: password
        - name: MYSQL_HOST
          valueFrom:
            secretKeyRef:
              name: mysql-host
              key: host

      # MySQL container
      - name: mysql-container
        image: mysql:5.6
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-root-pass
              key: password
        - name: MYSQL_DATABASE
          valueFrom:
            secretKeyRef:
              name: mysql-db-url
              key: database
        - name: MYSQL_USER
          valueFrom:
            secretKeyRef:
              name: mysql-user-pass
              key: username
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-user-pass
              key: password

      volumes:
      - name: php-config
        configMap:
          name: php-config
      - name: app-volume
        emptyDir: {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f lemp-wp-deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkujf89in71kqhm7nozo5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkujf89in71kqhm7nozo5.png" alt=" " width="497" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Create Services
&lt;/h1&gt;

&lt;p&gt;services.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Service
metadata:
  name: lemp-service
spec:
  type: NodePort
  selector:
    app: lemp-wp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30008
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  selector:
    app: lemp-wp
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f services.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6rwqoya4t2o2tmlj0wkw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6rwqoya4t2o2tmlj0wkw.png" alt=" " width="415" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Copy and Modify index.php
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /tmp/index.php 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F28eqdsl1p2wo2zlngfsi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F28eqdsl1p2wo2zlngfsi.png" alt=" " width="799" height="321"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chmod 777 /tmp/index.php   **Password:** `mjolnir123
vi index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn5n4fxh7n5wm34vb4uzb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn5n4fxh7n5wm34vb4uzb.png" alt=" " width="557" height="199"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
$dbname = getenv('MYSQL_DATABASE');
$dbuser = getenv('MYSQL_USER');
$dbpass = getenv('MYSQL_PASSWORD');
$dbhost = getenv('MYSQL_HOST');

$connect = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);

if (!$connect) {
    die("Connection failed: " . mysqli_connect_error());
}
echo "Connected successfully";
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the file to the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Get the pod name
POD_NAME=$(kubectl get pods -l app=lemp-wp -o jsonpath='{.items[0].metadata.name}')

# Copy the modified file
kubectl cp /tmp/index.php $POD_NAME:/app -c nginx-php-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxhlw9utcnobbred817cn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxhlw9utcnobbred817cn.png" alt=" " width="800" height="60"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Verify Resources
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get secret mysql-root-pass mysql-user-pass mysql-db-url mysql-host
kubectl get configmap php-config
kubectl get deploy lemp-wp
kubectl get pod -l app=lemp-wp
kubectl get svc lemp-service mysql-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn5p3zbwed31qat8q40a7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn5p3zbwed31qat8q40a7.png" alt=" " width="738" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft7j3ye2t71x5ddd7dp5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft7j3ye2t71x5ddd7dp5k.png" alt=" " width="738" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgqe3olpuhdgib3h33cmm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgqe3olpuhdgib3h33cmm.png" alt=" " width="406" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnx7z5c98vqrh7b0shooc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnx7z5c98vqrh7b0shooc.png" alt=" " width="406" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbpet4hhc29yiwze20hc0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbpet4hhc29yiwze20hc0.png" alt=" " width="644" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 7: Verify Application Accessibility
&lt;/h1&gt;

&lt;p&gt;Access the Application:&lt;/p&gt;

&lt;p&gt;Click the Website button in the lab interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fumze90hq2sh8qnu3ginc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fumze90hq2sh8qnu3ginc.png" alt=" " width="644" height="82"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kodekloud</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>6.Environment Variables in Kubernetes</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Fri, 24 Jul 2026 15:02:09 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/6environment-variables-in-kubernetes-2bda</link>
      <guid>https://dev.to/thukhakyawe_cloud/6environment-variables-in-kubernetes-2bda</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;There are a number of parameters that are used by the applications. We need to define these as environment variables, so that we can use them as needed within different configs. Below is a scenario which needs to be configured on Kubernetes cluster. Please find below more details about the same.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a pod named envars.

Container name should be fieldref-container, use image busybox preferable latest tag, use command 'sh', '-c' and args should be
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;'while true; do&lt;br&gt;
      echo -en '/n';&lt;br&gt;
                                  printenv NODE_NAME POD_NAME;&lt;br&gt;
                                  printenv POD_IP POD_SERVICE_ACCOUNT;&lt;br&gt;
              sleep 10;&lt;br&gt;
         done;'&lt;/p&gt;

&lt;p&gt;(Note: please take care of indentations)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Define Four environment variables as mentioned below:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;a.) The first env should be named as NODE_NAME, set valueFrom fieldref and fieldPath should be spec.nodeName.&lt;/p&gt;

&lt;p&gt;b.) The second env should be named as POD_NAME, set valueFrom fieldref and fieldPath should be metadata.name.&lt;/p&gt;

&lt;p&gt;c.) The third env should be named as POD_IP, set valueFrom fieldref and fieldPath should be status.podIP.&lt;/p&gt;

&lt;p&gt;d.) The fourth env should be named as POD_SERVICE_ACCOUNT, set valueFrom fieldref and fieldPath shoulbe be spec.serviceAccountName.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set restart policy to Never.

To check the output, exec into the pod and use printenv command.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Note: The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;


&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;
&lt;h1&gt;
  
  
  Step 1: Create the Pod Configuration
&lt;/h1&gt;

&lt;p&gt;Create a file named envars-pod.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: envars
spec:
  containers:
  - name: fieldref-container
    image: busybox:latest
    command: 
      - 'sh'
      - '-c'
    args:
      - |
        while true; do
          echo -en '\n';
          printenv NODE_NAME POD_NAME;
          printenv POD_IP POD_SERVICE_ACCOUNT;
          sleep 10;
        done;
    env:
    - name: NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    - name: POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    - name: POD_SERVICE_ACCOUNT
      valueFrom:
        fieldRef:
          fieldPath: spec.serviceAccountName
  restartPolicy: Never
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 2: Apply the Pod Configuration
&lt;/h1&gt;

&lt;p&gt;Deploy the pod to the Kubernetes cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f envars-pod.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7bcds5bejvuefczip4pk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7bcds5bejvuefczip4pk.png" alt=" " width="425" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Verify the Pod is Running
&lt;/h1&gt;

&lt;p&gt;Check the pod status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6skesx7xb3f4m5w1vwp7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6skesx7xb3f4m5w1vwp7.png" alt=" " width="359" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Check the Pod Logs
&lt;/h1&gt;

&lt;p&gt;Since the container is running a continuous loop that prints environment variables, you can check the logs to see the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl logs envars
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo64ccupiicp3yfad70b7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo64ccupiicp3yfad70b7.png" alt=" " width="336" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Exec into the Pod and Verify Environment Variables
&lt;/h1&gt;

&lt;p&gt;Execute into the pod to manually check the environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl exec -it envars -- /bin/sh

#Once inside the container, run:
printenv

#Exit the container:
exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcgh3dx2jyjdx850rgqx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcgh3dx2jyjdx850rgqx.png" alt=" " width="577" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Detailed Verification
&lt;/h1&gt;

&lt;p&gt;Let's verify all components are correctly configured:&lt;br&gt;
Check pod details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl describe pod envars
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thor@jumphost ~$ kubectl describe pod envars
Name:             envars
Namespace:        default
Priority:         0
Service Account:  default
Node:             kodekloud-control-plane/172.17.0.2
Start Time:       Tue, 04 Nov 2025 10:37:43 +0000
Labels:           &amp;lt;none&amp;gt;
Annotations:      &amp;lt;none&amp;gt;
Status:           Running
IP:               10.244.0.5
IPs:
  IP:  10.244.0.5
Containers:
  fieldref-container:
    Container ID:  containerd://5c07316533aab139456369be9719d5d5bf8b25850aa7123700ee6e0af29277d4
    Image:         busybox:latest
    Image ID:      docker.io/library/busybox@sha256:e3652a00a2fabd16ce889f0aa32c38eec347b997e73bd09e69c962ec7f8732ee
    Port:          &amp;lt;none&amp;gt;
    Host Port:     &amp;lt;none&amp;gt;
    Command:
      sh
      -c
    Args:
      while true; do
        echo -en '\n';
        printenv NODE_NAME POD_NAME;
        printenv POD_IP POD_SERVICE_ACCOUNT;
        sleep 10;
      done;

    State:          Running
      Started:      Tue, 04 Nov 2025 10:37:44 +0000
    Ready:          True
    Restart Count:  0
    Environment:
      NODE_NAME:             (v1:spec.nodeName)
      POD_NAME:             envars (v1:metadata.name)
      POD_IP:                (v1:status.podIP)
      POD_SERVICE_ACCOUNT:   (v1:spec.serviceAccountName)
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-mvs4m (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-mvs4m:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       &amp;lt;nil&amp;gt;
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              &amp;lt;none&amp;gt;
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  3m20s  default-scheduler  Successfully assigned default/envars to kodekloud-control-plane
  Normal  Pulling    3m19s  kubelet            Pulling image "busybox:latest"
  Normal  Pulled     3m19s  kubelet            Successfully pulled image "busybox:latest" in 315.653926ms (315.66919ms including waiting)
  Normal  Created    3m19s  kubelet            Created container fieldref-container
  Normal  Started    3m19s  kubelet            Started container fieldref-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the environment variables in the pod spec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pod envars -o yaml | grep -A 20 "env:"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv10pwxbqza3h2mghg5cr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv10pwxbqza3h2mghg5cr.png" alt=" " width="565" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 7: Understanding the Field References
&lt;/h1&gt;

&lt;p&gt;The environment variables are set using Downward API field references:&lt;/p&gt;

&lt;p&gt;NODE_NAME: spec.nodeName - Gets the name of the node where the pod is running&lt;/p&gt;

&lt;p&gt;POD_NAME: metadata.name - Gets the name of the pod (envars)&lt;/p&gt;

&lt;p&gt;POD_IP: status.podIP - Gets the IP address assigned to the pod&lt;/p&gt;

&lt;p&gt;POD_SERVICE_ACCOUNT: spec.serviceAccountName - Gets the service account name (defaults to default)&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 8: Continuous Monitoring
&lt;/h1&gt;

&lt;p&gt;To watch the logs in real-time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl logs envars -f
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press Ctrl+C to exit the log view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fimuue8cfevexkhkddbqq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fimuue8cfevexkhkddbqq.png" alt=" " width="343" height="120"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>5.Manage Secrets in Kubernetes</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Fri, 24 Jul 2026 14:57:04 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/5manage-secrets-in-kubernetes-1gl3</link>
      <guid>https://dev.to/thukhakyawe_cloud/5manage-secrets-in-kubernetes-1gl3</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;The Nautilus DevOps team is working to deploy some tools in Kubernetes cluster. Some of the tools are licence based so that licence information needs to be stored securely within Kubernetes cluster. Therefore, the team wants to utilize Kubernetes secrets to store those secrets. Below you can find more details about the requirements:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;We already have a secret key file official.txt under /opt location on jump host. Create a generic secret named official, it should contain the password/license-number present in official.txt file.

Also create a pod named secret-devops.

Configure pod's spec as container name should be secret-container-devops, image should be fedora with latest tag (remember to mention the tag with image). Use sleep command for container so that it remains in running state. Consume the created secret and mount it under /opt/demo within the container.

To verify you can exec into the container secret-container-devops, to check the secret key under the mounted path /opt/demo. Before hitting the Check button please make sure pod/pods are in running state, also validation can take some time to complete so keep patience.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note: The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Step 1: Check the Secret Key File
&lt;/h1&gt;

&lt;p&gt;First, let's verify the content of the official.txt file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /opt/official.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will show you the password/license-number that needs to be stored as a secret.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Create the Kubernetes Secret
&lt;/h1&gt;

&lt;p&gt;Create a generic secret named official from the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl create secret generic official --from-file=official=/opt/official.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8zpa9qhukdue2g4sl9rj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8zpa9qhukdue2g4sl9rj.png" alt=" " width="795" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Verify the Secret was Created
&lt;/h1&gt;

&lt;p&gt;Check if the secret was created successfully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get secrets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpju2m83fx6m1pfdgi2xc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpju2m83fx6m1pfdgi2xc.png" alt=" " width="315" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see more details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl describe secret official
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdcbrogugzy0hjh6x2pid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdcbrogugzy0hjh6x2pid.png" alt=" " width="417" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Create the Pod Configuration
&lt;/h1&gt;

&lt;p&gt;Create a file named secret-devops.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: secret-devops
spec:
  containers:
  - name: secret-container-devops
    image: fedora:latest
    command: ["/bin/bash", "-c", "sleep infinity"]
    volumeMounts:
    - name: secret-volume
      mountPath: /opt/demo
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: official
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 5: Deploy the Pod
&lt;/h1&gt;

&lt;p&gt;Apply the pod configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f secret-devops.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F44u4dud5y9ocgo8fjw9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F44u4dud5y9ocgo8fjw9v.png" alt=" " width="433" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Verify the Pod is Running
&lt;/h1&gt;

&lt;p&gt;Check the pod status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3dikcbhverrvmwrs8tpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3dikcbhverrvmwrs8tpo.png" alt=" " width="404" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 7: Verify the Secret is Mounted Correctly
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Once the pod is running, execute into the container to verify the secret:
kubectl exec -it secret-devops -- /bin/bash


# Inside the container, check the mounted secret:
ls -la /opt/demo/

# You should see the secret file. Then check its content:
cat /opt/demo/official

# Exit the container:
exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhg7cxnzvta0rokviar28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhg7cxnzvta0rokviar28.png" alt=" " width="677" height="235"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kodekloud</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>4.Persistent Volumes in Kubernetes</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Fri, 24 Jul 2026 14:52:15 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/4persistent-volumes-in-kubernetes-4gg4</link>
      <guid>https://dev.to/thukhakyawe_cloud/4persistent-volumes-in-kubernetes-4gg4</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;The Nautilus DevOps team is working on a Kubernetes template to deploy a web application on the cluster. There are some requirements to create/use persistent volumes to store the application code, and the template needs to be designed accordingly. Please find more details below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a PersistentVolume named as pv-devops. Configure the spec as storage class should be manual, set capacity to 5Gi, set access mode to ReadWriteOnce, volume type should be hostPath and set path to /mnt/sysops (this directory is already created, you might not be able to access it directly, so you need not to worry about it).

Create a PersistentVolumeClaim named as pvc-devops. Configure the spec as storage class should be manual, request 1Gi of the storage, set access mode to ReadWriteOnce.

Create a pod named as pod-devops, mount the persistent volume you created with claim name pvc-devops at document root of the web server, the container within the pod should be named as container-devops using image httpd with latest tag only (remember to mention the tag i.e httpd:latest).

Create a node port type service named web-devops using node port 30008 to expose the web server running within the pod.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note: The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;p&gt;Step 2: Create Configuration File&lt;br&gt;
Create a file named devops-deployment.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Define PersistentVolume for storage
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-devops
spec:
  storageClassName: "manual"
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/sysops
---
# Define PersistentVolumeClaim to request storage
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-devops
spec:
  storageClassName: "manual"
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
# Define Pod with Apache web server
apiVersion: v1
kind: Pod
metadata:
  name: pod-devops
  labels:
    app: web-devops
spec:
  containers:
    - name: container-devops
      image: httpd:latest
      volumeMounts:
        - mountPath: /usr/local/apache2/htdocs
          name: web-storage
  volumes:
    - name: web-storage
      persistentVolumeClaim:
        claimName: pvc-devops
---
# Define NodePort service to expose the web server
apiVersion: v1
kind: Service
metadata:
  name: web-devops
spec:
  type: NodePort
  selector:
    app: web-devops
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30008
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 2: Apply Configuration
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f devops-deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8tf35pgaxbgh0tg10851.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8tf35pgaxbgh0tg10851.png" alt=" " width="490" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Verify PersistentVolume and Claim
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pv pv-devops 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verification: Confirm the PersistentVolume is bound to pvc-datacenter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pvc pvc-devops 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjfov9l5xed7ozr8iqtxs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjfov9l5xed7ozr8iqtxs.png" alt=" " width="798" height="123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Verify Pod
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pod pod-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiaolhoa68vi8kii8pqwh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiaolhoa68vi8kii8pqwh.png" alt=" " width="405" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Verify Service
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get svc web-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyoep0u8g7bp79180snal.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyoep0u8g7bp79180snal.png" alt=" " width="597" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Verification: Confirm the service uses NodePort 30008.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Verify Application Accessibility
&lt;/h1&gt;

&lt;p&gt;Access the Application:&lt;/p&gt;

&lt;p&gt;Click on the App or Website button in the lab interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3zn97cumg2afphbhoqp9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3zn97cumg2afphbhoqp9.png" alt=" " width="800" height="51"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>3.Init Containers in Kubernetes</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Thu, 23 Jul 2026 14:54:45 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/3init-containers-in-kubernetes-3c84</link>
      <guid>https://dev.to/thukhakyawe_cloud/3init-containers-in-kubernetes-3c84</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;There are some applications that need to be deployed on Kubernetes cluster and these apps have some pre-requisites where some configurations need to be changed before deploying the app container. Some of these changes cannot be made inside the images so the DevOps team has come up with a solution to use init containers to perform these tasks during deployment. Below is a sample scenario that the team is going to test first.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a Deployment named as ic-deploy-devops.

Configure spec as replicas should be 1, labels app should be ic-devops, template's metadata lables app should be the same ic-devops.

The initContainers should be named as ic-msg-devops, use image fedora with latest tag and use command '/bin/bash', '-c' and 'echo Init Done - Welcome to xFusionCorp Industries &amp;gt; /ic/blog'. The volume mount should be named as ic-volume-devops and mount path should be /ic.

Main container should be named as ic-main-devops, use image fedora with latest tag and use command '/bin/bash', '-c' and 'while true; do cat /ic/blog; sleep 5; done'. The volume mount should be named as ic-volume-devops and mount path should be /ic.

Volume to be named as ic-volume-devops and it should be an emptyDir type.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note: The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Step 1: Create the Deployment YAML File
&lt;/h1&gt;

&lt;p&gt;Create a file named ic-deploy-devops.yaml with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: ic-deploy-devops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ic-devops
  template:
    metadata:
      labels:
        app: ic-devops
    spec:
      initContainers:
      - name: ic-msg-devops
        image: fedora:latest
        command: ['/bin/bash', '-c', 'echo Init Done - Welcome to xFusionCorp Industries &amp;gt; /ic/blog']
        volumeMounts:
        - name: ic-volume-devops
          mountPath: /ic
      containers:
      - name: ic-main-devops
        image: fedora:latest
        command: ['/bin/bash', '-c', 'while true; do cat /ic/blog; sleep 5; done']
        volumeMounts:
        - name: ic-volume-devops
          mountPath: /ic
      volumes:
      - name: ic-volume-devops
        emptyDir: {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 2: Apply the Deployment
&lt;/h1&gt;

&lt;p&gt;Deploy the configuration to your Kubernetes cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f ic-deploy-devops.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F55zyybhve7rl8xdo8icq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F55zyybhve7rl8xdo8icq.png" alt=" " width="473" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Verify the Deployment
&lt;/h1&gt;

&lt;p&gt;Check if the deployment was created successfully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get deployment ic-deploy-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkgor58w01j253oo717f3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkgor58w01j253oo717f3.png" alt=" " width="464" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Check the Pod Status
&lt;/h1&gt;

&lt;p&gt;Monitor the pod creation and init container execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pods -l app=ic-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flvowqfre3ja41ri68g6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flvowqfre3ja41ri68g6g.png" alt=" " width="563" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Verify Init Container Execution
&lt;/h1&gt;

&lt;p&gt;Check the init container logs to ensure it ran successfully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Get the pod name first
POD_NAME=$(kubectl get pods -l app=ic-devops -o jsonpath='{.items[0].metadata.name}')

# Check init container logs
kubectl logs $POD_NAME -c ic-msg-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 6: Verify Main Container Operation
&lt;/h1&gt;

&lt;p&gt;Check the main container logs to see the continuous output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl logs $POD_NAME -c ic-main-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqu8jhtf0vl3eix6gbzvh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqu8jhtf0vl3eix6gbzvh.png" alt=" " width="498" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main container should be printing the message every 5 seconds.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 7: Detailed Verification
&lt;/h1&gt;

&lt;p&gt;Let's verify all components are correctly configured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Check the deployment details:
kubectl describe deployment ic-deploy-devops

# Check the pod details:
kubectl describe pod $POD_NAME

# Verify the volume mount:
kubectl exec $POD_NAME -c ic-main-devops -- ls -la /ic/

# Check the file content directly:
kubectl exec $POD_NAME -c ic-main-devops -- cat /ic/blog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thor@jumphost ~$ kubectl describe deployment ic-deploy-devops
Name:                   ic-deploy-devops
Namespace:              default
CreationTimestamp:      Fri, 31 Oct 2025 13:43:39 +0000
Labels:                 &amp;lt;none&amp;gt;
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=ic-devops
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=ic-devops
  Init Containers:
   ic-msg-devops:
    Image:      fedora:latest
    Port:       &amp;lt;none&amp;gt;
    Host Port:  &amp;lt;none&amp;gt;
    Command:
      /bin/bash
      -c
      echo Init Done - Welcome to xFusionCorp Industries &amp;gt; /ic/blog
    Environment:  &amp;lt;none&amp;gt;
    Mounts:
      /ic from ic-volume-devops (rw)
  Containers:
   ic-main-devops:
    Image:      fedora:latest
    Port:       &amp;lt;none&amp;gt;
    Host Port:  &amp;lt;none&amp;gt;
    Command:
      /bin/bash
      -c
      while true; do cat /ic/blog; sleep 5; done
    Environment:  &amp;lt;none&amp;gt;
    Mounts:
      /ic from ic-volume-devops (rw)
  Volumes:
   ic-volume-devops:
    Type:          EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:        
    SizeLimit:     &amp;lt;unset&amp;gt;
  Node-Selectors:  &amp;lt;none&amp;gt;
  Tolerations:     &amp;lt;none&amp;gt;
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  &amp;lt;none&amp;gt;
NewReplicaSet:   ic-deploy-devops-68789fbb69 (1/1 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  3m55s  deployment-controller  Scaled up replica set ic-deploy-devops-68789fbb69 to 1
thor@jumphost ~$ kubectl describe pod $POD_NAME
Name:             ic-deploy-devops-68789fbb69-n46fh
Namespace:        default
Priority:         0
Service Account:  default
Node:             kodekloud-control-plane/172.17.0.2
Start Time:       Fri, 31 Oct 2025 13:43:39 +0000
Labels:           app=ic-devops
                  pod-template-hash=68789fbb69
Annotations:      &amp;lt;none&amp;gt;
Status:           Running
IP:               10.244.0.5
IPs:
  IP:           10.244.0.5
Controlled By:  ReplicaSet/ic-deploy-devops-68789fbb69
Init Containers:
  ic-msg-devops:
    Container ID:  containerd://fda2d6a406793fce4784b97fbd48e04fc4562a26b6153f877bedff8460ffa44e
    Image:         fedora:latest
    Image ID:      docker.io/library/fedora@sha256:aa7befe5cfd1f0e062728c16453cd1c479d4134c7b85eac00172f3025ab0d522
    Port:          &amp;lt;none&amp;gt;
    Host Port:     &amp;lt;none&amp;gt;
    Command:
      /bin/bash
      -c
      echo Init Done - Welcome to xFusionCorp Industries &amp;gt; /ic/blog
    State:          Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Fri, 31 Oct 2025 13:43:46 +0000
      Finished:     Fri, 31 Oct 2025 13:43:46 +0000
    Ready:          True
    Restart Count:  0
    Environment:    &amp;lt;none&amp;gt;
    Mounts:
      /ic from ic-volume-devops (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-mqkwp (ro)
Containers:
  ic-main-devops:
    Container ID:  containerd://dbc7396b61602a895278a5ebf5eb61bc231ef702bd607c39237866dd6c5a5b5a
    Image:         fedora:latest
    Image ID:      docker.io/library/fedora@sha256:aa7befe5cfd1f0e062728c16453cd1c479d4134c7b85eac00172f3025ab0d522
    Port:          &amp;lt;none&amp;gt;
    Host Port:     &amp;lt;none&amp;gt;
    Command:
      /bin/bash
      -c
      while true; do cat /ic/blog; sleep 5; done
    State:          Running
      Started:      Fri, 31 Oct 2025 13:43:47 +0000
    Ready:          True
    Restart Count:  0
    Environment:    &amp;lt;none&amp;gt;
    Mounts:
      /ic from ic-volume-devops (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-mqkwp (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  ic-volume-devops:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     
    SizeLimit:  &amp;lt;unset&amp;gt;
  kube-api-access-mqkwp:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       &amp;lt;nil&amp;gt;
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              &amp;lt;none&amp;gt;
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  4m3s   default-scheduler  Successfully assigned default/ic-deploy-devops-68789fbb69-n46fh to kodekloud-control-plane
  Normal  Pulling    4m2s   kubelet            Pulling image "fedora:latest"
  Normal  Pulled     3m57s  kubelet            Successfully pulled image "fedora:latest" in 5.558670958s (5.558686183s including waiting)
  Normal  Created    3m57s  kubelet            Created container ic-msg-devops
  Normal  Started    3m56s  kubelet            Started container ic-msg-devops
  Normal  Pulling    3m56s  kubelet            Pulling image "fedora:latest"
  Normal  Pulled     3m55s  kubelet            Successfully pulled image "fedora:latest" in 144.822007ms (144.841997ms including waiting)
  Normal  Created    3m55s  kubelet            Created container ic-main-devops
  Normal  Started    3m55s  kubelet            Started container ic-main-devops
thor@jumphost ~$ kubectl exec $POD_NAME -c ic-main-devops -- ls -la /ic/
total 12
drwxrwxrwx 2 root root 4096 Oct 31 13:43 .
drwxr-xr-x 1 root root 4096 Oct 31 13:43 ..
-rw-r--r-- 1 root root   46 Oct 31 13:43 blog
thor@jumphost ~$ kubectl exec $POD_NAME -c ic-main-devops -- cat /ic/blog
Init Done - Welcome to xFusionCorp Industries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 8: Continuous Monitoring
&lt;/h1&gt;

&lt;p&gt;To see the real-time output from the main container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl logs $POD_NAME -c ic-main-devops -f
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press Ctrl+C to exit the continuous log view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr0zz68kil0ybmi9tj5fo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr0zz68kil0ybmi9tj5fo.png" alt=" " width="511" height="48"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Explanation of the Solution&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Init Container (ic-msg-devops):

Runs before the main container starts

Creates a file /ic/blog with the welcome message

Uses the shared volume ic-volume-devops

Main Container (ic-main-devops):

Starts after the init container completes successfully

Reads the file created by the init container every 5 seconds

Shares the same volume mount

Volume (ic-volume-devops):

emptyDir type creates a temporary directory that survives container restarts

Shared between init container and main container

Data persists for the lifetime of the pod

Workflow:

Init container writes message to file → Init container completes → Main container starts → Main container reads file repeatedly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>2.Deploy Lamp Stack on Kubernetes Cluster</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Thu, 23 Jul 2026 14:51:19 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/2deploy-lamp-stack-on-kubernetes-cluster-487f</link>
      <guid>https://dev.to/thukhakyawe_cloud/2deploy-lamp-stack-on-kubernetes-cluster-487f</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;The Nautilus DevOps team want to deploy a PHP website on Kubernetes cluster. They are going to use Apache as a web server and Mysql for database. The team had already gathered the requirements and now they want to make this website live. Below you can find more details:&lt;/p&gt;

&lt;p&gt;1) Create a config map php-config for php.ini with variables_order = "EGPCS" data.&lt;/p&gt;

&lt;p&gt;2) Create a deployment named lamp-wp.&lt;/p&gt;

&lt;p&gt;3) Create two containers under it. First container must be httpd-php-container using image webdevops/php-apache:alpine-3-php7 and second container must be mysql-container from image mysql:5.6. Mount php-config configmap in httpd container at /opt/docker/etc/php/php.ini location.&lt;/p&gt;

&lt;p&gt;4) Create kubernetes generic secrets for mysql related values like myql root password, mysql user, mysql password, mysql host and mysql database. Set any values of your choice.&lt;/p&gt;

&lt;p&gt;5) Add some environment variables for both containers:&lt;/p&gt;

&lt;p&gt;a) MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD and MYSQL_HOST. Take their values from the secrets you created. Please make sure to use env field (do not use envFrom) to define the name-value pair of environment variables.&lt;/p&gt;

&lt;p&gt;6) Create a node port type service lamp-service to expose the web application, nodePort must be 30008.&lt;/p&gt;

&lt;p&gt;7) Create a service for mysql named mysql-service and its port must be 3306.&lt;/p&gt;

&lt;p&gt;8) We already have /tmp/index.php file on jump_host server.&lt;/p&gt;

&lt;p&gt;a) Copy this file into httpd container under Apache document root i.e /app and replace the dummy values for mysql related variables with the environment variables you have set for mysql related parameters. Please make sure you do not hard code the mysql related details in this file, you must use the environment variables to fetch those values.&lt;/p&gt;

&lt;p&gt;b) You must be able to access this index.php on node port 30008 at the end, please note that you should see Connected successfully message while accessing this page.&lt;/p&gt;

&lt;p&gt;Note:&lt;/p&gt;

&lt;p&gt;The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Step 1: Create the ConfigMap for php.ini
&lt;/h1&gt;

&lt;p&gt;First, create the php-config ConfigMap with the required php.ini setting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create configmap php-config &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;php.ini&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'variables_order = "EGPCS"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the ConfigMap was created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get configmap php-config &lt;span class="nt"&gt;-o&lt;/span&gt; yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhakktmszm399gcrmdjtc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhakktmszm399gcrmdjtc.png" alt=" " width="799" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ဋ Step 2: Create MySQL Secrets&lt;/p&gt;

&lt;p&gt;Create a generic secret for MySQL credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create secret generic mysql-secrets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mysql-root-password&lt;span class="o"&gt;=&lt;/span&gt;rootpass123 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mysql-user&lt;span class="o"&gt;=&lt;/span&gt;wpuser &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mysql-password&lt;span class="o"&gt;=&lt;/span&gt;wppass123 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mysql-database&lt;span class="o"&gt;=&lt;/span&gt;wordpress &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mysql-host&lt;span class="o"&gt;=&lt;/span&gt;mysql-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the secret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get secret mysql-secrets &lt;span class="nt"&gt;-o&lt;/span&gt; yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd5kbxm3aqkb8mwvvl74f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd5kbxm3aqkb8mwvvl74f.png" alt=" " width="507" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Create the Deployment
&lt;/h1&gt;

&lt;p&gt;Create a file named lamp-wp-deployment.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lamp-wp&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lamp-wp&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lamp-wp&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-php-container&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;webdevops/php-apache:alpine-3-php7&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
        &lt;span class="na"&gt;volumeMounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;php-config&lt;/span&gt;
          &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/opt/docker/etc/php/php.ini&lt;/span&gt;
          &lt;span class="na"&gt;subPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;php.ini&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app-volume&lt;/span&gt;
          &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/app&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-root-password&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_DATABASE&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-database&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_USER&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-user&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-password&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_HOST&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-host&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-container&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql:5.6&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3306&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-root-password&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_DATABASE&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-database&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_USER&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-user&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_PASSWORD&lt;/span&gt;
          &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-secrets&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-password&lt;/span&gt;
      &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;php-config&lt;/span&gt;
        &lt;span class="na"&gt;configMap&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;php-config&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app-volume&lt;/span&gt;
        &lt;span class="na"&gt;emptyDir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; lamp-wp-deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fze9412j0al7b6kr5rck0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fze9412j0al7b6kr5rck0.png" alt=" " width="497" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Create the Services
&lt;/h1&gt;

&lt;p&gt;Create a file named services.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lamp-service&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NodePort&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lamp-wp&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;nodePort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30008&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-service&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lamp-wp&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3306&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3306&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; services.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv9f9vrph5e04fq5jvhu2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv9f9vrph5e04fq5jvhu2.png" alt=" " width="407" height="78"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Prepare and Copy index.php
&lt;/h1&gt;

&lt;p&gt;First, let's check the original index.php file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F47w3ozu41fm2gpi2lba3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F47w3ozu41fm2gpi2lba3.png" alt=" " width="798" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's update modified version that uses environment variables. Create a new file /tmp/index-modified.php:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="nv"&gt;$servername&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"MYSQL_HOST"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"MYSQL_USER"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"MYSQL_PASSWORD"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$dbname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"MYSQL_DATABASE"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Create connection&lt;/span&gt;
&lt;span class="nv"&gt;$conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;mysqli&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$servername&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$dbname&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Check connection&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$conn&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;connect_error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;die&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Connection failed: "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$conn&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;connect_error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Connected successfully"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If permission issues occur, fix them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;777 /tmp/index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Password: &lt;code&gt;mjolnir123&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6: Copy index.php to Apache Container
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;cp&lt;/span&gt; /tmp/index.php lamp-wp-7ccc97bf65-6nhv6:/app/index.php &lt;span class="nt"&gt;-c&lt;/span&gt; httpd-php-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Explanation of Commands:

    Command 1: POD=$(kubectl get pod -l app=lamp-app -o jsonpath='{.items[0].metadata.name}')
        Purpose: Retrieves the name of the first pod with the label app=lamp-app and stores it in the POD variable.
        Details:
            kubectl get pod: Lists pods in the current namespace.
            -l app=lamp-app: Filters pods with the label app=lamp-app, matching the deployment's selector.
            -o jsonpath='{.items[0].metadata.name}': Extracts the name of the first pod using JSONPath.
            POD=$(): Stores the pod name (e.g., lamp-wp-5f7b8d4c5-xyz12) in the POD variable.
        Why Needed: Pod names are dynamically generated by Kubernetes, so this command dynamically retrieves the correct pod name for the file copy operation.

    Command 2: kubectl cp /tmp/index.php $POD:/app -c httpd-php-container
        Purpose: Copies the index.php file from the jump host's /tmp directory to the /app directory in the httpd-php-container of the specified pod.
        Details:
            kubectl cp: Copies files between the local filesystem and a container.
            /tmp/index.php: Source file on the jump host.
            $POD:/app: Destination path, where $POD is the pod name and /app is the Apache document root.
            -c httpd-php-container: Specifies the target container within the pod (since the pod has both httpd-php-container and mysql-container).
        Why Needed: The index.php file contains the PHP code for the website, which must be placed in the Apache document root to make the application functional.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 7: Verify Deployment and Services
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get configmap php-config
kubectl get secret mysql-secrets
kubectl get deploy lamp-wp
kubectl get pods
kubectl get svc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F45zr5uz0csvorkr5ltub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F45zr5uz0csvorkr5ltub.png" alt=" " width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 8: Verify Application Accessibility
&lt;/h1&gt;

&lt;p&gt;Access the Application:&lt;/p&gt;

&lt;p&gt;Click on the App button in the lab interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm6bww0yy3vgen7o5pi63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm6bww0yy3vgen7o5pi63.png" alt=" " width="799" height="70"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>1.Deploy Apache Web Server on Kubernetes Cluster</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Thu, 23 Jul 2026 14:51:02 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/1deploy-apache-web-server-on-kubernetes-cluster-4bk7</link>
      <guid>https://dev.to/thukhakyawe_cloud/1deploy-apache-web-server-on-kubernetes-cluster-4bk7</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;There is an application that needs to be deployed on Kubernetes cluster under Apache web server. The Nautilus application development team has asked the DevOps team to deploy it. We need to develop a template as per requirements mentioned below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a namespace named as httpd-namespace-devops.

Create a deployment named as httpd-deployment-devops under newly created namespace. For the deployment use httpd image with latest tag only and remember to mention the tag i.e httpd:latest, and make sure replica counts are 2.

Create a service named as httpd-service-devops under same namespace to expose the deployment, nodePort should be 30004.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note: The kubectl utility on jump_host has been configured to work with the kubernetes cluster.&lt;/p&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Step 1: Create the Namespace
&lt;/h1&gt;

&lt;p&gt;First, let's create the required namespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace httpd-namespace-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the namespace was created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get namespaces
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 2: Create the Deployment
&lt;/h1&gt;

&lt;p&gt;Create a YAML file for the deployment. Let's create a file called httpd-deployment.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;cat &amp;gt; httpd-deployment.yaml &amp;lt;&amp;lt; EOF&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-deployment-devops&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-namespace-devops&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-app&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-app&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-container&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd:latest&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; httpd-deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5mw8jwoaluo1jast43u3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5mw8jwoaluo1jast43u3.png" alt=" " width="540" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Create the Service
&lt;/h1&gt;

&lt;p&gt;Create a YAML file for the service. Let's create a file called httpd-service.yaml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;cat &amp;gt; httpd-service.yaml &amp;lt;&amp;lt; EOF&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-service-devops&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-namespace-devops&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NodePort&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;httpd-app&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;nodePort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30004&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; httpd-service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkhueeoomsq5rzjzrf3l9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkhueeoomsq5rzjzrf3l9.png" alt=" " width="468" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Verify All Resources
&lt;/h1&gt;

&lt;p&gt;Let's verify everything was created correctly:&lt;/p&gt;

&lt;p&gt;Check the deployments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get deployment &lt;span class="nt"&gt;-n&lt;/span&gt; httpd-namespace-devops
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; httpd-namespace-devops
kubectl get service &lt;span class="nt"&gt;-n&lt;/span&gt; httpd-namespace-devops
kubectl get all &lt;span class="nt"&gt;-n&lt;/span&gt; httpd-namespace-devops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhwt0eywm68jvp7e3xpmw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhwt0eywm68jvp7e3xpmw.png" alt=" " width="743" height="442"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-DevOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>kubernetes</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>Day 19: Complete a Production DVC Pipeline with SeaweedFS Remote</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Sun, 19 Jul 2026 05:10:53 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/day-19-complete-a-production-dvc-pipeline-with-seaweedfs-remote-17k9</link>
      <guid>https://dev.to/thukhakyawe_cloud/day-19-complete-a-production-dvc-pipeline-with-seaweedfs-remote-17k9</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;Complete the xFusionCorp Industries fraud-detection production DVC pipeline. Three stages are already wired in dvc.yaml, two remain, and the pipeline must finish as a reproducible, SeaweedFS-backed, v1.0-tagged release.&lt;/p&gt;

&lt;p&gt;A project exists at /root/code/ml-pipeline/ with Git and DVC initialised. The params.yaml is in place and the .dvc/config is pre-configured to push to the SeaweedFS bucket dvc-storage at &lt;a href="http://localhost:8333" rel="noopener noreferrer"&gt;http://localhost:8333&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The ingest, validate, and preprocess stages are already declared in dvc.yaml, but one of them is misconfigured and prevents dvc repro from completing — run dvc repro to see it fail. The two scripts for the remaining stages are pre-staged at /root/code/ml-pipeline/scripts-staging/train.py and scripts-staging/evaluate.py, and belong in scripts/.&lt;/p&gt;

&lt;p&gt;Acceptance criteria:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The misconfigured existing stage is corrected so dvc repro can complete.
Two further stages are declared in dvc.yaml:
    train – Depends on the preprocessed dataset and scripts/train.py; reads n_estimators, max_depth, test_size, and random_seed from params.yaml; outputs models/model.pkl and data/processed/test_split.csv; declares metrics.json as a DVC metric with cache: false.
    evaluate – Depends on models/model.pkl, data/processed/test_split.csv, and scripts/evaluate.py; outputs reports/evaluation.json declared with cache: false.
The full pipeline has been reproduced, the cache pushed to the SeaweedFS remote, and the current state tagged v1.0.
Every change is committed to Git so the release is fully captured.

Open the SeaweedFS Filer button at the top of the lab and navigate to /buckets/dvc-storage/ to confirm that the bucket holds the pushed artefacts under the files/md5/... layout.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;p&gt;✅ Part 1: Lab Step-by-Step Guidelines&lt;/p&gt;

&lt;p&gt;Step 1: Enter the project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /root/code/ml-pipeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Run the pipeline once&lt;/p&gt;

&lt;p&gt;The lab tells you one stage is intentionally broken.&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc repro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't fix anything yet.&lt;/p&gt;

&lt;p&gt;Read the error carefully.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;p&gt;Missing dependency&lt;br&gt;
Output mismatch&lt;br&gt;
Script not found&lt;br&gt;
Wrong filename&lt;/p&gt;

&lt;p&gt;The error will tell you exactly which existing stage is misconfigured.&lt;/p&gt;

&lt;p&gt;Step 3: Inspect the existing pipeline&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;cat dvc.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;root@controlplane ml-pipeline on  main [?] ✖ cat dvc.yaml&lt;/span&gt;
&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ingest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 scripts/ingest.py&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;scripts/ingest.py&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/raw/data.csv&lt;/span&gt;

  &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 scripts/validate.py&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/raw/data.csv&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;scripts/validate.py&lt;/span&gt;
    &lt;span class="na"&gt;outs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;reports/validation.json&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

  &lt;span class="na"&gt;preprocess&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3 scripts/preprocess.py&lt;/span&gt;
    &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/raw/data.csv&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;scripts/preprocess.py&lt;/span&gt;
    &lt;span class="na"&gt;outs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;data/processed/cleaned.csv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4: Check what preprocess.py actually created&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; data/processed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;root@controlplane ml-pipeline on  main [?] ➜  ls -l data/processed
total 4
-rw-r--r-- 1 root root 702 Jul 19 00:15 clean.csv
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5: Fix the preprocess output path.&lt;/p&gt;

&lt;p&gt;Open dvc.yaml in the VS Code editor. In the preprocess stage, change the last line from:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - data/processed/cleaned.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - data/processed/clean.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Save the file (Ctrl+S).&lt;/p&gt;

&lt;p&gt;Step 6: Copy the remaining scripts into scripts/.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;scripts-staging/train.py    scripts/train.py
&lt;span class="nb"&gt;cp &lt;/span&gt;scripts-staging/evaluate.py scripts/evaluate.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the train and evaluate stages to dvc.yaml.&lt;/p&gt;

&lt;p&gt;Step 7: Declare the train and evaluate stages with dvc stage add.&lt;/p&gt;

&lt;p&gt;Train stage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc stage add &lt;span class="nt"&gt;-n&lt;/span&gt; train &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; data/processed/clean.csv &lt;span class="nt"&gt;-d&lt;/span&gt; scripts/train.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; n_estimators,max_depth,test_size,random_seed &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; models/model.pkl &lt;span class="nt"&gt;-o&lt;/span&gt; data/processed/test_split.csv &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-M&lt;/span&gt; metrics.json &lt;span class="se"&gt;\&lt;/span&gt;
  python3 scripts/train.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Evaluate stage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc stage add &lt;span class="nt"&gt;-n&lt;/span&gt; evaluate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; models/model.pkl &lt;span class="nt"&gt;-d&lt;/span&gt; data/processed/test_split.csv &lt;span class="nt"&gt;-d&lt;/span&gt; scripts/evaluate.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-O&lt;/span&gt; reports/evaluation.json &lt;span class="se"&gt;\&lt;/span&gt;
  python3 scripts/evaluate.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc repro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push to SeaweedFS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Complete production DVC pipeline"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tag the release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git tag v1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 8: Verify the SeaweedFS bucket&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpro1uix69mf8zbfe1qm1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpro1uix69mf8zbfe1qm1.png" alt=" " width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;🧠 Part 2: Simple Step-by-Step Explanation (Beginner Friendly)&lt;/p&gt;

&lt;p&gt;In this lab, the ingest and validate stages completed successfully, but the pipeline stopped during the preprocess stage.&lt;/p&gt;

&lt;p&gt;When you ran:&lt;/p&gt;

&lt;p&gt;dvc repro&lt;/p&gt;

&lt;p&gt;DVC executed the preprocess.py script successfully, and the script printed:&lt;/p&gt;

&lt;p&gt;Preprocessed: 20 clean rows&lt;/p&gt;

&lt;p&gt;However, DVC then displayed the following error:&lt;/p&gt;

&lt;p&gt;ERROR: failed to reproduce 'preprocess':&lt;br&gt;
output 'data/processed/cleaned.csv' does not exist&lt;/p&gt;

&lt;p&gt;This tells us that the Python script itself did not fail. Instead, DVC could not find the output file that was defined in dvc.yaml.&lt;/p&gt;

&lt;p&gt;To investigate, we opened the pipeline configuration:&lt;/p&gt;

&lt;p&gt;cat dvc.yaml&lt;/p&gt;

&lt;p&gt;Inside the preprocess stage, the output was configured as:&lt;/p&gt;

&lt;p&gt;outs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data/processed/cleaned.csv&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, we checked the actual contents of the data/processed directory:&lt;/p&gt;

&lt;p&gt;ls -l data/processed&lt;/p&gt;

&lt;p&gt;The output showed:&lt;/p&gt;

&lt;p&gt;clean.csv&lt;/p&gt;

&lt;p&gt;This revealed the problem: the script created clean.csv, but dvc.yaml expected cleaned.csv.&lt;/p&gt;

&lt;p&gt;Because DVC verifies that every declared output exists after a stage finishes, it stopped the pipeline when it couldn't find cleaned.csv.&lt;/p&gt;

&lt;p&gt;To fix the issue, we updated the outs section of the preprocess stage so that it matched the file actually produced by the script:&lt;/p&gt;

&lt;p&gt;preprocess:&lt;br&gt;
  cmd: python3 scripts/preprocess.py&lt;br&gt;
  deps:&lt;br&gt;
    - data/raw/data.csv&lt;br&gt;
    - scripts/preprocess.py&lt;br&gt;
  outs:&lt;br&gt;
    - data/processed/clean.csv&lt;/p&gt;

&lt;p&gt;After saving the change, running:&lt;/p&gt;

&lt;p&gt;dvc repro&lt;/p&gt;

&lt;p&gt;again allows DVC to locate the correct output file and continue executing the remaining stages of the pipeline.&lt;/p&gt;

&lt;p&gt;Key Takeaway&lt;/p&gt;

&lt;p&gt;A very common DVC error is:&lt;/p&gt;

&lt;p&gt;output '' does not exist&lt;/p&gt;

&lt;p&gt;When you see this message, the first thing to check is whether the output filename in dvc.yaml exactly matches the filename created by the script. Even a small difference—such as clean.csv versus cleaned.csv—is enough to cause the pipeline to fail. Always verify the actual output file (for example, using ls) before updating the pipeline configuration.&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-MLOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>100daysofmlops</category>
      <category>kodekloud</category>
    </item>
    <item>
      <title>Day 18: Version Datasets and Models Across Git Branches</title>
      <dc:creator>Thu Kha Kyawe</dc:creator>
      <pubDate>Sun, 19 Jul 2026 05:04:56 +0000</pubDate>
      <link>https://dev.to/thukhakyawe_cloud/day-18-version-datasets-and-models-across-git-branches-2c5c</link>
      <guid>https://dev.to/thukhakyawe_cloud/day-18-version-datasets-and-models-across-git-branches-2c5c</guid>
      <description>&lt;h1&gt;
  
  
  Lab Information
&lt;/h1&gt;

&lt;p&gt;The xFusionCorp Industries MLOps team versions datasets and models on separate Git branches so it can reproduce and roll between versions cleanly. Tag the current state as v1.0, create a v2-improved branch built on a newer dataset (which retrains the model), and confirm that switching back restores the original data and model.&lt;/p&gt;

&lt;p&gt;A project exists at /root/code/fraud-detection/ with a working DVC pipeline (it processes the data and trains a model) and the baseline data/raw/transactions.csv already tracked.&lt;/p&gt;

&lt;p&gt;An improved dataset has been pre-staged at /root/code/fraud-detection/data/raw/transactions_v2.csv and is visible in the file explorer. Do not delete this file.&lt;/p&gt;

&lt;p&gt;Acceptance criteria:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;On the main branch, the current state is tagged v1.0.
A branch named v2-improved holds the v2 state: the tracked dataset carries the contents of the v2 file (re-tracked with DVC), the pipeline has been re-run so models/model.pkl is retrained and versioned alongside the dataset, and the changes are committed.
Back on the main branch, the v1 dataset and model are restored on disk, matching the hashes recorded by the v1.0 tag.

The DVC extension's DVC TRACKED section in the EXPLORER panel reflects the tracked dataset and model for the branch you currently have checked out. To compare the exact hashes recorded on each branch, use git show &amp;lt;ref&amp;gt;:dvc.lock or dvc status.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h1&gt;
  
  
  Lab Solutions
&lt;/h1&gt;

&lt;p&gt;✅ Part 1: Lab Step-by-Step Guidelines&lt;/p&gt;

&lt;p&gt;This is one of the most realistic DVC labs. You'll combine Git branches + DVC + pipeline reproducibility.&lt;/p&gt;

&lt;p&gt;Step 1: Go to the project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /root/code/fraud-detection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Make sure everything is committed&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;/p&gt;

&lt;p&gt;On branch main&lt;br&gt;
nothing to commit, working tree clean&lt;/p&gt;

&lt;p&gt;If not clean, commit your changes before continuing.&lt;/p&gt;

&lt;p&gt;Step 3: Tag the current version&lt;/p&gt;

&lt;p&gt;The lab requires the current main branch to be tagged as v1.0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git tag v1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git tag
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;/p&gt;

&lt;p&gt;v1.0&lt;/p&gt;

&lt;p&gt;Step 4: Create the new branch&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; v2-improved
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;v2-improved
main&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 5: Replace the tracked dataset with the new version&lt;/p&gt;

&lt;p&gt;The improved dataset already exists:&lt;/p&gt;

&lt;p&gt;data/raw/transactions_v2.csv&lt;/p&gt;

&lt;p&gt;Replace the original dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;data/raw/transactions_v2.csv data/raw/transactions.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 6: Update DVC tracking&lt;/p&gt;

&lt;p&gt;Since the tracked file changed, update the DVC metadata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc add data/raw/transactions.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This updates:&lt;/p&gt;

&lt;p&gt;transactions.csv.dvc&lt;br&gt;
DVC cache&lt;/p&gt;

&lt;p&gt;Step 7: Retrain the pipeline&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc repro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should rerun:&lt;/p&gt;

&lt;p&gt;process_data&lt;br&gt;
split_data&lt;br&gt;
train&lt;/p&gt;

&lt;p&gt;and regenerate:&lt;/p&gt;

&lt;p&gt;models/model.pkl&lt;br&gt;
metrics.json&lt;br&gt;
dvc.lock&lt;/p&gt;

&lt;p&gt;Step 8: Check Git status&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see changes similar to:&lt;/p&gt;

&lt;p&gt;modified: data/raw/transactions.csv.dvc&lt;br&gt;
modified: dvc.lock&lt;br&gt;
modified: metrics.json&lt;br&gt;
modified: models/model.pkl.dvc   (if model is DVC tracked)&lt;/p&gt;

&lt;p&gt;Note: The exact files may differ depending on how the lab repository is set up.&lt;/p&gt;

&lt;p&gt;Step 9: Commit the v2 state&lt;/p&gt;

&lt;p&gt;Stage everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Update dataset to v2 and retrain model"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 10: Return to main&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 11: Restore the DVC-tracked files&lt;/p&gt;

&lt;p&gt;After switching branches, restore the correct dataset and model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc checkout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 12: Verify&lt;/p&gt;

&lt;p&gt;Check the dataset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;md5sum &lt;/span&gt;data/raw/transactions.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; models/model.pkl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify DVC:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dvc status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;/p&gt;

&lt;p&gt;Data and pipelines are up to date.&lt;/p&gt;




&lt;p&gt;🧠 Part 2: Simple Step-by-Step Explanation (Beginner Friendly)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why do we create a Git tag?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The command:&lt;/p&gt;

&lt;p&gt;git tag v1.0&lt;/p&gt;

&lt;p&gt;creates a permanent label for the current project state.&lt;/p&gt;

&lt;p&gt;Think of it as taking a snapshot:&lt;/p&gt;

&lt;p&gt;main&lt;br&gt;
 │&lt;br&gt;
 ├── v1.0  ← Snapshot&lt;/p&gt;

&lt;p&gt;You can always return to exactly this version later.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why create a new branch?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of changing the main branch directly, we create:&lt;/p&gt;

&lt;p&gt;v2-improved&lt;/p&gt;

&lt;p&gt;This allows us to safely experiment with a new dataset.&lt;/p&gt;

&lt;p&gt;The structure becomes:&lt;/p&gt;

&lt;p&gt;main&lt;br&gt;
 │&lt;br&gt;
 └── v2-improved&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why run dvc add again?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The file name stays the same:&lt;/p&gt;

&lt;p&gt;transactions.csv&lt;/p&gt;

&lt;p&gt;but its contents change because you copied in the improved dataset.&lt;/p&gt;

&lt;p&gt;DVC tracks file contents (using hashes), not just filenames.&lt;/p&gt;

&lt;p&gt;Running:&lt;/p&gt;

&lt;p&gt;dvc add data/raw/transactions.csv&lt;/p&gt;

&lt;p&gt;updates the .dvc pointer to reference the new dataset version.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why rerun the pipeline?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dataset changed.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;p&gt;transactions.csv&lt;br&gt;
        │&lt;br&gt;
        ▼&lt;br&gt;
process_data&lt;br&gt;
        ▼&lt;br&gt;
split_data&lt;br&gt;
        ▼&lt;br&gt;
train&lt;br&gt;
        ▼&lt;br&gt;
model.pkl&lt;/p&gt;

&lt;p&gt;Every downstream stage depends on the dataset, so DVC reruns the pipeline to produce a model trained on the new data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why use dvc checkout?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you switch back to:&lt;/p&gt;

&lt;p&gt;git checkout main&lt;/p&gt;

&lt;p&gt;Git restores:&lt;/p&gt;

&lt;p&gt;dvc.yaml&lt;br&gt;
.dvc files&lt;br&gt;
dvc.lock&lt;/p&gt;

&lt;p&gt;However, Git does not restore the actual dataset or model, because DVC manages those files.&lt;/p&gt;

&lt;p&gt;Running:&lt;/p&gt;

&lt;p&gt;dvc checkout&lt;/p&gt;

&lt;p&gt;reads the .dvc files and restores the correct versions of:&lt;/p&gt;

&lt;p&gt;transactions.csv&lt;br&gt;
model.pkl&lt;/p&gt;

&lt;p&gt;from the DVC cache.&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  📦 Full Code Repository: &lt;a href="https://github.com/thukhakyawe/100-Days-Of-MLOps-KodeKloud-Challenges-Solutions" rel="noopener noreferrer"&gt;KodeKloud Learning Labs&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💬 Join Discussion: &lt;a href="https://dev.to/thukhakyawe_cloud"&gt;DEV Community&lt;/a&gt; - Share your thoughts and questions
&lt;/h5&gt;

&lt;h5&gt;
  
  
  💼 Let's Connect: &lt;a href="https://www.linkedin.com/in/thukhakyawe/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - I'd love to connect with you
&lt;/h5&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Credits&lt;/strong&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • All labs are from: &lt;a href="https://kodekloud.com/" rel="noopener noreferrer"&gt;KodeKloud&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  • I sincerely appreciate your provision of these valuable resources.
&lt;/h5&gt;




</description>
      <category>100daysofmlops</category>
      <category>kodekloud</category>
    </item>
  </channel>
</rss>
