Skip to content

Services — Example Manifests

clusterip-service.yaml — Internal Service

apiVersion: v1
kind: Service
metadata:
  name: my-clusterip-service
  labels:
    app: my-app
spec:
  type: ClusterIP  # Default service type (can be omitted)
  selector:
    app: my-app
  ports:
    - name: http
      protocol: TCP
      port: 80        # Service port
      targetPort: 8080  # Container port

nodeport-service.yaml — External access via NodePort

apiVersion: v1
kind: Service
metadata:
  name: web-nodeport
  labels:
    app: web
spec:
  type: NodePort
  selector:
    app: web
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080  # Optional: specify port in 30000-32767 range

loadbalancer-service.yaml — Cloud load balancer

apiVersion: v1
kind: Service
metadata:
  name: frontend-loadbalancer
  labels:
    app: frontend
spec:
  type: LoadBalancer
  selector:
    app: frontend
    tier: web
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080

simple-service.yaml — Minimal Service definition

# ClusterIP Service - Internal cluster communication only
apiVersion: v1
kind: Service
metadata:
  name: web-service
  labels:
    app: web
spec:
  type: ClusterIP
  selector:
    app: web
  ports:
    - name: http
      protocol: TCP
      port: 80        # Port exposed by the service
      targetPort: 80  # Port on the container
---
# Deployment for the service to route traffic to
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  labels:
    app: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.25-alpine
        ports:
        - containerPort: 80

multi-port-service.yaml — Service exposing multiple ports

# Multi-port Service - Expose multiple ports from the same application
apiVersion: v1
kind: Service
metadata:
  name: webapp-service
  labels:
    app: webapp
spec:
  type: ClusterIP
  selector:
    app: webapp
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080
    - name: metrics
      protocol: TCP
      port: 9090
      targetPort: 9090
---
# Deployment with multiple ports
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
  labels:
    app: webapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: app
        image: nginx:1.25-alpine
        ports:
        - name: http
          containerPort: 8080
        - name: metrics
          containerPort: 9090
        command: ["/bin/sh", "-c"]
        args:
          - |
            # Start nginx on port 8080
            sed -i 's/listen.*80;/listen 8080;/g' /etc/nginx/conf.d/default.conf
            nginx -g 'daemon off;'

compose.yaml — Docker Compose comparison

# Docker Compose equivalent for Services
# In Compose, services are automatically discoverable by their service name
# This is similar to Kubernetes Services providing DNS-based discovery

services:
  # Similar to ClusterIP Service
  web:
    image: nginx:1.25-alpine
    deploy:
      replicas: 3
    # In Compose, this service is accessible via DNS name "web"
    # In K8s, ClusterIP Service makes it accessible via "web-service"
    networks:
      - app-network

  # Similar to NodePort Service - exposing ports to host
  web-external:
    image: nginx:1.25-alpine
    ports:
      - "30080:80"  # Similar to NodePort 30080
    deploy:
      replicas: 2
    networks:
      - app-network

  # Multi-port service example
  webapp:
    image: nginx:1.25-alpine
    command: >
      sh -c "sed -i 's/listen.*80;/listen 8080;/g' /etc/nginx/conf.d/default.conf && 
             nginx -g 'daemon off;'"
    deploy:
      replicas: 2
    # Both ports accessible via service name "webapp"
    # No need to explicitly map internal ports
    networks:
      - app-network

  # Client accessing the services
  client:
    image: busybox:1.36
    command: sh -c "while true; do sleep 3600; done"
    networks:
      - app-network
    # Can access via:
    # - wget -O- http://web
    # - wget -O- http://webapp:80
    # - wget -O- http://webapp:9090

networks:
  app-network:

# Key Differences:
# 1. Compose: Service name = DNS name (automatic)
#    K8s: Service resource name = DNS name (explicit)
# 
# 2. Compose: No distinction between internal/external by default
#    K8s: ClusterIP (internal) vs NodePort/LoadBalancer (external)
# 
# 3. Compose: ports: ["host:container"] for external exposure
#    K8s: NodePort or LoadBalancer Service types
# 
# 4. Compose: All containers in same network can communicate freely
#    K8s: Need Service resource for stable DNS and load balancing