Docs

This repository contains several documentations and guidelines about web development.

View project on GitHub

How to expose Kubernetes ports

All urls and ports inside the kubernetes cluster are not accessible per default from outside. There are several ways to expose them so that we can interact with them.

kubectl port-forward

Kubectl port-forward allows you to access and interact with internal Kubernetes cluster processes from your localhost. You can use this method to investigate issues and adjust your services locally without the need to expose them beforehand.

It will expose the port temporary while the script is running and performs load balancing. Accessible as localhost:15672.

kubectl port-forward svc/rabbitmq 15672:15672

kubectl expose pod

Looks up a deployment, service, replica set, replication controller or pod by name and uses the selector for that resource as the selector for a new service on the specified port. A deployment or replica set will be exposed as a service only if its selector is convertible to a selector that service supports, i.e. when the selector contains only the matchLabels component. Note that if no port is specified via –port and the exposed resource has multiple ports, all will be re-used by the new service. Also if no labels are specified, the new service will re-use the labels from the resource it exposes.

It will expose the port permanently but without load balancing. Accessible as localhost:15672.

kubectl expose pod rabbitmq-0 --port=15672 --target-port=15672 --type=NodePort

List all services and get the nodePort which can be used locally, e.g. localhost:{nodePort}

kubectl get services

service nodeport

Exposes the Service on each Node’s IP at a static port (the NodePort). A ClusterIP Service, to which the NodePort Service routes, is automatically created. You’ll be able to contact the NodePort Service, from outside the cluster, by requesting :

Using a NodePort gives you the freedom to set up your own load balancing solution, to configure environments that are not fully supported by Kubernetes, or even to just expose one or more nodes’ IPs directly.

It will expose the port permanently and performs load balancing. Accessible as localhost:30012.

kubectl describe pod rabbitmq
Labels:       app.kubernetes.io/instance=rabbitmq
              app.kubernetes.io/managed-by=Helm
              app.kubernetes.io/name=rabbitmq
              controller-revision-hash=rabbitmq-558574dd9c
              helm.sh/chart=rabbitmq-8.11.3
              statefulset.kubernetes.io/pod-name=rabbitmq-0
apiVersion: v1
kind: Service
metadata:
  name: rabbitmq-nodeport
spec:
  type: NodePort
  selector:
    app.kubernetes.io/instance: rabbitmq # label of the pod
  ports:
    - name: amqp
      protocol: TCP
      port: 5672
      targetPort: 5672
      # By default and for convenience, the Kubernetes control plane will allocate a port from a range (default: 30000-32767)
      nodePort: 30011
    - name: http
      protocol: TCP
      port: 15672
      targetPort: 15672
      # By default and for convenience, the Kubernetes control plane will allocate a port from a range (default: 30000-32767)
      nodePort: 30012

save as rabbitmq-nodeport.yaml

kubectl apply -f rabbitmq-nodeport.yaml

service ingress

NodePorts let you expose a service by specifying that value in the service’s type. Ingress, on the other hand, is a completely independent resource to your service. You declare, create and destroy it separately to your services.

This makes it decoupled and isolated from the services you want to expose. It also helps you to consolidate routing rules into one place.

It will expose the port permanently, performs load balancing and dns name resolution. UI accessible as localhost/rabbitmq and localhost:30011 for amqp traffic.

helm show values ingress-nginx/ingress-nginx > nginx-deployment.yaml
helm install -f nginx-deployment.yaml nginx ingress-nginx/ingress-nginx 
  # rabbitmq-ui-ingress.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: rabbitmq-ui-ingress
spec:
  rules:
    - host:
      http:
        paths:
          - path: /rabbitmq(/|$)(.*)
            pathType: Exact
            backend:
              service:
                name: rabbitmq
                port: 
                  number: 15672

The amqp port cannot be used in http proxies like nginx. The solution service nodeport is the best way.

kubectl apply -f rabbitmq-ui-ingress.yaml
apiVersion: v1
kind: Service
metadata:
  name: rabbitmq-amqp-nodeport
spec:
  type: NodePort
  selector:
    app.kubernetes.io/instance: rabbitmq # label of the pod
  ports:
    - name: amqp
      protocol: TCP
      port: 5672
      targetPort: 5672
      nodePort: 30011

save as rabbitmq-amqp-nodeport.yaml

kubectl apply -f rabbitmq-amqp-nodeport.yaml