How to use NodePort with kind?
Asked Answered
C

8

34

I'm trying to use NodePort with kind but somehow it doesn't want to work.

I've successfully deployed the following cluster:

apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 80
    hostPort: 30000
    listenAddress: "0.0.0.0" # Optional, defaults to "0.0.0.0"
    protocol: tcp # Optional, defaults to tcp
- role: worker

and then a very simple deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hostname-deployment
  labels:
    app: hostname
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hostname
  template:
    metadata:
      labels:
        app: hostname
    spec:
      containers:
      - name: hostname
        image: hostname:0.1
        ports:
        - containerPort: 80

and a service:

apiVersion: v1
kind: Service
metadata:
  name: hostname-service
spec:
  type: NodePort
  selector:
    app: hostname
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30000

and I can connect to the service via e.g.

(in one terminal)
k port-forward service/hostname-service 8080:80
Forwarding from 127.0.0.1:8080 -> 80

(another one)
curl localhost:8080
hostname: hostname-deployment-75c9fd6584-ddc59 at Wed, 17 Jun 2020 15:38:33 UTC

But I cannot connect to the service via the exposed NodePort

curl -v localhost:30000
* Rebuilt URL to: localhost:30000/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 30000 (#0)
> GET / HTTP/1.1
> Host: localhost:30000
> User-Agent: curl/7.58.0
> Accept: */*
>
* Recv failure: Connection reset by peer
* stopped the pause stream!
* Closing connection 0
curl: (56) Recv failure: Connection reset by peer

kubectl get all output:

NAME                                       READY   STATUS    RESTARTS   AGE
pod/hostname-deployment-75c9fd6584-ddc59   1/1     Running   0          34m
pod/hostname-deployment-75c9fd6584-tg8db   1/1     Running   0          34m

NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/hostname-service   NodePort    10.107.104.231   <none>        80:30000/TCP   34m
service/kubernetes         ClusterIP   10.96.0.1        <none>        443/TCP        35m

NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/hostname-deployment   2/2     2            2           34m

NAME                                             DESIRED   CURRENT   READY   AGE
replicaset.apps/hostname-deployment-75c9fd6584   2         2         2       34m
Captain answered 17/6, 2020 at 15:42 Comment(2)
are you on Mac?Sexuality
That's on LinuxCaptain
S
47

Kind cluster configuration needs to be like below

apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000
    hostPort: 30000
    listenAddress: "0.0.0.0" # Optional, defaults to "0.0.0.0"
    protocol: tcp # Optional, defaults to tcp
- role: worker

This file is then passed to your creation command as kind create cluster --config=config.yaml (according to docs).

Sexuality answered 17/6, 2020 at 15:54 Comment(3)
I did not try but would like to know if in this case, only one port 30000 works or multiple services with different ports work?Zante
Then set the 30000 port as nodePort in NodePort service. Service should be available at localhost:30000, unfortunately for me it was very unstable (kind thing?), sometimes working but mostly failing.Oates
In my case, i had to add this mapping in order to access a service of a cluster running within GitLab CI/DinD.Nardone
C
5

Actually doing what Arghya Sadhu suggested worked. Not sure why the answer got deleted.

apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000
    hostPort: 30000
    listenAddress: "0.0.0.0"
    protocol: tcp
- role: worker
Captain answered 17/6, 2020 at 17:27 Comment(4)
Glad it worked..I was not sure so asked if you are on mac..I have undeleted my answer..Sexuality
So it's just the containerPort: 30000 setting what was wrong? And after that localhost:30000 worked? Because I am still having problemsBookmaker
@MichaelLossagk were you able to figure this out?Minesweeper
It is working even on a Mac, please delete the Kind Cluster first then re-create. I was able to get it working this way. Make sure the NodePort is mapped to the same container port.Lyric
M
4

Below configs shows how to configure nodeport with kind and expose a port to outside of the k8s cluster.

Step 1

kind-api-cluster.yml

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30950
    hostPort: 30950
    listenAddress: "127.0.0.1"
    protocol: TCP
- role: worker
- role: worker

Step 2 Kubernetes service and deployment file. ( FYN, kind's control-plane hostPort and kubernetes service's nodePort should be the same )

helloworld-api.yml

apiVersion: v1
kind: Pod
metadata:
  name: helloworld
  labels:
    app: helloworld
spec:
  containers:
    - name: helloworld
      image: hello-world-api:latest
      imagePullPolicy: Never
      ports:
      - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: helloworld-svc
spec:
  selector:
    app: helloworld
  type: NodePort
  ports:
    - name: http
      nodePort: 30950
      targetPort: 8080
      port: 8080

Additional Notes:-

kubectl version

Client Version: version.Info{Major:"1", Minor:"20+", GitVersion:"v1.20.4-dirty", GitCommit:"e87da0bd6e03ec3fea7933c4b5263d151aafd07c", GitTreeState:"dirty", BuildDate:"2021-03-15T09:55:27Z", GoVersion:"go1.16.2", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.2", GitCommit:"faecb196815e248d3ecfb03c680a4507229c2a56", GitTreeState:"clean", BuildDate:"2021-01-21T01:11:42Z", GoVersion:"go1.15.5", Compiler:"gc", Platform:"linux/amd64"}

kind --version

kind version 0.10.0

Browser url

localhost:30950/greet
Margit answered 2/6, 2021 at 7:49 Comment(1)
hostPort and containerport value of 30000 worked for me.Chromophore
Z
4

You shouldn't use nodeport with local IP. Instead you should:

  1. use command : kubectl get nodes -o wide
  2. note down the IP of the node
  3. curl :30000

or

  1. docker exec -it /bin/bash

  2. curl localhost:30000

Zaporozhye answered 5/1, 2022 at 5:5 Comment(2)
u are right however, the kind clusters don't expose external node ipsLangtry
@Langtry In you machine, it is if you use extraPortMappings of kind config. If you use aws ec2, you can even use aws ec2 public IP to access it. kind.sigs.k8s.io/docs/user/configuration/….Zaporozhye
M
3

in the kind config yaml

containerPort must be the same with the 'NodePort' in service config. in your case is 30000

tips: hostPort can be any port ,it does not need to be the same with containerPort

Merrilee answered 1/9, 2021 at 7:30 Comment(0)
R
3
kubectl port-forward svc/hostname-service 30000:80

Now your service will be accessed on host port 30000

Reversioner answered 13/5, 2022 at 10:57 Comment(0)
A
2

I got it worked by two options:

  1. Either you keep the same nodePort config while creating the service and the one used to create the kind cluster.
  2. The second is to keep any nodePort in the service manifest just use the port forward command

kubectl port-forward svc/hostname-service [assigned node port to service]:80

Then access it using localhost:[nodePort]

Appanage answered 9/9, 2023 at 22:44 Comment(0)
A
1

I would try removing the nodePort: 30000 and check that the newly assigned nodePort works with the loopback interface. If you do an update of the service, kube has a problem with satically asigned nodePorts, you have to manige yourself the port collision. Trying to delete the deployment and redeploy could also help.

Aftereffect answered 17/6, 2020 at 16:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.