Skip to content

Commit 27ca7dc

Browse files
committedFeb 17, 2025
add feature-gate to allow cri metrics instead of cAdvisor
1 parent c44de42 commit 27ca7dc

File tree

3 files changed

+126
-0
lines changed

3 files changed

+126
-0
lines changed
 

‎pkg/agent/baker.go

+6
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,12 @@ func ValidateAndSetLinuxNodeBootstrappingConfiguration(config *datamodel.NodeBoo
327327
!IsKubernetesVersionGe(config.ContainerService.Properties.OrchestratorProfile.OrchestratorVersion, "1.25.0") {
328328
kubeletFlags["--feature-gates"] = addFeatureGateString(kubeletFlags["--feature-gates"], "DisableAcceleratorUsageMetrics", false)
329329
}
330+
331+
// https://kubernetes.io/docs/reference/instrumentation/cri-pod-container-metrics/
332+
// use cri metrics instead of cAdvisor
333+
if IsKubeletCriMetricsEnabled(config) {
334+
kubeletFlags["--feature-gates"] = addFeatureGateString(kubeletFlags["--feature-gates"], "PodAndContainerStatsFromCRI", true)
335+
}
330336
}
331337

332338
func validateAndSetWindowsNodeBootstrappingConfiguration(config *datamodel.NodeBootstrappingConfiguration) {

‎pkg/agent/utils.go

+7
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,13 @@ func IsKubeletServingCertificateRotationEnabled(config *datamodel.NodeBootstrapp
444444
return config.KubeletConfig["--rotate-server-certificates"] == "true"
445445
}
446446

447+
func IsKubeletCriMetricsEnabled(config *datamodel.NodeBootstrappingConfiguration) bool {
448+
if config == nil || config.KubeletConfig == nil {
449+
return false
450+
}
451+
return config.KubeletConfig["--pod-container-stats-cri"] == "true"
452+
}
453+
447454
func getAKSKubeletConfiguration(kc map[string]string) *datamodel.AKSKubeletConfiguration {
448455
kubeletConfig := &datamodel.AKSKubeletConfiguration{
449456
APIVersion: "kubelet.config.k8s.io/v1beta1",

‎pkg/agent/utils_test.go

+113
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,41 @@ func TestGetKubeletConfigFileFromFlags(t *testing.T) {
6969
}
7070
}
7171

72+
func getTelescopeKubeletConfig() map[string]string {
73+
kc := map[string]string{
74+
"--address": "0.0.0.0",
75+
"--pod-manifest-path": "/etc/kubernetes/manifests",
76+
"--cluster-domain": "cluster.local",
77+
"--cluster-dns": "10.0.0.10",
78+
"--cgroups-per-qos": "true",
79+
"--tls-cert-file": "/etc/kubernetes/certs/kubeletserver.crt",
80+
"--tls-private-key-file": "/etc/kubernetes/certs/kubeletserver.key",
81+
"--tls-cipher-suites": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256", //nolint:lll
82+
"--max-pods": "110",
83+
"--node-status-update-frequency": "10s",
84+
"--node-status-report-frequency": "5m0s",
85+
"--image-gc-high-threshold": "85",
86+
"--image-gc-low-threshold": "80",
87+
"--event-qps": "0",
88+
"--pod-max-pids": "-1",
89+
"--enforce-node-allocatable": "pods",
90+
"--streaming-connection-idle-timeout": "4h0m0s",
91+
"--rotate-certificates": "true",
92+
"--read-only-port": "10255",
93+
"--protect-kernel-defaults": "true",
94+
"--resolv-conf": "/etc/resolv.conf",
95+
"--anonymous-auth": "false",
96+
"--client-ca-file": "/etc/kubernetes/certs/ca.crt",
97+
"--authentication-token-webhook": "true",
98+
"--authorization-mode": "Webhook",
99+
"--eviction-hard": "memory.available<750Mi,nodefs.available<10%,nodefs.inodesFree<5%",
100+
"--feature-gates": "PodAndContainerStatsFromCRI=true",
101+
"--system-reserved": "cpu=2,memory=1Gi",
102+
"--kube-reserved": "cpu=100m,memory=1638Mi",
103+
}
104+
return kc
105+
}
106+
72107
func getExampleKcWithNodeStatusReportFrequency() map[string]string {
73108
kc := map[string]string{
74109
"--address": "0.0.0.0",
@@ -222,6 +257,74 @@ var expectedKubeletJSON = `{
222257
"seccompDefault": true
223258
}`
224259

260+
var expectedKubeletTelescopeJSON = `{
261+
"kind": "KubeletConfiguration",
262+
"apiVersion": "kubelet.config.k8s.io/v1beta1",
263+
"staticPodPath": "/etc/kubernetes/manifests",
264+
"address": "0.0.0.0",
265+
"readOnlyPort": 10255,
266+
"tlsCertFile": "/etc/kubernetes/certs/kubeletserver.crt",
267+
"tlsPrivateKeyFile": "/etc/kubernetes/certs/kubeletserver.key",
268+
"tlsCipherSuites": [
269+
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
270+
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
271+
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
272+
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
273+
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
274+
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
275+
"TLS_RSA_WITH_AES_256_GCM_SHA384",
276+
"TLS_RSA_WITH_AES_128_GCM_SHA256"
277+
],
278+
"rotateCertificates": true,
279+
"authentication": {
280+
"x509": {
281+
"clientCAFile": "/etc/kubernetes/certs/ca.crt"
282+
},
283+
"webhook": {
284+
"enabled": true
285+
},
286+
"anonymous": {}
287+
},
288+
"authorization": {
289+
"mode": "Webhook",
290+
"webhook": {}
291+
},
292+
"eventRecordQPS": 0,
293+
"clusterDomain": "cluster.local",
294+
"clusterDNS": [
295+
"10.0.0.10"
296+
],
297+
"streamingConnectionIdleTimeout": "4h0m0s",
298+
"nodeStatusUpdateFrequency": "10s",
299+
"nodeStatusReportFrequency": "5m0s",
300+
"imageGCHighThresholdPercent": 85,
301+
"imageGCLowThresholdPercent": 80,
302+
"cgroupsPerQOS": true,
303+
"maxPods": 110,
304+
"podPidsLimit": -1,
305+
"resolvConf": "/etc/resolv.conf",
306+
"evictionHard": {
307+
"memory.available": "750Mi",
308+
"nodefs.available": "10%",
309+
"nodefs.inodesFree": "5%"
310+
},
311+
"protectKernelDefaults": true,
312+
"featureGates": {
313+
"PodAndContainerStatsFromCRI": true
314+
},
315+
"systemReserved": {
316+
"cpu": "2",
317+
"memory": "1Gi"
318+
},
319+
"kubeReserved": {
320+
"cpu": "100m",
321+
"memory": "1638Mi"
322+
},
323+
"enforceNodeAllocatable": [
324+
"pods"
325+
]
326+
}`
327+
225328
var expectedKubeletJSONWithNodeStatusReportFrequency = `{
226329
"kind": "KubeletConfiguration",
227330
"apiVersion": "kubelet.config.k8s.io/v1beta1",
@@ -462,6 +565,16 @@ func TestGetKubeletConfigFileFlagsWithNodeStatusReportFrequency(t *testing.T) {
462565
}
463566
}
464567

568+
func TestGetKubeletConfigFileFlagsUsingCriMetrics(t *testing.T) {
569+
kc := getTelescopeKubeletConfig()
570+
customKc := &datamodel.CustomKubeletConfig{}
571+
configFileStr := GetKubeletConfigFileContent(kc, customKc)
572+
diff := cmp.Diff(expectedKubeletTelescopeJSON, configFileStr)
573+
if diff != "" {
574+
t.Errorf("Generated config file is different than expected: %s", diff)
575+
}
576+
}
577+
465578
func TestGetKubeletConfigFileFromFlagsWithContainerLogMaxSize(t *testing.T) {
466579
kc := getExampleKcWithContainerLogMaxSize()
467580
customKc := &datamodel.CustomKubeletConfig{

0 commit comments

Comments
 (0)