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

# Lab Solution Network Policies optional

> Hands-on Kubernetes lab demonstrating inspecting a payroll NetworkPolicy and creating an egress policy to restrict internal pod outbound traffic to payroll on 8080 and mysql on 3306

This lab walks through a practical NetworkPolicy exercise: inspecting an existing policy that restricts access to a payroll pod, then creating a new NetworkPolicy to restrict egress from an internal pod. You'll review the cluster state, interpret the active policy, implement a policy that limits egress, and validate the result.

## 1. Inspect the cluster

Start by listing pods and services to understand which workloads and endpoints exist.

Pods:

```bash theme={null}
root@controlplane:~# k get pods
NAME       READY   STATUS    RESTARTS   AGE
external   1/1     Running   0          2m20s
internal   1/1     Running   0          2m19s
mysql      1/1     Running   0          2m19s
payroll    1/1     Running   0          2m19s
```

Services:

```bash theme={null}
root@controlplane:~# k get service
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
db-service         ClusterIP   10.109.89.42    <none>        3306/TCP         2m42s
external-service   NodePort    10.108.170.44   <none>        8080:30080/TCP   2m42s
internal-service   NodePort    10.98.11.243    <none>        8080:30082/TCP   2m42s
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP          39m
payroll-service    NodePort    10.110.165.31   <none>        8080:30083/TCP   2m42s
```

Quick summary of key resources:

| Resource | Purpose / Notes |
| - | - |
| `payroll` pod | Application listening on TCP 8080 (backed by `payroll-service`). |
| `internal` pod | Internal application that will be subject to egress restrictions. |
| `mysql` pod / `db-service` | MySQL database on TCP 3306. |
| `external` pod / `external-service` | External-facing app (NodePort). |

## 2. Check for existing NetworkPolicies

List NetworkPolicies to see what's already enforced:

```bash theme={null}
root@controlplane:~# k get networkpolicies
NAME            POD-SELECTOR   AGE
payroll-policy  name=payroll   3m25s
```

There is one policy: `payroll-policy`, which targets pods with the label `name=payroll`.

Describe that policy to see the exact rules:

```bash theme={null}
root@controlplane:~# k describe netpol payroll-policy
Name:        payroll-policy
Namespace:   default
Created on:  2022-04-18 20:35:54 +0000 UTC
Labels:      <none>
Annotations: <none>
Spec:
  PodSelector:   name=payroll
  Allowing ingress traffic:
    To Port: 8080/TCP
    From:
      PodSelector: name=internal

  Not affecting egress traffic
  Policy Types: Ingress
```

Interpretation:

* `payroll-policy` selects the `payroll` pod and defines Ingress rules only.
* Because the policy selects the pod and includes Ingress rules, any ingress not explicitly allowed will be denied. In this case only traffic from pods labeled `name=internal` to TCP port 8080 is permitted.
* There are no Egress rules for the `payroll` pod, so its egress remains unrestricted.

<Callout icon="lightbulb" color="#1CB2FE">
  Note: By default, pods allow all ingress and egress. When a NetworkPolicy selects a pod and defines Ingress rules, it denies other ingress that is not explicitly allowed. Likewise, defining Egress rules denies other egress unless explicitly allowed. To restrict only egress (and leave ingress unchanged), set `policyTypes` to `Egress` only and omit `ingress`.
</Callout>

Connectivity (high-level):

* internal → payroll on TCP 8080: allowed (policy explicitly permits).
* external → payroll on TCP 8080: blocked/timeout (not allowed by policy).
* ICMP (ping) is not covered by TCP rules — NetworkPolicies work at L3/L4 (TCP/UDP/SCTP).

## 3. Task: restrict egress from the internal pod

Goal

* Create a NetworkPolicy named `internal-policy`.
* Target the pod labeled `name=internal`.
* Restrict egress so the `internal` pod can only initiate connections to:
  * the payroll pod on TCP port 8080
  * the mysql pod on TCP port 3306
* Do not change ingress behavior for the `internal` pod (leave ingress unaffected).

(Reference screenshot of Kubernetes docs used to get the template: [https://kubernetes.io/docs/concepts/services-networking/network-policies/](https://kubernetes.io/docs/concepts/services-networking/network-policies/))

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/pXrdl7vTZCGrBGHr/images/Certified-Kubernetes-Administrator-CKA/Security/Lab-Solution-Network-Policies-optional/kubernetes-dockershim-removal-docs.jpg?fit=max&auto=format&n=pXrdl7vTZCGrBGHr&q=85&s=8334f2c17c4966c529c496b9e621c332" alt="A screenshot of the Kubernetes documentation webpage, with a blue header announcing &#x22;Dockershim removal set for Kubernetes 1.24&#x22; and a left navigation pane. The main content shows three columns titled &#x22;Understand Kubernetes,&#x22; &#x22;Try Kubernetes,&#x22; and &#x22;Set up a K8s cluster&#x22; with links and action buttons." width="1920" height="1080" data-path="images/Certified-Kubernetes-Administrator-CKA/Security/Lab-Solution-Network-Policies-optional/kubernetes-dockershim-removal-docs.jpg" />
</Frame>

Create `internal-policy.yaml` with the following content:

```yaml theme={null}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internal-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      name: internal
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels:
          name: payroll
    ports:
    - protocol: TCP
      port: 8080

  - to:
    - podSelector:
        matchLabels:
          name: mysql
    ports:
    - protocol: TCP
      port: 3306
```

Apply the policy:

```bash theme={null}
root@controlplane:~# k create -f internal-policy.yaml
networkpolicy.networking.k8s.io/internal-policy created
```

Verify the policy with describe:

```bash theme={null}
root@controlplane:~# k describe netpol internal-policy
Name:        internal-policy
Namespace:   default
Created on:  2022-04-18 20:53:13 +0000 UTC
Labels:      <none>
Annotations: <none>
Spec:
  PodSelector:    name=internal
  Not affecting ingress traffic
  Allowing egress traffic:
    To Port: 8080/TCP
    To:
        PodSelector: name=payroll

    To Port: 3306/TCP
    To:
        PodSelector: name=mysql
Policy Types: Egress
```

Result

* The `internal` pod can now only initiate outbound TCP connections to:
  * `payroll` pods on port 8080
  * `mysql` pods on port 3306
* All other egress connections (to other pods or external IPs) are denied by default because the NetworkPolicy selects the pod and defines Egress rules.
* Ingress to the `internal` pod remains unchanged by this policy.

Validation tips

* Exec into the `internal` pod and test connectivity:
  * Test allowed connections (e.g., `curl` or `nc` to payroll:8080 and mysql:3306).
  * Test denied connections (e.g., try connecting to `external-service` or other cluster IPs).
* Example validation commands (run from within the `internal` pod):
  * `# curl http://payroll-service:8080` (should succeed)
  * `# nc -zv payroll 8080` (should succeed)
  * `# nc -zv mysql 3306` (should succeed)
  * `# nc -zv external-service 8080` (should fail / timeout)

## Links and references

* Kubernetes NetworkPolicy docs: [https://kubernetes.io/docs/concepts/services-networking/network-policies/](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
* Kubernetes concepts overview: [https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/](https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/)
* CKA / networking resources: [https://github.com/cncf/curriculum](https://github.com/cncf/curriculum) (useful for exam-style labs)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/cka-certification-course-certified-kubernetes-administrator/module/77826599-d456-4cb5-8cbc-b713cc077b45/lesson/bc63e8eb-dddc-4b87-a4ef-b04ac9532504" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.