Learnitweb

Kubernetes Service YAML Manifest In-Detail

1. Why Do We Need a Kubernetes Service?

In traditional deployments, applications are accessed using IP address + Port. However, in Kubernetes:

  • Pods are ephemeral — they can be destroyed and recreated at any time.
  • Each new Pod gets a new IP address.
  • Kubernetes doesn’t assign IPs to Pods until they’re scheduled, so there’s no way to hardcode IPs.
  • You usually deploy multiple replicas of the same app. Accessing them individually is not practical.

Problem:

How do we access a group of Pods (that may come and go) through a stable IP and Port?

Solution: Kubernetes Service

A Kubernetes Service provides a stable network endpoint (Cluster IP, DNS name, and Port) that routes traffic to a dynamic set of Pods. It ensures:

  • Load balancing across Pods
  • Service discovery within the cluster
  • Loose coupling between clients and Pods

2. How Services Work Internally

  • Services select Pods using labels (like app: nginx).
  • When a Service is created, Kubernetes also creates an Endpoints object with the same name.
  • The Endpoints object holds the Pod IPs that match the selector.
  • Kube-proxy watches for Services and Endpoints, and sets up iptables or IPVS rules for routing traffic.

3. How to Define a Service with YAML

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 8081
      targetPort: 80

Explanation of Fields:

FieldDescription
apiVersionKubernetes API version used (for Services: v1)
kindType of resource: Service
metadataStandard metadata including name
spec.selectorLabel selector used to find matching Pods
spec.portsList of ports exposed by the service
portPort on which service is exposed
targetPortPort on the container where the traffic will be forwarded
protocolUsually TCP, but can also be UDP

Tip: Use the same port number for port and targetPort to avoid confusion.

4. Step-by-Step: Create a Deployment First

Before creating a Service, ensure Pods are running. For example:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.14.2
          ports:
            - containerPort: 80

Apply the Deployment:

kubectl apply -f nginx-deployment.yaml

Check Pods and Labels:

kubectl get pods --show-labels

5. Apply the Service Manifest

Create the Service

kubectl apply -f nginx-service.yaml

Verify the Service

kubectl get services

Sample Output:

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)     AGE
nginx-service   ClusterIP   10.105.224.36   <none>        8081/TCP    112s

6. Behind the Scenes: Endpoints Resource

When the Service is created, Kubernetes also creates an Endpoints resource:

kubectl get endpoints

Sample Output:

NAME            ENDPOINTS                          AGE
nginx-service   10.1.1.68:80,10.1.1.69:80,10.1.1.70:80   19m

This shows that the Service routes traffic to these Pods with label app=nginx.

7. Test the Service (Internal Access)

Enter into a Pod:

kubectl exec -it <nginx-pod-name> -- /bin/bash

Install curl and test:

apt-get update
apt-get install curl
curl http://nginx-service:8081

Or:

curl http://10.105.224.36:8081

8. Test the Service (External Access using Port Forwarding)

If you want to test the Service from your local computer:

kubectl port-forward service/nginx-service 8081:8081

Then, open your browser and go to:

http://localhost:8081

This forwards traffic from your local machine’s port 8081 to the service port inside the cluster.

9. Create Service via kubectl expose Command

Instead of YAML, you can use the imperative command:

kubectl expose deployment nginx-deployment --name=nginx-service --port=8081 --target-port=80

This does the same thing — it creates a Service targeting Pods managed by the Deployment.

10. Summary Table

FeatureDescription
Stable IP & PortClusterIP doesn’t change while Service exists
Pod DiscoveryUses label selectors to route to correct Pods
Load BalancingBalances traffic across all matching Pods
Kube-ProxyHandles low-level network routing
EndpointsTracks IP:Port of matching Pods
Port ForwardingLets you access Services locally
Multiple PortsA Service can expose multiple ports
Service TypesClusterIP, NodePort, LoadBalancer, etc. (default: ClusterIP)

11. Key Takeaways

  • Never rely on Pod IPs directly — they’re short-lived.
  • A Service provides decoupling, stability, and discoverability.
  • Always label your Pods appropriately so they can be discovered by Services.
  • Use port-forwarding for local development and testing.
  • Services are core building blocks in making a microservices architecture work in Kubernetes.