Support passing custom headers to AKS Managed Cluster and Node Pool create/update requests#2020
Conversation
|
|
|
Thanks for your pull request. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please follow instructions at https://git.k8s.io/community/CLA.md#the-contributor-license-agreement to sign the CLA. It may take a couple minutes for the CLA signature to be fully registered; after that, please reply here with a new comment and we'll verify. Thanks.
DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
|
Welcome @michalno1! |
|
Hi @michalno1. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
|
|
|
/area managedclusters |
|
/ok-to-test |
|
looks like the tests hit the quota issue /retest |
|
/test pull-cluster-api-provider-azure-e2e-exp |
| // Whatever follows the prefix will be passed as a header to cluster/node pool creation/update requests. | ||
| // E.g. add `"custom-headers.azure.dev/UseGPUDedicatedVHD": "true"` annotation to AzureManagedMachinePool CR | ||
| // to enable creating GPU nodes by the node pool. | ||
| CustomHeaderPrefix = "custom-headers.azure.dev/" |
There was a problem hiding this comment.
nit:
Do annotation/labels follow a specific pattern? In case of annotations I have seen cluster.x-k8s.io in CAPI. May be worth discussing as his will help us being consistent while we may introduce more annotations in near future. WDYT?
There was a problem hiding this comment.
Definitely. Do you suggest opening a thread in Disussions or should we do it here? Do you have any suggestions? Maybe we can use cluster-azure.x-k8s.io/ for all project annotations and cluster-azure.x-k8s.io/custom-header-{HEADER_NAME} specifically for this feature?
There was a problem hiding this comment.
cluster-azure.x-k8s.io -- This one sounds good to me. Copying @CecileRobertMichon @shysank to provide more input.
There was a problem hiding this comment.
how about infrastructure.cluster.x-k8s.io? cluster-azure.x-k8s.io is the API Group for Cluster API. CAPZ resources use infrastructure.cluster.x-k8s.io as its Group.
There was a problem hiding this comment.
@CecileRobertMichon makes sense, thanks. I've changed it.
| func (s *ManagedControlPlaneScope) ManagedClusterAnnotations() map[string]string { | ||
| return s.ControlPlane.Annotations | ||
| } | ||
|
|
There was a problem hiding this comment.
nit:
Do we need this function? Can't we simply use s.ControlPlane.Annotations at places wherever required?
There was a problem hiding this comment.
I see why it is so. You basically implemented it as part of ManagedMachinePoolScope interface.
There was a problem hiding this comment.
This particular method implements ManagedClusterScope rather than ManagedMachinePoolScope. This is done in the same spirit as ManagedControlPlaneScope.ManagedClusterSpec().
| func (s *ManagedControlPlaneScope) AgentPoolAnnotations() map[string]string { | ||
| return s.InfraMachinePool.Annotations | ||
| } | ||
|
|
| var result = map[string]string{} | ||
| for key, value := range s.scope.AgentPoolAnnotations() { | ||
| if strings.HasPrefix(key, azure.CustomHeaderPrefix) { | ||
| result[strings.TrimPrefix(key, azure.CustomHeaderPrefix)] = value |
There was a problem hiding this comment.
Just a thought:
What if the value is empty? We can have probably move this function to another that takes input as annotations and prefix and returns the filtered values. This could help reuse.
And here we can probably just sanitise the values if required.
There was a problem hiding this comment.
Refactored for reuse. What issue do you see with an empty value? We'll just pass a header with empty value if that is what someone intends.
There was a problem hiding this comment.
Sure. My only point was -- does the azure api tolerates the empty value. I do not know. Just thought to bring up, in case. If yes, I do not think we need to do anything here.
There was a problem hiding this comment.
Just checked- API does accept empty values.
| } | ||
| } | ||
| return result | ||
| } |
There was a problem hiding this comment.
shysank
left a comment
There was a problem hiding this comment.
Thanks for the pr @michalno1! The changes in general looks good. Just a couple of clarifications regarding cluster/nodepool update. wdyt about adding some documentation for this feature? I'm fine with doing it in a followup pr if it's easier.
| if diff != "" { | ||
| log.V(2).Info(fmt.Sprintf("Update required (+new -old):\n%s", diff)) | ||
| err = s.Client.CreateOrUpdate(ctx, agentPoolSpec.ResourceGroup, agentPoolSpec.Cluster, agentPoolSpec.Name, profile) | ||
| err = s.Client.CreateOrUpdate(ctx, agentPoolSpec.ResourceGroup, agentPoolSpec.Cluster, agentPoolSpec.Name, |
There was a problem hiding this comment.
can we enable/disable features after node pool creation?
There was a problem hiding this comment.
it depends on the feature, the headers are usually used with experimental features in AKS so lets say in case of GPU nodepool, we cannot. We cannot convert an existing agentpool to support GPU, its just a creation operation.
I'm ok with providing a way for users to use these experimental features and at most add some warning documentation about untested behaviors.
There was a problem hiding this comment.
I think the most sane way to move forward is to support "enable feature via custom header" on create only. There may be some aks nodepool update operations that are initiated via an "empty" PUT w/ HTTP header data, but that's kind of weird from a UX perspective and I would not expect to rely upon that.
As @zmalik suggests, we should consider feature configuration delivered via HTTP headers as an interface for AKS to rapidly deliver experimental features, and then eventually they may graduate to fully supported features (after which point capz would have to implement them in their final form).
Does that make sense? Is the PR as-is implemented to forbid updates of custom headers after cluster/nodepool creation?
There was a problem hiding this comment.
The PR right now allows for updates, although not intentionally. If there is a non zero diff along with annotations changes, the new headers will be set. I'd rather we be more explicit by adding a validation webhook to make it immutable. wdyt?
| if diff != "" { | ||
| klog.V(2).Infof("Update required (+new -old):\n%s", diff) | ||
| managedCluster, err = s.Client.CreateOrUpdate(ctx, managedClusterSpec.ResourceGroupName, managedClusterSpec.Name, managedCluster) | ||
| managedCluster, err = s.Client.CreateOrUpdate(ctx, managedClusterSpec.ResourceGroupName, managedClusterSpec.Name, managedCluster, customHeaders) |
There was a problem hiding this comment.
similar comment as above regarding enabling/disabling features after cluster creation?
There was a problem hiding this comment.
@shysank added validation webhook with immutability check to AzureManagedCluster as well.
@shysank I've added some docs |
|
/test pull-cluster-api-provider-azure-e2e |
|
@michalno1: The following test failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
|
/test pull-cluster-api-provider-azure-e2e |
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: shysank The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
What type of PR is this?
/kind feature
What this PR does / why we need it:
To use some AKS features one needs to pass custom headers when creating/updating a resource. One example is when you want to use a GPU node pool, you need to register
GPUDedicatedVHDPreviewfeature and pass a custom header to node pool creation request:This PR adds a mechanism where you can pass custom headers to cluster and node pool create/update requests by using annotations prefixed with
custom-headers.azure.dev/. E.g. to create mentioned GPU node pool one would set"custom-headers.azure.dev/UseGPUDedicatedVHD": trueannotation onAzureManagedMachinePool.Which issue(s) this PR fixes:
fixes #1981, fixes #1979
TODOs:
Release note: