Exposing Kubernetes Ports

Service Types

Exposing Containers

  • kubectl expose creates a service for existing pods

  • A service is a stable address for pod(s)

  • If we want to connect to pod(s), we need a service

  • CoreDNS allows us to resolve services by name

  • There are different types of services

    • ClusterIP

    • NodePort

    • LoadBalancer

    • ExternalName

Basic Service Types

  • ClusterIP (default)

    • Single, internal virtual IP allocated

    • Only reachable from within the cluster (nodes and podes)

    • Pods can reach service on apps port number

  • NodePort

    • High port allocated on each node

    • Port is open on every node’s IP

    • Anyone can connect (if they can reach the node)

    • Other pods need to be updated to this port

  • These services are always available in Kubernetes

More Service Types

  • LoadBalancer

    • Controls a LB endpoint external to the cluster

    • Only available when infra provider gives ou a LB (AWS ELB, etc)

    • Creates NodePort+ClusterIP services, tells LB to send to NodePort

  • ExternalName

    • Adds CNAME DNS record to CoreDNS only

    • Not used for Pods, but for giving pods a DNS name to use for something outside Kubernetes

Creating a ClusterIP Service

  • Open two shell windos so we can watch this

    • kubectl get pods -w

  • In second window, lets start a simple http server using sample code

    • kubectl create deployment httpenv –image=bretfisher/httpenv

  • Scale it to 5 replicas

    • kubectl scale deployment/httpenv –replicas=5

  • Lets create a ClusterIP service (default)

    • kubectl expose deployment/httpenv –port 8888

Inspecting ClusterIP Service

  • Look up what IP was allocated

    • kubectl get service

  • Remember this IP is cluster internal only, how do we curl it?

  • If you’re on DOcker Desktop (Host OS is not container OS)

    • kubectl run –generator=run-pod/v1 tmp-shell –rm -it –image bretfisher/netshoot – bash

    • curl httpenv:8888

  • If you’re on Linux host

    • curl [ip of service]:8888

Creating a NodePort and LoadBalancer Service

Create a NodePort Service

  • Lets expose a NodePort so we can access it via the host IP (including localhost)

    • kubetcl expose deployment/httpenv –port 8888 -name httpenv-np –type NodePort

  • Did you know that a NodePort service also creates a ClusterIP?

  • These three services are additive, each one creates the ones above it:

    • ClusterIP

    • NodePort

    • LoadBalancer

Add a LoadBalancer Service

  • If you’re on Docker Desktop, it provides a built-in LoadBalancer that publishes the –port on localhost

    • kubectl expose deployment/httpenv –port 8888 –name httpenv-lb –type LoadBalancer

    • curl localhost:8888

  • If you’re on kubeadm, minikube, or microk8s

    • No built-in LB

    • You can still run the command, it’ll just stay at “pending” (but its NodePort works)

Kubernetes Services DNS

  • Starting with 1.11, internal DNS is provided by CoreDNS

  • Like Swarm, this is DNS-Based Service Discovery

  • So far we’ve been using hostnames to access services

    • curl <hostname>

  • But that only works for Services in the same Namespace

    • kubectl get namespaces

  • Services also have a FQDN

    • curl <hostname>.<namespace>.svc.cluster.local