Search code examples
dockerkubernetesasp.net-core-webapi.net-5docker-desktop

Cannot connect to service on NodePort using Kubernetes on Windows Docker Desktop


Firstly, this is my folder:

enter image description here

This is my Dockerfile:

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build-env
WORKDIR /app

COPY *.csproj ./
RUN dotnet restore

COPY . ./
RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "PlatformService.dll"]

platforms-depl.yaml (deployment file)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: platforms-depl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: platformservice
  template:
    metadata:
      labels:
        app: platformservice
    spec:
      containers:
        - name: platformservice
          image: hao14102000/platformservice:latest

platforms-np-srv.yaml (NodePort Service file)

apiVersion: v1
kind: Service
metadata:
  name: platformnpservice-srv
spec:
  type: NodePort
  selector:
    app: platformservice
  ports:
    - name: platformservice
      protocol: TCP
      port: 80
      targetPort: 80

When I apply 2 files this is what I see:

enter image description here

When I try to connect on port 31023 using both options below:

http://localhost:31023/api/platforms
http://10.109.215.230:31023/api/platforms

It doesn't work. This happens:

enter image description here

enter image description here

I don't know what wrong with this...


Solution

  • What happens with Linux containers:

    Kubernetes on Windows Docker Desktop by default runs its components in WSL2 (Windows subsystem for Linux), it's separate virtual machine with its own IP address and localhost. This is the reason why service is not reachable on localhost from host OS (in this case Windows).

    Another option is to disable using WSL2 based engine in settings, instead hyper-v will be used and virtual machine will be created however in Docker Desktop it's said that preferably WSL2 should be used for performance benefits.

    Available options how to access the service using WSL2:

    1. Fastest and easiest (loadbalancer)

    Set up a service with LoadBalancer type. EXTERNAL-IP will be localhost which solves all questions immediately. For example:

    kubectl get svc
    NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
    kubernetes   ClusterIP      10.96.0.1      <none>        443/TCP          11m
    nginx        LoadBalancer   10.110.15.53   localhost     8080:30654/TCP   4m10s
    

    Nginx is available in browser on localhost:8080.

    1. Using virtual machine's IP and nodeport

    Another option is to find WSL virtual machine and then access service on this IP and nodeport.

    To find WSL VM address, you need to run wsl command to connect to this VM and then find its IP address:

    wsl
    
    # ip a | grep eth0
    
    6: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
        inet 172.19.xxx.yyy/20 brd 172.19.xxx.yyy scope global eth0
    

    Nginx is available in browser on 172.19.xxx.yyy:30654.

    1. Port-forward - for testing purposes

    Port-forward is useful for testing purposes, but it shouldn't be used on production systems.

    To start the proxy to the service, run following command:

    kubectl port-forward service/nginx 8080:80 &
    

    Nginx is available in browser on localhost:8080

    Assumptions when Hyper-V is used

    First hyper-v should be installed on host machine. Note that not all versions of Windows are supported. Please refer to documentation on which versions and how to enable hyper-v here.

    When using WSL2 based engine is deselected, hyper-v is used to work with containers. It creates a separate virtual machine which can be found in Hyper-v Manager.

    • nodeport works on localhost + nodeport
    • loadbalancer doesn't work, you can't connect to localhost with service port even though External-IP shows localhost.

    Windows containers on Windows Docker Desktop

    It's also possible to run Windows containers on Windows Docker Desktop.

    It's required to change daemon which will be used. In tray select on switch to Windows containers. Switch between linux and windows containers.

    However kubernetes option will become unavailable, because control plane components are designed to be run on linux host.

    Environment:

    OS: Windows 10 Enterprise, build: 19041.1165

    Docker Desktop: 4.0.0 (67817)

    Engine: 20.10.8

    Kubernetes: 1.21.4

    Useful links: