Skip to content

Commit b4d07b5

Browse files
committed
fix: add retries to wireserver, cache first time response to avoid spam
1 parent 3602edb commit b4d07b5

File tree

67 files changed

+376
-326
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+376
-326
lines changed

parts/linux/cloud-init/artifacts/cse_config.sh

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ EOF
343343
if [ "${GPU_NODE}" = "true" ]; then
344344
# Check VM tag directly to determine if GPU drivers should be skipped
345345
export -f should_skip_nvidia_drivers
346-
should_skip=$(retrycmd_silent 10 1 10 bash -cx should_skip_nvidia_drivers)
346+
should_skip=$(should_skip_nvidia_drivers)
347347
if [ "$?" -eq 0 ] && [ "${should_skip}" = "true" ]; then
348348
echo "Generating non-GPU containerd config for GPU node due to VM tags"
349349
echo "${CONTAINERD_CONFIG_NO_GPU_CONTENT}" | base64 -d > /etc/containerd/config.toml || exit $ERR_FILE_WATCH_TIMEOUT
@@ -356,8 +356,8 @@ EOF
356356
echo "${CONTAINERD_CONFIG_CONTENT}" | base64 -d > /etc/containerd/config.toml || exit $ERR_FILE_WATCH_TIMEOUT
357357
fi
358358

359-
export -f e2e_mock_azure_china_cloud
360-
E2EMockAzureChinaCloud=$(retrycmd_silent 10 1 10 bash -cx e2e_mock_azure_china_cloud)
359+
export -f should_e2e_mock_azure_china_cloud
360+
E2EMockAzureChinaCloud=$(should_e2e_mock_azure_china_cloud)
361361
if [ -n "${BOOTSTRAP_PROFILE_CONTAINER_REGISTRY_SERVER}" ]; then
362362
logs_to_events "AKS.CSE.ensureContainerd.configureContainerdRegistryHost" configureContainerdRegistryHost
363363
elif [ "${TARGET_CLOUD}" = "AzureChinaCloud" ] || [ "${E2EMockAzureChinaCloud}" = "true" ]; then
@@ -428,23 +428,10 @@ ensureDHCPv6() {
428428
}
429429

430430
getPrimaryNicIP() {
431-
local sleepTime=1
432-
local maxRetries=10
433-
local i=0
434431
local ip=""
435-
436-
while [ "$i" -lt "$maxRetries" ]; do
437-
ip=$(curl -sSL -H "Metadata: true" "http://169.254.169.254/metadata/instance/network/interface?api-version=2021-02-01")
438-
if [ "$?" -eq 0 ]; then
439-
ip=$(echo "$ip" | jq -r '.[0].ipv4.ipAddress[0].privateIpAddress')
440-
if [ -n "$ip" ]; then
441-
break
442-
fi
443-
fi
444-
sleep $sleepTime
445-
i=$((i+1))
446-
done
447-
echo "$ip"
432+
export -f get_primary_nic_ip
433+
ip=$(get_primary_nic_ip)
434+
echo "${ip}"
448435
}
449436

450437
generateSelfSignedKubeletServingCertificate() {
@@ -470,7 +457,7 @@ configureKubeletServing() {
470457

471458
# check if kubelet serving certificate rotation is disabled by customer-specified nodepool tags
472459
export -f should_disable_kubelet_serving_certificate_rotation
473-
DISABLE_KUBELET_SERVING_CERTIFICATE_ROTATION=$(retrycmd_silent 10 1 10 bash -cx should_disable_kubelet_serving_certificate_rotation)
460+
DISABLE_KUBELET_SERVING_CERTIFICATE_ROTATION=$(should_disable_kubelet_serving_certificate_rotation)
474461
if [ "$?" -ne 0 ]; then
475462
echo "failed to determine if kubelet serving certificate rotation should be disabled by nodepool tags"
476463
exit $ERR_LOOKUP_DISABLE_KUBELET_SERVING_CERTIFICATE_ROTATION_TAG
@@ -1131,18 +1118,18 @@ configCredentialProvider() {
11311118
}
11321119

11331120
setKubeletNodeIPFlag() {
1134-
imdsOutput=$(curl -s -H Metadata:true --noproxy "*" --max-time 5 "http://169.254.169.254/metadata/instance/network/interface?api-version=2021-02-01" 2> /dev/null)
1135-
if [ "$?" -eq 0 ]; then
1136-
nodeIPAddrs=()
1137-
ipv4Addr=$(echo $imdsOutput | jq -r '.[0].ipv4.ipAddress[0].privateIpAddress // ""')
1138-
[ -n "$ipv4Addr" ] && nodeIPAddrs+=("$ipv4Addr")
1139-
ipv6Addr=$(echo $imdsOutput | jq -r '.[0].ipv6.ipAddress[0].privateIpAddress // ""')
1140-
[ -n "$ipv6Addr" ] && nodeIPAddrs+=("$ipv6Addr")
1141-
nodeIPArg=$(IFS=, ; echo "${nodeIPAddrs[*]}") # join, comma-separated
1142-
if [ -n "$nodeIPArg" ]; then
1143-
echo "Adding --node-ip=$nodeIPArg to kubelet flags"
1144-
KUBELET_FLAGS="$KUBELET_FLAGS --node-ip=$nodeIPArg"
1145-
fi
1121+
local imdsOutput
1122+
export -f get_imds_network_metadata
1123+
imdsOutput=$(get_imds_network_metadata)
1124+
nodeIPAddrs=()
1125+
ipv4Addr=$(echo $imdsOutput | jq -r '.[0].ipv4.ipAddress[0].privateIpAddress // ""')
1126+
[ -n "$ipv4Addr" ] && nodeIPAddrs+=("$ipv4Addr")
1127+
ipv6Addr=$(echo $imdsOutput | jq -r '.[0].ipv6.ipAddress[0].privateIpAddress // ""')
1128+
[ -n "$ipv6Addr" ] && nodeIPAddrs+=("$ipv6Addr")
1129+
nodeIPArg=$(IFS=, ; echo "${nodeIPAddrs[*]}") # join, comma-separated
1130+
if [ -n "$nodeIPArg" ]; then
1131+
echo "Adding --node-ip=$nodeIPArg to kubelet flags"
1132+
KUBELET_FLAGS="$KUBELET_FLAGS --node-ip=$nodeIPArg"
11461133
fi
11471134
}
11481135

parts/linux/cloud-init/artifacts/cse_helpers.sh

Lines changed: 103 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ ERR_ORAS_IMDS_TIMEOUT=210 # Error timeout waiting for IMDS response
121121
ERR_ORAS_PULL_NETWORK_TIMEOUT=211 # Error pulling oras tokens for login
122122
ERR_ORAS_PULL_UNAUTHORIZED=212 # Error pulling artifact with oras from registry with authorization issue
123123

124+
ERR_IMDS_FETCH_FAILED=231 # Error fetching or caching IMDS instance metadata
125+
124126
# Error checking nodepools tags for whether we need to disable kubelet serving certificate rotation
125127
ERR_LOOKUP_DISABLE_KUBELET_SERVING_CERTIFICATE_ROTATION_TAG=213
126128

@@ -651,70 +653,128 @@ logs_to_events() {
651653
fi
652654
}
653655

654-
should_skip_nvidia_drivers() {
656+
# Cache file for IMDS instance metadata to avoid redundant network calls.
657+
# The IMDS endpoint provides VM metadata that doesn't change during provisioning,
658+
# so we can safely cache it for the duration of CSE execution.
659+
IMDS_INSTANCE_METADATA_CACHE_FILE="/opt/azure/containers/imds_instance_metadata_cache.json"
660+
661+
# Fetches IMDS instance metadata and caches it to a file.
662+
# Exits with ERR_IMDS_FETCH_FAILED on failure.
663+
# The cache is stored in IMDS_INSTANCE_METADATA_CACHE_FILE.
664+
fetch_and_cache_imds_instance_metadata() {
655665
set -x
656-
body=$(curl -fsSL -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2021-02-01")
657-
ret=$?
658-
if [ "$ret" -ne 0 ]; then
659-
return $ret
666+
# If cache file already exists and is valid, skip fetching
667+
if [ -f "$IMDS_INSTANCE_METADATA_CACHE_FILE" ]; then
668+
# Validate the cache file contains valid JSON
669+
if jq -e . "$IMDS_INSTANCE_METADATA_CACHE_FILE" > /dev/null 2>&1; then
670+
echo "IMDS instance metadata cache already exists and is valid"
671+
return 0
672+
else
673+
echo "IMDS instance metadata cache exists but is invalid, refetching"
674+
rm -f "$IMDS_INSTANCE_METADATA_CACHE_FILE"
675+
fi
660676
fi
661-
should_skip=$(echo "$body" | jq -e '.compute.tagsList | map(select(.name | test("SkipGpuDriverInstall"; "i")))[0].value // "false" | test("true"; "i")')
677+
678+
local body
679+
body=$(curl -fsSL -H "Metadata: true" --noproxy "*" --retry 20 --retry-delay 2 --retry-connrefused --connect-timeout 5 --max-time 5 "http://169.254.169.254/metadata/instance?api-version=2021-02-01")
680+
if [ "$?" -ne 0 ]; then
681+
echo "Failed to fetch IMDS instance metadata"
682+
exit $ERR_IMDS_FETCH_FAILED
683+
fi
684+
685+
# Validate response is valid JSON before caching
686+
if ! echo "$body" | jq -e . > /dev/null 2>&1; then
687+
echo "IMDS response is not valid JSON"
688+
exit $ERR_IMDS_FETCH_FAILED
689+
fi
690+
691+
echo "$body" > "$IMDS_INSTANCE_METADATA_CACHE_FILE"
692+
echo "IMDS instance metadata cached successfully"
693+
}
694+
695+
# Retrieves IMDS network interface metadata from the cached instance metadata.
696+
# The /metadata/instance endpoint contains both compute and network data,
697+
# so we extract .network.interface from the instance metadata cache.
698+
# Outputs:
699+
# The JSON network interface array
700+
# Returns:
701+
# 0 on success, non-zero on failure
702+
get_imds_network_metadata() {
703+
local network_metadata=""
704+
network_metadata=$(jq -r '.network.interface' "$IMDS_INSTANCE_METADATA_CACHE_FILE")
705+
echo "$network_metadata"
706+
}
707+
708+
# Retrieves the primary NIC's private IPv4 address from IMDS instance metadata.
709+
# Outputs:
710+
# The private IPv4 address or empty string if not found.
711+
# Returns:
712+
# 0 on success, non-zero on failure
713+
get_primary_nic_ip() {
714+
local primary_ip=""
715+
primary_ip=$(jq -r '.network.interface[0].ipv4.ipAddress[0].privateIpAddress // ""' "$IMDS_INSTANCE_METADATA_CACHE_FILE")
716+
echo "$primary_ip"
717+
}
718+
719+
# Retrieves a VM tag value from the cached IMDS instance metadata.
720+
# Arguments:
721+
# $1 - tag_name: The name of the tag to look up (case-sensitive match)
722+
# $2 - case_insensitive_name: Optional. If "true", performs case-insensitive name matching
723+
# $3 - case_insensitive_value: Optional. If "true", performs case-insensitive value matching for "true"
724+
# Outputs:
725+
# The tag value (lowercased) or empty string if not found.
726+
# For case_insensitive_value="true", outputs "true" or "false" based on whether value matches "true" case-insensitively.
727+
# Returns:
728+
# 0 on success, 1 if cache file doesn't exist or tag not found
729+
get_imds_vm_tag_value() {
730+
local tag_name="$1"
731+
local tag_value
732+
tag_value=$(jq -r --arg name "$tag_name" '.compute.tagsList | map(select(.name | test($name; "i")))[0].value // "false" | test("true"; "i")' "$IMDS_INSTANCE_METADATA_CACHE_FILE")
733+
# Output lowercase value for consistency
734+
echo "${tag_value,,}"
735+
}
736+
737+
should_skip_nvidia_drivers() {
738+
set -x
739+
# Case-insensitive match for both tag name and value
740+
local should_skip
741+
should_skip=$(get_imds_vm_tag_value "SkipGpuDriverInstall")
662742
echo "$should_skip"
663743
}
664744

665745
should_disable_kubelet_serving_certificate_rotation() {
666746
set -x
667-
body=$(curl -fsSL -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2021-02-01")
668-
ret=$?
669-
if [ "$ret" -ne 0 ]; then
670-
return $ret
671-
fi
672-
should_disable=$(echo "$body" | jq -r '.compute.tagsList[] | select(.name == "aks-disable-kubelet-serving-certificate-rotation") | .value')
673-
echo "${should_disable,,}"
747+
local should_disable
748+
should_disable=$(get_imds_vm_tag_value "aks-disable-kubelet-serving-certificate-rotation")
749+
echo "$should_disable"
674750
}
675751

676752
should_skip_binary_cleanup() {
677753
set -x
678-
body=$(curl -fsSL -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2021-02-01")
679-
ret=$?
680-
if [ "$ret" -ne 0 ]; then
681-
return $ret
682-
fi
683-
should_skip=$(echo "$body" | jq -r '.compute.tagsList[] | select(.name == "SkipBinaryCleanup") | .value')
684-
echo "${should_skip,,}"
754+
local should_skip
755+
should_skip=$(get_imds_vm_tag_value "SkipBinaryCleanup")
756+
echo "$should_skip"
685757
}
686758

687759
should_enforce_kube_pmc_install() {
688760
set -x
689-
body=$(curl -fsSL -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2021-02-01")
690-
ret=$?
691-
if [ "$ret" -ne 0 ]; then
692-
return $ret
693-
fi
694-
should_enforce=$(echo "$body" | jq -r '.compute.tagsList[] | select(.name == "ShouldEnforceKubePMCInstall") | .value')
695-
echo "${should_enforce,,}"
761+
local should_enforce
762+
should_enforce=$(get_imds_vm_tag_value "ShouldEnforceKubePMCInstall")
763+
echo "$should_enforce"
696764
}
697765

698-
e2e_mock_azure_china_cloud() {
766+
should_e2e_mock_azure_china_cloud() {
699767
set -x
700-
body=$(curl -fsSL -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2021-02-01")
701-
ret=$?
702-
if [ "$ret" -ne 0 ]; then
703-
return $ret
704-
fi
705-
should_enforce=$(echo "$body" | jq -r '.compute.tagsList[] | select(.name == "E2EMockAzureChinaCloud") | .value')
706-
echo "${should_enforce,,}"
768+
local should_enforce
769+
should_enforce=$(get_imds_vm_tag_value "E2EMockAzureChinaCloud")
770+
echo "$should_enforce"
707771
}
708772

709-
enableManagedGPUExperience() {
773+
should_enable_managed_gpu_experience() {
710774
set -x
711-
body=$(curl -fsSL -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2021-02-01")
712-
ret=$?
713-
if [ "$ret" -ne 0 ]; then
714-
return $ret
715-
fi
716-
should_enforce=$(echo "$body" | jq -r '.compute.tagsList[] | select(.name == "EnableManagedGPUExperience") | .value')
717-
echo "${should_enforce,,}"
775+
local should_enforce
776+
should_enforce=$(get_imds_vm_tag_value "EnableManagedGPUExperience")
777+
echo "$should_enforce"
718778
}
719779

720780
isMarinerOrAzureLinux() {

parts/linux/cloud-init/artifacts/cse_main.sh

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ if [ -f /opt/azure/containers/provision.complete ]; then
88
exit 0
99
fi
1010

11+
# Cleanup cache file to force fetch fresh instance metadata from IMDS
12+
rm -f /opt/azure/containers/imds_instance_metadata_cache.json
13+
1114
for i in $(seq 1 120); do
1215
if [ -s "${CSE_HELPERS_FILEPATH}" ]; then
1316
grep -Fq '#HELPERSEOF' "${CSE_HELPERS_FILEPATH}" && break
@@ -130,7 +133,7 @@ function basePrep {
130133
export -f getInstallModeAndCleanupContainerImages
131134
export -f should_skip_binary_cleanup
132135

133-
SKIP_BINARY_CLEANUP=$(retrycmd_silent 10 1 10 bash -cx should_skip_binary_cleanup)
136+
SKIP_BINARY_CLEANUP=$(should_skip_binary_cleanup)
134137
# this needs better fix to separate logs and return value;
135138
FULL_INSTALL_REQUIRED=$(getInstallModeAndCleanupContainerImages "$SKIP_BINARY_CLEANUP" "$IS_VHD" | tail -1)
136139
if [ "$?" -ne 0 ]; then
@@ -163,7 +166,7 @@ function basePrep {
163166
# Added as a temporary workaround to test installing packages from PMC prior to 1.34.0 GA.
164167
# TODO: Remove tag and usages once 1.34.0 is GA.
165168
export -f should_enforce_kube_pmc_install
166-
SHOULD_ENFORCE_KUBE_PMC_INSTALL=$(retrycmd_silent 10 1 10 bash -cx should_enforce_kube_pmc_install)
169+
SHOULD_ENFORCE_KUBE_PMC_INSTALL=$(should_enforce_kube_pmc_install)
167170
logs_to_events "AKS.CSE.configureKubeletAndKubectl" configureKubeletAndKubectl
168171

169172
createKubeManifestDir
@@ -310,6 +313,7 @@ EOF
310313
# After this stage the node should be fully integrated into the cluster.
311314
# IMPORTANT: This stage should only run when actually joining a node to the cluster. This step should not be run when creating a VHD image
312315
function nodePrep {
316+
logs_to_events "AKS.CSE.fetch_and_cache_imds_instance_metadata" fetch_and_cache_imds_instance_metadata
313317
# IMPORTANT NOTE: We do this here since this function can mutate kubelet flags and node labels,
314318
# which is used by configureK8s and other functions. Thus, we need to make sure flag and label content is correct beforehand.
315319
logs_to_events "AKS.CSE.configureKubeletServing" configureKubeletServing
@@ -337,7 +341,7 @@ function nodePrep {
337341

338342
# Determine if GPU driver installation should be skipped
339343
export -f should_skip_nvidia_drivers
340-
skip_nvidia_driver_install=$(retrycmd_silent 10 1 10 bash -cx should_skip_nvidia_drivers)
344+
skip_nvidia_driver_install=$(should_skip_nvidia_drivers)
341345

342346
if [ "$?" -ne 0 ]; then
343347
echo "Failed to determine if nvidia driver install should be skipped"
@@ -395,8 +399,8 @@ function nodePrep {
395399
echo $(date),$(hostname), "End configuring GPU drivers"
396400
fi
397401

398-
export -f enableManagedGPUExperience
399-
ENABLE_MANAGED_GPU_EXPERIENCE=$(retrycmd_silent 10 1 10 bash -cx enableManagedGPUExperience)
402+
export -f should_enable_managed_gpu_experience
403+
ENABLE_MANAGED_GPU_EXPERIENCE=$(should_enable_managed_gpu_experience)
400404
if [ "$?" -ne 0 ] && [ "${GPU_NODE}" = "true" ] && [ "${skip_nvidia_driver_install}" != "true" ]; then
401405
echo "failed to determine if managed GPU experience should be enabled by nodepool tags"
402406
exit $ERR_LOOKUP_ENABLE_MANAGED_GPU_EXPERIENCE_TAG

parts/linux/cloud-init/artifacts/cse_start.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ JSON_STRING=$( jq -n \
4949
mkdir -p /var/log/azure/aks
5050
echo $JSON_STRING | tee /var/log/azure/aks/provision.json
5151

52+
# Cleanup cache file
53+
rm -f /opt/azure/containers/imds_instance_metadata_cache.json || true
54+
5255
# Create stage marker for two-stage workflow
5356
if [ "${PRE_PROVISION_ONLY}" = "true" ]; then
5457
# Stage 1: Create marker indicating Stage 2 is needed
@@ -118,4 +121,4 @@ else
118121
upload_logs &
119122
fi
120123

121-
exit "$EXIT_CODE"
124+
exit "$EXIT_CODE"

0 commit comments

Comments
 (0)