apiVersion: v1 # string: API version for Service resource
kind: Service # string: Type of resource
metadata:
name: my-app-service # string: Name of the Service
namespace: production # string: Namespace where the service is created
labels: # map[string]string: Metadata for organization
app: my-app
tier: backend
annotations: # map[string]string: Optional metadata (e.g., for monitoring)
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
spec:
type: ClusterIP # string: Type of service (ClusterIP | NodePort | LoadBalancer | ExternalName)
clusterIP: None # string: Use `None` to create a "headless" service (optional for direct pod access)
selector: # map[string]string: Selects the pods that this service targets
app: my-app
tier: backend
ports: # array: List of ports this service exposes
- name: http
protocol: TCP # string: Protocol for this port (TCP | UDP | SCTP)
port: 80 # int: Port that the service exposes inside the cluster
targetPort: 8080 # int or string: Port on the pod/container
- name: metrics
protocol: TCP
port: 9090
targetPort: 9090
- name: grpc
protocol: TCP
port: 50051
targetPort: grpc-port # targetPort can be a named port in the pod
sessionAffinity: ClientIP # string: Session stickiness (None | ClientIP)
sessionAffinityConfig: # object: Additional config for session affinity
clientIP:
timeoutSeconds: 10800 # int: Timeout for client IP-based session (3 hours)
ipFamilyPolicy: PreferDualStack # string: IPv4/IPv6 support (SingleStack | PreferDualStack | RequireDualStack)
ipFamilies: # array: Preferred IP protocol versions
- IPv4
- IPv6
IPVS mode = kernel-powered load balancing for Kubernetes Services.
It's faster, more flexible, and better for high-scale environments than iptables.
IPVS uses the Linux kernel's Layer 4 load balancer, which is faster and more efficient than iptables for large-scale environments.
- Handles traffic using connection tracking
- Scales better when managing thousands of services/endpoints
- Offers load balancing algorithms like:
- Round Robin
- Least Connection
- Weighted Round Robin
- Source Hashing, etc.
Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default that is used if you don't explicitly specify a type for a Service. You can expose the Service to the public internet using an Ingress or a Gateway.
Headless Service | ClusterIP is not None | |
---|---|---|
ClusterIP | None | Has Value |
Load Balancer | No, return all IPs | Yes |
DNS | Return Pod's IPs (A records) | Return clusterIP (single value) |
For | Accessing each pod | Accessing service |
Pod visibility | Yes, every pod is visible | No, only exposes service's IP |
Exposes the Service on each Node's IP at a static port (the NodePort). To make the node port available, Kubernetes sets up a cluster IP address, the same as if you had requested a Service of type: ClusterIP.
Exposes the Service externally using an external load balancer. Kubernetes does not directly offer a load balancing component; you must provide one, or you can integrate your Kubernetes cluster with a cloud provider.
apiVersion: v1
kind: Service
metadata:
name: my-app-lb
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb" # available values: nlb | clb
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
Maps the Service to the contents of the externalName field (for example, to the hostname api.foo.bar.example). The mapping configures your cluster's DNS server to return a CNAME record with that external hostname value. No proxying of any kind is set up.
Supposed that there is a external database service, the IP is db.example.com
, then you can create a service that could access the external service by external-db
apiVersion: v1
kind: Service
metadata:
name: external-db # service name in Pod
namespace: default
spec:
type: ExternalName
externalName: db.example.com # Destination DNS name
Type | Has ClusterIP? | Load Balancing? | Public Access? | Traffic Proxy? | Typical Use Case |
---|---|---|---|---|---|
ClusterIP |
✅ Yes | ✅ Yes | ❌ No (internal only) | ✅ Yes | Internal service-to-service communication |
NodePort |
✅ Yes | ✅ Yes | ✅ Yes (via Node IP) | ✅ Yes | Basic external access (e.g., dev/test) |
LoadBalancer |
✅ Yes | ✅ Yes | ✅ Yes (via cloud LB) | ✅ Yes | Production-grade public service |
ExternalName |
❌ No | ❌ No | ✅ Yes (DNS mapping) | ❌ No | Map to external DNS-based resource |
Headless (None) |
❌ No | ❌ No | ❌ No (internal DNS) | ❌ No | Direct pod access, StatefulSets |
Ingress is an API object in Kubernetes that manages external access to services, typically HTTP and HTTPS traffic.
It acts like a smart router or application-level load balancer that sits at the edge of your cluster.
Now, Ingress is frozen. New features are being added to the Gateway API.
Gateway API is a Kubernetes networking API standard that defines how external traffic is routed into your cluster, similar to Ingress — but more powerful, modular, and extensible.
It introduces a new set of custom resource definitions (CRDs) such as:
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: my-nginx-gateway-class
spec:
controllerName: nginx.org/gateway-controller
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
spec:
gatewayClassName: my-nginx-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app-route
spec:
parentRefs:
- name: my-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: my-app-service
port: 80