Kubernetes Port Configuration

Key Insight: The Full Traffic Chain

Internet
   โ†“
Ingress  (routes by hostname/path โ†’ service name + service port)
   โ†“
Service  (port โ†’ targetPort)
   โ†“
Pod/Container  (containerPort / what the process actually binds)

Each arrow is where a port number must match its neighbour. A mismatch at any link causes traffic to silently fail to route.


containerPort is Documentation Only

spec:
  containers:
    ports:
      - containerPort: 3005  # โ† has NO effect on actual network behaviour
  • This is purely informational โ€” a hint for humans and tooling.
  • Kubernetes does not use it to expose or map any port.
  • The container listens on whatever port its process actually binds to.
  • The container will still listen on its default port (e.g. 80) regardless of what containerPort says.
Edge case

Some tools (e.g. kubectl port-forward) can use named ports defined here, but the field has zero effect on actual network routing.


Environment Variable PORT Actually Changes the Listening Port

# configMap
data:
  PORT: "3005"
  • Setting PORT=3005 via a ConfigMap causes the container to actually listen on port 3005.
  • Visible in the pod logs and verifiable via port-forwarding.
  • โš ๏ธ This only works if the application is coded to respect the PORT environment variable.
    audiobookshelf supports this โ€” many images do not.
  • Works regardless of what value is set in containerPort.

Port Numbers Refer to the Container/Cluster Network โ€” Not the Host

  • In Docker Compose: HOST_PORT:CONTAINER_PORT โ€” maps a port from the physical machine into the container.
  • In Kubernetes: there is (almost) no host port. The single port number always refers to the container-side port.
  • Exposure to the outside world is handled by Services and Ingress at a higher level.
Edge case: hostPort

There is a hostPort field in the container spec that mimics Docker’s host-side mapping โ€” but it is considered an anti-pattern in Kubernetes and almost never used.


Service Ports

apiVersion: v1
kind: Service
spec:
  ports:
    - port: 8080        # Port other pods in the cluster use to reach this Service
      targetPort: 3005  # Must match the containerPort (the actual listening port)
  selector:
    app: audiobookshelf  # Must match the pod's label
Field What it means
port Port that other pods use to reach this Service (via cluster-internal DNS)
targetPort Port on the pod/container โ€” must match containerPort
selector Connects the Service to the correct pods via matching labels

Important rules:

  • targetPort and containerPort must match.
  • If targetPort is omitted, Kubernetes uses the value of port โ€” so in that case port must equal containerPort.
  • Always set targetPort explicitly to avoid subtle bugs when values change.
  • targetPort can also be a named port string (defined via name: in containerPort), which decouples the service from exact port numbers.

Ingress Port

apiVersion: networking.k8s.io/v1
kind: Ingress
spec:
  rules:
    - host: audiobookshelf.example.com
      http:
        paths:
          - backend:
              service:
                name: audiobookshelf-svc  # Must match Service name
                port:
                  number: 8080            # Must match Service's `port` field
  • The port number here must match the port field in the corresponding Service (not targetPort, not containerPort).
  • The service name must also match.

Summary: What Must Match What

Ingress backend port  โ”€โ”€โ–บ  Service port
                               โ”‚
                           targetPort  โ”€โ”€โ–บ  containerPort / actual process port
                                                    โ–ฒ
                                             set via env var PORT
                                             (if app supports it)

Practical Verification Steps

  1. Check what port the container actually listens on โ†’ look at pod logs

  2. Verify via port-forwarding:

    kubectl port-forward pod/<pod-name> 3005:3005
    # then curl localhost:3005
  3. Describe the pod to see reported containerPort (remember: this may not reflect reality)