Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Commit

Permalink
Generic controller-manager config (#1960)
Browse files Browse the repository at this point in the history
* wip generic controller-manager config

* clean up tests

* controller-manager yaml uses controllerManagerConfig

* array command usage for controller-manager yaml

* more rebase fun

* dispatch --route-reconciliation-period to cloud controller manager

* 1 fix and 2 cleanups

- actually using passed-in *api.KubernetesConfig reference in GetControllerManagerConfigKeyVals()
- removing unnecessary validations for both controller manager and kubelet
  • Loading branch information
jackfrancis authored Dec 22, 2017
1 parent 2137719 commit 39081b8
Show file tree
Hide file tree
Showing 25 changed files with 672 additions and 2,926 deletions.
46 changes: 45 additions & 1 deletion docs/clusterdefinition.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,51 @@ Below is a list of kubelet options that are *not* currently user-configurable, e
|"--register-with-taints" (master nodes only)|"node-role.kubernetes.io/master=true:NoSchedule"|
|"--feature-gates" (agent nodes only)|"Accelerators=true"|

We consider `kubeletConfig` to be a generic convenience that is powerful and comes with no operational guarantees when used! It is a manual tuning feature that enables low-level configuration of a kubernetes cluster.
#### controllerManagerConfig

`controllerManagerConfig` declares runtime configuration for the kube-controller-manager daemon running on all master nodes. Like `kubeletConfig` it is a generic key/value object, and a child property of `kubernetesConfig`. An example custom controller-manager config:

```
"kubernetesConfig": {
"controllerManagerConfig": {
"--node-monitor-grace-period": "40s",
"--pod-eviction-timeout": "5m0s",
"--route-reconciliation-period": "10s"
}
}
```

See [here](https://kubernetes.io/docs/reference/generated/kube-controller-manager/) for a reference of supported controller-manager options.

Below is a list of controller-manager options that acs-engine will configure by default:

|controller-manager option|default value|
|---|---|
|"--node-monitor-grace-period"|"40s"|
|"--pod-eviction-timeout"|"5m0s"|
|"--route-reconciliation-period"|"10s"|


Below is a list of kubelet options that are *not* currently user-configurable, either because a higher order configuration vector is available that enforces kubelet configuration, or because a static configuration is required to build a functional cluster:

|controller-manager option|default value|
|---|---|
|"--kubeconfig"|"/var/lib/kubelet/kubeconfig"|
|"--allocate-node-cidrs"|"false"|
|"--cluster-cidr"|"10.240.0.0/12"|
|"--cluster-name"|<auto-generated using api model properties>|
|"--cloud-provider"|"azure"|
|"--cloud-config"|"/etc/kubernetes/azure.json"|
|"--root-ca-file"|"/etc/kubernetes/certs/ca.crt"|
|"--cluster-signing-cert-file"|"/etc/kubernetes/certs/ca.crt"|
|"--cluster-signing-key-file"|"/etc/kubernetes/certs/ca.key"|
|"--service-account-private-key-file"|"/etc/kubernetes/certs/apiserver.key"|
|"--leader-elect"|"true"|
|"--v"|"2"|
|"--profiling"|"false"|
|"--use-service-account-credentials"|"false" ("true" if kubernetesConfig.enableRbac is true)|

We consider `kubeletConfig` and `controllerManagerConfig` to be generic conveniences that add power/flexibility to cluster deployments. Their usage comes with no operational guarantees! They are manual tuning features that enable low-level configuration of a kubernetes cluster.

### masterProfile
`masterProfile` describes the settings for master configuration.
Expand Down
14 changes: 5 additions & 9 deletions docs/kubernetes-large-clusters.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,13 @@ The following configuration parameters are available in the `properties.orchestr
"cloudProviderRatelimitQPS": {
"value": "3" // rate limit QPS
},
"kubernetesCtrlMgrNodeMonitorGracePeriod": {
"value": "5m" // duration after which controller manager marks an AWOL node as NotReady
},
"kubernetesCtrlMgrPodEvictionTimeout": {
"value": "1m" // grace period for deleting pods on failed nodes
},
"kubernetesCtrlMgrRouteReconciliationPeriod": {
"value": "1m" // how often to reconcile cloudprovider-originating node routes
},
"kubeletConfig": {
"--node-status-update-frequency": "1m" // how often kubelet posts node status to master
},
"controllerManagerConfig": {
"--node-monitor-grace-period": "5m", // duration after which controller manager marks an AWOL node as NotReady
"--pod-eviction-timeout": "1m", // grace period for deleting pods on failed nodes
"--route-reconciliation-period": "1m" // how often to reconcile cloudprovider-originating node routes
}
```
The [examples/largeclusters/kubernetes.json](https://github.com/Azure/acs-engine/blob/master/examples/largeclusters/kubernetes.json) api model example suggests how you might opt into these large cluster features following the guidelines above.
8 changes: 5 additions & 3 deletions examples/largeclusters/kubernetes.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
"orchestratorType": "Kubernetes",
"orchestratorRelease": "1.6",
"kubernetesConfig": {
"ctrlMgrNodeMonitorGracePeriod": "5m",
"ctrlMgrPodEvictionTimeout": "1m",
"ctrlMgrRouteReconciliationPeriod": "1m",
"cloudProviderBackoff": true,
"cloudProviderBackoffRetries": 6,
"cloudProviderBackoffJitter": 1,
Expand All @@ -18,6 +15,11 @@
"cloudProviderRateLimitBucket": 10,
"kubeletConfig": {
"--node-status-update-frequency": "1m"
},
"controllerManagerConfig": {
"--node-monitor-grace-period": "5m",
"--pod-eviction-timeout": "1m",
"--route-reconciliation-period": "1m"
}
}
},
Expand Down
7 changes: 3 additions & 4 deletions parts/k8s/kubernetesmastercustomdata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ MASTER_ARTIFACTS_CONFIG_PLACEHOLDER
{{end}}
sed -i "s|<kubernetesAddonManagerSpec>|{{WrapAsVariable "kubernetesAddonManagerSpec"}}|g" "/etc/kubernetes/manifests/kube-addon-manager.yaml"
sed -i "s|<kubernetesHyperkubeSpec>|{{WrapAsVariable "kubernetesHyperkubeSpec"}}|g; s|<kubeServiceCidr>|{{WrapAsVariable "kubeServiceCidr"}}|g; s|<masterEtcdClientPort>|{{WrapAsVariable "masterEtcdClientPort"}}|g; s|<kubernetesAPIServerIP>|{{WrapAsVariable "kubernetesAPIServerIP"}}|g" "/etc/kubernetes/manifests/kube-apiserver.yaml"
sed -i "s|<kubernetesHyperkubeSpec>|{{WrapAsVariable "kubernetesHyperkubeSpec"}}|g; s|<masterFqdnPrefix>|{{WrapAsVariable "masterFqdnPrefix"}}|g; s|<allocateNodeCidrs>|{{WrapAsVariable "allocateNodeCidrs"}}|g; s|<kubeClusterCidr>|{{WrapAsVariable "kubeClusterCidr"}}|g; s|<kubernetesCtrlMgrNodeMonitorGracePeriod>|{{WrapAsVariable "kubernetesCtrlMgrNodeMonitorGracePeriod"}}|g; s|<kubernetesCtrlMgrPodEvictionTimeout>|{{WrapAsVariable "kubernetesCtrlMgrPodEvictionTimeout"}}|g; s|<kubernetesCtrlMgrRouteReconciliationPeriod>|{{WrapAsVariable "kubernetesCtrlMgrRouteReconciliationPeriod"}}|g" "/etc/kubernetes/manifests/kube-controller-manager.yaml"
sed -i "s|<kubernetesHyperkubeSpec>|{{WrapAsVariable "kubernetesHyperkubeSpec"}}|g" "/etc/kubernetes/manifests/kube-controller-manager.yaml"
sed -i "s|<kubernetesHyperkubeSpec>|{{WrapAsVariable "kubernetesHyperkubeSpec"}}|g" "/etc/kubernetes/manifests/kube-scheduler.yaml"
sed -i "s|<kubernetesHyperkubeSpec>|{{WrapAsVariable "kubernetesHyperkubeSpec"}}|g; s|<kubeClusterCidr>|{{WrapAsVariable "kubeClusterCidr"}}|g" "/etc/kubernetes/addons/kube-proxy-daemonset.yaml"
sed -i "s|<kubernetesKubeDNSSpec>|{{WrapAsVariable "kubernetesKubeDNSSpec"}}|g; s|<kubernetesDNSMasqSpec>|{{WrapAsVariable "kubernetesDNSMasqSpec"}}|g; s|<kubernetesExecHealthzSpec>|{{WrapAsVariable "kubernetesExecHealthzSpec"}}|g" "/etc/kubernetes/addons/kube-dns-deployment.yaml"
Expand Down Expand Up @@ -228,10 +228,8 @@ MASTER_ARTIFACTS_CONFIG_PLACEHOLDER
{{if .OrchestratorProfile.KubernetesConfig.EnableRbac }}
# If RBAC enabled then add parameters to API server and Controller manager configuration
sed -i "s|<kubernetesEnableRbac>|--authorization-mode=RBAC|g" "/etc/kubernetes/manifests/kube-apiserver.yaml"
sed -i "s|<kubernetesEnableRbac>|--use-service-account-credentials|g" "/etc/kubernetes/manifests/kube-controller-manager.yaml"
{{else}}
sed -i "/<kubernetesEnableRbac>/d" "/etc/kubernetes/manifests/kube-apiserver.yaml"
sed -i "/<kubernetesEnableRbac>/d" "/etc/kubernetes/manifests/kube-controller-manager.yaml"
{{end}}

{{if eq .OrchestratorProfile.KubernetesConfig.NetworkPolicy "calico"}}
Expand All @@ -251,14 +249,15 @@ MASTER_ARTIFACTS_CONFIG_PLACEHOLDER
sed -i "s|<etcdApiVersion>|{{ .OrchestratorProfile.GetAPIServerEtcdAPIVersion }}|g" "/etc/kubernetes/manifests/kube-apiserver.yaml"

{{if UseCloudControllerManager }}
sed -i "s|<kubernetesCcmImageSpec>|{{WrapAsVariable "kubernetesCcmImageSpec"}}|g; s|<masterFqdnPrefix>|{{WrapAsVariable "masterFqdnPrefix"}}|g; s|<allocateNodeCidrs>|{{WrapAsVariable "allocateNodeCidrs"}}|g; s|<kubeClusterCidr>|{{WrapAsVariable "kubeClusterCidr"}}|g; s|<kubernetesCtrlMgrRouteReconciliationPeriod>|{{WrapAsVariable "kubernetesCtrlMgrRouteReconciliationPeriod"}}|g" \
sed -i "s|<kubernetesCcmImageSpec>|{{WrapAsVariable "kubernetesCcmImageSpec"}}|g; s|<masterFqdnPrefix>|{{WrapAsVariable "masterFqdnPrefix"}}|g; s|<allocateNodeCidrs>|{{WrapAsVariable "allocateNodeCidrs"}}|g; s|<kubeClusterCidr>|{{WrapAsVariable "kubeClusterCidr"}}|g; s|<kubernetesCtrlMgrRouteReconciliationPeriod>|{{GetCloudControllerManagerRouteReconciliationPeriod .OrchestratorProfile.KubernetesConfig}}|g" \
/etc/kubernetes/manifests/cloud-controller-manager.yaml

sed -i "/--\(cloud-config\|cloud-provider\|route-reconciliation-period\)=/d" \
/etc/kubernetes/manifests/kube-controller-manager.yaml
sed -i "/--\(cloud-config\|cloud-provider\)=/d" \
/etc/kubernetes/manifests/kube-apiserver.yaml
{{end}}
sed -i "s|<kubernetesControllerManagerConfig>|{{GetControllerManagerConfigKeyVals .OrchestratorProfile.KubernetesConfig}}|g" "/etc/kubernetes/manifests/kube-controller-manager.yaml"

- path: "/opt/azure/containers/provision.sh"
permissions: "0744"
Expand Down
3 changes: 0 additions & 3 deletions parts/k8s/kubernetesmastervars.t
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@
"kubernetesReschedulerCPULimit": "[parameters('kubernetesReschedulerCPULimit')]",
"kubernetesReschedulerMemoryLimit": "[parameters('kubernetesReschedulerMemoryLimit')]",
"kubernetesPodInfraContainerSpec": "[parameters('kubernetesPodInfraContainerSpec')]",
"kubernetesCtrlMgrNodeMonitorGracePeriod": "[parameters('kubernetesCtrlMgrNodeMonitorGracePeriod')]",
"kubernetesCtrlMgrPodEvictionTimeout": "[parameters('kubernetesCtrlMgrPodEvictionTimeout')]",
"kubernetesCtrlMgrRouteReconciliationPeriod": "[parameters('kubernetesCtrlMgrRouteReconciliationPeriod')]",
"cloudProviderBackoff": "[parameters('cloudProviderBackoff')]",
"cloudProviderBackoffRetries": "[parameters('cloudProviderBackoffRetries')]",
"cloudProviderBackoffExponent": "[parameters('cloudProviderBackoffExponent')]",
Expand Down
21 changes: 0 additions & 21 deletions parts/k8s/kubernetesparams.t
Original file line number Diff line number Diff line change
Expand Up @@ -408,27 +408,6 @@
},
"type": "string"
},
"kubernetesCtrlMgrNodeMonitorGracePeriod": {
{{PopulateClassicModeDefaultValue "kubernetesCtrlMgrNodeMonitorGracePeriod"}}
"metadata": {
"description": "Kubernetes controller manager grace period for node status updates."
},
"type": "string"
},
"kubernetesCtrlMgrPodEvictionTimeout": {
{{PopulateClassicModeDefaultValue "kubernetesCtrlMgrPodEvictionTimeout"}}
"metadata": {
"description": "Kubernetes controller manager pod eviction timeout."
},
"type": "string"
},
"kubernetesCtrlMgrRouteReconciliationPeriod": {
{{PopulateClassicModeDefaultValue "kubernetesCtrlMgrRouteReconciliationPeriod"}}
"metadata": {
"description": "Kubernetes controller manager route reconciliation period."
},
"type": "string"
},
"cloudProviderBackoff": {
{{PopulateClassicModeDefaultValue "cloudProviderBackoff"}}
"metadata": {
Expand Down
22 changes: 2 additions & 20 deletions parts/k8s/manifests/kubernetesmaster-kube-controller-manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,8 @@ spec:
containers:
- name: "kube-controller-manager"
image: "<kubernetesHyperkubeSpec>"
command:
- "/hyperkube"
- "controller-manager"
- "--kubeconfig=/var/lib/kubelet/kubeconfig"
- "--allocate-node-cidrs=<allocateNodeCidrs>"
- "--cluster-cidr=<kubeClusterCidr>"
- "--cluster-name=<masterFqdnPrefix>"
- "--cloud-provider=azure"
- "--cloud-config=/etc/kubernetes/azure.json"
- "--root-ca-file=/etc/kubernetes/certs/ca.crt"
- "--cluster-signing-cert-file=/etc/kubernetes/certs/ca.crt"
- "--cluster-signing-key-file=/etc/kubernetes/certs/ca.key"
- "--service-account-private-key-file=/etc/kubernetes/certs/apiserver.key"
- "--leader-elect=true"
- "<kubernetesEnableRbac>"
- "--v=2"
- "--node-monitor-grace-period=<kubernetesCtrlMgrNodeMonitorGracePeriod>"
- "--pod-eviction-timeout=<kubernetesCtrlMgrPodEvictionTimeout>"
- "--route-reconciliation-period=<kubernetesCtrlMgrRouteReconciliationPeriod>"
- "--profiling=false"
command: ["/hyperkube", "controller-manager"]
args: [<kubernetesControllerManagerConfig>]
volumeMounts:
- name: "etc-kubernetes"
mountPath: "/etc/kubernetes"
Expand Down
75 changes: 75 additions & 0 deletions pkg/acsengine/defaults-controller-manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package acsengine

import (
"strconv"

"github.com/Azure/acs-engine/pkg/api"
)

func setControllerManagerConfig(cs *api.ContainerService) {
o := cs.Properties.OrchestratorProfile
staticLinuxControllerManagerConfig := map[string]string{
"--kubeconfig": "/var/lib/kubelet/kubeconfig",
"--allocate-node-cidrs": strconv.FormatBool(!o.IsAzureCNI()),
"--cluster-cidr": o.KubernetesConfig.ClusterSubnet,
"--cloud-provider": "azure",
"--cloud-config": "/etc/kubernetes/azure.json",
"--root-ca-file": "/etc/kubernetes/certs/ca.crt",
"--cluster-signing-cert-file": "/etc/kubernetes/certs/ca.crt",
"--cluster-signing-key-file": "/etc/kubernetes/certs/ca.key",
"--service-account-private-key-file": "/etc/kubernetes/certs/apiserver.key",
"--leader-elect": "true",
"--v": "2",
"--profiling": "False",
}

// Set --cluster-name based on appropriate DNS prefix
if cs.Properties.MasterProfile != nil {
staticLinuxControllerManagerConfig["--cluster-name"] = cs.Properties.MasterProfile.DNSPrefix
} else if cs.Properties.HostedMasterProfile != nil {
staticLinuxControllerManagerConfig["--cluster-name"] = cs.Properties.HostedMasterProfile.DNSPrefix
}

staticWindowsControllerManagerConfig := make(map[string]string)
for key, val := range staticLinuxControllerManagerConfig {
staticWindowsControllerManagerConfig[key] = val
}
// Windows controller-manager config overrides
// TODO placeholder for specific config overrides for Windows clusters

// Default controller-manager config
defaultControllerManagerConfig := map[string]string{
"--node-monitor-grace-period": DefaultKubernetesCtrlMgrNodeMonitorGracePeriod,
"--pod-eviction-timeout": DefaultKubernetesCtrlMgrPodEvictionTimeout,
"--route-reconciliation-period": DefaultKubernetesCtrlMgrRouteReconciliationPeriod,
}

// If no user-configurable controller-manager config values exists, use the defaults
if o.KubernetesConfig.ControllerManagerConfig == nil {
o.KubernetesConfig.ControllerManagerConfig = defaultControllerManagerConfig
} else {
for key, val := range defaultControllerManagerConfig {
// If we don't have a user-configurable controller-manager config for each option
if _, ok := o.KubernetesConfig.ControllerManagerConfig[key]; !ok {
// then assign the default value
o.KubernetesConfig.ControllerManagerConfig[key] = val
}
}
}

// We don't support user-configurable values for the following,
// so any of the value assignments below will override user-provided values
var overrideControllerManagerConfig map[string]string
if cs.Properties.HasWindows() {
overrideControllerManagerConfig = staticWindowsControllerManagerConfig
} else {
overrideControllerManagerConfig = staticLinuxControllerManagerConfig
}
for key, val := range overrideControllerManagerConfig {
o.KubernetesConfig.ControllerManagerConfig[key] = val
}

if *o.KubernetesConfig.EnableRbac {
o.KubernetesConfig.ControllerManagerConfig["--use-service-account-credentials"] = "true"
}
}
106 changes: 106 additions & 0 deletions pkg/acsengine/defaults-kubelet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package acsengine

import (
"strconv"

"github.com/Azure/acs-engine/pkg/api"
"github.com/Azure/acs-engine/pkg/helpers"
)

func setKubeletConfig(cs *api.ContainerService) {
o := cs.Properties.OrchestratorProfile
cloudSpecConfig := GetCloudSpecConfig(cs.Location)
staticLinuxKubeletConfig := map[string]string{
"--address": "0.0.0.0",
"--allow-privileged": "true",
"--pod-manifest-path": "/etc/kubernetes/manifests",
"--cloud-config": "/etc/kubernetes/azure.json",
"--cluster-domain": "cluster.local",
"--cluster-dns": DefaultKubernetesDNSServiceIP,
"--cgroups-per-qos": "false",
"--enforce-node-allocatable": "",
"--kubeconfig": "/var/lib/kubelet/kubeconfig",
"--azure-container-registry-config": "/etc/kubernetes/azure.json",
}

staticWindowsKubeletConfig := make(map[string]string)
for key, val := range staticLinuxKubeletConfig {
staticWindowsKubeletConfig[key] = val
}
// Windows kubelet config overrides
staticWindowsKubeletConfig["--network-plugin"] = NetworkPluginKubenet

// Default Kubelet config
defaultKubeletConfig := map[string]string{
"--network-plugin": "cni",
"--pod-infra-container-image": cloudSpecConfig.KubernetesSpecConfig.KubernetesImageBase + KubeConfigs[o.OrchestratorVersion]["pause"],
"--max-pods": strconv.Itoa(DefaultKubernetesKubeletMaxPods),
"--eviction-hard": DefaultKubernetesHardEvictionThreshold,
"--node-status-update-frequency": KubeConfigs[o.OrchestratorVersion]["nodestatusfreq"],
"--image-gc-high-threshold": strconv.Itoa(DefaultKubernetesGCHighThreshold),
"--image-gc-low-threshold": strconv.Itoa(DefaultKubernetesGCLowThreshold),
"--non-masquerade-cidr": DefaultNonMasqueradeCidr,
"--cloud-provider": "azure",
}

// If no user-configurable kubelet config values exists, use the defaults
setMissingKubeletValues(o.KubernetesConfig, defaultKubeletConfig)

// Override default cloud-provider?
if helpers.IsTrueBoolPointer(o.KubernetesConfig.UseCloudControllerManager) {
staticLinuxKubeletConfig["--cloud-provider"] = "external"
}

// Override default --network-plugin?
if o.KubernetesConfig.NetworkPolicy == NetworkPolicyNone {
o.KubernetesConfig.KubeletConfig["--network-plugin"] = NetworkPluginKubenet
}

// We don't support user-configurable values for the following,
// so any of the value assignments below will override user-provided values
var overrideKubeletConfig map[string]string
if cs.Properties.HasWindows() {
overrideKubeletConfig = staticWindowsKubeletConfig
} else {
overrideKubeletConfig = staticLinuxKubeletConfig
}
for key, val := range overrideKubeletConfig {
o.KubernetesConfig.KubeletConfig[key] = val
}

// Get rid of values not supported in v1.5 clusters
if !isKubernetesVersionGe(o.OrchestratorVersion, "1.6.0") {
for _, key := range []string{"--non-masquerade-cidr", "--cgroups-per-qos", "--enforce-node-allocatable"} {
delete(o.KubernetesConfig.KubeletConfig, key)
}
}

// Master-specific kubelet config changes go here
if cs.Properties.MasterProfile != nil {
if cs.Properties.MasterProfile.KubernetesConfig == nil {
cs.Properties.MasterProfile.KubernetesConfig = &api.KubernetesConfig{}
}
setMissingKubeletValues(cs.Properties.MasterProfile.KubernetesConfig, o.KubernetesConfig.KubeletConfig)
}
// Agent-specific kubelet config changes go here
for _, profile := range cs.Properties.AgentPoolProfiles {
if profile.KubernetesConfig == nil {
profile.KubernetesConfig = &api.KubernetesConfig{}
}
setMissingKubeletValues(profile.KubernetesConfig, o.KubernetesConfig.KubeletConfig)
}
}

func setMissingKubeletValues(p *api.KubernetesConfig, d map[string]string) {
if p.KubeletConfig == nil {
p.KubeletConfig = d
} else {
for key, val := range d {
// If we don't have a user-configurable value for each option
if _, ok := p.KubeletConfig[key]; !ok {
// then assign the default value
p.KubeletConfig[key] = val
}
}
}
}
Loading

0 comments on commit 39081b8

Please sign in to comment.