kubectl port-forward is not working/too slow - kubernetes

I am setting up Traefik in my CentOS VM. I tried to port-forward as specified here:
https://github.com/jakubhajek/traefik-workshop/tree/3cbbb3b8d3dbafcb2a56f3bb715fee41ba8ffe8b/exercise-2
It displays the following, taking hours, and does nothing:
Forwarding from 127.0.0.1:9000 -> 9000
Forwarding from [::1]:9000 -> 9000
Handling connection for 9000
Handling connection for 9000
Handling connection for 9000
Handling connection for 9000
Please advise what I should do to make the kubectl port-forward work.

kubectl port-forward makes a specific Kubernetes API request. That means the system running it needs access to the API server, and any traffic will get tunneled over a single HTTP connection.
If it is saying 404 page not found, then probably there is something wrong with the deployment ( application ) as the port 9000 is listening and opened connection. So you can check whether you have done port-forwarding to the right pod or not.

Related

What is the best way to reverse port forward information from a Kubernetes cluster to localhost?

I am attempting to reverse port forward information from a Kubernetes pod 192.168.49.2:30085 to my locoalhost:8000 but I am having issues.
The goal is to get the same response as curl 192.168.49.2:30085 on localhost:8000
One thing I have tried has been using ktunnel with the command ktunnel expose <service_name> 30085:8000 to try to forward this info. Doing this I get the output
INFO[0000] Exposed service's cluster ip is: 10.101.77.99
.INFO[0000] waiting for deployment to be ready
.....
INFO[0001] port forwarding to https://192.168.49.2:8443/api/v1/namespaces/default/pods/thisisatest-59d5584c84-b5qrc/portforward
INFO[0001] Waiting for port forward to finish
INFO[0001] Forwarding from 127.0.0.1:28688 -> 28688
INFO[2022-08-03 20:23:48.605] starting tcp tunnel from source 30085 to target 8000
Which seems normal and I am able to get a response when using curl http://10.101.77.99:30085 on local host 8000 but not the correct response.
I have also attempted to run a tcp server with the command nc 127.0.0.1 8000 | kubectl exec -i <pod_name> tcpserver 127.0.0.1 30085 cat But am having poor results as well. Am I using these services incorrectly? Or is there a better way to do this all together?

Port fowarding in kubernetes

