|
| 1 | +# KEP-2079: Network Policy to support Port Ranges |
| 2 | + |
| 3 | +<!-- toc --> |
| 4 | +- [Release Signoff Checklist](#release-signoff-checklist) |
| 5 | +- [Summary](#summary) |
| 6 | +- [Motivation](#motivation) |
| 7 | + - [Goals](#goals) |
| 8 | + - [Non-Goals](#non-goals) |
| 9 | +- [Proposal](#proposal) |
| 10 | + - [User Stories](#user-stories) |
| 11 | + - [Story 1 - Opening communication to NodePorts of other cluster](#story-1---opening-communication-to-nodeports-of-other-cluster) |
| 12 | + - [Story 2 - Blocking the egress for not allowed insecure ports](#story-2---blocking-the-egress-for-not-allowed-insecure-ports) |
| 13 | + - [Story 3 - Containerized Passive FTP Server](#story-3---containerized-passive-ftp-server) |
| 14 | + - [Notes/Constraints/Caveats](#notesconstraintscaveats) |
| 15 | + - [Risks and Mitigations](#risks-and-mitigations) |
| 16 | +- [Design Details](#design-details) |
| 17 | + - [Validations](#validations) |
| 18 | + - [Test Plan](#test-plan) |
| 19 | + - [Graduation Criteria](#graduation-criteria) |
| 20 | + - [Alpha](#alpha) |
| 21 | + - [Beta](#beta) |
| 22 | + - [GA Graduation](#ga-graduation) |
| 23 | + - [Upgrade / Downgrade Strategy](#upgrade--downgrade-strategy) |
| 24 | +- [Production Readiness Review Questionnaire](#production-readiness-review-questionnaire) |
| 25 | + - [Feature Enablement and Rollback](#feature-enablement-and-rollback) |
| 26 | + - [Monitoring Requirements](#monitoring-requirements) |
| 27 | + - [Dependencies](#dependencies) |
| 28 | + - [Scalability](#scalability) |
| 29 | + - [Troubleshooting](#troubleshooting) |
| 30 | +- [Implementation History](#implementation-history) |
| 31 | +- [Drawbacks](#drawbacks) |
| 32 | +- [Alternatives](#alternatives) |
| 33 | +<!-- /toc --> |
| 34 | + |
| 35 | +## Release Signoff Checklist |
| 36 | + |
| 37 | +Items marked with (R) are required *prior to targeting to a milestone / release*. |
| 38 | + |
| 39 | +- [ ] (R) Enhancement issue in release milestone, which links to KEP dir in [kubernetes/enhancements] (not the initial KEP PR) |
| 40 | +- [ ] (R) KEP approvers have approved the KEP status as `implementable` |
| 41 | +- [ ] (R) Design details are appropriately documented |
| 42 | +- [ ] (R) Test plan is in place, giving consideration to SIG Architecture and SIG Testing input |
| 43 | +- [ ] (R) Graduation criteria is in place |
| 44 | +- [ ] (R) Production readiness review completed |
| 45 | +- [ ] Production readiness review approved |
| 46 | +- [ ] "Implementation History" section is up-to-date for milestone |
| 47 | +- [ ] User-facing documentation has been created in [kubernetes/website], for publication to [kubernetes.io] |
| 48 | +- [ ] Supporting documentation—e.g., additional design documents, links to mailing list discussions/SIG meetings, relevant PRs/issues, release notes |
| 49 | + |
| 50 | + |
| 51 | +## Summary |
| 52 | + |
| 53 | +Today the `ports` field in ingress and egress network policies is an array |
| 54 | +that needs a declaration of each single port to be contemplated. This KEP |
| 55 | +proposes to add a new field that allows a declaration of a port range, |
| 56 | +simplifying the creation of rules with multiple ports. |
| 57 | + |
| 58 | +## Motivation |
| 59 | + |
| 60 | +NetworkPolicy object is a complex object, that allows a developer to specify |
| 61 | +what's the traffic behavior expected of the application and allow/deny |
| 62 | +undesired traffic. |
| 63 | + |
| 64 | +There are a number of user issues like [kubernetes #67526](https://github.com/kubernetes/kubernetes/issues/67526) |
| 65 | +and [kubernetes #93111](https://github.com/kubernetes/kubernetes/issues/93111) |
| 66 | +where users expose the need to create a policy that allow a range of ports but some |
| 67 | +specific port, or also cases that a user wants to create a policy that allows |
| 68 | +the egress to other cluster to the NodePort range (eg 32000-32768) and in this case, |
| 69 | +the rule should be created specifying each port separately, as: |
| 70 | + |
| 71 | +``` |
| 72 | +spec: |
| 73 | + egress: |
| 74 | + - ports: |
| 75 | + - protocol: TCP |
| 76 | + port: 32000 |
| 77 | + - protocol: TCP |
| 78 | + port: 32001 |
| 79 | + - protocol: TCP |
| 80 | + port: 32002 |
| 81 | + - protocol: TCP |
| 82 | + port: 32003 |
| 83 | +[...] |
| 84 | + - protocol: TCP |
| 85 | + port: 32768 |
| 86 | +``` |
| 87 | + |
| 88 | +So for the user: |
| 89 | +* To allow a range of ports, each of them must be declared as an item from |
| 90 | +`ports` array |
| 91 | +* To make an exception needs a declaration of all ports but the exception |
| 92 | + |
| 93 | +Adding a new `endPort` field inside the `ports` will allow a simpler |
| 94 | +creation of NetworkPolicy to the user. |
| 95 | + |
| 96 | +### Goals |
| 97 | + |
| 98 | +Add an endPort field in `NetworkPolicyPort` |
| 99 | + |
| 100 | +### Non-Goals |
| 101 | + |
| 102 | +* Support specific `Exception` field. |
| 103 | +* Support `endPort` when the starting `port` is a named port. |
| 104 | + |
| 105 | +## Proposal |
| 106 | + |
| 107 | +In NetworkPolicy specification, inside `NetworkPolicyPort` specify a new |
| 108 | +`endPort` field composed of a numbered port that defines if this is a range |
| 109 | +and when it ends. |
| 110 | + |
| 111 | +### User Stories |
| 112 | + |
| 113 | +#### Story 1 - Opening communication to NodePorts of other cluster |
| 114 | + |
| 115 | +I have an application that communicates with NodePorts of a different cluster |
| 116 | +and I want to allow the egress of the traffic only the NodePort range |
| 117 | +(eg. 30000-32767) as I don't know which port is going to be allocated on the |
| 118 | +other side, but don't want to create a rule for each of them. |
| 119 | + |
| 120 | +#### Story 2 - Blocking the egress for not allowed insecure ports |
| 121 | +As a developer, I need to create an application that scrapes informations from |
| 122 | +multiple sources, being those sources databases running in random ports, web |
| 123 | +applications and other sources. But the security policy of my company asks me |
| 124 | +to block communication with well known ports, like 111 and 445, so I need to create |
| 125 | +a network policy that allows me to communicate with any port except those two and so |
| 126 | +I can be compliant with the company's policy. |
| 127 | + |
| 128 | +#### Story 3 - Containerized Passive FTP Server |
| 129 | +As a Kubernetes User, I've received a demand from my boss to run our FTP server in an |
| 130 | +existing Kubernetes cluster, to support some of my legacy applications. |
| 131 | +This FTP Server must be acessible from inside the cluster and outside the cluster, |
| 132 | +but I still need to keep the basic security policies from my company, that demands |
| 133 | +the existence of a default deny rule for all workloads and allowing only specific ports. |
| 134 | + |
| 135 | +Because this FTP Server runs in PASV mode, I need to open the Network Policy to ports 21 |
| 136 | +and also to the range 49152-65535 without allowing any other ports. |
| 137 | + |
| 138 | + |
| 139 | +### Notes/Constraints/Caveats |
| 140 | + |
| 141 | +* The technology used by the CNI provider might not support port range in a |
| 142 | +trivial way as described in [#drawbacks] |
| 143 | + |
| 144 | +### Risks and Mitigations |
| 145 | + |
| 146 | +CNIs will need to support the new field in their controllers. For this case |
| 147 | +we'll try to make broader communication with the main CNIs so they can be aware |
| 148 | +of the new field. |
| 149 | + |
| 150 | +## Design Details |
| 151 | + |
| 152 | +API changes to NetworkPolicy: |
| 153 | +* Add a new field called `EndPort` inside `NetworkPolicyPort` as the following: |
| 154 | +``` |
| 155 | +// NetworkPolicyPort describes a port to allow traffic on |
| 156 | +type NetworkPolicyPort struct { |
| 157 | + // The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this |
| 158 | + // field defaults to TCP. |
| 159 | + // +optional |
| 160 | + Protocol *v1.Protocol `json:"protocol,omitempty" protobuf:"bytes,1,opt,name=protocol,casttype=k8s.io/api/core/v1.Protocol"` |
| 161 | +
|
| 162 | + // The port on the given protocol. This can either be a numerical or named |
| 163 | + // port on a pod. If this field is not provided, this matches all port names and |
| 164 | + // numbers, whether an endPort is defined or not. |
| 165 | + // +optional |
| 166 | + Port *intstr.IntOrString `json:"port,omitempty" protobuf:"bytes,2,opt,name=port"` |
| 167 | +
|
| 168 | + // EndPort defines the last port included in the port range. |
| 169 | + // Example: |
| 170 | + // endPort: 12345 |
| 171 | + // +optional |
| 172 | + EndPort int32 `json:"port,omitempty" protobuf:"bytes,2,opt,name=endPort"` |
| 173 | +} |
| 174 | +``` |
| 175 | + |
| 176 | +### Validations |
| 177 | +The `NetworkPolicyPort` will need to be validated, with the following scenarios: |
| 178 | +* If an `EndPort` is specified a `Port` must also be specified |
| 179 | +* If `Port` is a string (named port) `EndPort` cannot be specified |
| 180 | +* `EndPort` must be equal or bigger than `Port` |
| 181 | + |
| 182 | +### Test Plan |
| 183 | + |
| 184 | +Unit tests: |
| 185 | +* test API validation logic |
| 186 | +* test API strategy to ensure disabled fields |
| 187 | + |
| 188 | +E2E tests: |
| 189 | +* Add e2e tests exercising only the API operations for port ranges. Data-path |
| 190 | +validation should be done by CNIs. |
| 191 | + |
| 192 | + |
| 193 | +### Graduation Criteria |
| 194 | + |
| 195 | +#### Alpha |
| 196 | +- Add a feature gated new field to NetworkPolicy |
| 197 | +- Communicate CNI providers about the new field |
| 198 | +- Add validation tests in API |
| 199 | + |
| 200 | +#### Beta |
| 201 | +- `EndPort` has been supported for at least 1 minor release |
| 202 | +- Four commonly used NetworkPolicy (or CNI providers) implement the new field, |
| 203 | +with generally positive feedback on its usage. |
| 204 | +- Feature Gate is enabled by Default. |
| 205 | + |
| 206 | +#### GA Graduation |
| 207 | + |
| 208 | +- At least **four** NetworkPolicy providers (or CNI providers) support the `EndPort` field |
| 209 | +- `EndPort` has been enabled by default for at least 1 minor release |
| 210 | + |
| 211 | +### Upgrade / Downgrade Strategy |
| 212 | + |
| 213 | +If upgraded no impact should happen as this is a new field. |
| 214 | + |
| 215 | +If downgraded the CNI wont be able to look into the new field, as this does not |
| 216 | +exists and network policies using this field will stop working correctly and |
| 217 | +start working incorrectly. This is a fail-closed failure, so it is acceptable. |
| 218 | + |
| 219 | +## Production Readiness Review Questionnaire |
| 220 | + |
| 221 | +### Feature Enablement and Rollback |
| 222 | + |
| 223 | +_This section must be completed when targeting alpha to a release._ |
| 224 | + |
| 225 | +* **How can this feature be enabled / disabled in a live cluster?** |
| 226 | + - [X] Feature gate (also fill in values in `kep.yaml`) |
| 227 | + - Feature gate name: NetworkPolicyEndPort |
| 228 | + - Components depending on the feature gate: Kubernetes API Server |
| 229 | + |
| 230 | +* **Does enabling the feature change any default behavior?** |
| 231 | + No |
| 232 | + |
| 233 | +* **Can the feature be disabled once it has been enabled (i.e. can we roll back |
| 234 | + the enablement)?** |
| 235 | + Yes, but CNIs relying on the new field wont recognize it anymore |
| 236 | + |
| 237 | +* **What happens if we reenable the feature if it was previously rolled back?** |
| 238 | + Nothing. Just need to check if the data is persisted in `etcd` after the |
| 239 | + feature is disabled and reenabled or if the data is missed |
| 240 | + |
| 241 | +* **Are there any tests for feature enablement/disablement?** |
| 242 | + |
| 243 | + TBD |
| 244 | + |
| 245 | +### Monitoring Requirements |
| 246 | + |
| 247 | +_This section must be completed when targeting beta graduation to a release._ |
| 248 | + |
| 249 | +* **How can an operator determine if the feature is in use by workloads?** |
| 250 | + |
| 251 | + Operators can determine if NetworkPolicies are making use of EndPort creating |
| 252 | + an object specifying the range and validating if the traffic is allowed within |
| 253 | + the specified range |
| 254 | + |
| 255 | +* **What are the SLIs (Service Level Indicators) an operator can use to determine |
| 256 | +the health of the service?** |
| 257 | + Operators would need to monitor the traffic of the Pods to verify if a |
| 258 | + specified port range is applied and allowed in their workloads |
| 259 | + |
| 260 | +* **What are the reasonable SLOs (Service Level Objectives) for the above SLIs?** |
| 261 | + N/A |
| 262 | + |
| 263 | +* **Are there any missing metrics that would be useful to have to improve observability |
| 264 | +of this feature?** |
| 265 | + N/A |
| 266 | + |
| 267 | + |
| 268 | +### Dependencies |
| 269 | + |
| 270 | +* **Does this feature depend on any specific services running in the cluster?** |
| 271 | + No |
| 272 | + |
| 273 | + |
| 274 | +### Scalability |
| 275 | + |
| 276 | +_For alpha, this section is encouraged: reviewers should consider these questions |
| 277 | +and attempt to answer them._ |
| 278 | + |
| 279 | +_For beta, this section is required: reviewers must answer these questions._ |
| 280 | + |
| 281 | +_For GA, this section is required: approvers should be able to confirm the |
| 282 | +previous answers based on experience in the field._ |
| 283 | + |
| 284 | +* **Will enabling / using this feature result in any new API calls?** |
| 285 | + TBD |
| 286 | + |
| 287 | +* **Will enabling / using this feature result in introducing new API types?** |
| 288 | + No, unless the new `EndPort` is considered a new API type |
| 289 | + |
| 290 | +* **Will enabling / using this feature result in any new calls to the cloud |
| 291 | +provider?** |
| 292 | + No |
| 293 | + |
| 294 | +* **Will enabling / using this feature result in increasing size or count of |
| 295 | +the existing API objects?** |
| 296 | + |
| 297 | + - API type(s): NetworkPolicyPorts |
| 298 | + - Estimated increase in size: 2 bytes for each new `EndPort` specified |
| 299 | + - Estimated amount of new objects: N/A |
| 300 | + |
| 301 | +* **Will enabling / using this feature result in increasing time taken by any |
| 302 | +operations covered by [existing SLIs/SLOs]?** |
| 303 | + N/A |
| 304 | + |
| 305 | +* **Will enabling / using this feature result in non-negligible increase of |
| 306 | +resource usage (CPU, RAM, disk, IO, ...) in any components?** |
| 307 | + It might get some increase of resource usage by the CNI while parsing the |
| 308 | + new field. |
| 309 | + |
| 310 | +### Troubleshooting |
| 311 | + |
| 312 | +_This section must be completed when targeting beta graduation to a release._ |
| 313 | + |
| 314 | +* **How does this feature react if the API server and/or etcd is unavailable?** |
| 315 | + As this feature is mainly used by CNI providers, the reaction with API server |
| 316 | + and/or etcd being unavailable will be the same as before. |
| 317 | + |
| 318 | +* **What are other known failure modes?** |
| 319 | + N/A |
| 320 | + |
| 321 | +* **What steps should be taken if SLOs are not being met to determine the problem?** |
| 322 | + N/A |
| 323 | + |
| 324 | +## Implementation History |
| 325 | +- 2020-10-08 Initial [KEP PR](https://github.com/kubernetes/enhancements/pull/2079) |
| 326 | + |
| 327 | +## Drawbacks |
| 328 | + |
| 329 | +* The technology used by the CNI provider might not support port range in a |
| 330 | +trivial way. As an example, OpenFlow did not supported to specify port range |
| 331 | +for a while as commented in [kubernetes #67526](https://github.com/kubernetes/kubernetes/issues/67526#issuecomment-415170435). |
| 332 | +While this has changed in Open vSwitch v1.6, this still might be a caveat |
| 333 | +for other CNIs, like eBPF based CNIs will need to populate their maps in a |
| 334 | +different way. |
| 335 | + |
| 336 | +For this cases, CNIs will have to iteract through the Port Range and |
| 337 | +populate their packet filtering tables with each port. |
| 338 | + |
| 339 | +## Alternatives |
| 340 | + |
| 341 | +During the development of this KEP there was an alternative implementation |
| 342 | +of the `NetworkPolicyPortRange` field inside the `NetworkPolicyPort` as the following: |
| 343 | + |
| 344 | +``` |
| 345 | +// NetworkPolicyPort describes a port or a range of ports to allow traffic on |
| 346 | +type NetworkPolicyPort struct { |
| 347 | + // The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this |
| 348 | + // field defaults to TCP. |
| 349 | + // +optional |
| 350 | + Protocol *api.Protocol |
| 351 | + |
| 352 | + // The port on the given protocol. This can either be a numerical or named |
| 353 | + // port on a pod. If this field is not provided but a Range is |
| 354 | + // provided, this field is ignored. Otherwise this matches all port names and |
| 355 | + // numbers. |
| 356 | + // +optional |
| 357 | + Port *intstr.IntOrString |
| 358 | +
|
| 359 | + // A range of ports on a given protocol and the exceptions. If this field |
| 360 | + // is not provided, this doesn't matches anything |
| 361 | + // +optional |
| 362 | + Range *NetworkPolicyPortRange |
| 363 | +} |
| 364 | +``` |
| 365 | + |
| 366 | +But the main design suggested in this Kep seems more clear, so this alternative |
| 367 | +has been discarded. |
| 368 | + |
| 369 | +Also it has been proposed that the implementation contains an `Except` array and a new |
| 370 | +struct to be used in Ingress/Egress rules, but because it would bring much more complexity |
| 371 | +than desired the proposal has been dropped right now: |
| 372 | + |
| 373 | +``` |
| 374 | +// NetworkPolicyPortRange describes the range of ports to be used in a |
| 375 | +// NetworkPolicyPort struct |
| 376 | +type NetworkPolicyPortRange struct { |
| 377 | + // From defines the start of the port range |
| 378 | + From uint16 |
| 379 | + |
| 380 | + // To defines the end of the port range, being the end included within the |
| 381 | + // range |
| 382 | + To uint16 |
| 383 | + // Except defines all the exceptions in the port range |
| 384 | + +optional |
| 385 | + Except []uint16 |
| 386 | +``` |
0 commit comments