hcavarsan / kftray

kubectl port-forward on steroids 🦀 ⚡ kftray makes it easy for you to manage and share multiple k8s port forwards right from your menu bar (or terminal)
https://kftray.app/
GNU General Public License v3.0
836 stars 70 forks source link

Error fetching ports #305

Closed whoissteven closed 1 month ago

whoissteven commented 1 month ago

Hello, I am unable to fetch any target ports.

To Reproduce Steps to reproduce the behavior: This is a bit of an odd one.. I uninstalled and reinstalled kftray, added a new kubeconfig, and the issue persists.

Expected behavior To see the available target ports associated with my service.

Screenshots image

Desktop (please complete the following information):

Additional context I have no issues port forwarding with kubectl

hcavarsan commented 1 month ago

hey @whoissteven,

can you give me more details ? here’s what you can do:

  1. right-click and select "Inspect" to open the browser console in kftray. Run the process again, and you should see an error when trying to fetch the namespaces.

  2. To enable debug logs on Windows, open the Command Prompt and run these commands one by one:

    set RUST_LOG=trace
    set KFTRAY_DEBUG=enabled
    "C:\Program Files\kftray\kftray.exe"
  3. after that, just open the app and reproduce the error. you’ll find the debug log at $HOME/.kftray/app.log.

with this info, ill be able to figure out what’s going on and help you out.

thx!

whoissteven commented 1 month ago

I do see this image

However, this same kubeconfig file does work, allowing me to access my k8s cluster via kubectl.

hcavarsan commented 1 month ago

got it, thx for the info,

did this work in previous versions of kftray?

either way, if you can send me the logs or any extra info, i can try to replicate it on my end and dig deeper into the issue

lcasavola commented 1 month ago

Hello I have the same issue, still on windows 11. I set the debug as indicated but I couldn't see any errors related to fetching ports

hcavarsan commented 1 month ago

@lcasavola does this issue occur in the latest app versions or all versions? I couldn't reproduce the issue on my Windows setup

please test with version v0.14.0

lcasavola commented 1 month ago

yes, is the latest . I tried with v0.14.0 and now there is no more red "Error fetching ports" but still I cannot retrieve any pod esposed ports

lcasavola commented 1 month ago

I would achieve the same result as this working kubectl running: kubectl -n omnis-bas-001 port-forward pod/pgadmin-7d9fffd47d-cj49v :80 Forwarding from 127.0.0.1:43121 -> 80 Forwarding from [::1]:43121 -> 80

I tried to overcome the interactive setup and importa a json file like this: [ { "target": "pgadmin-7d9fffd47d-cj49v", "namespace": "omnis-bas-001", "local_port": 8081, "remote_port": 80, "context": "kubernetes-admin@kubernetes", "workload_type": "pod", "protocol": "tcp", "kubeconfig": "C:\Users\luca\Documents\kubeconfigAll", "alias": "pgadmin" } ]

after importing if I edit the configuration I see the value "default-service" on Pod Label attribute

hcavarsan commented 1 month ago

got it! i was able to simulate the issue. the problem occurs when a custom kubeconfig is selected. i'm already working on a fix and will update the thread once it's ready.

just one important point:

the "target" field in the json is actually the label of the pod, not the pod name itself. it should follow the kubernetes label format. if you want, you can test it with an example json like this:

[
  {
    "target": "app.kubernetes.io/component=server",
    "namespace": "argocd",
    "local_port": 8585,
    "remote_port": 8080,
    "context": "kind-1",
    "workload_type": "pod",
    "protocol": "tcp",
    "kubeconfig": "/users/henrique/.kube/config.bkp",
    "alias": "argocd"
  }
]

the reason for using the label instead of the pod name is to ensure that if the pod dies, kftray keeps the port forward up and always forwards the request to a healthy pod.

regarding the default-service value, it shouldn't be an issue. if you export the config, it should remove those default fields.

anyway, i'm working on a fix for the behavior in the ui! thanks for the report.

lcasavola commented 1 month ago

Great, I'll wait for your fix. any way you said " the problem occurs when a custom kubeconfig is selected", why is there any other ways and not providing a custom kubeconfig ? Can you send an example ? May be it has to be with the context name: don't you need the @domain suffix?

hcavarsan commented 1 month ago

