diff --git a/parts/k8s/addons/kubernetesmasteraddons-metrics-server-deployment.yaml b/parts/k8s/addons/kubernetesmasteraddons-metrics-server-deployment.yaml new file mode 100644 index 0000000000..d722af419b --- /dev/null +++ b/parts/k8s/addons/kubernetesmasteraddons-metrics-server-deployment.yaml @@ -0,0 +1,146 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: metrics-server + namespace: kube-system + labels: + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: EnsureExists +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: system:metrics-server + labels: + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: EnsureExists +rules: +- apiGroups: + - "" + resources: + - pods + - nodes + - namespaces + verbs: + - get + - list + - watch +- apiGroups: + - "extensions" + resources: + - deployments + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: system:metrics-server + labels: + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: EnsureExists +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:metrics-server +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: metrics-server-auth-reader + namespace: kube-system + labels: + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: EnsureExists +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: metrics-server:system:auth-delegator + labels: + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: EnsureExists +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: v1 +kind: Service +metadata: + name: metrics-server + namespace: kube-system + labels: + addonmanager.kubernetes.io/mode: EnsureExists + kubernetes.io/name: "Metrics-server" + kubernetes.io/cluster-service: "true" +spec: + selector: + k8s-app: metrics-server + ports: + - port: 443 + protocol: TCP + targetPort: 443 +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: metrics-server + namespace: kube-system + labels: + k8s-app: metrics-server + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: EnsureExists +spec: + selector: + matchLabels: + k8s-app: metrics-server + template: + metadata: + name: metrics-server + labels: + k8s-app: metrics-server + spec: + serviceAccountName: metrics-server + containers: + - name: metrics-server + image: + imagePullPolicy: Always + command: + - /metrics-server + - --source=kubernetes.summary_api:'' +--- +apiVersion: apiregistration.k8s.io/v1beta1 +kind: APIService +metadata: + name: v1beta1.metrics.k8s.io + labels: + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: EnsureExists +spec: + service: + name: metrics-server + namespace: kube-system + group: metrics.k8s.io + version: v1beta1 + insecureSkipTLSVerify: true + groupPriorityMinimum: 100 + versionPriority: 100 diff --git a/parts/k8s/kubernetesmastercustomdata.yml b/parts/k8s/kubernetesmastercustomdata.yml index 3c35e4f304..644448263c 100644 --- a/parts/k8s/kubernetesmastercustomdata.yml +++ b/parts/k8s/kubernetesmastercustomdata.yml @@ -230,6 +230,10 @@ MASTER_ARTIFACTS_CONFIG_PLACEHOLDER sed -i "s||{{WrapAsVariable "kubernetesReschedulerMemoryLimit"}}|g" "/etc/kubernetes/addons/kube-rescheduler-deployment.yaml" {{end}} +{{if .OrchestratorProfile.IsMetricsServerEnabled}} + sed -i "s||{{WrapAsVariable "kubernetesMetricsServerSpec"}}|g" "/etc/kubernetes/addons/kube-metrics-server-deployment.yaml" +{{end}} + {{if EnableDataEncryptionAtRest }} ETCD_ENCRYPTION_SECRET="$(head -c 32 /dev/urandom | base64)" sed -i "s||$ETCD_ENCRYPTION_SECRET|g" "/etc/kubernetes/encryption-config.yaml" diff --git a/parts/k8s/kubernetesmastervars.t b/parts/k8s/kubernetesmastervars.t index 9fdc346375..db338e4506 100644 --- a/parts/k8s/kubernetesmastervars.t +++ b/parts/k8s/kubernetesmastervars.t @@ -82,6 +82,7 @@ "kubernetesDashboardMemoryLimit": "[parameters('kubernetesDashboardMemoryLimit')]", "kubernetesExecHealthzSpec": "[parameters('kubernetesExecHealthzSpec')]", "kubernetesHeapsterSpec": "[parameters('kubernetesHeapsterSpec')]", + "kubernetesMetricsServerSpec": "[parameters('kubernetesMetricsServerSpec')]", "kubernetesTillerSpec": "[parameters('kubernetesTillerSpec')]", "kubernetesTillerCPURequests": "[parameters('kubernetesTillerCPURequests')]", "kubernetesTillerMemoryRequests": "[parameters('kubernetesTillerMemoryRequests')]", diff --git a/parts/k8s/kubernetesparams.t b/parts/k8s/kubernetesparams.t index d5d83781e2..ae273f4c23 100644 --- a/parts/k8s/kubernetesparams.t +++ b/parts/k8s/kubernetesparams.t @@ -293,6 +293,13 @@ }, "type": "string" }, + "kubernetesMetricsServerSpec": { + {{PopulateClassicModeDefaultValue "kubernetesMetricsServerSpec"}} + "metadata": { + "description": "The container spec for Metrics Server." + }, + "type": "string" + }, "kubernetesTillerSpec": { {{PopulateClassicModeDefaultValue "kubernetesTillerSpec"}} "metadata": { diff --git a/pkg/acsengine/addons.go b/pkg/acsengine/addons.go index 07170e309c..5473a3b5a9 100644 --- a/pkg/acsengine/addons.go +++ b/pkg/acsengine/addons.go @@ -76,6 +76,11 @@ func kubernetesAddonSettingsInit(profile *api.Properties) []kubernetesFeatureSet "azure-cloud-provider-deployment.yaml", true, }, + { + "kubernetesmasteraddons-metrics-server-deployment.yaml", + "kube-metrics-server-deployment.yaml", + profile.OrchestratorProfile.IsMetricsServerEnabled(), + }, } } diff --git a/pkg/acsengine/const.go b/pkg/acsengine/const.go index c1377e9ee0..044ada3ac6 100644 --- a/pkg/acsengine/const.go +++ b/pkg/acsengine/const.go @@ -113,6 +113,8 @@ const ( DefaultReschedulerImage = "rescheduler:v0.3.1" // DefaultReschedulerAddonName is the name of the rescheduler addon deployment DefaultReschedulerAddonName = "rescheduler" + // DefaultMetricsServerAddonName is the name of the kubernetes Metrics server addon deployment + DefaultMetricsServerAddonName = "metrics-server" // DefaultKubernetesKubeletMaxPods is the max pods per kubelet DefaultKubernetesKubeletMaxPods = 110 // DefaultMasterEtcdServerPort is the default etcd server port for Kubernetes master nodes diff --git a/pkg/acsengine/defaults.go b/pkg/acsengine/defaults.go index 7b1636067a..dd5ba3c4ef 100644 --- a/pkg/acsengine/defaults.go +++ b/pkg/acsengine/defaults.go @@ -241,6 +241,17 @@ var ( }, }, } + + // DefaultMetricsServerAddonsConfig is the default metrics-server Kubernetes addon Config + DefaultMetricsServerAddonsConfig = api.KubernetesAddon{ + Name: DefaultMetricsServerAddonName, + Enabled: pointerToBool(api.DefaultMetricsServerAddonEnabled), + Containers: []api.KubernetesContainerSpec{ + { + Name: DefaultMetricsServerAddonName, + }, + }, + } ) // SetPropertiesDefaults for the container Properties, returns true if certs are generated @@ -292,6 +303,7 @@ func setOrchestratorDefaults(cs *api.ContainerService) { DefaultACIConnectorAddonsConfig, DefaultDashboardAddonsConfig, DefaultReschedulerAddonsConfig, + DefaultMetricsServerAddonsConfig, } } else { // For each addon, provide default configuration if user didn't provide its own config @@ -315,6 +327,11 @@ func setOrchestratorDefaults(cs *api.ContainerService) { // Provide default acs-engine config for Rescheduler o.KubernetesConfig.Addons = append(o.KubernetesConfig.Addons, DefaultReschedulerAddonsConfig) } + m := getAddonsIndexByName(o.KubernetesConfig.Addons, DefaultMetricsServerAddonName) + if m < 0 { + // Provide default acs-engine config for Metrics Server + o.KubernetesConfig.Addons = append(o.KubernetesConfig.Addons, DefaultMetricsServerAddonsConfig) + } } if o.KubernetesConfig.KubernetesImageBase == "" { o.KubernetesConfig.KubernetesImageBase = cloudSpecConfig.KubernetesSpecConfig.KubernetesImageBase @@ -409,6 +426,10 @@ func setOrchestratorDefaults(cs *api.ContainerService) { if a.OrchestratorProfile.KubernetesConfig.Addons[r].IsEnabled(api.DefaultReschedulerAddonEnabled) { a.OrchestratorProfile.KubernetesConfig.Addons[r] = assignDefaultAddonVals(a.OrchestratorProfile.KubernetesConfig.Addons[r], DefaultReschedulerAddonsConfig) } + m := getAddonsIndexByName(a.OrchestratorProfile.KubernetesConfig.Addons, DefaultMetricsServerAddonName) + if a.OrchestratorProfile.KubernetesConfig.Addons[m].IsEnabled(api.DefaultMetricsServerAddonEnabled) { + a.OrchestratorProfile.KubernetesConfig.Addons[m] = assignDefaultAddonVals(a.OrchestratorProfile.KubernetesConfig.Addons[m], DefaultMetricsServerAddonsConfig) + } if "" == a.OrchestratorProfile.KubernetesConfig.EtcdDiskSizeGB { a.OrchestratorProfile.KubernetesConfig.EtcdDiskSizeGB = DefaultEtcdDiskSize diff --git a/pkg/acsengine/engine.go b/pkg/acsengine/engine.go index 917f33c1bb..c1cde07d8d 100644 --- a/pkg/acsengine/engine.go +++ b/pkg/acsengine/engine.go @@ -621,6 +621,15 @@ func getParameters(cs *api.ContainerService, isClassicMode bool, generatorCode s addValue(parametersMap, "kubernetesReschedulerSpec", cloudSpecConfig.KubernetesSpecConfig.KubernetesImageBase+KubeConfigs[k8sVersion][DefaultReschedulerAddonName]) } } + metricsServerAddon := getAddonByName(properties.OrchestratorProfile.KubernetesConfig.Addons, DefaultMetricsServerAddonName) + c = getAddonContainersIndexByName(metricsServerAddon.Containers, DefaultMetricsServerAddonName) + if c > -1 { + if metricsServerAddon.Containers[c].Image != "" { + addValue(parametersMap, "kubernetesMetricsServerSpec", metricsServerAddon.Containers[c].Image) + } else { + addValue(parametersMap, "kubernetesMetricsServerSpec", cloudSpecConfig.KubernetesSpecConfig.KubernetesImageBase+KubeConfigs[k8sVersion][DefaultMetricsServerAddonName]) + } + } addValue(parametersMap, "kubernetesKubeDNSSpec", cloudSpecConfig.KubernetesSpecConfig.KubernetesImageBase+KubeConfigs[k8sVersion]["dns"]) addValue(parametersMap, "kubernetesPodInfraContainerSpec", cloudSpecConfig.KubernetesSpecConfig.KubernetesImageBase+KubeConfigs[k8sVersion]["pause"]) addValue(parametersMap, "cloudProviderBackoff", strconv.FormatBool(properties.OrchestratorProfile.KubernetesConfig.CloudProviderBackoff)) @@ -1283,6 +1292,8 @@ func (t *TemplateGenerator) getTemplateFuncMap(cs *api.ContainerService) templat dC := getAddonContainersIndexByName(dashboardAddon.Containers, DefaultDashboardAddonName) reschedulerAddon := getAddonByName(cs.Properties.OrchestratorProfile.KubernetesConfig.Addons, DefaultReschedulerAddonName) rC := getAddonContainersIndexByName(reschedulerAddon.Containers, DefaultReschedulerAddonName) + metricsServerAddon := getAddonByName(cs.Properties.OrchestratorProfile.KubernetesConfig.Addons, DefaultMetricsServerAddonName) + mC := getAddonContainersIndexByName(metricsServerAddon.Containers, DefaultMetricsServerAddonName) switch attr { case "kubernetesHyperkubeSpec": val = cs.Properties.OrchestratorProfile.KubernetesConfig.KubernetesImageBase + KubeConfigs[k8sVersion]["hyperkube"] @@ -1464,6 +1475,14 @@ func (t *TemplateGenerator) getTemplateFuncMap(cs *api.ContainerService) templat } else { val = "0" } + case "kubernetesMetricsServerSpec": + if mC > -1 { + if metricsServerAddon.Containers[mC].Image != "" { + val = metricsServerAddon.Containers[mC].Image + } + } else { + val = cloudSpecConfig.KubernetesSpecConfig.KubernetesImageBase + KubeConfigs[k8sVersion][DefaultMetricsServerAddonName] + } case "kubernetesReschedulerSpec": if rC > -1 { if reschedulerAddon.Containers[rC].Image != "" { diff --git a/pkg/acsengine/k8s_versions.go b/pkg/acsengine/k8s_versions.go index 77afdaa5e5..939c62f80b 100644 --- a/pkg/acsengine/k8s_versions.go +++ b/pkg/acsengine/k8s_versions.go @@ -11,11 +11,12 @@ var KubeConfigs = map[string]map[string]string{ common.KubernetesVersion1Dot9Dot3: { "hyperkube": "hyperkube-amd64:v1.9.3", "ccm": "cloud-controller-manager-amd64:v1.9.3", - "dockerEngineVersion": "1.13.*", - DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", - "exechealthz": "exechealthz-amd64:1.2", - "addonresizer": "addon-resizer:1.7", - "heapster": "heapster-amd64:v1.5.0", + "dockerEngineVersion": "1.13.*", + DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", + "exechealthz": "exechealthz-amd64:1.2", + "addonresizer": "addon-resizer:1.7", + "heapster": "heapster-amd64:v1.5.0", + DefaultMetricsServerAddonName: "metrics-server-amd64:v0.2.1", "dns": "k8s-dns-kube-dns-amd64:1.14.8", "addonmanager": "kube-addon-manager-amd64:v6.5", "dnsmasq": "k8s-dns-dnsmasq-nanny-amd64:1.14.8", @@ -39,11 +40,12 @@ var KubeConfigs = map[string]map[string]string{ common.KubernetesVersion1Dot9Dot2: { "hyperkube": "hyperkube-amd64:v1.9.2", "ccm": "cloud-controller-manager-amd64:v1.9.2", - "dockerEngineVersion": "1.13.*", - DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", - "exechealthz": "exechealthz-amd64:1.2", - "addonresizer": "addon-resizer:1.7", - "heapster": "heapster-amd64:v1.5.0", + "dockerEngineVersion": "1.13.*", + DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", + "exechealthz": "exechealthz-amd64:1.2", + "addonresizer": "addon-resizer:1.7", + "heapster": "heapster-amd64:v1.5.0", + DefaultMetricsServerAddonName: "metrics-server-amd64:v0.2.1", "dns": "k8s-dns-kube-dns-amd64:1.14.8", "addonmanager": "kube-addon-manager-amd64:v6.5", "dnsmasq": "k8s-dns-dnsmasq-nanny-amd64:1.14.8", @@ -67,11 +69,12 @@ var KubeConfigs = map[string]map[string]string{ common.KubernetesVersion1Dot9Dot1: { "hyperkube": "hyperkube-amd64:v1.9.1", "ccm": "cloud-controller-manager-amd64:v1.9.1", - "dockerEngineVersion": "1.13.*", - DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", - "exechealthz": "exechealthz-amd64:1.2", - "addonresizer": "addon-resizer:1.7", - "heapster": "heapster-amd64:v1.5.0", + "dockerEngineVersion": "1.13.*", + DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", + "exechealthz": "exechealthz-amd64:1.2", + "addonresizer": "addon-resizer:1.7", + "heapster": "heapster-amd64:v1.5.0", + DefaultMetricsServerAddonName: "metrics-server-amd64:v0.2.1", "dns": "k8s-dns-kube-dns-amd64:1.14.8", "addonmanager": "kube-addon-manager-amd64:v6.5", "dnsmasq": "k8s-dns-dnsmasq-nanny-amd64:1.14.8", @@ -95,11 +98,12 @@ var KubeConfigs = map[string]map[string]string{ common.KubernetesVersion1Dot9Dot0: { "hyperkube": "hyperkube-amd64:v1.9.0", "ccm": "cloud-controller-manager-amd64:v1.9.0", - "dockerEngineVersion": "1.13.*", - DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", - "exechealthz": "exechealthz-amd64:1.2", - "addonresizer": "addon-resizer:1.7", - "heapster": "heapster-amd64:v1.5.0", + "dockerEngineVersion": "1.13.*", + DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", + "exechealthz": "exechealthz-amd64:1.2", + "addonresizer": "addon-resizer:1.7", + "heapster": "heapster-amd64:v1.5.0", + DefaultMetricsServerAddonName: "metrics-server-amd64:v0.2.1", "dns": "k8s-dns-kube-dns-amd64:1.14.8", "addonmanager": "kube-addon-manager-amd64:v6.5", "dnsmasq": "k8s-dns-dnsmasq-nanny-amd64:1.14.8", @@ -123,11 +127,12 @@ var KubeConfigs = map[string]map[string]string{ common.KubernetesVersion1Dot8Dot8: { "hyperkube": "hyperkube-amd64:v1.8.8", "ccm": "cloud-controller-manager-amd64:v1.8.8", - "dockerEngineVersion": "1.13.*", - DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", - "exechealthz": "exechealthz-amd64:1.2", - "addonresizer": "addon-resizer:1.7", - "heapster": "heapster-amd64:v1.5.0", + "dockerEngineVersion": "1.13.*", + DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", + "exechealthz": "exechealthz-amd64:1.2", + "addonresizer": "addon-resizer:1.7", + "heapster": "heapster-amd64:v1.5.0", + DefaultMetricsServerAddonName: "metrics-server-amd64:v0.2.1", "dns": "k8s-dns-kube-dns-amd64:1.14.8", "addonmanager": "kube-addon-manager-amd64:v6.5", "dnsmasq": "k8s-dns-dnsmasq-nanny-amd64:1.14.8", @@ -151,11 +156,12 @@ var KubeConfigs = map[string]map[string]string{ common.KubernetesVersion1Dot8Dot7: { "hyperkube": "hyperkube-amd64:v1.8.7", "ccm": "cloud-controller-manager-amd64:v1.8.7", - "dockerEngineVersion": "1.13.*", - DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", - "exechealthz": "exechealthz-amd64:1.2", - "addonresizer": "addon-resizer:1.7", - "heapster": "heapster-amd64:v1.5.0", + "dockerEngineVersion": "1.13.*", + DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", + "exechealthz": "exechealthz-amd64:1.2", + "addonresizer": "addon-resizer:1.7", + "heapster": "heapster-amd64:v1.5.0", + DefaultMetricsServerAddonName: "metrics-server-amd64:v0.2.1", "dns": "k8s-dns-kube-dns-amd64:1.14.8", "addonmanager": "kube-addon-manager-amd64:v6.5", "dnsmasq": "k8s-dns-dnsmasq-nanny-amd64:1.14.8", @@ -179,11 +185,12 @@ var KubeConfigs = map[string]map[string]string{ common.KubernetesVersion1Dot8Dot6: { "hyperkube": "hyperkube-amd64:v1.8.6", "ccm": "cloud-controller-manager-amd64:v1.8.6", - "dockerEngineVersion": "1.13.*", - DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", - "exechealthz": "exechealthz-amd64:1.2", - "addonresizer": "addon-resizer:1.7", - "heapster": "heapster-amd64:v1.5.0", + "dockerEngineVersion": "1.13.*", + DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", + "exechealthz": "exechealthz-amd64:1.2", + "addonresizer": "addon-resizer:1.7", + "heapster": "heapster-amd64:v1.5.0", + DefaultMetricsServerAddonName: "metrics-server-amd64:v0.2.1", "dns": "k8s-dns-kube-dns-amd64:1.14.8", "addonmanager": "kube-addon-manager-amd64:v6.5", "dnsmasq": "k8s-dns-dnsmasq-nanny-amd64:1.14.8", @@ -207,11 +214,12 @@ var KubeConfigs = map[string]map[string]string{ common.KubernetesVersion1Dot8Dot4: { "hyperkube": "hyperkube-amd64:v1.8.4", "ccm": "cloud-controller-manager-amd64:v1.8.4", - "dockerEngineVersion": "1.13.*", - DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", - "exechealthz": "exechealthz-amd64:1.2", - "addonresizer": "addon-resizer:1.7", - "heapster": "heapster-amd64:v1.5.0", + "dockerEngineVersion": "1.13.*", + DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", + "exechealthz": "exechealthz-amd64:1.2", + "addonresizer": "addon-resizer:1.7", + "heapster": "heapster-amd64:v1.5.0", + DefaultMetricsServerAddonName: "metrics-server-amd64:v0.2.1", "dns": "k8s-dns-kube-dns-amd64:1.14.8", "addonmanager": "kube-addon-manager-amd64:v6.5", "dnsmasq": "k8s-dns-dnsmasq-nanny-amd64:1.14.8", @@ -235,11 +243,12 @@ var KubeConfigs = map[string]map[string]string{ common.KubernetesVersion1Dot8Dot2: { "hyperkube": "hyperkube-amd64:v1.8.2", "ccm": "cloud-controller-manager-amd64:v1.8.2", - "dockerEngineVersion": "1.13.*", - DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", - "exechealthz": "exechealthz-amd64:1.2", - "addonresizer": "addon-resizer:1.7", - "heapster": "heapster-amd64:v1.5.0", + "dockerEngineVersion": "1.13.*", + DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", + "exechealthz": "exechealthz-amd64:1.2", + "addonresizer": "addon-resizer:1.7", + "heapster": "heapster-amd64:v1.5.0", + DefaultMetricsServerAddonName: "metrics-server-amd64:v0.2.1", "dns": "k8s-dns-kube-dns-amd64:1.14.8", "addonmanager": "kube-addon-manager-amd64:v6.5", "dnsmasq": "k8s-dns-dnsmasq-nanny-amd64:1.14.8", @@ -264,11 +273,12 @@ var KubeConfigs = map[string]map[string]string{ common.KubernetesVersion1Dot8Dot1: { "hyperkube": "hyperkube-amd64:v1.8.1", "ccm": "cloud-controller-manager-amd64:v1.8.1", - "dockerEngineVersion": "1.13.*", - DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", - "exechealthz": "exechealthz-amd64:1.2", - "addonresizer": "addon-resizer:1.7", - "heapster": "heapster-amd64:v1.5.0", + "dockerEngineVersion": "1.13.*", + DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", + "exechealthz": "exechealthz-amd64:1.2", + "addonresizer": "addon-resizer:1.7", + "heapster": "heapster-amd64:v1.5.0", + DefaultMetricsServerAddonName: "metrics-server-amd64:v0.2.1", "dns": "k8s-dns-kube-dns-amd64:1.14.8", "addonmanager": "kube-addon-manager-amd64:v6.5", "dnsmasq": "k8s-dns-dnsmasq-nanny-amd64:1.14.8", @@ -293,11 +303,12 @@ var KubeConfigs = map[string]map[string]string{ common.KubernetesVersion1Dot8Dot0: { "hyperkube": "hyperkube-amd64:v1.8.0", "ccm": "cloud-controller-manager-amd64:v1.8.0", - "dockerEngineVersion": "1.13.*", - DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", - "exechealthz": "exechealthz-amd64:1.2", - "addonresizer": "addon-resizer:1.7", - "heapster": "heapster-amd64:v1.5.0", + "dockerEngineVersion": "1.13.*", + DefaultDashboardAddonName: "kubernetes-dashboard-amd64:v1.8.2", + "exechealthz": "exechealthz-amd64:1.2", + "addonresizer": "addon-resizer:1.7", + "heapster": "heapster-amd64:v1.5.0", + DefaultMetricsServerAddonName: "metrics-server-amd64:v0.2.1", "dns": "k8s-dns-kube-dns-amd64:1.14.8", "addonmanager": "kube-addon-manager-amd64:v6.5", "dnsmasq": "k8s-dns-dnsmasq-nanny-amd64:1.14.8", diff --git a/pkg/api/const.go b/pkg/api/const.go index 7afe120c44..1513fcd460 100644 --- a/pkg/api/const.go +++ b/pkg/api/const.go @@ -95,6 +95,8 @@ const ( DefaultRBACEnabled = true // DefaultSecureKubeletEnabled determines the acs-engine provided default for securing kubelet communications DefaultSecureKubeletEnabled = true + // DefaultMetricsServerAddonEnabled determines the acs-engine provided default for enabling kubernetes metrics-server addon + DefaultMetricsServerAddonEnabled = false // DefaultTillerAddonName is the name of the tiller addon deployment DefaultTillerAddonName = "tiller" // DefaultACIConnectorAddonName is the name of the tiller addon deployment @@ -103,4 +105,6 @@ const ( DefaultDashboardAddonName = "kubernetes-dashboard" // DefaultReschedulerAddonName is the name of the rescheduler addon deployment DefaultReschedulerAddonName = "rescheduler" + // DefaultMetricsServerAddonName is the name of the kubernetes metrics server addon deployment + DefaultMetricsServerAddonName = "metrics-server" ) diff --git a/pkg/api/types.go b/pkg/api/types.go index ab4cf8a118..4f3a5ba4f1 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -692,3 +692,17 @@ func (k *KubernetesConfig) IsReschedulerEnabled() bool { } return reschedulerAddon.IsEnabled(DefaultReschedulerAddonEnabled) } + +// IsMetricsServerEnabled checks if the metrics server addon is enabled +func (o *OrchestratorProfile) IsMetricsServerEnabled() bool { + var metricsServerAddon KubernetesAddon + k := o.KubernetesConfig + for i := range k.Addons { + if k.Addons[i].Name == DefaultMetricsServerAddonName { + metricsServerAddon = k.Addons[i] + } + } + k8sSemVer, _ := semver.NewVersion(o.OrchestratorVersion) + constraint, _ := semver.NewConstraint(">= 1.9.0") + return metricsServerAddon.IsEnabled(DefaultMetricsServerAddonEnabled) || constraint.Check(k8sSemVer) +} diff --git a/pkg/api/types_test.go b/pkg/api/types_test.go index 06fbb04739..2e1e40d3fd 100644 --- a/pkg/api/types_test.go +++ b/pkg/api/types_test.go @@ -204,6 +204,59 @@ func TestIsReschedulerEnabled(t *testing.T) { } } +func TestIsMetricsServerEnabled(t *testing.T) { + v := "1.9.0" + o := OrchestratorProfile{ + OrchestratorType: "Kubernetes", + OrchestratorVersion: v, + KubernetesConfig: &KubernetesConfig{Addons: []KubernetesAddon{ + getMockAddon("addon"), + }, + }, + } + e := o.IsMetricsServerEnabled() + if e != true { + t.Fatalf("KubernetesConfig.IsMetricsServerEnabled() should return true for kubernetes version %s when no metrics-server addon has been specified, instead returned %t", v, e) + } + + v = "1.8.0" + o = OrchestratorProfile{ + OrchestratorType: "Kubernetes", + OrchestratorVersion: v, + KubernetesConfig: &KubernetesConfig{Addons: []KubernetesAddon{ + getMockAddon("addon"), + }, + }, + } + e = o.IsMetricsServerEnabled() + if e != DefaultMetricsServerAddonEnabled { + t.Fatalf("KubernetesConfig.IsMetricsServerEnabled() should return %t for kubernetes version %s when no metrics-server addon has been specified, instead returned %t", DefaultMetricsServerAddonEnabled, v, e) + } + + o.KubernetesConfig.Addons = append(o.KubernetesConfig.Addons, getMockAddon(DefaultMetricsServerAddonName)) + e = o.IsMetricsServerEnabled() + if e != DefaultMetricsServerAddonEnabled { + t.Fatalf("KubernetesConfig.IsMetricsServerEnabled() should return %t for kubernetes version %s when the metrics-server addon has been specified, instead returned %t", DefaultMetricsServerAddonEnabled, v, e) + } + + b := true + o = OrchestratorProfile{ + OrchestratorType: "Kubernetes", + OrchestratorVersion: v, + KubernetesConfig: &KubernetesConfig{Addons: []KubernetesAddon{ + { + Name: DefaultMetricsServerAddonName, + Enabled: &b, + }, + }, + }, + } + e = o.IsMetricsServerEnabled() + if e != true { + t.Fatalf("KubernetesConfig.IsMetricsServerEnabled() should return true for kubernetes version %s when the metrics-server addon has been specified as enabled, instead returned %t", v, e) + } +} + func getMockAddon(name string) KubernetesAddon { return KubernetesAddon{ Name: name, diff --git a/test/e2e/kubernetes/kubernetes_test.go b/test/e2e/kubernetes/kubernetes_test.go index 845a927b18..e8322cef08 100644 --- a/test/e2e/kubernetes/kubernetes_test.go +++ b/test/e2e/kubernetes/kubernetes_test.go @@ -257,11 +257,7 @@ var _ = Describe("Azure Container Cluster using the Kubernetes Orchestrator", fu Describe("with a linux agent pool", func() { It("should be able to autoscale", func() { - By("Determining whether this version of Kubernetes can hpa autoscale") - version, err := node.Version() - Expect(err).NotTo(HaveOccurred()) - re := regexp.MustCompile("v1.9") - if eng.HasLinuxAgents() && re.FindString(version) == "" { + if eng.HasLinuxAgents() { By("Creating a test php-apache deployment with request limit thresholds") // Inspired by http://blog.kubernetes.io/2016/07/autoscaling-in-kubernetes.html r := rand.New(rand.NewSource(time.Now().UnixNano()))