📡 Accessing Applications in a Kubernetes Cluster¶
This guide provides a comprehensive overview of methods to access applications running in a Kubernetes cluster, categorized by whether access originates from inside the cluster (e.g., nodes or Pods) or outside the cluster (e.g., a local machine or external network). The guide is designed for developers, administrators, and CKA exam candidates working in local, cloud, or hybrid environments.
1. Accessing from Inside the Cluster¶
These methods are used when you have direct access to cluster nodes or Pods, such as when SSH’d into a node, running commands from the control plane, or troubleshooting within a Pod. They are particularly useful in CKA exam scenarios or for debugging connectivity and DNS resolution.
A. Direct curl from a Node or Control Plane¶
- Description: Access a Pod or Service directly using its IP address (Pod IP or ClusterIP) from a node or control plane. This method tests raw connectivity without relying on Kubernetes DNS.
- Use Case: Debugging Pod-to-Pod or Pod-to-Service connectivity, verifying Service ClusterIP accessibility.
-
Commands:
# Access a Pod directly curl http://<pod-ip>:<container-port> # Example: curl http://10.244.0.5:8081 # Access a Service via ClusterIP curl http://<service-cluster-ip>:<service-port> # Example: curl http://10.96.0.15:80 -
Considerations:
- Requires SSH access to the node or control plane.
- Pod IPs are ephemeral and change when Pods are rescheduled.
- Ensure the container’s port is exposed and matches the Service’s target port.
B. From a Temporary Pod¶
- Description: Launch a temporary Pod to test Service connectivity or DNS resolution from within the cluster. This simulates how applications communicate internally using Kubernetes DNS.
- Use Case: Verify Service name resolution, test DNS-based access, or troubleshoot in-cluster networking.
- Commands:
# Launch a temporary Pod with an interactive shell kubectl run test --image=busybox -it --rm --restart=Never -- sh # Inside the Pod shell, test Service access wget <service-name>.<namespace>.svc.cluster.local # Example: wget amor.amor.svc.cluster.local # Inside Pod shell, test the pod directly by-passing service wget <pod-Ip>.<namespace>.pod.cluster.local # Example: wget 172-10-0-1.amor.pod.cluster.local # Inside Pod shell, get the response from the Service curl <svc-name>.<svc-ns>:<svc-port> # Example: curl project-plt-6cc-svc.dev:3333 or curl 10.96.12.55:3333
2. Accessing from Outside the Cluster¶
These methods enable access from a local machine, external network, or cloud environment, suitable for development, testing, or production. They are critical for interacting with applications from outside the Kubernetes cluster, such as during development on a laptop or exposing services to end users.
A. Using NodePort¶
- Description: Expose a Service on a high-numbered port (30000–32767) across all cluster nodes. Access the Service using any node’s IP (public or private) and the assigned NodePort.
- Use Case: Simple external access to applications without requiring an Ingress or LoadBalancer, often used in development or testing.
- Commands:
- From a local machine or external network:
curl http://<node-public-ip>:<nodePort> # Example: curl http://54.242.167.17:30000 -
From the node itself (via SSH):
curl http://localhost:<nodePort> curl http://<private-node-ip>:<nodePort> # Example: curl http://172.31.29.71:30000 -
Considerations:
- NodePort exposes the Service on all nodes, even if the Pod isn’t running on that node.
- Not ideal for production due to lack of load balancing and security concerns.
B. Port Forwarding¶
- Description: Forward a local port on your machine to a Pod or Service port in the cluster, creating a temporary tunnel for testing. This method is developer-focused and doesn’t require external exposure.
- Use Case: Local development, debugging, or testing an application without exposing it to the network.
-
Commands:
# Forward to a Service kubectl port-forward svc/<service-name> <local-port>:<service-port> # Example: kubectl port-forward svc/amor 8080:80 # Forward to a Pod kubectl port-forward pod/<pod-name> <local-port>:<pod-port> # Example: kubectl port-forward pod/amor-pod 8080:80 # On your local machine, access the application curl http://localhost:8080 # Or open in browser: http://localhost:8080 -
Considerations:
- The port-forward session must remain active; closing the terminal stops access.
- Only accessible from the machine running
kubectl port-forward. - Suitable for HTTP, TCP, or other protocols supported by the application.
C. Using Ingress¶
- Description: Route external HTTP/HTTPS traffic to Services based on domain names or paths, using an IngressController (e.g., NGINX, Traefik). Ingress is the preferred method for production HTTP applications.
- Use Case: Expose multiple Services under a single IP or domain, support path-based routing, or enable TLS.
- Commands:
- If the IngressController is exposed via NodePort:
curl http://<node-ip>:<nodePort>/<path> # Example: curl http://54.242.167.17:30080/asia - If DNS is configured:
curl http://<domain-name>/<asia> # Example: curl http://local.ibtisam-iq.com/asia - For testing with a specific host header (bypassing DNS):
curl -H "Host: local.ibtisam-iq.com" http://<node-ip>:<ingress-nodePort>/<asia> # Example: curl -H "Host: local.ibtisam-iq.com" http://54.242.167.17:30080/asia - Testing with ingress IP
# this ingress doesn't contain any host. cluster3-controlplane ~ ➜ k get ingress NAME CLASS HOSTS ADDRESS PORTS AGE nginx-ingress-cka04-svcn traefik * 192.168.141.37 80 47m cluster3-controlplane ~ ➜ curl 192.168.141.37 # worked cluster3-controlplane ~ ➜ k get svc -n kube-system traefik NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE traefik LoadBalancer 10.43.213.246 192.168.141.37 80:31459/TCP,443:31013/TCP 151m cluster3-controlplane ~ ➜ curl localhost:31459 # worked
cluster4-controlplane ~ ➜ cat ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pink-ing-cka16-trb
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # Not worked, if not added.
spec:
ingressClassName: nginx
rules:
- host: kodekloud-pink.app
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: pink-svc-cka16-trb # This must carry TCP, UDP
port:
number: 5000
cluster4-controlplane ~ ➜ k get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 172.20.168.117 <none> 80:30242/TCP,443:31374/TCP 14m
ingress-nginx-controller-admission ClusterIP 172.20.212.223 <none> 443/TCP 14m
cluster4-controlplane ~ ➜ k get no -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP
cluster4-controlplane Ready control-plane 96m v1.32.0 192.168.129.240
cluster4-node01 Ready <none> 96m v1.32.0 192.168.36.224
cluster4-controlplane ~ ➜ curl http://192.168.129.240:30242/ # Not worked
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
cluster4-controlplane ~ ➜ curl http://kodekloud-pink.app/ # worked # No need to add svc-port or node-port
<!DOCTYPE html>
cluster4-controlplane ~ ➜ curl -H "Host: kodekloud-pink.app" curl 192.168.129.240:30242/ # worked
curl: (6) Could not resolve host: curl
<!DOCTYPE html>
D. GatewayAPI¶
cluster2-controlplane ~ ➜ k get svc -n nginx-gateway
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-gateway NodePort 172.20.236.169 <none> 80:30080/TCP,443:30081/TCP 53m
cluster2-controlplane ~ ➜ k get gateway -n nginx-gateway -o yaml
apiVersion: v1
items:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: nginx-gateway
namespace: nginx-gateway
spec:
gatewayClassName: nginx
listeners:
- allowedRoutes:
namespaces:
from: All
name: http
port: 80
protocol: HTTP
status:
listeners:
- attachedRoutes: 0
cluster2-controlplane ~ ➜ vi 9.yaml
cluster2-controlplane ~ ➜ k get svc -n cka3658
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web-portal-service-v1 ClusterIP 172.20.22.199 <none> 80/TCP 5m24s
web-portal-service-v2 ClusterIP 172.20.62.201 <none> 80/TCP 5m23s
cluster2-controlplane ~ ➜ k apply -f 9.yaml
httproute.gateway.networking.k8s.io/web-portal-httproute created
cluster2-controlplane ~ ➜ k get gateway -n nginx-gateway -o yaml | grep -i attachedRoutes
- attachedRoutes: 1
cluster2-controlplane ~ ➜ curl http://cluster2-controlplane:30080
<h1>Hello from Web Portal App 2</h1>
cluster2-controlplane ~ ➜ k get httproutes.gateway.networking.k8s.io -n cka3658 web-portal-httproute -o yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web-portal-httproute
namespace: cka3658
spec:
hostnames:
- cluster2-controlplane
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: nginx-gateway
namespace: nginx-gateway
rules:
- backendRefs:
- group: ""
kind: Service
name: web-portal-service-v1
port: 80
weight: 80
- group: ""
kind: Service
name: web-portal-service-v2
port: 80
weight: 20
matches:
- path:
type: PathPrefix
value: /
cluster2-controlplane ~ ➜
D. Using LoadBalancer (Cloud Environments)¶
- Description: Expose a Service externally using a cloud provider’s load balancer (e.g., AWS ELB, GCP Load Balancer). The Service is assigned an external IP or DNS name.
- Use Case: Production-grade external access with load balancing and high availability.
- Commands:
# Get the external IP or hostname kubectl get svc <service-name> -o wide # Example output: amor LoadBalancer 10.96.0.15 a12b3c4d.elb.amazonaws.com 80:30080/TCP # Access the Service curl http://<external-ip-or-hostname>:<port> # Example: curl http://a12b3c4d.elb.amazonaws.com
3. SSH and Shell Access Methods¶
These commands provide direct access to nodes or Pods for running the above methods or additional debugging.
| Environment | Command | Use Case | Cluster Notes |
|---|---|---|---|
| Minikube Node | minikube ssh | Access Minikube VM | Single-node cluster; limited resources. Use minikube ip for node IP. |
| Kind Node | docker exec -it <node-name> /bin/bash | Access Kind containerized node | Multi-node possible; install curl if missing (apk add curl or apt-get). |
| kubeadm Node | ssh -i <key.pem> ubuntu@<public-ip> | Access cloud or bare-metal node | Cloud (e.g., AWS EC2) or on-prem; ensure SSH key and security group access. |
| Pod Shell | kubectl exec -it <pod-name> -- sh | Access a Pod’s container | Use bash if sh is unavailable; specify container with -c <container-name>. |
- Troubleshooting:
- For Minikube, ensure the VM is running (
minikube status). - For Kind, list nodes with
docker psto find<node-name>. - For kubeadm, verify SSH access and key permissions (
chmod 400 <key.pem>). - For Pods, check if the container has a shell (
kubectl describe pod <pod-name>).
4. Summary of Access Methods¶
| Method | Access From | Best For | Production-Ready? |
|---|---|---|---|
Direct curl | Node/Control Plane | Low-level IP-based testing | No |
| Temporary Pod | Inside Cluster | DNS/Service resolution testing | No |
| NodePort | Local/External | Simple external access | Limited |
| Port Forwarding | Local Machine | Developer testing | No |
| Ingress | Local/External | HTTP apps with DNS | Yes |
| LoadBalancer | Local/External | Cloud-based production access | Yes |