on the screen to add a new config, if you don't select a kubeconfig, the app will always try to look in the path specified by the KUBECONFIG environment variable. if the variable doesn't exist, it will try the default kubeconfig path, which is $HOME/.kube/config.

the option in the ui to select a kubeconfig is just in case you want to use a kubeconfig that isn't in the variable or the default path.

in the config json, you can import without the kubeconfig field/value in json, and the app will assume default, example:

[
  {
    "target": "app.kubernetes.io/component=server",
    "namespace": "argocd",
    "local_port": 8585,
    "remote_port": 8080,
    "context": "kind-1",
    "workload_type": "pod",
    "protocol": "tcp",
    "alias": "argocd"
  }
]

example with custom kubeconfig: CleanShot 2024-09-20 at 19 45 19

example with default kubeconfig (in this case, i have the kubeconfig in default path /users/henrique/.kube/config): CleanShot 2024-09-20 at 19 44 43

this is the function with this logic: https://github.com/hcavarsan/kftray/blob/main/crates/kftray-commons/src/utils/config_dir.rs#L58-L84

lcasavola commented 1 month ago

Argh! I didn't install kubectl on the windows machine, I took the .kube/config file from another machine. The reason is I would like to use your ( apparently great tool, compliments) for a tenant user who even doesn't know to work with k8s. I am striving to develop a SaaS solution built on top of kubernetes.. I don't want to bther you but if interested I would glad to share with you my project

hcavarsan commented 1 month ago

oh, but kftray doesn't depend on kubectl! the default kubeconfig path is just there to make it easier so you don't have to specify a custom kubeconfig path if you don't want to, but everything should work fine even if kubectl isn't installed on the machine and passing a kubeconfig path...

i have a bunch of homelab vms with various os's that do not have kubectl installed, and kftray works fine.

about the SaaS: that sounds cool. you can reach out to me on the kftray slack :) , here's the link to join the workspace: https://join.slack.com/t/kftray/shared_invite/zt-2q6lwn15f-Y8Mi_4NlenH9TuEDMjxPUA

hcavarsan commented 1 month ago

released the version v0.14.3 with fix: https://github.com/hcavarsan/kftray/releases/tag/v0.14.3

@lcasavola @whoissteven could you check if it's working now?

whoissteven commented 1 month ago

This resolved my issue, thank you.

lcasavola commented 1 month ago

Great, now it works! :-) can i tell some small issues I found while I was testing? 1- when I add a new configuration I need to fill the Alias otherwise I cannot complete ( Add Config is disable) so you consider it mandatory but it is not indicated as mandatory (*), what is the alias purpose ? 2 - if you add more configurations even for the same context you need to set each time the kubeconfig from scratch , it is annoying but I can overcome the issu and just save my configuration under .kube/config, do I ? 3 - I want to let no-network expert to use kftray , would be possibile leave the local port empy and let the tool to find out a free local port ( similar to kubectl port-forward syntax :remotePort ? I wait for your commets , Thanks in advance ( for slack channeol another time , I am going to go to sleep now , I live in italy , where are you located ?

hcavarsan commented 1 month ago

@lcasavola cool! i'm from Brazil, so, we'll talk sometime on slack :)

regarding your points:

  1. Alias Field: The alias is meant to be an identifier for each configuration that you will see in the UI to make it easier to visualize, but what you said makes sense and this field doesn't need to be required. A default value would be a sensible improvement.
  2. Kubeconfig Path: Yes, in this case, there's not much to do. The easiest way is to save it in the default path, so it will always be recognized without any other changes.
  3. Local Port: That makes total sense.

i think your feedback makes total sense and thanks for it. i've already made these changes and created a PR with these updates, and i'll let you know as soon as a new version is released...

in this new version, the alias and local_port fields are no longer required, and these are the new behaviors:

  1. If the local_port field is left blank, it will assume the same value as the remote_port, as done in kubectl. I want to avoid searching for free ports in the OS, and I think this approach should solve it.
  2. If the alias field is not defined, the default will be ${workload_type}-${protocol}-${local_port}.

For example, for a JSON like this:

[
  {
    "context": "kind-1",
    "kubeconfig": "/Users/henrique/.kube/config.bkp",
    "namespace": "argocd",
    "protocol": "tcp",
    "remote_port": 8080,
    "service": "argocd-server",
    "workload_type": "service"
  }
]

PS- This same behavior applies if you add it via the UI too!

and just to point, in kftray v0.14.0 i released a feature to auto import configs from the kubernetes cluster based on the annotations. this might help you in case you need to not pass anything and just configure the annotations on the kubernetes side. on the client side, you just click the auto import button to fetch all those configs automatically :) (specifically this feature, need the kubeconfig in default local path to works, im still developing the custom kubeconfig for this)

