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

generic Kubernetes API server config interface #2012

Merged
merged 10 commits into from Jan 9, 2018
57 changes: 55 additions & 2 deletions docs/clusterdefinition.md
Expand Up @@ -209,7 +209,7 @@ Below is a list of controller-manager options that acs-engine will configure by
|"--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:
Below is a list of controller-manager options that are *not* currently user-configurable, either because a higher order configuration vector is available that enforces controller-manager configuration, or because a static configuration is required to build a functional cluster:
Copy link
Member Author

Choose a reason for hiding this comment

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

Correcting copy/paste errors from a prior, related PR.


|controller-manager option|default value|
|---|---|
Expand All @@ -228,7 +228,60 @@ Below is a list of kubelet options that are *not* currently user-configurable, e
|"--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.
#### apiServerConfig

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

```
"kubernetesConfig": {
"apiServerConfig": {
"--request-timeout": "30s"
}
}
```

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

Below is a list of apiserver 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:

|apiserver option|default value|
|---|---|
|"--admission-control"|"NamespaceLifecycle, LimitRanger, ServiceAccount, DefaultStorageClass, ResourceQuota, DenyEscalatingExec"|
|"--address"|"0.0.0.0"|
|"--advertise-address"|*calculated value that represents listening URI for API server*|
|"--allow-privileged"|"true"|
|"--insecure-port"|"8080"|
|"--secure-port"|"443"|
|"--etcd-cafile"|"/etc/kubernetes/certs/ca.crt"|
|"--etcd-certfile"|"/etc/kubernetes/certs/etcdclient.crt"|
|"--etcd-keyfile"|"/etc/kubernetes/certs/etcdclient.key"|
|"--etcd-servers"|*calculated value that represents etcd servers*|
|"--etcd-quorum-read"|"true"|
|"--tls-cert-file"|"/etc/kubernetes/certs/apiserver.crt"|
|"--tls-private-key-file"|"/etc/kubernetes/certs/apiserver.key"|
|"--client-ca-file"|"/etc/kubernetes/certs/ca.crt"|
|"--service-account-key-file"|"/etc/kubernetes/certs/apiserver.key"|
|"--kubelet-client-certificate"|"/etc/kubernetes/certs/client.crt"|
|"--kubelet-client-key"|"/etc/kubernetes/certs/client.key"|
|"--service-cluster-ip-range"|*see serviceCIDR*|
|"--storage-backend"|*calculated value that represents etcd version*|
|"--v"|"4"|
|"--authorization-mode"|"RBAC" (*if enabledRbac is true*)|
|"--experimental-encryption-provider-config"|"/etc/kubernetes/encryption-config.yaml" (*if enableDataEncryptionAtRest is true*)|
|"--requestheader-client-ca-file"|"/etc/kubernetes/certs/proxy-ca.crt" (*if enableAggregatedAPIs is true*)|
|"--proxy-client-cert-file"|"/etc/kubernetes/certs/proxy.crt" (*if enableAggregatedAPIs is true*)|
|"--proxy-client-key-file"|"/etc/kubernetes/certs/proxy.key" (*if enableAggregatedAPIs is true*)|
|"--requestheader-allowed-names"|"" (*if enableAggregatedAPIs is true*)|
|"--requestheader-extra-headers-prefix"|"X-Remote-Extra-" (*if enableAggregatedAPIs is true*)|
|"--requestheader-group-headers"|"X-Remote-Group" (*if enableAggregatedAPIs is true*)|
|"--requestheader-username-headers"|"X-Remote-User" (*if enableAggregatedAPIs is true*)|
|"--cloud-provider"|"azure" (*unless useCloudControllerManager is true*)|
|"--cloud-config"|"/etc/kubernetes/azure.json" (*unless useCloudControllerManager is true*)|
|"--oidc-username-claim"|"oid" (*if has AADProfile*)|
|"--oidc-client-id"|*calculated value that represents OID client ID* (*if has AADProfile*)|
|"--oidc-issuer-url"|*calculated value that represents OID issuer URL* (*if has AADProfile*)|

We consider `kubeletConfig`, `controllerManagerConfig`, and `apiServerConfig` 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
53 changes: 9 additions & 44 deletions parts/k8s/kubernetesmastercustomdata.yml
Expand Up @@ -180,25 +180,8 @@ MASTER_ARTIFACTS_CONFIG_PLACEHOLDER
# SNAT outbound traffic from pods to destinations outside of VNET.
iptables -t nat -A POSTROUTING -m iprange ! --dst-range 168.63.129.16 -m addrtype ! --dst-type local ! -d {{WrapAsVariable "vnetCidr"}} -j MASQUERADE
{{end}}

{{ if .HasAadProfile }}
OIDC_CLIENT_ID=spn:{{WrapAsVariable "aadServerAppId"}}
VAR_AAD_TENANT_ID={{WrapAsVariable "aadTenantId"}}
VAR_TENANT_ID={{WrapAsVariable "tenantId"}}
VAR_TARGET_ENV={{WrapAsVariable "targetEnvironment"}}
AAD_TENANT_ID=${VAR_AAD_TENANT_ID:-$VAR_TENANT_ID}
AAD_ISSUER_HOST="sts.windows.net"
if [ "$VAR_TARGET_ENV" = "AzureChinaCloud" ]; then
AAD_ISSUER_HOST="sts.chinacloudapi.cn"
fi

OIDC_ISSUER_URL="https://$AAD_ISSUER_HOST/$AAD_TENANT_ID/"
perl -pi -e "s|--oidc-client-id=\K(?=\")|$OIDC_CLIENT_ID| || s|--oidc-issuer-url=\K(?=\")|$OIDC_ISSUER_URL|" "/etc/kubernetes/manifests/kube-apiserver.yaml"
{{else}}
sed -i "/--oidc-client-id\|--oidc-issuer-url\|--oidc-username-claim/d" "/etc/kubernetes/manifests/kube-apiserver.yaml"
{{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" "/etc/kubernetes/manifests/kube-apiserver.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"
Expand Down Expand Up @@ -245,47 +228,29 @@ MASTER_ARTIFACTS_CONFIG_PLACEHOLDER
sed -i "s|<kubernetesReschedulerMemoryLimit>|{{WrapAsVariable "kubernetesReschedulerMemoryLimit"}}|g" "/etc/kubernetes/addons/kube-rescheduler-deployment.yaml"
{{end}}

{{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"
{{else}}
sed -i "/<kubernetesEnableRbac>/d" "/etc/kubernetes/manifests/kube-apiserver.yaml"
{{end}}

{{if EnableDataEncryptionAtRest }}
ETCD_ENCRYPTION_SECRET="$(head -c 32 /dev/urandom | base64)"
sed -i "s|<etcdEncryptionSecret>|$ETCD_ENCRYPTION_SECRET|g" "/etc/kubernetes/encryption-config.yaml"
sed -i "s|<kubernetesEnableEtcdEncryption>|--experimental-encryption-provider-config=/etc/kubernetes/encryption-config.yaml|g" "/etc/kubernetes/manifests/kube-apiserver.yaml"
{{else}}
sed -i "/<kubernetesEnableEtcdEncryption>/d" "/etc/kubernetes/manifests/kube-apiserver.yaml"
{{end}}

{{if eq .OrchestratorProfile.KubernetesConfig.NetworkPolicy "calico"}}
# If Calico Policy enabled then update Cluster Cidr
sed -i "s|<kubeClusterCidr>|{{WrapAsVariable "kubeClusterCidr"}}|g" "/etc/kubernetes/addons/calico-daemonset.yaml"
{{end}}

{{if not .OrchestratorProfile.KubernetesConfig.EnableAggregatedAPIs}}
sed -i "/requestheader-client-ca-file/d" "/etc/kubernetes/manifests/kube-apiserver.yaml"
sed -i "/proxy-client-cert-file/d" "/etc/kubernetes/manifests/kube-apiserver.yaml"
sed -i "/proxy-client-key-file/d" "/etc/kubernetes/manifests/kube-apiserver.yaml"
sed -i "/requestheader-allowed-names/d" "/etc/kubernetes/manifests/kube-apiserver.yaml"
sed -i "/requestheader-extra-headers-prefix/d" "/etc/kubernetes/manifests/kube-apiserver.yaml"
sed -i "/requestheader-group-headers/d" "/etc/kubernetes/manifests/kube-apiserver.yaml"
sed -i "/requestheader-username-headers/d" "/etc/kubernetes/manifests/kube-apiserver.yaml"
{{end}}
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>|{{GetCloudControllerManagerRouteReconciliationPeriod .OrchestratorProfile.KubernetesConfig}}|g" \
/etc/kubernetes/manifests/cloud-controller-manager.yaml

sed -i "/--\(cloud-config\|cloud-provider\|route-reconciliation-period\)=/d" \
Copy link
Member Author

Choose a reason for hiding this comment

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

This should have been removed in #1960, doing so now.

/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"
sed -i "s|<kubernetesAPIServerConfig>|{{GetAPIServerConfigKeyVals .OrchestratorProfile.KubernetesConfig}}|g" "/etc/kubernetes/manifests/kube-apiserver.yaml"
Copy link
Collaborator

Choose a reason for hiding this comment

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

It is probably better to take APIServerConfig (instead of KubernetesConfig) as argument for GetAPIServerConfigKeyVals.

The original code logic is pretty tangled here and I have not dig very deep, I assume GetAPIServerConfigKeyVals will return the already processed argument map. Please just confirm it.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is good feedback. Let's do this: after all of these config refactors are done, we can optimize the number of key/val getter functions in engine.go (we have two types, I think, which is better than having one function per config file). A part of that improvement would be passing in the specific config as the arg instead of kubernetesConfig.

sed -i "s|<kubernetesAPIServerIP>|{{WrapAsVariable "kubernetesAPIServerIP"}}|g" "/etc/kubernetes/manifests/kube-apiserver.yaml"
{{ if .HasAadProfile }}
VAR_AAD_TENANT_ID={{WrapAsVariable "aadTenantId"}}
VAR_TENANT_ID={{WrapAsVariable "tenantId"}}
AAD_TENANT_ID=${VAR_AAD_TENANT_ID:-$VAR_TENANT_ID}
sed -i "/--oidc-issuer-url/s/$/$AAD_TENANT_ID/" "/etc/kubernetes/manifests/kube-apiserver.yaml"
Copy link
Collaborator

Choose a reason for hiding this comment

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

If the above GetAPIServerConfigKeyVals returns already processed map, why are we overriding "--oidc-issuer-url" here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good question. It's because the only way (that I know of) to assign the right tenantId value is in the flow of this template: we depend upon {{WrapAsVariable "tenantId"}} as a fallback value, and that fallback value is not available in the flow of the map-producing code. See the subscription() method which the tenantId variable depends upon in kubernetesmastervars.t.

{{end}}

- path: "/opt/azure/containers/provision.sh"
permissions: "0744"
Expand Down
1 change: 0 additions & 1 deletion parts/k8s/kubernetesmastervars.t
Expand Up @@ -109,7 +109,6 @@
{{end}}
"sshPublicKeyData": "[parameters('sshRSAPublicKey')]",
{{if .HasAadProfile}}
"aadServerAppId": "[parameters('aadServerAppId')]",
"aadTenantId": "[parameters('aadTenantId')]",
{{end}}
{{if not IsHostedMaster}}
Expand Down
6 changes: 0 additions & 6 deletions parts/k8s/kubernetesparams.t
@@ -1,10 +1,4 @@
{{if .HasAadProfile}}
"aadServerAppId": {
"metadata": {
"description": "The server AAD application ID"
},
"type": "string"
},
"aadTenantId": {
"defaultValue": "",
"metadata": {
Expand Down
Expand Up @@ -21,7 +21,6 @@ spec:
- "--cloud-config=/etc/kubernetes/azure.json"
- "--leader-elect=true"
# TODO: RBAC support
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you want to remove RBAC placeholder here? Seems not related to this PR. If so, remove the above TODO comment too?

# - "<kubernetesEnableRbac>"
- "--route-reconciliation-period=<kubernetesCtrlMgrRouteReconciliationPeriod>"
- "--v=2"
volumeMounts:
Expand Down
39 changes: 2 additions & 37 deletions parts/k8s/manifests/kubernetesmaster-kube-apiserver.yaml
Expand Up @@ -11,43 +11,8 @@ spec:
containers:
- name: "kube-apiserver"
image: "<kubernetesHyperkubeSpec>"
command:
- "/hyperkube"
- "apiserver"
- "--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota,DenyEscalatingExec"
- "--address=0.0.0.0"
- "--allow-privileged"
- "--insecure-port=8080"
- "--secure-port=443"
- "--cloud-provider=azure"
- "--cloud-config=/etc/kubernetes/azure.json"
- "--service-cluster-ip-range=<kubeServiceCidr>"
- "--etcd-cafile=/etc/kubernetes/certs/ca.crt"
- "--etcd-certfile=/etc/kubernetes/certs/etcdclient.crt"
- "--etcd-keyfile=/etc/kubernetes/certs/etcdclient.key"
- "--etcd-servers=https://127.0.0.1:<masterEtcdClientPort>"
- "--etcd-quorum-read=true"
- "--advertise-address=<kubernetesAPIServerIP>"
- "--tls-cert-file=/etc/kubernetes/certs/apiserver.crt"
- "--tls-private-key-file=/etc/kubernetes/certs/apiserver.key"
- "--client-ca-file=/etc/kubernetes/certs/ca.crt"
- "--requestheader-client-ca-file=/etc/kubernetes/certs/proxy-ca.crt"
- "--proxy-client-cert-file=/etc/kubernetes/certs/proxy.crt"
- "--proxy-client-key-file=/etc/kubernetes/certs/proxy.key"
- "--service-account-key-file=/etc/kubernetes/certs/apiserver.key"
- "--kubelet-client-certificate=/etc/kubernetes/certs/client.crt"
- "--kubelet-client-key=/etc/kubernetes/certs/client.key"
- "--oidc-client-id="
- "--oidc-issuer-url="
- "--oidc-username-claim=oid"
- "--storage-backend=<etcdApiVersion>"
- "--v=4"
- "<kubernetesEnableRbac>"
- "<kubernetesEnableEtcdEncryption>"
- "--requestheader-allowed-names="
- "--requestheader-extra-headers-prefix=X-Remote-Extra-"
- "--requestheader-group-headers=X-Remote-Group"
- "--requestheader-username-headers=X-Remote-User"
command: ["/hyperkube", "apiserver"]
args: [<kubernetesAPIServerConfig>]
volumeMounts:
- name: "etc-kubernetes"
mountPath: "/etc/kubernetes"
Expand Down
105 changes: 105 additions & 0 deletions pkg/acsengine/defaults-apiserver.go
@@ -0,0 +1,105 @@
package acsengine

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

func setAPIServerConfig(cs *api.ContainerService) {
o := cs.Properties.OrchestratorProfile
staticLinuxAPIServerConfig := map[string]string{
"--admission-control": "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota,DenyEscalatingExec",
"--address": "0.0.0.0",
"--advertise-address": "<kubernetesAPIServerIP>",
"--allow-privileged": "true",
"--insecure-port": "8080",
"--secure-port": "443",
"--etcd-cafile": "/etc/kubernetes/certs/ca.crt",
"--etcd-certfile": "/etc/kubernetes/certs/etcdclient.crt",
"--etcd-keyfile": "/etc/kubernetes/certs/etcdclient.key",
"--etcd-servers": "https://127.0.0.1:2379",
"--etcd-quorum-read": "true",
"--tls-cert-file": "/etc/kubernetes/certs/apiserver.crt",
"--tls-private-key-file": "/etc/kubernetes/certs/apiserver.key",
"--client-ca-file": "/etc/kubernetes/certs/ca.crt",
"--service-account-key-file": "/etc/kubernetes/certs/apiserver.key",
"--kubelet-client-certificate": "/etc/kubernetes/certs/client.crt",
"--kubelet-client-key": "/etc/kubernetes/certs/client.key",
"--service-cluster-ip-range": o.KubernetesConfig.ServiceCIDR,
"--storage-backend": o.GetAPIServerEtcdAPIVersion(),
"--v": "4",
}

// RBAC configuration
if helpers.IsTrueBoolPointer(o.KubernetesConfig.EnableRbac) {
staticLinuxAPIServerConfig["--authorization-mode"] = "RBAC"
}

// Data Encryption at REST configuration
if helpers.IsTrueBoolPointer(o.KubernetesConfig.EnableDataEncryptionAtRest) {
staticLinuxAPIServerConfig["--experimental-encryption-provider-config"] = "/etc/kubernetes/encryption-config.yaml"
}

// Aggregated API configuration
if o.KubernetesConfig.EnableAggregatedAPIs {
staticLinuxAPIServerConfig["--requestheader-client-ca-file"] = "/etc/kubernetes/certs/proxy-ca.crt"
staticLinuxAPIServerConfig["--proxy-client-cert-file"] = "/etc/kubernetes/certs/proxy.crt"
staticLinuxAPIServerConfig["--proxy-client-key-file"] = "/etc/kubernetes/certs/proxy.key"
staticLinuxAPIServerConfig["--requestheader-allowed-names"] = ""
staticLinuxAPIServerConfig["--requestheader-extra-headers-prefix"] = "X-Remote-Extra-"
staticLinuxAPIServerConfig["--requestheader-group-headers"] = "X-Remote-Group"
staticLinuxAPIServerConfig["--requestheader-username-headers"] = "X-Remote-User"
}

// Enable cloudprovider if we're not using cloud controller manager
if !helpers.IsTrueBoolPointer(o.KubernetesConfig.UseCloudControllerManager) {
staticLinuxAPIServerConfig["--cloud-provider"] = "azure"
staticLinuxAPIServerConfig["--cloud-config"] = "/etc/kubernetes/azure.json"
}

// AAD configuration
if cs.Properties.HasAadProfile() {
staticLinuxAPIServerConfig["--oidc-username-claim"] = "oid"
staticLinuxAPIServerConfig["--oidc-client-id"] = "spn:" + cs.Properties.AADProfile.ServerAppID
issuerHost := "sts.windows.net"
if GetCloudTargetEnv(cs.Location) == "AzureChinaCloud" {
issuerHost = "sts.chinacloudapi.cn"
}
staticLinuxAPIServerConfig["--oidc-issuer-url"] = "https://" + issuerHost + "/"
}

staticWindowsAPIServerConfig := make(map[string]string)
for key, val := range staticLinuxAPIServerConfig {
staticWindowsAPIServerConfig[key] = val
}
// Windows apiserver config overrides
// TODO placeholder for specific config overrides for Windows clusters

// Default apiserver config
defaultAPIServerConfig := map[string]string{}

// If no user-configurable apiserver config values exists, use the defaults
if o.KubernetesConfig.APIServerConfig == nil {
o.KubernetesConfig.APIServerConfig = defaultAPIServerConfig
} else {
for key, val := range defaultAPIServerConfig {
// If we don't have a user-configurable apiserver config for each option
if _, ok := o.KubernetesConfig.APIServerConfig[key]; !ok {
// then assign the default value
o.KubernetesConfig.APIServerConfig[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 overrideAPIServerConfig map[string]string
if cs.Properties.HasWindows() {
overrideAPIServerConfig = staticWindowsAPIServerConfig
} else {
overrideAPIServerConfig = staticLinuxAPIServerConfig
}
for key, val := range overrideAPIServerConfig {
o.KubernetesConfig.APIServerConfig[key] = val
Copy link
Collaborator

Choose a reason for hiding this comment

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

Some argument like "--admission-control" and "--authorization-mode" takes a list of features, and probably should allow feature addition (as long as static config is a subset of the user input config), instead of override. It can be done in a later change if needed.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree this would be a useful addition to this surface area. Feature gates also are special, in that they essentially contain key/vals themselves. Yeah, I'd prefer a follow-up PR for that.

}
}
9 changes: 7 additions & 2 deletions pkg/acsengine/defaults-controller-manager.go
Expand Up @@ -4,6 +4,7 @@ import (
"strconv"

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

func setControllerManagerConfig(cs *api.ContainerService) {
Expand All @@ -12,8 +13,6 @@ func setControllerManagerConfig(cs *api.ContainerService) {
"--kubeconfig": "/var/lib/kubelet/kubeconfig",
"--allocate-node-cidrs": strconv.FormatBool(!o.IsAzureCNI()),
"--cluster-cidr": o.KubernetesConfig.ClusterSubnet,
"--cloud-provider": "azure",
Copy link
Member Author

Choose a reason for hiding this comment

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

This should have been done in #1960, doing so now.

"--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",
Expand All @@ -30,6 +29,12 @@ func setControllerManagerConfig(cs *api.ContainerService) {
staticLinuxControllerManagerConfig["--cluster-name"] = cs.Properties.HostedMasterProfile.DNSPrefix
}

// Enable cloudprovider if we're not using cloud controller manager
Copy link
Member Author

Choose a reason for hiding this comment

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

This should have been done in #1960, doing so now.

if !helpers.IsTrueBoolPointer(o.KubernetesConfig.UseCloudControllerManager) {
staticLinuxControllerManagerConfig["--cloud-provider"] = "azure"
staticLinuxControllerManagerConfig["--cloud-config"] = "/etc/kubernetes/azure.json"
}

staticWindowsControllerManagerConfig := make(map[string]string)
for key, val := range staticLinuxControllerManagerConfig {
staticWindowsControllerManagerConfig[key] = val
Expand Down