(with Services, Nodes, Ingress, and DNS)
In this guide, we will deploy a Kubernetes cluster and configure:
β
Nodes (Worker + Control Plane)
β
Service for accessing pods
β
Ingress for HTTP request routing
β
DNS inside the cluster
1. Deploying a Kubernetes Cluster
π You can deploy a cluster using different methods:
β’ Minikube (for local testing).
β’ Kubeadm (for production clusters).
β’ K3s (a lightweight version for small projects).
Deploying with Minikube (Locally)
minikube start
Check the nodes:
kubectl get nodes
2. Deploying a Service in Kubernetes
We will create a Deployment with pods and a Service to expose them.
π File: deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: nginx
ports:
- containerPort: 80
Deploy it:
kubectl apply -f deployment.yaml
Check the pods:
kubectl get pods
3. Configuring a Service (NodePort)
To expose our application, we will create a Service.
π File: service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080 # Port on nodes
type: NodePort
Apply it:
kubectl apply -f service.yaml
Check the service:
kubectl get svc
Now the application is accessible via:
minikube service my-service --url
4. Configuring Ingress for Routing
π Enable Ingress Controller in Minikube
minikube addons enable ingress
For other clusters, use NGINX Ingress Controller:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
π File: ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
Apply it:
kubectl apply -f ingress.yaml
Add the domain to /etc/hosts (for local testing):
echo "$(minikube ip) myapp.local" | sudo tee -a /etc/hosts
Now the application is accessible at http://myapp.local
5. DNS in Kubernetes
Kubernetes uses CoreDNS for internal DNS management.
π Check if CoreDNS is running:
kubectl get pods -n kube-system | grep coredns
π Check service resolution:
kubectl run dns-test --image=busybox --restart=Never -- nslookup my-service.default.svc.cluster.local
Expected output:
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: my-service.default.svc.cluster.local
Address: 10.104.116.230
If itβs not working, enable CoreDNS:
kubectl apply -f https://storage.googleapis.com/kubernetes-the-hard-way/coredns.yaml
π Final Architecture
+------------------------+
| User |
| (curl myapp.local) |
+----------+------------+
|
+----------v------------+
| Ingress | (Routes HTTP requests)
+----------+------------+
|
+----------v------------+
| Service | (Proxy for pods)
+----------+------------+
|
+----------v------------+
| Pods (Nginx) | (Containers running the app)
+------------------------+
π Summary
β
Deployed Kubernetes
β
Created a Service (NodePort)
β
Configured Ingress for routing
β
Verified DNS inside the cluster
Now you have a fully functional Kubernetes application with network infrastructure! π
π Assigning an External IP in Kubernetes
If you have a dedicated external IP, you can use it with Service, Ingress, or a LoadBalancer.
1. Using ExternalIPs in a Service
If you have a static external IP, you can specify it in externalIPs for direct traffic forwarding.
π Example: service.yaml with external IP
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP # External IP is manually set
selector:
app: my-app
externalIPs:
- 203.0.113.10 # Your external IP
ports:
- protocol: TCP
port: 80
targetPort: 80
π Check the service:
kubectl apply -f service.yaml
kubectl get svc my-service
Now the service will be accessible at http://203.0.113.10:80.
β οΈ Limitations:
β’ Kubernetes does not reserve this IP; it must be pre-configured in your network.
β’ Works only if the external IP is manually assigned to a node (e.g., via iptables).
2. Using a LoadBalancer for Automatic External IP Allocation
If youβre running in a cloud provider environment (AWS, GCP, Azure, DigitalOcean), use a LoadBalancer.
π Example: loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
π Apply and check the assigned IP:
kubectl apply -f loadbalancer.yaml
kubectl get svc my-service
After deployment, an external IP will be automatically assigned.
β οΈ Limitations:
β’ Works only in cloud environments that support LoadBalancer.
β’ It may take a few minutes to allocate an IP.
3. Exposing a NodePort on a Static External IP
If you have a dedicated IP on one of the nodes, you can use NodePort and manually configure port forwarding.
π Example: nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080 # External node port
π Configure port forwarding on a Linux server with an external IP:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 30080
Now the service is accessible at http://203.0.113.10:80.
β οΈ Limitations:
β’ Not suitable for cloud environments without manual setup.
β’ Requires iptables access on the node.
Choosing the Best Method
Method | Use When | Limitations |
---|---|---|
externalIPs | Static external IP | Requires network setup |
LoadBalancer | Cloud environment | Cloud-only |
NodePort | Dedicated node IP | Requires iptables |
Ingress | Ingress Controller available | Needs Nginx/Traefik |
Now your Kubernetes service is accessible via an external IP!