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

chore: don't require azure.json on node vms #2849

Merged

Conversation

jackfrancis
Copy link
Member

Reason for Change:

This PR supports empty string ("") values for kubeletConfig configuration properties, to reflect that those values are interpreted significantly by the kubelet runtime. Specifically, when these three properties are empty strings, it tells the kubelet runtime that it is not running in an azure cloudprovider context (e.g., on a master vm):

"--cloud-provider":                  "",
"--cloud-config":                    "",
"--azure-container-registry-config": ""

To accommodate the significance of the above configuration set, this PR delivers the /etc/kubernetes/azure.json file to node vms only if those above three configuration properties are not all empty. In other words, if any one of the above properties is not "", then /etc/kubernetes/azure.json is paved on the vm just as it is prior to this change.

Issue Fixed:

Requirements:

Notes:

@codecov
Copy link

codecov bot commented Mar 6, 2020

Codecov Report

Merging #2849 into master will decrease coverage by 0.01%.
The diff coverage is 80.95%.

@@            Coverage Diff             @@
##           master    #2849      +/-   ##
==========================================
- Coverage   72.47%   72.45%   -0.02%     
==========================================
  Files         140      140              
  Lines       25589    25629      +40     
==========================================
+ Hits        18545    18569      +24     
- Misses       5976     5987      +11     
- Partials     1068     1073       +5

echo "${KUBELET_PRIVATE_KEY}" | base64 --decode > "${KUBELET_PRIVATE_KEY_PATH}"
echo "${APISERVER_PUBLIC_KEY}" | base64 --decode > "${APISERVER_PUBLIC_KEY_PATH}"
configureKubeletServerCert
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved this up here to accommodate the "return early if no azure.json" logic. It's not related to the azure.json paving, so can be done in any order.

AZURE_JSON_PATH="/etc/kubernetes/azure.json"
if [[ -n "${MASTER_NODE}" ]]; then
if [[ "${ENABLE_AGGREGATED_APIS}" = True ]]; then
generateAggregatedAPICerts
Copy link
Member Author

Choose a reason for hiding this comment

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

Ditto moved this up earlier as well.

@@ -33,7 +33,7 @@ func (cs *ContainerService) setKubeletConfig(isUpgrade bool) {
switch key {
case "--anonymous-auth", "--client-ca-file":
if !to.Bool(o.KubernetesConfig.EnableSecureKubelet) { // Don't add if EnableSecureKubelet is disabled
staticLinuxKubeletConfig[key] = ""
delete(staticLinuxKubeletConfig, key)
Copy link
Member Author

Choose a reason for hiding this comment

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

Now that we are no longer deleting empty string keys in the removeKubeletFlags func we do it here.

@@ -270,13 +270,6 @@ func removeKubeletFlags(k map[string]string, v string) {
delete(k, key)
}
}

// Get rid of keys with empty string values
Copy link
Member Author

Choose a reason for hiding this comment

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

We don't remove empty string valued keys because they are significant

@@ -2166,3 +2167,77 @@ func TestReadOnlyPort(t *testing.T) {
}

}

func TestRemoveKubeletFlags(t *testing.T) {
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 never had UT coverage

// RequiresCloudproviderConfig returns true if the azure.json cloudprovider config should be delivered to the nodes in this pool
func (a *AgentPoolProfile) RequiresCloudproviderConfig() bool {
if a.KubernetesConfig != nil && a.KubernetesConfig.KubeletConfig != nil {
if v, ok := a.KubernetesConfig.KubeletConfig["--cloud-provider"]; ok {
Copy link
Member Author

Choose a reason for hiding this comment

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

Open to a better way to implement this logic. The UT cases below tell the truth in terms of proving that we're doing what we want to do.

Copy link

Choose a reason for hiding this comment

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

The logic could also be stated as:

if all 3 keys exist in the config with a value of empty string ""
return false
else
return true

Right? Just making sure I'm reading it correctly.

Copy link

Choose a reason for hiding this comment

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

Never mind, I read the UT. :-)

generateAggregatedAPICerts
fi
else
{{- /* If we are a node vm then we only proceed w/ local azure.json configuration if cloud-init has pre-paved that file */}}
Copy link
Member Author

Choose a reason for hiding this comment

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

To be clear, we are not pre-paving azure.json for master vms (note that there is no diff to masternodecustomdata.yml. The existing code (specifically cat << EOF > "${AZURE_JSON_PATH}") works as-is whether or not the file is there (the > "${AZURE_JSON_PATH}" part). So we are just using the pre-existence of azure.json, in a non-master flow only, to determine whether or not we will include the azure.json on this node. If the "check for file" test fails, we return immediately, because that tells us we aren't including azure.json on this node.

This works because:

  1. we are paving azure.json on nodes, if needed, prior to paving this file itself (cse_config.sh in code, and /opt/azure/containers/provision_configs.sh on the local vm fs)
  2. we are waiting for this file in cse_main.sh before executing code in this file, and because the cloud-init write_files property is a yaml sequence, those will be processed in order. Thus, by the time we are in this execution flow, if azure.json should be here, it will be here.

// RequiresCloudproviderConfig returns true if the azure.json cloudprovider config should be delivered to the nodes in this pool
func (a *AgentPoolProfile) RequiresCloudproviderConfig() bool {
if a.KubernetesConfig != nil && a.KubernetesConfig.KubeletConfig != nil {
if v, ok := a.KubernetesConfig.KubeletConfig["--cloud-provider"]; ok {
Copy link

Choose a reason for hiding this comment

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

The logic could also be stated as:

if all 3 keys exist in the config with a value of empty string ""
return false
else
return true

Right? Just making sure I'm reading it correctly.

// RequiresCloudproviderConfig returns true if the azure.json cloudprovider config should be delivered to the nodes in this pool
func (a *AgentPoolProfile) RequiresCloudproviderConfig() bool {
if a.KubernetesConfig != nil && a.KubernetesConfig.KubeletConfig != nil {
if v, ok := a.KubernetesConfig.KubeletConfig["--cloud-provider"]; ok {
Copy link

Choose a reason for hiding this comment

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

Never mind, I read the UT. :-)

parts/k8s/cloud-init/nodecustomdata.yml Show resolved Hide resolved
Copy link
Member

@mboersma mboersma left a comment

Choose a reason for hiding this comment

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

/lgtm

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants