# Kubernetes Services

A Kubernetes Service is a logical abstraction that enables stable network access to a group of ephemeral Pods, ensuring consistent communication within a dynamic containerized environment. It provides a single entry point to access one or more Pods running the same application, even as those Pods are rescheduled or replaced.

## What does Kubernetes Services do?

In Kubernetes, Pods are frequently created and destroyed. Their IP addresses change, making direct communication unreliable. Kubernetes Services solve this by:

- Offering **a consistent DNS name and virtual IP (ClusterIP)** to represent a dynamic set of Pods
- Enabling **built-in load balancing** to distribute traffic across Pods
- Facilitating **internal and external communication** via well-defined service types
- Supporting **service discovery** with DNS resolution

For developers, this means you can deploy your app without worrying about the lifecycle of individual Pods. Your frontend app can talk to your backend using a simple internal DNS name, e.g., `backend.default.svc.cluster.local`, and Kubernetes takes care of routing the traffic to the right place.

## Key Features

- **Label selectors**: Services automatically find matching Pods using labels.
- **Port mapping**: You can expose your app on different ports internally and externally.
- **Traffic routing**: Kubernetes uses kube-proxy to forward requests to one of the matching Pods using round-robin or IPVS.
- **DNS resolution**: CoreDNS resolves service names to the virtual ClusterIP.
- **Endpoint management**: Kubernetes tracks the live IPs of Pods and updates the Service’s endpoints in real-time.

### Use Case Examples

#### 1. Internal Communication with ClusterIP (default)

Use this for internal service-to-service communication inside the cluster.

```none
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  selector:
    app: backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
```

This creates a stable DNS name `backend.default.svc.cluster.local`. Any Pod in the same namespace can reach the backend using this name, even if the actual Pod IPs change.

#### 2. External Access with LoadBalancer

Use this when you want to expose your app to the internet through a cloud provider.

```none
apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  type: LoadBalancer
  selector:
    app: webapp
  ports:
    - port: 80
      targetPort: 3000
```

Kubernetes will provision a cloud load balancer (e.g., AWS ELB, GCP Load Balancer) and route external traffic to port 3000 on your Pods.

#### 3. Static Port Access with NodePort

Use this for quick access to your service on each node’s IP and a fixed port.

```none
apiVersion: v1
kind: Service
metadata:
  name: debug-api
spec:
  type: NodePort
  selector:
    app: debug-api
  ports:
    - port: 80
      targetPort: 8080
      nodePort: 30080
```

You can now reach your service at `http://<node-ip>:30080`. Not recommended for production due to lack of load balancing and security features.

#### 4. Connecting to External Services with ExternalName

Use this to map a Kubernetes Service to an external DNS name without managing any Pods.

```none
apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  type: ExternalName
  externalName: db.example.com
```

Accessing `external-db.default.svc.cluster.local` will resolve to `db.example.com`.

### Types of Kubernetes Services

| Type          | Description                                                        | Use Case                                 |
|---------------|--------------------------------------------------------------------|------------------------------------------|
| `ClusterIP`   | Default type. Internal traffic only.                              | Microservice communication                |
| `NodePort`    | Opens a static port on each node for external access.            | Development, debugging                    |
| `LoadBalancer`| Integrates with cloud providers to provision external load balancer.| Production services exposed to internet  |
| `ExternalName`| Maps a service to an external DNS name.                           | Using external DBs or APIs from within K8s|

### Developer Notes

- **Health checks**: Services don’t perform health checks themselves. Use readiness probes on Pods to avoid routing traffic to unready backends.
- **Session affinity**: You can configure Services to use client IP for sticky sessions.

Example: `sessionAffinity: ClientIP`
- **Headless Services**: Set `clusterIP: None` to skip kube-proxy routing. Useful for StatefulSets or DNS-based service discovery.
- **Service without selector**: Manually define endpoints. Handy for legacy apps or external services.

### Common Pitfalls

- **Incorrect label selectors**: If labels don’t match, the Service won’t find any Pods.
- **Exposing too much**: Using `NodePort` or `LoadBalancer` without a firewall or Ingress controller can expose sensitive apps.
- **DNS delays**: In some environments, changes to Services may take time to propagate through CoreDNS.

### Security Considerations

- Always pair externally exposed Services with proper Ingress controllers, TLS, and authentication mechanisms.
- Apply NetworkPolicies to control which Pods can reach the Service.
- Monitor Endpoints and service access logs for unusual activity or misrouted traffic.

### Similar Concepts

- **[Ingress](/content/finops-glossary/kubernetes-ingress-controllers/index.html)**: Layer 7 routing for HTTP/S traffic, often used with LoadBalancer Services.
- **[EndpointSlice](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/)**: More scalable representation of Service endpoints.
- **Service Mesh**: Adds observability, traffic shaping, and mTLS to Service communication.