this is the release and it has a video to show the workflow of auto import: https://github.com/hcavarsan/kftray/releases/tag/v0.14.0

so thats it, i'll let you know here when the new version is out with default values when adding or importing configs via UI

hcavarsan commented 1 month ago

@lcasavola this is the new release with optional alias and local_port https://github.com/hcavarsan/kftray/releases/tag/v0.14.4

lcasavola commented 1 month ago

cool! I will test v0.14.4 asap, in the mean time I invite you to reconsider the feature to search for free local ports. Is a typical scenario for an user to have to connect in the same kluster context to different services which generally expose the http port 80 ( for example a nodejs or apache and wordpress with a postgresql db handled by a pgadmin service, all these services typically are listening on port 80). These administrative services should be not exposed on internet so it is supposed to be accessed directly on the cluster through port-forward mechanism. I think it would be cumbersome for an user try a local port , realize later it is laready opened, try another one and so one. The empty local port you implemented in this scenario wouldn't help. Better in my opinion fill the local port with a wildcard such as "?" , ".", "*" and let the code searching for free code. As I said, It is the same mechanism available on kubectl where you leave the localport item empy in the syntax local:remote , for example " :80". The same behaviour is implemented in the defintion of an ak8s service of type service where you can indicate the nodePort explicity

apiVersion: v1
kind: Service
metadata:
  name: somename
  namespace: somenamspace
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: http
   nodePort: 31080

or you can omit the nodePort attribute and let the the k8s controller choosing a free nodePort for you

hcavarsan commented 1 month ago

okay, i got it and i’ll think about it

but could you open a new issue for this? it might be a bit long, so it’d be good to have a separate issue just for that.

how’s that sound?”

lcasavola commented 1 month ago

yes sure I'll copy my last post and put in a new issue, no problem. In the mean time I tested 0.14.4: it works as expected. Unfortunately in my use-case it doesn't, let's me explain and eventualy I can open another new issue for that. As I said, in my Saas project the user is supposed not to know there is k8s cluster behind the scene. In my idea each user has all their resources on single namespace ( isolated from the others ) and is restricted only to list, view their inner resources ( implemented with rbac). My idea was initially to us use kftray with an unrestricted adminuser and set all the services the user is going to access through port forward than I export the configs.json. After that through a web page I instruct the user to install kftray and download the (restricted-user) kubeconfig and configs.json The problem is that this use case doesn't work because I think kftray when imports the configuration it still checks the conf against the cluster and in my case it fails because listing the namespaces is forbidden for the restricted user . I thought once there is a configuration in place kftray only had to use the ports/forward verb,

hcavarsan commented 1 month ago

I understand. but it wouldn't be possible with kftray because I perform some checks for available pods before establishing the port forward tunnel. also, kftray has some more complex sanitization routines that still depend on other permissions at the namespace level. I think it would be impossible for kftray to rely solely on the port forward verb today. It would require a simpler application focused more on port forward management without many additional features.

I'll close this issue, but I really appreciate your report! It helped me a lot, and the changes you suggested made sense. Thank you! If you need anything else or encounter any more bugs, feel free to open an issue, and I'm open to discussing it. :)

lcasavola commented 1 month ago

@hcavarsan: no problem I added a clusterrole to let the user to see namespaces and all it works now as expected. Many thanks for your help.

lcasavola commented 4 weeks ago

excuse me if I come back on this issue. with the clusterrole now the user is allwed to see all the namespaces but it is annoying. I wonder why you don't let, in the configuration panel, the user to manually set the value of an attribute ( Namespace in my case) other than let to search the value through the drop list ? In my scenario , I could remove the clusterrole and not allow the user to see all the namespeces names but I woul let hime to manually let him to set it manually ( or in my case importing it from the json config file. What do you think? Let me know. thanks