Auto Import
Discover port-forward configurations from Kubernetes service annotations in the desktop app and kftui.
Auto import reads port-forward configurations from Kubernetes service annotations, so you don't need to create them by hand. The configs stay in sync with the service definitions.
Annotation format
apiVersion: v1
kind: Service
metadata:
name: monitoring-stack
namespace: observability
annotations:
kftray.app/enabled: "true"
kftray.app/configs: "grafana-3000-3000,prometheus-9090-9090,alertmanager-9093-9093"
spec:
selector:
app: monitoring
ports:
- name: grafana
port: 3000
- name: prometheus
port: 9090
- name: alertmanager
port: 9093The kftray.app/configs annotation defines port forwards in the format alias-local_port-remote_port. Separate multiple forwards with commas. The alias and a Service port name can contain hyphens, as in my-api-8080-http-alt.
This example creates three configurations. Each one forwards localhost:<local_port> to the service's container port.
| Annotation | Value | Description |
|---|---|---|
kftray.app/enabled | "true" | Required. Without the exact string "true", kftray skips the service, even if it has a configs annotation |
kftray.app/configs | "alias-local-remote,..." | Comma-separated list of port-forward definitions. If you leave it out, kftray creates one config per service port, named after the service, with the same local and remote port |
Remote port names
remote_port can also be a Service port name. kftray then forwards to that port's targetPort on the pod, not to the Service's own port.
annotations:
kftray.app/enabled: "true"
kftray.app/configs: "api-8080-http,admin-8081-admin"
spec:
ports:
- name: http
port: 80
targetPort: 8080
- name: admin
port: 8080
targetPort: 9090Here api forwards localhost:8080 to container port 8080, and admin forwards localhost:8081 to container port 9090. A number in the annotation is used as given, so the Service's exposed port is never translated a second time.
A named targetPort is resolved from the container ports of the pods the Service selects. Those pods must declare the same number for that name.
If they disagree or kftray can't list them, it skips the port and logs a warning.
How discovery works
kftray scans services in every namespace you can access. It skips a namespace it can't list and logs the failure. For each service with kftray.app/enabled: "true", kftray:
Parses the kftray.app/configs value. It ignores entries it can't parse.
Creates a TCP service config from the service metadata, your Kubernetes context and the annotation. The metadata supplies service and namespace. The annotation supplies alias, local_port and remote_port.
Adds the configuration to your local database.
Discovery runs when you start it, from the desktop menu or from kftui. kftray doesn't rescan on a timer.
RBAC permissions required
Auto import needs permission to list services across namespaces. Check your permissions with kubectl auth can-i list services --all-namespaces. Cluster-wide discovery may need a ClusterRole binding.
Integration with Helm
# templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ include "myapp.fullname" . }}
annotations:
kftray.app/enabled: "true"
kftray.app/configs: "{{ .Values.kftray.alias }}-{{ .Values.kftray.localPort }}-http"
spec:
ports:
- name: http
port: {{ .Values.service.port }}
targetPort: 8080# values.yaml
service:
port: 80
kftray:
alias: "myapp"
localPort: 8080Deploy with Helm, then run auto import to pick up the service:
helm install myapp ./myapp
# auto import creates: myapp-8080-httpUsing auto import
Open the main menu in the footer and select Auto Import.
Select the kubeconfig and the context.
Optional: turn on the alias-as-domain or auto address toggles to apply them to every imported config.
Click Import.
Discovered configurations show up in your port-forward list.
Imported configurations merge with existing ones, so running auto import several times doesn't create duplicates.