I know that in kubernetes, we can't use a Service Node Port below 30000, because these ports are used by kubernetes. Can I use "kubectl port-forward svc/someservice 80:80" for instance... without causing conflict with the kubernetes ports below 30000?
In short - yes, you can.
In your question though it's clear that you're missing the understanding of NodePort type of service and the what the kubectl port-forward essentially does.
kubectl port-forward doesn't send the traffic through the port defined in the .spec.type: NodePort stanza in the Service resource. In fact using kubectl port-forward you're able to target a ClusterIP type of service (which doesn't have a .spec.type: NodePort stanza by definition).
Could you please describe what is the reason to have such a setup?
kubectl port-forward svc/someservice 80:80 merely forwards your local_machine:80 to port:80 of endpoints for someservice .
In other words, connections made to local port 80 are forwarded to port 80 of the pod that is running your app. With this connection in place you can use your local workstation to debug the app that is running in the pod.
Due to known limitations, port forward today only works for TCP protocol. The support to UDP protocol is being tracked in issue 47862.
As of now (Feb-2020) the issue is still open.
Node Port is used for totally different stuff. It is used for cases when you shall reach pods by sending traffic to particular port on any node in your cluster.
That is why the answer for your question is "Definitely you can do that"; however, as I said before, it is not clear why you shall do that. Without that inf it is hard to provide a guidance on "what is the best way to achieve the required functionality"
Hope that helps.

How kubectl port-forward works?

kubectl exposes commands that can be used to create a Service for an application and assigns an IP address to access it from internet.
As far as I understand, to access any application within Kubernetes cluster there should be a Service resource created and that should have an IP address which is accessible from an external network.
But in case of port-forward how does kubectl create a connection to the application without an IP address which is accessible externally?
To start, it's useful to note and remember that in Kubernetes, every pod gets its own ip address from 10.*, that is usable only within the cluster. Now, the port-forward feature of kubectl simply tunnels the traffic from a specified port at your local host machine to the specified port on the specified pod. API server then becomes, in a sense, a temporary gateway between your local port and the Kubernetes cluster.
kubectl port-forward forwards connections to a local port to a port on a pod. Compared to kubectl proxy, kubectl port-forward is more generic as it can forward TCP traffic while kubectl proxy can only forward HTTP traffic.
kubectl port-forward is useful for testing/debugging purposes so you can access your service locally without exposing it.
Below is the name of the pod and it will forward it's port 6379 to localhost:6379.
kubectl port-forward redis-master-765d459796-258hz 6379:6379
which is the same as
kubectl port-forward pods/redis-master-765d459796-258hz 6379:6379
or
kubectl port-forward deployment/redis-master 6379:6379
or
kubectl port-forward rs/redis-master 6379:6379
or
kubectl port-forward svc/redis-master 6379:6379
kubectl port-forward makes a specific Kubernetes API request. That means the system running it needs access to the API server, and any traffic will get tunneled over a single HTTP connection.
Having this is really useful for debugging (if one specific pod is acting up you can connect to it directly; in a microservice environment you can talk to a back-end service you wouldn't otherwise expose) but it's not an alternative to setting up service objects. When I've worked with kubectl port-forward it's been visibly slower than connecting to a pod via a service, and I've found seen the command just stop after a couple of minutes. Again these aren't big problems for debugging, but they're not what I'd want for a production system.
If you want to forward to a different port in localhost. Try this
kubectl port-forward <pod-name> <locahost-port>:<pod-port>
kubectl port-forward sample-pod-sadasds-sxawdd 8090:6379
The above command forwards to localhost 8090 from pod 6379
The port-forward command, Forwards one (or more) local ports to a pod.
This command is very useful for example in blue/green deployments where you would want to troubleshoot a misbehaving pod.
To take things even further, you could even execute some preliminary tests to the pods you feel could be more error-prone right inside your CI/CD pipeline in Jenkins by using multiple conditions, declarative pipeline.
Usage examples:
Listen on port 8888 locally, forwarding to 5000 in the pod
kubectl port-forward pod/mypod 8888:5000
Listen on port 8888 on all addresses, forwarding to 5000 in the pod
kubectl port-forward --address 0.0.0.0 pod/mypod 8888:5000
Listen on a random port locally, forwarding to 5000 in the pod
kubectl port-forward pod/mypod :5000
Listen on port 8888 on localhost and selected IP, forwarding to 5000 in the pod
kubectl port-forward --address localhost,10.19.21.23 pod/mypod 8888:5000
Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod
kubectl port-forward pod/mypod 5000 6000
Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in a pod selected by the deployment
kubectl port-forward deployment/mydeployment 5000 6000
Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in a pod selected by the service
kubectl port-forward service/myservice 5000 6000
To access something inside the cluster, there ae a couple of different options available to,
Cluster IP service with Ingress-Nginx
NodePort Service to expose the pod directly to the outside world.
Above both approach will require to write config file, In case if you want to access a pod without writing a config file then it comes to third option.
Port Forward: We can run a command at our terminal that tells our kubernets cluster to port-forward a port off a very specific pod inside of our cluster when we use this port forwarding thing that's going to cause our cluster to essentially behaves as though it has a node port service running inside it. It's going to expose this pod or a very specific port on it to the outside world and allow us to connect to it directly from our local machine.
Let's go by an example:
const stan = nats.connect('ticketing', 'abc', {
url: 'http://localhost:5000',
});
Our goal is to establish a connection between stan and a pod inside a kubernets cluster.
first we will need the pod name, you can get the name by command kubectl get pods
kubectl get pods
I am assuming my pod name is nats-depl-855d477f4d-xgbd7, and it is accessiable via a cluster IP service
apiVersion: v1
kind: Service
metadata:
name: nats-srv
spec:
selector:
app: nats
ports:
- name: client
protocol: TCP
port: 4222
targetPort: 4222
now to establish the connection run the below command:
kubectl port-forward nats-depl-855d477f4d-xgbd7 5000:4222
5000: is the port of my local machine
4222 : is the port of the pod I want to get access
kubectl port-forward is the easiest communication method with the Pod, but under the hood, this method is much more complicated. The communication goes through several Kubernetes components, so if anything is broken in the communication path, you will not be able to talk to the pod, even if the pod itself is accessible via regular communication channels.
The server proxy runs via kubectl port-forward command forwards the connection to the Kubernetes API Server living in Master node, then the API Server delivers the connection to the Kubelet on the node hosting your Pod, and then the Kubelet forwards the connection to the application running in the pod's container.
NOTE
The application in the container must be bound to a port on the
loopback device for the Kubelet to reach it. If it listens only on the
pod’s eth0 network interface, you won’t be able to reach it with the
kubectl port-forward command.
Marko Lukša "Kubernetes in Action, Second Edition"
TIP
kubectl port-forward allows you to forward communication also to Services and has several other useful features. Run kubectl port-forward --help to learn more.

why pods not getting incoming connections

I am making my first steps with Kubernetes and I have some difficulties.
I have a pod with it's service defined as NodePort at port 30010.
I have a load balancer configured in front of this Kubernetes cluster where port 8443 directs traffic to this 30010 port.
when I try to access this pod from outside the cluster to port 8443 the pod is not getting any connections but I can see the incoming connections via tcptrack in the host in port 30010 with means the load balancer is doing it's job.
when I do curl -k https://127.0.0.1:30010 in the host I get a response from the pods.
what am I missing?
how can I debug it?
thanks

closing a port in a running kubernetes service

Im trying to create a load balancer service in kubernetes which will have 2 ports: 80 and 8080. For the port 80 I want to open this port only when I want to use it. Is it possible to do this while the service is running?
Im trying to use 8080 for serving outside requests and 80 for debugging purpose.
I would suggest not exposing the debugging port at all by means of service (aspecially that you dont really know it will hit the same backing pod as port for real traffic). Instead it might be good enough for you to use kubectl port-forward to access the debug port when you need.