Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ support configuration of the agent priorityclass #358

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ spec:
type: object
type: array
type: object
priorityClassName:
description: PriorityClassName is the name of the PriorityClass that
will be used by the deployed klusterlet agent. It will be ignored
when the PriorityClass/v1 API is not available on the managed cluster.
type: string
registrationConfiguration:
description: RegistrationConfiguration contains the configuration
of registration
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
creationTimestamp: null
name: klusterlets.operator.open-cluster-management.io
spec:
group: operator.open-cluster-management.io
Expand All @@ -10,6 +9,7 @@ spec:
listKind: KlusterletList
plural: klusterlets
singular: klusterlet
preserveUnknownFields: false
scope: Cluster
versions:
- name: v1
Expand Down Expand Up @@ -172,6 +172,11 @@ spec:
type: object
type: array
type: object
priorityClassName:
description: PriorityClassName is the name of the PriorityClass that
will be used by the deployed klusterlet agent. It will be ignored
when the PriorityClass/v1 API is not available on the managed cluster.
type: string
registrationConfiguration:
description: RegistrationConfiguration contains the configuration
of registration
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ require (
k8s.io/kube-aggregator v0.29.0
k8s.io/utils v0.0.0-20240102154912-e7106e64919e
open-cluster-management.io/addon-framework v0.8.1-0.20240205013730-13fbb6259464
open-cluster-management.io/api v0.12.1-0.20240122084346-e7bd1bd9ea6a
open-cluster-management.io/api v0.12.1-0.20240205100623-abaf09c1e5d4
open-cluster-management.io/sdk-go v0.0.0-20240130025514-7385f9baadf0
sigs.k8s.io/controller-runtime v0.16.2
sigs.k8s.io/kube-storage-version-migrator v0.0.6-0.20230721195810-5c8923c5ff96
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,8 @@ k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCf
k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
open-cluster-management.io/addon-framework v0.8.1-0.20240205013730-13fbb6259464 h1:FGVcwgN1f5kKuHQF7p4WcWMUkNBYLIpKy9uirEBAFu0=
open-cluster-management.io/addon-framework v0.8.1-0.20240205013730-13fbb6259464/go.mod h1:SBs6wF0Umzr5/miJb9p8uMaTDbcjphHHQLa76nXnbU8=
open-cluster-management.io/api v0.12.1-0.20240122084346-e7bd1bd9ea6a h1:NjIU3aN4JSJjTotHiOkOCqYaPGG2tNtm7BY/o9uPb8M=
open-cluster-management.io/api v0.12.1-0.20240122084346-e7bd1bd9ea6a/go.mod h1:vOz9InrJq1BDFEI51+OwAyq2M3tjYPY+1cnoQhMhIlE=
open-cluster-management.io/api v0.12.1-0.20240205100623-abaf09c1e5d4 h1:vg944w17FVNzlM4zNG6UVqA0Rvscv2iYknMpPLtlg4s=
open-cluster-management.io/api v0.12.1-0.20240205100623-abaf09c1e5d4/go.mod h1:vOz9InrJq1BDFEI51+OwAyq2M3tjYPY+1cnoQhMhIlE=
open-cluster-management.io/sdk-go v0.0.0-20240130025514-7385f9baadf0 h1:A+l3SkDPWnRwK3+WE5MVMh7NBvDCKkhdA+AB7Tw/lRM=
open-cluster-management.io/sdk-go v0.0.0-20240130025514-7385f9baadf0/go.mod h1:p3oaf+iu9ghMl4cBJXWXlDnUHVn+QxL90YLTve9bn/k=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 h1:TgtAeesdhpm2SGwkQasmbeqDo8th5wOBA5h/AjTKA4I=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ rules:
- apiGroups: ["oauth.openshift.io"]
resources: ["oauthclients"]
verbs: ["get", "list", "watch", "create", "patch","update", "delete"]
# Allow agent to get/list/watch/create/patch/update/delete priorityclass.
- apiGroups: ["scheduling.k8s.io"]
resources: ["priorityclasses"]
verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ spec:
resources:
{{ .ResourceRequirements | indent 10 }}
{{- end }}
{{- if .PriorityClassName }}
priorityClassName: "{{ .PriorityClassName }}"
{{- end }}
volumes:
- name: bootstrap-secret
secret:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ spec:
resources:
{{ .ResourceRequirements | indent 10 }}
{{- end }}
{{- if .PriorityClassName }}
priorityClassName: "{{ .PriorityClassName }}"
{{- end }}
volumes:
- name: bootstrap-secret
secret:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ spec:
resources:
{{ .ResourceRequirements | indent 10 }}
{{- end }}
{{- if .PriorityClassName }}
priorityClassName: "{{ .PriorityClassName }}"
{{- end }}
volumes:
- name: hub-kubeconfig-secret
secret:
Expand Down
17 changes: 17 additions & 0 deletions pkg/operator/helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,23 @@ func ResourceRequirements(resourceRequirementAcquirer operatorapiv1.ResourceRequ
return marshal, nil
}

// AgentPriorityClassName return the name of the PriorityClass that should be used for the klusterlet agents
func AgentPriorityClassName(klusterlet *operatorapiv1.Klusterlet, kubeVersion *version.Version) string {
if kubeVersion == nil || klusterlet == nil {
return ""
}

// priorityclass.scheduling.k8s.io/v1 is supported since v1.14.
if cnt, err := kubeVersion.Compare("v1.14.0"); err != nil {
klog.Warningf("Ignore PriorityClass because it's failed to check whether the cluster supports PriorityClass/v1 or not: %v", err)
return ""
} else if cnt == -1 {
return ""
}

return klusterlet.Spec.PriorityClassName
}

// SyncSecret forked from:
// https://github.com/openshift/library-go/blob/d9cdfbd844ea08465b938c46a16bed2ea23207e4/pkg/operator/resource/resourceapply/core.go#L357,
// add an addition targetClient parameter to support sync secret to another cluster.
Expand Down
69 changes: 69 additions & 0 deletions pkg/operator/helpers/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,75 @@ func TestDeterminReplica(t *testing.T) {
}
}

