Skip to content

Commit f9442d3

Browse files
committed
address comments
1 parent 9485874 commit f9442d3

File tree

3 files changed

+80
-25
lines changed

3 files changed

+80
-25
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
kep-number: 4020
2+
alpha:
3+
approver: "@deads2k"

keps/sig-api-machinery/3903-unknown-version-interoperability-proxy/README.md renamed to keps/sig-api-machinery/4020-unknown-version-interoperability-proxy/README.md

Lines changed: 77 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ If none of those approvers are still appropriate, then changes to that list
5858
should be approved by the remaining approvers and/or the owning SIG (or
5959
SIG Architecture for cross-cutting KEPs).
6060
-->
61-
# KEP-3903: Unknown Version Interoperability Proxy
61+
# KEP-4020: Unknown Version Interoperability Proxy
6262

6363
<!--
6464
A table of contents is helpful for quickly jumping to sections of a KEP and for
@@ -157,8 +157,8 @@ Items marked with (R) are required *prior to targeting to a milestone / release*
157157
## Summary
158158

159159
When a cluster has multiple apiservers at mixed versions (such as during an
160-
upgrade or downgrade), not every apiserver can serve every resource at every
161-
version.
160+
upgrade/downgrade or when runtime-config changes and a rollout happens), not
161+
every apiserver can serve every resource at every version.
162162

163163
To fix this, we will add a filter to the handler chain in the aggregator which
164164
proxies clients to an apiserver that is capable of handling their request.
@@ -291,7 +291,7 @@ To prevent server-side request forgeries we will not give control over informati
291291
### Aggregation Layer
292292

293293
1. A new filter will be added to the [handler chain] of the aggregation layer. This filter will maintain an internal map with the key being the group-version-resource and the value being a list of server IDs of apiservers that are capable of serving that group-version-resource
294-
1. This internal map is populated using an informer for StorageVersion objects. An event handler will be added for this informer that will get the apiserver ID of the requested group-version-resource and update the internal map accordingly
294+
1. This internal map is populated using an informer for StorageVersion objects. An event handler will be added for this informer that will get the apiserver ID of the requested group-version-resource and update the internal map accordingly
295295

296296
2. This filter will pass on the request to the next handler in the local aggregator chain, if:
297297
1. It is a non resource request
@@ -314,17 +314,29 @@ StorageVersion API currently tells us whether a particular StorageVersion can be
314314

315315
#### Identifying destination apiserver's network location
316316

317-
* TODO: We need to find a place to store and retrieve the destination apiserver's host and port information given the server's ID.
318-
We do not want to store this information in
317+
We will use the already existing [masterlease reconciler](https://github.com/kubernetes/kubernetes/blob/master/pkg/controlplane/reconcilers/lease.go) to store/retrieve the IPs and ports for kube-apiservers. Major reasons to use this are
319318

320-
* StorageVersion : because we do not want to expose the network identity of the apiservers in this API that can be listed in multiple places where it may be unnecessary/redundant to do so
321-
* Endpoint reconciler lease : because the IP present here could be that of a load balancer for the apiservers, but we need to know the definite address of the identified destination apiserver
319+
1. masterlease reconciler already stores kube-apiserver IPs currently
320+
2. this information is not exposed to users in an API that can be used maliciously
321+
3. existing code to handle lifecycle of the masterleases is convenient
322+
323+
How the masterlease reconciler will be used is as follows:
324+
325+
1. We will use the already existing IP in Endpoints.Subsets.Addresses of the masterlease by default
326+
327+
2. For users with network configurations that would not allow Endpoints.Subsets.Addresses to be reachable from a kube-apiserver, we will introduce a new --advertise-peer-ip flag to kube-apiserver. We will store its value as an annotation on the masterlease and use this to route the request to the right destination server
328+
329+
3. We will also expose the IP and port information of the kube-apiservers as annotations in APIserver identity lease object for visibility/debugging purposes
330+
331+
4. We will also use an egress dialer for network connections made to peer kube-apiservers. For this, will create a new type for the network context to be used for peer kube-apiserver connections ([xref](https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/apis/apiserver/types.go#L55-L71))
322332

323333
#### Proxy transport between apiservers and authn
324334

325335
For the mTLS between source and destination apiservers, we will do the following
326336

327-
1. For server authentication by the client (source apiserver) : the client needs to validate the server certs (presented by the destination apiserver), for which it needs to know the CA bundle of the authority that signed those certs. We will introduce a new flag --peer-ca-file that must be passed to the kube-apiserver to verify the other kube-apiserver's server certs
337+
1. For server authentication by the client (source apiserver) : the client needs to validate the server certs (presented by the destination apiserver), for which it will
338+
1. look at the CA bundle of the authority that signed those certs. We will introduce a new flag --peer-ca-file that must be passed to the kube-apiserver to verify the other kube-apiserver's server certs
339+
2. look at the ServerName `kubernetes.default.svc` for SNI to verify server certs against
328340

329341
2. For client authentication by the server (destination apiserver) : destination apiserver will check the source apiserver certs to determine that the proxy request is from an authenticated client. The destination apiserver will use requestheader authentication (and NOT client cert authentication) for this using the kube-aggregator proxy client cert/key and the --requestheader-client-ca-file passed to the apiserver upon bootstrap
330342

@@ -344,7 +356,7 @@ when drafting this test plan.
344356
[testing-guidelines]: https://git.k8s.io/community/contributors/devel/sig-testing/testing.md
345357
-->
346358

347-
[ ] I/we understand the owners of the involved components may require updates to
359+
[X] I/we understand the owners of the involved components may require updates to
348360
existing tests to make this code solid enough prior to committing the changes necessary
349361
to implement this enhancement.
350362

@@ -388,7 +400,11 @@ For Beta and GA, add links to added tests together with links to k8s-triage for
388400
https://storage.googleapis.com/k8s-triage/index.html
389401
-->
390402

391-
- <test>: <link to test coverage>
403+
In the first alpha phase, the integration tests are expected to be added for:
404+
405+
- The behavior with feature gate turned on/off
406+
- Validation where an apiserver tries to serve a request that has already been proxied once
407+
- Validation where an apiserver tries to call a peer but actually calls itself (to simulate a networking configuration where this happens on accident), and the test fails
392408

393409
##### e2e tests
394410

@@ -402,14 +418,15 @@ https://storage.googleapis.com/k8s-triage/index.html
402418
We expect no non-infra related flakes in the last month as a GA graduation criteria.
403419
-->
404420

405-
- <test>: <link to test coverage>
421+
We will test the feature mostly in integration test and unit test. We may add e2e test for spot check of the feature presence.
406422

407423
### Graduation Criteria
408424

409425
#### Alpha
410426

411427
- Proxying implemented (behind feature flag)
412428
- mTLS or other secure system used for proxying
429+
- Ensure proper tests are in place.
413430

414431
#### Beta
415432

@@ -495,6 +512,8 @@ enhancement:
495512
cluster required to make on upgrade, in order to make use of the enhancement?
496513
-->
497514

515+
In alpha, no changes are required to maintain previous behavior. And the feature gate can be turned on to make use of the enhancement.
516+
498517
### Version Skew Strategy
499518

500519
<!--
@@ -552,9 +571,9 @@ well as the [existing list] of feature gates.
552571
[existing list]: https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/
553572
-->
554573

555-
- [ ] Feature gate (also fill in values in `kep.yaml`)
556-
- Feature gate name:
557-
- Components depending on the feature gate:
574+
- [x] Feature gate (also fill in values in `kep.yaml`)
575+
- Feature gate name: UnknownVersionInteroperabilityProxy
576+
- Components depending on the feature gate: kube-apiserver
558577
- [ ] Other
559578
- Describe the mechanism:
560579
- Will enabling / disabling the feature require downtime of the control
@@ -569,6 +588,8 @@ Any change of default behavior may be surprising to users or break existing
569588
automations, so be extremely careful here.
570589
-->
571590

591+
Yes, requests for built-in resources at the time when a cluster is at mixed versions will be served with a default 503 error instead of a 404 error, if the request is unable to be served.
592+
572593
###### Can the feature be disabled once it has been enabled (i.e. can we roll back the enablement)?
573594

574595
<!--
@@ -582,8 +603,12 @@ feature.
582603
NOTE: Also set `disable-supported` to `true` or `false` in `kep.yaml`.
583604
-->
584605

606+
Yes, disabling the feature will result in requests for built-in resources in a cluster at mixed versions to be served with a default 404 error in the case when the request is unable to be served locally.
607+
585608
###### What happens if we reenable the feature if it was previously rolled back?
586609

610+
The request for built-in resources will be proxied to the apiserver capable of serving it, or else be served with 503 error.
611+
587612
###### Are there any tests for feature enablement/disablement?
588613

589614
<!--
@@ -599,6 +624,8 @@ You can take a look at one potential example of such test in:
599624
https://github.com/kubernetes/kubernetes/pull/97058/files#diff-7826f7adbc1996a05ab52e3f5f02429e94b68ce6bce0dc534d1be636154fded3R246-R282
600625
-->
601626

627+
Unit test and integration test will be introduced in alpha implementation.
628+
602629
### Rollout, Upgrade and Rollback Planning
603630

604631
<!--
@@ -617,13 +644,17 @@ rollout. Similarly, consider large clusters and how enablement/disablement
617644
will rollout across nodes.
618645
-->
619646

647+
The proxy to remote apiserver can fail if there are network restrictions in place that do not allow an apiserver to talk to a remote apiserver. In this case, the request will fail with 503 error.
648+
620649
###### What specific metrics should inform a rollback?
621650

622651
<!--
623652
What signals should users be paying attention to when the feature is young
624653
that might indicate a serious problem?
625654
-->
626655

656+
- apiserver_request_total metric that will tell us if there's a spike in the number of errors seen meaning the feature is not working as expected
657+
627658
###### Were upgrade and rollback tested? Was the upgrade->downgrade->upgrade path tested?
628659

629660
<!--
@@ -632,12 +663,16 @@ Longer term, we may want to require automated upgrade/rollback tests, but we
632663
are missing a bunch of machinery and tooling and can't do that now.
633664
-->
634665

666+
Upgrade and rollback will be tested before the feature goes to Beta.
667+
635668
###### Is the rollout accompanied by any deprecations and/or removals of features, APIs, fields of API types, flags, etc.?
636669

637670
<!--
638671
Even if applying deprecation policies, they may still surprise some users.
639672
-->
640673

674+
No.
675+
641676
### Monitoring Requirements
642677

643678
<!--
@@ -655,6 +690,9 @@ checking if there are objects with field X set) may be a last resort. Avoid
655690
logs or events for this purpose.
656691
-->
657692

693+
The following metrics could be used to see if the feature is in use:
694+
- kubernetes_uvip_count
695+
658696
###### How can someone using this feature know that it is working for their instance?
659697

660698
<!--
@@ -666,13 +704,7 @@ and operation of this feature.
666704
Recall that end users cannot usually observe component logs or access metrics.
667705
-->
668706

669-
- [ ] Events
670-
- Event Reason:
671-
- [ ] API .status
672-
- Condition name:
673-
- Other field:
674-
- [ ] Other (treat as last resort)
675-
- Details:
707+
- Metrics like kubernetes_uvip_count can be used to check how many requests were proxied to remote apiserver
676708

677709
###### What are the reasonable SLOs (Service Level Objectives) for the enhancement?
678710

@@ -691,7 +723,6 @@ These goals will help you determine what you need to measure (SLIs) in the next
691723
question.
692724
-->
693725

694-
This feature depends on the `StorageVersion` feature, that generates objects with a `storageVersion.status.serverStorageVersions[*].apiServerID` field which is used to find the destination apiserver's network location.
695726

696727
###### What are the SLIs (Service Level Indicators) an operator can use to determine the health of the service?
697728

@@ -710,6 +741,8 @@ Describe the metrics themselves and the reasons why they weren't added (e.g., co
710741
implementation difficulties, etc.).
711742
-->
712743

744+
No. We are open to input.
745+
713746
### Dependencies
714747

715748
<!--
@@ -718,7 +751,10 @@ This section must be completed when targeting beta to a release.
718751

719752
###### Does this feature depend on any specific services running in the cluster?
720753

721-
No, but it does depend on the `StorageVersion` feature in kube-apiserver.
754+
No, but it does depend on
755+
756+
- the `StorageVersion` feature that generates objects with a `storageVersion.status.serverStorageVersions[*].apiServerID` field which is used to find the remote apiserver's network location.
757+
- `APIServerIdentity` feature in kube-apiserver that creates a lease object for APIServerIdentity which we will use to store the network location of the remote apiserver for visibility/debugging
722758

723759
<!--
724760
Think about both cluster-level services (e.g. metrics-server) as well
@@ -762,6 +798,8 @@ Focusing mostly on:
762798
heartbeats, leader election, etc.)
763799
-->
764800

801+
No.
802+
765803
###### Will enabling / using this feature result in introducing new API types?
766804

767805
<!--
@@ -771,6 +809,8 @@ Describe them, providing:
771809
- Supported number of objects per namespace (for namespace-scoped objects)
772810
-->
773811

812+
No.
813+
774814
###### Will enabling / using this feature result in any new calls to the cloud provider?
775815

776816
<!--
@@ -779,6 +819,8 @@ Describe them, providing:
779819
- Estimated increase:
780820
-->
781821

822+
No.
823+
782824
###### Will enabling / using this feature result in increasing size or count of the existing API objects?
783825

784826
<!--
@@ -788,6 +830,8 @@ Describe them, providing:
788830
- Estimated amount of new objects: (e.g., new Object X for every existing Pod)
789831
-->
790832

833+
No.
834+
791835
###### Will enabling / using this feature result in increasing time taken by any operations covered by existing SLIs/SLOs?
792836

793837
<!--
@@ -811,6 +855,8 @@ This through this both in small and large cases, again with respect to the
811855
[supported limits]: https://git.k8s.io/community//sig-scalability/configs-and-limits/thresholds.md
812856
-->
813857

858+
Requests will consume egress bandwidth for 2 apiservers when proxied. We can put a limit on this value if needed.
859+
814860
###### Can enabling / using this feature result in resource exhaustion of some node resources (PIDs, sockets, inodes, etc.)?
815861

816862
<!--
@@ -823,6 +869,8 @@ Are there any tests that were run/should be run to understand performance charac
823869
and validate the declared limits?
824870
-->
825871

872+
No.
873+
826874
### Troubleshooting
827875

828876
<!--
@@ -838,6 +886,8 @@ details). For now, we leave it here.
838886

839887
###### How does this feature react if the API server and/or etcd is unavailable?
840888

889+
If the API server/etcd is unavailable the request will fail with 503 error.
890+
841891
###### What are other known failure modes?
842892

843893
<!--
@@ -855,6 +905,9 @@ For each of them, fill in the following information by copying the below templat
855905

856906
###### What steps should be taken if SLOs are not being met to determine the problem?
857907

908+
- The feature can be disabled by setting the feature-gate to false if the performance impact of it is not tolerable.
909+
- The peer-to-peer connection between API servers should be checked to ensure that the remote API servers are reachable from a given API server
910+
858911
## Implementation History
859912

860913
<!--

keps/sig-api-machinery/3903-unknown-version-interoperability-proxy/kep.yaml renamed to keps/sig-api-machinery/4020-unknown-version-interoperability-proxy/kep.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ status: provisional
99
creation-date: 2023-05-17
1010
reviewers:
1111
- "@deads2k"
12-
- "@liggitt"
1312
- "@jpbetz"
1413

1514
approvers:

0 commit comments

Comments
 (0)