Skip to content

Service Port-Forwarding Ignores Service Port Mapping #7372

@tomplummercarfax

Description

@tomplummercarfax

Describe the bug

Summary:
Service-based port forwarding fails when the service port differs from the target port, because Fabric8 attempts to connect to the service port inside the pod's network namespace instead of the target port specified in the service definition.

Expected Behavior:
When using service.portForward(servicePort, localPort), Fabric8 should connect to the service's targetPort inside the pod, similar to how kubectl port-forward service/name works.

Actual Behavior:
Fabric8 attempts to connect to the servicePort inside the pod's network namespace, ignoring the service's port mapping to targetPort.

Service Configuration:

apiVersion: v1
kind: Service
metadata:
  name: my-webapp
  namespace: my-namespace
spec:
  ports:
  - name: http
    port: 80          # Service port
    targetPort: 8080  # Pod port where application actually listens
  selector:
    app: my-webapp

Reproduction Code:

// This fails - tries to connect to pod's port 80 instead of 8080
LocalPortForward servicePortForward = client.services()
    .inNamespace("my-namespace")
    .withName("my-webapp") 
    .portForward(80, 8080);

Comparison with kubectl:

# This works correctly - kubectl properly maps service port 80 to target port 8080
kubectl port-forward service/my-webapp 8080:80 -n my-namespace

Root Cause:
The service port-forwarding implementation appears to use the service port (80) when establishing the connection inside the pod's network namespace, but should use the service's targetPort (8080) instead.

Workaround:
Use pod-based port forwarding instead of service-based port forwarding:

Pod targetPod = client.pods()
    .inNamespace("my-namespace")
    .withLabel("app", "my-webapp")
    .list().getItems().get(0);
    
LocalPortForward portForward = client.pods()
    .inNamespace("my-namespace") 
    .withName(targetPod.getMetadata().getName())
    .portForward(8080, 8080);

Fabric8 Kubernetes Client version

7.4.0

Steps to reproduce

Service Configuration:

apiVersion: v1
kind: Service
metadata:
  name: my-webapp
  namespace: my-namespace
spec:
  ports:
  - name: http
    port: 80          # Service port
    targetPort: 8080  # Pod port where application actually listens
  selector:
    app: my-webapp

Reproduction Code:

// This fails - tries to connect to pod's port 80 instead of 8080, but does not throw any exceptions and reports that the portForward is alive
LocalPortForward servicePortForward = client.services()
    .inNamespace("my-namespace")
    .withName("my-webapp") 
    .portForward(80, "127.0.0.1", 8080);

Expected behavior

When using service.portForward(servicePort, localPort), Fabric8 should connect to the service's targetPort inside the pod, similar to how kubectl port-forward service/name works.

Runtime

other (please specify in additional context)

Kubernetes API Server version

other (please specify in additional context)

Environment

macOS

Fabric8 Kubernetes Client Logs

io.fabric8.kubernetes.client.KubernetesClientException: Received an error from the remote socket 
error forwarding port 80 to pod [pod-id], uid : failed to execute portforward in network namespace 
"/var/run/netns/cni-[namespace-id]": failed to connect to localhost:80 inside namespace "[pod-id]", 
IPv4: dial tcp4 127.0.0.1:80: connect: connection refused 
IPv6 dial tcp6 [::1]:80: connect: connection refused

Additional context

Environment:

  • Java version: Corretto-21.0.8.9.1
  • Kubernetes version: v1.34.1+k3s1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions