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

Generic controller-manager config #1960

Merged
merged 7 commits into from
Dec 22, 2017
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
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) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since o.KubernetesConfig.ControllerManagerConfig is now exposed to user, it looks we allow user to define other configs beyond the list below (default + static + rbac) but in https://kubernetes.io/docs/reference/generated/kube-controller-manager/ . Do we want to support this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's what this statement in the doc update supports:

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.

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