By Tcoch

Kubernetes - Exposing a port on Minikube


Technical stack addressed

Let's begin by describing the exact technical stack used for this article. I am working on a Windows computer (please show me some mercy). On this computer, Docker Desktop is installed.
> docker info
Client:
 Version:    27.5.1
 Context:    desktop-linux
And I'm thinking to myself, it's time to try Kubernetes.

Installing Kubernetes on Windows, as a docker container

Please follow the official documentation for installing the components you need based on your architecture. This article describe the way I did it, and therefore the exact stack used, as a base for this article topic.

Let's install kubectl first, using choco:
> choco install kubernetes-cli
> kubectl version --client
Client Version: v1.32.1
Kustomize Version: v5.5.0
And then, minikube:
> choco install minikube
> minikube status
minikube
type: Control Plane
host: Stopped
kubelet: Stopped
apiserver: Stopped
kubeconfig: Stopped
Now that everything is installed (damn, that was quick !), I can see that I have a new container running inside docker.
> docker ps
92e8fb7d574a   gcr.io/k8s-minikube/kicbase:v0.0.42   "/usr/local/bin/entr…"   3 minutes ago    Up 3 minutes             127.0.0.1:32768->22/tcp, 127.0.0.1:32769->2376/tcp, 127.0.0.1:32770->5000/tcp, 127.0.0.1:32771->8443/tcp, 127.0.0.1:32772->32443/tcp   minikube

Deploying nginx and exposing port 80

Great, now that's everything is installed and running, let's creating something beautiful, using this brand new kubernetes environment.
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 12380 # Port exposé par le service
    targetPort: 80 # Port du conteneur
And apply this config:
> kubectl apply -f deployment.yaml
deployment.apps/nginx created
> kubectl apply -f service.yaml
service/nginx created
Now, I should be able to access http://localhost:12380/, and be redirect to a beautiful nginx homepage.
But no. Instead, I get ERR_CONNECTION_REFUSED by my browser. Why?

Understanding how the port is exposed

Like I said before, my kubernetes infrastructure is running as part of a docker container. My minikube instance is a container, which expose some ports for administration and such, but it does not provide exposition for all ports. The port declared in my service (port 12380) is, in fact, not in the published port of the minikube container! Here's the ports actually available from my host and that lead to some services inside the minikube container:
127.0.0.1:32768->22/tcp
127.0.0.1:32769->2376/tcp
127.0.0.1:32770->5000/tcp
127.0.0.1:32771->8443/tcp
127.0.0.1:32772->32443/tcp
Clearly, port 12380 is unknown here. And this is why, from my host, I get ERR_CONNECTION_REFUSED.

Remember: an application inside a docker container, that expose a port, is only accessible if the port is published / forwarded.

How to expose my service ?

We'll talk about two methods : tunneling and port forwarding.
Tunneling
We can use the following command to create a tunnel to our minikube container
> minikube tunnel
However, this will only work towards LoadBalancer services!
See https://minikube.sigs.k8s.io/docs/commands/tunnel/.
But I don't have a LoadBalancer service. And quite frankly, for my simple lab, I don't need one. Is there another way?
Port forwarding
Port forwarding will enable us to forward a trafic between a port on the host machine, towards a port inside the minikube container.
In order to fully comprehend the differences, I'll expose port 12381 on my machine, and redirect it to port 12380 inside minikube.

Now, what's the command for this? Here it is:
kubectl port-forward service/myservice <HOST_PORT>:<SERVICE_PORT>
Let's check my services first:
> kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP     PORT(S)           AGE
kubernetes   ClusterIP   10.96.0.1       <none>          443/TCP           28d
nginx        NodePort    10.105.6.13     192.168.10.13   12380:30254/TCP   5m50s
OK, so we'll do:
kubectl port-forward service/nginx 12381:12380
OK, this works!

Well, it will work, as long as I keep my cmd open ...
Articles

Find a random article based on a tag:
Socials