https://drive.google.com/file/d/1Ga-gnT2z7j17YMyyRHL_8qb0t3XJdNa-/view?usp=sharing
apiVersion: v1
kind: Service
meta
name: website-svc
spec:
type: NodePort # โ Exposes on ALL node IPs
selector:
app: nginx # โ Must match Deployment labels
ports:
- port: 80 # โ Service port (internal)
targetPort: 80 # โ Pod port (where app listens)
nodePort: 30007 # โ Fixed external port (30000-32767)
๐ Key Insight:
This Service creates a stable external endpoint:
- Internal:
http://website-svc:80(from inside cluster)- External:
http://<ANY-k3s-NODE-IP>:30007(from your laptop, browser, etc.)
๐ก Why nodePort: 30007?
- Fixed port = easier firewall rules, documentation, and testing
- Without it, k3s assigns a random port in
30000-32767
| Component | Role |
|---|---|
Deployment (webapp) |
Runs 1 Pod with app: nginx label + PVC-mounted /var/www/html |
Service (website-svc) |
Routes traffic to that Pod via selector: app: nginx |
PVC (myclaim) |
Persists web content across Pod restarts |
| NodePort | Exposes the app externally on :30007 |
๐ฏ End-to-End Flow:
curl http://<NODE-IP>:30007โ NodePort (
30007)โ Service (
website-svc:80)โ Pod (
webapp-xxxx:80)โ Persistent content from NFS/PV
# 1. PVC (from earlier)
kubectl get pvc myclaim
# 2. Deployment (with PVC)
kubectl apply -f deployment-using-pvc.yaml
# 3. Service
kubectl apply -f service-node-port.yaml
# Get Pod name
POD=$(kubectl get pods -l app=nginx -o jsonpath='{.items[0].metadata.name}')
# Write file
kubectl exec $POD -- sh -c "echo '<h1>Hello from Persistent NFS!</h1>' > /var/www/html/index.html"
๐ก Get k3s node IP(s):
kubectl get nodes -o wide
# NAME INTERNAL-IP
# k3s-master 192.168.1.10
# k3s-node1 192.168.1.11
๐ From your laptop:
curl <http://192.168.1.10:30007>
# โ
"Hello from Persistent NFS!"
curl <http://192.168.1.11:30007>
# โ
Same response! (kube-proxy forwards to Pod anywhere in cluster)