func TestAgentPriorityClassName(t *testing.T) {
kubeVersionV113, _ := version.ParseGeneric("v1.13.0")
kubeVersionV114, _ := version.ParseGeneric("v1.14.0")
kubeVersionV122, _ := version.ParseGeneric("v1.22.5+5c84e52")

cases := []struct {
name string
klusterlet *operatorapiv1.Klusterlet
kubeVersion *version.Version
expectedPriorityClassName string
}{
{
name: "klusterlet is nil",
kubeVersion: kubeVersionV114,
},
{
name: "kubeVersion is nil",
klusterlet: &operatorapiv1.Klusterlet{
Spec: operatorapiv1.KlusterletSpec{
PriorityClassName: "test",
},
},
},
{
name: "klusterlet without PriorityClass",
kubeVersion: kubeVersionV114,
klusterlet: &operatorapiv1.Klusterlet{},
},
{
name: "kube v1.13",
kubeVersion: kubeVersionV113,
klusterlet: &operatorapiv1.Klusterlet{
Spec: operatorapiv1.KlusterletSpec{
PriorityClassName: "test",
},
},
},
{
name: "kube v1.14",
kubeVersion: kubeVersionV114,
klusterlet: &operatorapiv1.Klusterlet{
Spec: operatorapiv1.KlusterletSpec{
PriorityClassName: "test",
},
},
expectedPriorityClassName: "test",
},
{
name: "kube v1.22.5+5c84e52",
klusterlet: &operatorapiv1.Klusterlet{
Spec: operatorapiv1.KlusterletSpec{
PriorityClassName: "test",
},
},
kubeVersion: kubeVersionV122,
expectedPriorityClassName: "test",
},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
priorityClassName := AgentPriorityClassName(c.klusterlet, c.kubeVersion)
if priorityClassName != c.expectedPriorityClassName {
t.Errorf("Unexpected priorityClassName, actual: %s, expected: %s", priorityClassName, c.expectedPriorityClassName)
}
})
}
}

