Kubernetes Services and Service Discovery

Kubernetes Services and Service Discovery

  1. Exposing Kubernetes workloads

Kubernetes offers several types of Services to expose workloads:

  • ClusterIP (Default): Exposes the Service only within the cluster. It’s not accessible from the outside.

  • NodePort: Exposes the Service on each Node’s IP at a static port. It’s accessible from outside the cluster using <NodeIP>:<NodePort>.

  • LoadBalancer: Exposes the Service externally using a cloud provider's load balancer. It’s accessible via the load balancer’s external IP.

  • ExternalName: Maps the Service to the contents of the externalName field (e.g., a DNS name).

Using NodePort service

Note that the NodePort Service has a lot of downsides:

  • you can only have one service per port

  • you can only use ports 30000–32767,

  • if your Node/VM IP address changes, you need to deal with that.

  • Running nginx application using deployment.

  • Deploy a simple Nginx application,

  • Create POD using deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
  • Apply deployment.yml file,
kubectl apply -f deployment.yml
  • Create service for the application using service.yml file,
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30001

  • Apply services.yml file,
kubectl apply -f service.yml

  • Verify service status,
kubectl get svc -o wide

  • Expose port to access application on browser,
kubectl port-forward svc/nginx-service 8081:80 --address=0.0.0.0 &
  • Now try to access,


  1. Discover Services and Pods within a Kubernetes cluster using DNS

Service Discovery Using DNS

Let’s start by deploying a simple Service,

  • Create deployment and service and apply both of them,
# deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-world
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-world
        image: hashicorp/http-echo:0.2.3
        args:
        - "-text=Hello, Kubernetes!"
        ports:
        - containerPort: 5678

# service.yml
apiVersion: v1
kind: Service
metadata:
  name: hello-world-service
  namespace: default
spec:
  selector:
    app: hello-world
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5678

  • Apply both files,
kubectl apply -f deployment.yml
kubectl apply -f service.yml
  • Test deployment and service at once,
kubectl get all

  • Discover the Service Using DNS,

  • You can resolve the Service DNS name from within any Pod in the same namespace. Deploy a test Pod,

kubectl run -it --rm --image=busybox dns-test -- /bin/sh
  • Within this Pod, you can use the nslookup or dig command to resolve the Service name,
nslookup hello-world-service.default.svc.cluster.local

Pod Discovery Using DNS

  • Step 1 : Enable Headless Service

To discover individual Pods, you should create a Headless Service by setting clusterIP: None,

apiVersion: v1
kind: Service
metadata:
  name: hello-world-headless
  namespace: default
spec:
  clusterIP: None
  selector:
    app: hello-world
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5678
  • Apply file,
kubectl apply -f dns-headless.yml

  • Step 2 : Discover Pods Using DNS

Test DNS Resolution Inside a Pod,

Use a test Pod to check DNS resolution. Let’s use a busybox Pod for this,

kubectl run -it --rm --image=busybox dns-test -- /bin/sh

Inside the shell of the dns-test Pod, use the nslookup command to try to resolve the Headless Service and Pods,

nslookup hello-world-headless.default.svc.cluster.local

This will return a list of IP addresses, each corresponding to a Pod running under the hello-world deployment.


Connect With Me

Thank you for reading. I hope you were able to understand and learn something new from my blog.

Happy Learning!

LinkedIn | GitHub