|
| 1 | +# Make Skaffold port-forwarding less surprising |
| 2 | + |
| 3 | +* Author(s): Brian de Alwis |
| 4 | +* Date: 2020-09-22 |
| 5 | +* Late updated: 2021-03-16 |
| 6 | +* Status: Reviewed/Cancelled/**Under implementation**/Complete |
| 7 | + |
| 8 | +## Objective |
| 9 | + |
| 10 | +Align Skaffold port-forwarding behaviour with user expectations. |
| 11 | + |
| 12 | + |
| 13 | +## Background |
| 14 | + |
| 15 | +Skaffold supports establishing port-forwarding to deployed Kubernetes resources through |
| 16 | +several mechanisms: |
| 17 | + |
| 18 | +- A user can configure one or more [port forwards in their `skaffold.yaml`](https://skaffold.dev/docs/references/yaml/#portForward) |
| 19 | + to connect a local port to a remote port on a pod, a service, or some workload resource that |
| 20 | + has a pod-spec (e.g., Deployment, ReplicaSet, Job). |
| 21 | +- Skaffold automatically configures port-forwards for services. |
| 22 | +- When in _debug_ mode (`skaffold debug`), Skaffold automatically configures port-forwards to pods too. |
| 23 | + |
| 24 | +Port-forwards are only established when a user runs Skaffold with `--port-forward`. This was a conscious |
| 25 | +choice in [#969](https://github.com/GoogleContainerTools/skaffold/issues/969) as Skaffold had been |
| 26 | +forwarding all containerPorts defined on pods, and doing so led to conflicts |
| 27 | +in ports chosen. Users with many services encountered confusion when dealing with many services |
| 28 | +([#1564](https://github.com/GoogleContainerTools/skaffold/issues/1564)). |
| 29 | + |
| 30 | +But putting all port-forwards behind the `--port-forward` flag has resulted in new user confusion |
| 31 | +(e.g., [#4163](https://github.com/GoogleContainerTools/skaffold/issues/4163), |
| 32 | +[#4818](https://github.com/GoogleContainerTools/skaffold/issues/4818)): |
| 33 | + |
| 34 | +> *discr33t* 12:32 PM: I’m having a problem getting Skaffold to port-forward to my service after |
| 35 | +> doing a Helm deploy. If I use the --port-forward flag it will port-forward all my services. But |
| 36 | +> if I define portForward: anywhere in my `skaffold.yaml` nothing is working. |
| 37 | +
|
| 38 | +Forwarding all `containerPort`s on pods in `skaffold debug` has also resulted in odd situations |
| 39 | +such as container-ports being allocated before service ports. For example, the Skaffold |
| 40 | +[`examples/react-reload`](https://github.com/GoogleContainerTools/skaffold/tree/HEAD/examples/react-reload/) example |
| 41 | +has a [service on port 8080](https://github.com/GoogleContainerTools/skaffold/tree/HEAD/examples/react-reload/k8s/deployment.yaml#L7) |
| 42 | +and a [deployment/pod on port 8080](https://github.com/GoogleContainerTools/skaffold/blob/master/examples/react-reload/k8s/deployment.yaml#L29). |
| 43 | + |
| 44 | + |
| 45 | + |
| 46 | +## Design |
| 47 | + |
| 48 | +This document proposes to change Skaffold port-forwarding's defaults in a similar fashion as proposed |
| 49 | +by @corneliusweig in https://github.com/GoogleContainerTools/skaffold/issues/1564#issuecomment-473528574. |
| 50 | +These changes are intended to be backwards-compatible with the previous version |
| 51 | +of Skaffold except where noted. |
| 52 | + |
| 53 | + |
| 54 | +### Command-Line Changes |
| 55 | + |
| 56 | +> **NOTE**: Ideally we would re-purpose Skaffold's existing `--port-forward` CLI argument in |
| 57 | +> a backward-compatible manner (still under investigation). This document assumes it is |
| 58 | +> not possible. |
| 59 | +
|
| 60 | +~Skaffold's `--port-forward` argument should be changed from a binary true/false option to~ |
| 61 | + |
| 62 | +Skaffold will introduce a new `--port-forward-modes` argument that takes |
| 63 | +a set of comma-separated values with the following defined modes: |
| 64 | + |
| 65 | + - `user`: user-defined port-forwards as defined in the `skaffold.yaml` |
| 66 | + - `services`: service ports are forwarded |
| 67 | + - `pods`: `containerPort`s defined on Pods and Kubernetes workload objects that have pod-specs |
| 68 | + are forwarded (Deployment, ReplicaSet, StatefulSet, DaemonSet, Job, CronJob) |
| 69 | + - `debug`: an internal strategy to forward debugging-related ports on Pods as set up |
| 70 | + from `skaffold debug` |
| 71 | + - `off`: no ports are ever forwarded |
| 72 | + |
| 73 | +#### Changes to port-forwarding defaults |
| 74 | + |
| 75 | +Skaffold will default to enabling port-forwarding for establishing user-defined port-forwards |
| 76 | +as defined in the `skaffold.yaml`. Skaffold's `dev` and `debug` will be changed to the following defaults. |
| 77 | + |
| 78 | +Command-line | v1.15.0 default modes | New default modes |
| 79 | +----------------------------------- | ---------------- | ------------------- |
| 80 | +`skaffold dev` | off | user |
| 81 | +`skaffold dev --port-forward` | user, services | user, services (no change) |
| 82 | +`skaffold dev --port-forward=false` | off | off (no change) |
| 83 | +`skaffold debug` | off | user, debug |
| 84 | +`skaffold debug --port-forward` | user, services, pods | user, services, debug |
| 85 | +`skaffold debug --port-forward=false` | off | off (no change) |
| 86 | + |
| 87 | +**Compatibility Change:** The behaviour of `skaffold debug --port-forward` no longer forwards all |
| 88 | +`containerPort`s defined on pods. Container ports were forwarded as there was no other option to forward |
| 89 | +just debug ports. With this proposed change, the `debug` mode will only select debug ports. Forwarding all |
| 90 | +`containerPort`s was the cause of some confusion in earlier iterations of port-forwarding. |
| 91 | + |
| 92 | + |
| 93 | +### Open Issues/Questions |
| 94 | + |
| 95 | +Please list any open questions here in the following format: |
| 96 | + |
| 97 | +**\<Question\>** |
| 98 | + |
| 99 | +Resolution: Please list the resolution if resolved during the design process or |
| 100 | +specify __Not Yet Resolved__ |
| 101 | + |
| 102 | + |
| 103 | +## Implementation plan |
| 104 | + |
| 105 | +1. Separate user-defined forwarding from [ResourceForwarder](https://github.com/GoogleContainerTools/skaffold/blob/master/pkg/skaffold/kubernetes/portforward/resource_forwarder.go) |
| 106 | +2. Amend `WatchingPodForwarder` to take a pod/port-filter to allow determining if a port is |
| 107 | + a debug port, as determined by the `debug.cloud.google.com` annotation. |
| 108 | +3. Somehow turn `--port-forward` into string slice argument, if possible! |
| 109 | +4. Add support to the skaffold.yaml schema |
| 110 | +5. Add support to the global configuration schema. |
| 111 | + |
| 112 | +___ |
| 113 | + |
| 114 | + |
| 115 | +## Integration test plan |
| 116 | + |
| 117 | +Please describe what new test cases you are going to consider. |
| 118 | + |
| 119 | +1. `skaffold dev` should forward user-defined ports (no services, not container ports). |
| 120 | +2. `skaffold dev --port-forward` should forward services (no container ports). |
| 121 | +3. `skaffold dev --port-forward-modes=off` should forward nothing. |
| 122 | +4. `skaffold dev --port-forward-modes=X` for X={user,debug,pods,services}` should only forward those items. |
| 123 | +5. `skaffold debug` should forward user-defined ports and debug ports (no services, no other container ports). |
| 124 | +6. `skaffold debug --port-forward` should forward user-defined ports, debug ports, and services (no container ports). |
| 125 | +7. `skaffold debug --port-forward-modes=off` should forward nothing. |
| 126 | +8. `skaffold debug --port-forward-modes=X` for X={user,debug,pods,services}` should only forward those items. |
0 commit comments