func newNode(name string) *corev1.Node {
return &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ type klusterletConfig struct {
ExternalManagedKubeConfigAgentSecret string
InstallMode operatorapiv1.InstallMode

// PriorityClassName is the name of the PriorityClass used by the deployed agents
PriorityClassName string

RegistrationFeatureGates []string
WorkFeatureGates []string

Expand Down Expand Up @@ -192,6 +195,7 @@ func (n *klusterletController) sync(ctx context.Context, controllerContext facto
ExternalServerURL: getServersFromKlusterlet(klusterlet),
OperatorNamespace: n.operatorNamespace,
Replica: helpers.DetermineReplica(ctx, n.kubeClient, klusterlet.Spec.DeployOption.Mode, n.kubeVersion),
PriorityClassName: helpers.AgentPriorityClassName(klusterlet, n.kubeVersion),

ExternalManagedKubeConfigSecret: helpers.ExternalManagedKubeConfig,
ExternalManagedKubeConfigRegistrationSecret: helpers.ExternalManagedKubeConfigRegistration,
Expand Down
38 changes: 38 additions & 0 deletions test/integration/operator/klusterlet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,44 @@ var _ = ginkgo.Describe("Klusterlet", func() {
}, eventuallyTimeout, eventuallyInterval).Should(gomega.BeTrue())
})

ginkgo.It("Deployment should have priorityclass configurated when setting priorityclass in klusterlet", func() {
priorityClassName := "test-priority-class"
_, err := operatorClient.OperatorV1().Klusterlets().Create(context.Background(), klusterlet, metav1.CreateOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())

// Check deployment without priorityclass
gomega.Eventually(func() bool {
deployment, err := kubeClient.AppsV1().Deployments(klusterletNamespace).Get(context.Background(), registrationDeploymentName, metav1.GetOptions{})
if err != nil {
return false
}
if len(deployment.Spec.Template.Spec.PriorityClassName) != 0 {
return false
}
return true
}, eventuallyTimeout, eventuallyInterval).Should(gomega.BeTrue())

gomega.Eventually(func() error {
KlusterletObj, err := operatorClient.OperatorV1().Klusterlets().Get(context.Background(), klusterlet.Name, metav1.GetOptions{})
if err != nil {
return err
}

KlusterletObj.Spec.PriorityClassName = priorityClassName
_, err = operatorClient.OperatorV1().Klusterlets().Update(context.Background(), KlusterletObj, metav1.UpdateOptions{})
return err
}, eventuallyTimeout, eventuallyInterval).Should(gomega.BeNil())

// Check deployment with priorityclass
gomega.Eventually(func() bool {
deployment, err := kubeClient.AppsV1().Deployments(klusterletNamespace).Get(context.Background(), registrationDeploymentName, metav1.GetOptions{})
if err != nil {
return false
}
return deployment.Spec.Template.Spec.PriorityClassName == priorityClassName
}, eventuallyTimeout, eventuallyInterval).Should(gomega.BeTrue())
})

ginkgo.It("should have correct registration deployment when server url is empty", func() {
klusterlet.Spec.ExternalServerURLs = []operatorapiv1.ServerURL{}
_, err := operatorClient.OperatorV1().Klusterlets().Create(context.Background(), klusterlet, metav1.CreateOptions{})
Expand Down
2 changes: 1 addition & 1 deletion vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1508,7 +1508,7 @@ open-cluster-management.io/addon-framework/pkg/index
open-cluster-management.io/addon-framework/pkg/manager/controllers/addonconfiguration
open-cluster-management.io/addon-framework/pkg/manager/controllers/addonowner
open-cluster-management.io/addon-framework/pkg/utils
# open-cluster-management.io/api v0.12.1-0.20240122084346-e7bd1bd9ea6a
# open-cluster-management.io/api v0.12.1-0.20240205100623-abaf09c1e5d4
## explicit; go 1.20
open-cluster-management.io/api/addon/v1alpha1
open-cluster-management.io/api/client/addon/clientset/versioned
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading