Skip to content

Commit

Permalink
feat: oras pull kubernetes-node for network isolated cluster (#4867)
Browse files Browse the repository at this point in the history
Co-authored-by: Alison Burgess <[email protected]>
  • Loading branch information
fseldow and AlisonB319 authored Sep 4, 2024
1 parent 72f3cd8 commit 0515c7a
Show file tree
Hide file tree
Showing 435 changed files with 5,097 additions and 779 deletions.
46 changes: 46 additions & 0 deletions e2e/scenario_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ func Test_azurelinuxv2AirGap(t *testing.T) {
BootstrapConfigMutator: func(nbc *datamodel.NodeBootstrappingConfiguration) {
nbc.ContainerService.Properties.AgentPoolProfiles[0].Distro = "aks-azurelinux-v2-gen2"
nbc.AgentPoolProfile.Distro = "aks-azurelinux-v2-gen2"

// TODO(xinhl): define below in the cluster config instead of mutate bootstrapConfig
nbc.OutboundType = datamodel.OutboundTypeBlock
nbc.ContainerService.Properties.SecurityProfile = &datamodel.SecurityProfile{
PrivateEgress: &datamodel.PrivateEgress{
Enabled: true,
ContainerRegistryServer: "mcr.microsoft.com",
},
}
},
},
})
Expand Down Expand Up @@ -85,6 +94,15 @@ func Test_azurelinuxv2ARM64AirGap(t *testing.T) {
nbc.AgentPoolProfile.VMSize = "Standard_D2pds_V5"
nbc.AgentPoolProfile.Distro = "aks-azurelinux-v2-arm64-gen2"
nbc.IsARM64 = true

// TODO(xinhl): define below in the cluster config instead of mutate bootstrapConfig
nbc.OutboundType = datamodel.OutboundTypeBlock
nbc.ContainerService.Properties.SecurityProfile = &datamodel.SecurityProfile{
PrivateEgress: &datamodel.PrivateEgress{
Enabled: true,
ContainerRegistryServer: "mcr.microsoft.com",
},
}
},
VMConfigMutator: func(vmss *armcompute.VirtualMachineScaleSet) {
vmss.SKU.Name = to.Ptr("Standard_D2pds_V5")
Expand Down Expand Up @@ -276,6 +294,15 @@ func Test_marinerv2AirGap(t *testing.T) {
BootstrapConfigMutator: func(nbc *datamodel.NodeBootstrappingConfiguration) {
nbc.ContainerService.Properties.AgentPoolProfiles[0].Distro = "aks-cblmariner-v2-gen2"
nbc.AgentPoolProfile.Distro = "aks-cblmariner-v2-gen2"

// TODO(xinhl): define below in the cluster config instead of mutate bootstrapConfig
nbc.OutboundType = datamodel.OutboundTypeBlock
nbc.ContainerService.Properties.SecurityProfile = &datamodel.SecurityProfile{
PrivateEgress: &datamodel.PrivateEgress{
Enabled: true,
ContainerRegistryServer: "mcr.microsoft.com",
},
}
},
},
})
Expand Down Expand Up @@ -318,6 +345,16 @@ func Test_marinerv2ARM64AirGap(t *testing.T) {
nbc.AgentPoolProfile.VMSize = "Standard_D2pds_V5"
nbc.AgentPoolProfile.Distro = "aks-cblmariner-v2-arm64-gen2"
nbc.IsARM64 = true

// TODO(xinhl): define below in the cluster config instead of mutate bootstrapConfig
nbc.OutboundType = datamodel.OutboundTypeBlock
nbc.ContainerService.Properties.SecurityProfile = &datamodel.SecurityProfile{
PrivateEgress: &datamodel.PrivateEgress{
Enabled: true,
ContainerRegistryServer: "mcr.microsoft.com",
},
}

},
VMConfigMutator: func(vmss *armcompute.VirtualMachineScaleSet) {
vmss.SKU.Name = to.Ptr("Standard_D2pds_V5")
Expand Down Expand Up @@ -619,6 +656,15 @@ func Test_ubuntu2204AirGap(t *testing.T) {
BootstrapConfigMutator: func(nbc *datamodel.NodeBootstrappingConfiguration) {
nbc.ContainerService.Properties.AgentPoolProfiles[0].Distro = "aks-ubuntu-containerd-22.04-gen2"
nbc.AgentPoolProfile.Distro = "aks-ubuntu-containerd-22.04-gen2"

// TODO(xinhl): define below in the cluster config instead of mutate bootstrapConfig
nbc.OutboundType = datamodel.OutboundTypeBlock
nbc.ContainerService.Properties.SecurityProfile = &datamodel.SecurityProfile{
PrivateEgress: &datamodel.PrivateEgress{
Enabled: true,
ContainerRegistryServer: "mcr.microsoft.com",
},
}
},
},
})
Expand Down
1 change: 1 addition & 0 deletions parts/linux/cloud-init/artifacts/cse_cmd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ IS_KATA="{{IsKata}}"
ARTIFACT_STREAMING_ENABLED="{{IsArtifactStreamingEnabled}}"
SYSCTL_CONTENT="{{GetSysctlContent}}"
PRIVATE_EGRESS_PROXY_ADDRESS="{{GetPrivateEgressProxyAddress}}"
BOOTSTRAP_PROFILE_CONTAINER_REGISTRY_SERVER="{{GetBootstrapProfileContainerRegistryServer}}"
ENABLE_IMDS_RESTRICTION="{{EnableIMDSRestriction}}"
INSERT_IMDS_RESTRICTION_RULE_TO_MANGLE_TABLE="{{InsertIMDSRestrictionRuleToMangleTable}}"
/usr/bin/nohup /bin/bash -c "/bin/bash /opt/azure/containers/provision_start.sh"
29 changes: 29 additions & 0 deletions parts/linux/cloud-init/artifacts/cse_helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ ERR_CNI_VERSION_INVALID=206 # reference CNI (not azure cni) needs a valid versio

# For both Ubuntu and Mariner/AzureLinux, /etc/*-release should exist.
# In AzureLinux 3.0, /etc/*-release are symlinks to /usr/lib/*-release, so the find command includes -type f,l.

ERR_ORAS_PULL_K8S_FAIL=207 # Error pulling kube-node artifact via oras from registry
ERR_ORAS_PULL_FAIL_RESERVE_1=208 # Error pulling artifact with oras from registry
ERR_ORAS_PULL_FAIL_RESERVE_2=209 # Error pulling artifact with oras from registry
ERR_ORAS_PULL_FAIL_RESERVE_3=210 # Error pulling artifact with oras from registry
ERR_ORAS_PULL_FAIL_RESERVE_4=211 # Error pulling artifact with oras from registry
ERR_ORAS_PULL_FAIL_RESERVE_5=212 # Error pulling artifact with oras from registry

# For both Ubuntu and Mariner, /etc/*-release should exist.
# For unit tests, the OS and OS_VERSION will be set in the unit test script.
# So whether it's if or else actually doesn't matter to our unit test.
if find /etc -type f,l -name "*-release" -print -quit 2>/dev/null | grep -q '.'; then
Expand Down Expand Up @@ -145,6 +154,8 @@ APT_CACHE_DIR=/var/cache/apt/archives/
PERMANENT_CACHE_DIR=/root/aptcache/
EVENTS_LOGGING_DIR=/var/log/azure/Microsoft.Azure.Extensions.CustomScript/events/
CURL_OUTPUT=/tmp/curl_verbose.out
ORAS_OUTPUT=/tmp/oras_verbose.out
ORAS_REGISTRY_CONFIG_FILE=/etc/oras/config.yaml # oras registry auth config file, not used, but have to define to avoid error "Error: failed to get user home directory: $HOME is not defined"

retrycmd_if_failure() {
retries=$1; wait_sleep=$2; timeout=$3; shift && shift && shift
Expand Down Expand Up @@ -202,6 +213,24 @@ retrycmd_get_tarball() {
fi
done
}
retrycmd_get_tarball_from_registry_with_oras() {
tar_retries=$1; wait_sleep=$2; tarball=$3; url=$4
tar_folder=$(dirname "$tarball")
echo "${tar_retries} retries"
for i in $(seq 1 $tar_retries); do
tar -tzf $tarball && break || \
if [ $i -eq $tar_retries ]; then
return 1
else
# TODO: support private acr via kubelet identity
timeout 60 oras pull $url -o $tar_folder --registry-config ${ORAS_REGISTRY_CONFIG_FILE} > $ORAS_OUTPUT 2>&1
if [[ $? != 0 ]]; then
cat $ORAS_OUTPUT
fi
sleep $wait_sleep
fi
done
}
retrycmd_curl_file() {
curl_retries=$1; wait_sleep=$2; timeout=$3; filepath=$4; url=$5
echo "${curl_retries} retries"
Expand Down
37 changes: 32 additions & 5 deletions parts/linux/cloud-init/artifacts/cse_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ CONTAINERD_DOWNLOADS_DIR="/opt/containerd/downloads"
RUNC_DOWNLOADS_DIR="/opt/runc/downloads"
K8S_DOWNLOADS_DIR="/opt/kubernetes/downloads"
K8S_PRIVATE_PACKAGES_CACHE_DIR="/opt/kubernetes/downloads/private-packages"
K8S_REGISTRY_REPO="oss/binaries/kubernetes/kubernetes-node"
UBUNTU_RELEASE=$(lsb_release -r -s)
# For Mariner 2.0, this returns "MARINER" and for AzureLinux 3.0, this returns "AZURELINUX"
OS=$(sort -r /etc/*-release | gawk 'match($0, /^(ID_LIKE=(coreos)|ID=(.*))$/, a) { print toupper(a[2] a[3]); exit }')
Expand All @@ -28,6 +29,11 @@ MAN_DB_AUTO_UPDATE_FLAG_FILEPATH="/var/lib/man-db/auto-update"
CURL_OUTPUT=/tmp/curl_verbose.out
UBUNTU_OS_NAME="UBUNTU"
MARINER_OS_NAME="MARINER"
CPU_ARCH=""

setCPUArch() {
CPU_ARCH=$(getCPUArch)
}

removeManDbAutoUpdateFlagFile() {
rm -f $MAN_DB_AUTO_UPDATE_FLAG_FILEPATH
Expand Down Expand Up @@ -422,10 +428,22 @@ extractKubeBinaries() {
else
k8s_tgz_tmp="${k8s_downloads_dir}/${k8s_tgz_tmp_filename}"
mkdir -p ${k8s_downloads_dir}

retrycmd_get_tarball 120 5 "${k8s_tgz_tmp}" ${kube_binary_url} || exit $ERR_K8S_DOWNLOAD_TIMEOUT
if [[ ! -f ${k8s_tgz_tmp} ]]; then
exit "$ERR_K8S_DOWNLOAD_TIMEOUT"
# if the url is a registry url, use oras to pull the artifact instead of curl
registry_regex='^.+\/.+\/.+:.+$'
if [[ ${kube_binary_url} =~ $registry_regex ]]; then
echo "detect kube_binary_url, ${kube_binary_url}, as registry url, will use oras to pull artifact binary"
# download the kube package from registry as oras artifact
k8s_tgz_tmp="${k8s_downloads_dir}/kubernetes-node-linux-${CPU_ARCH}.tar.gz"
retrycmd_get_tarball_from_registry_with_oras 120 5 "${k8s_tgz_tmp}" ${kube_binary_url} || exit $ERR_ORAS_PULL_K8S_FAIL
if [[ ! -f ${k8s_tgz_tmp} ]]; then
exit "$ERR_ORAS_PULL_K8S_FAIL"
fi
else
# download the kube package from the default URL
retrycmd_get_tarball 120 5 "${k8s_tgz_tmp}" ${kube_binary_url} || exit $ERR_K8S_DOWNLOAD_TIMEOUT
if [[ ! -f ${k8s_tgz_tmp} ]]; then
exit "$ERR_K8S_DOWNLOAD_TIMEOUT"
fi
fi
fi

Expand Down Expand Up @@ -465,8 +483,17 @@ installKubeletKubectlAndKubeProxy() {
# if the custom url is not specified and the required kubectl/kubelet-version via private url is not installed, install using the default url/package
if [[ ! -f "/usr/local/bin/kubectl-${KUBERNETES_VERSION}" ]] || [[ ! -f "/usr/local/bin/kubelet-${KUBERNETES_VERSION}" ]]; then
if [[ "$install_default_if_missing" == true ]]; then
if [[ ! -z ${BOOTSTRAP_PROFILE_CONTAINER_REGISTRY_SERVER} ]]; then
# network isolated cluster
echo "Detect Bootstrap profile artifact is Cache, will use oras to pull artifact binary"
registry_url="${BOOTSTRAP_PROFILE_CONTAINER_REGISTRY_SERVER}/${K8S_REGISTRY_REPO}:v${KUBERNETES_VERSION}-linux-${CPU_ARCH}"
K8S_DOWNLOADS_TEMP_DIR_FROM_REGISTRY="/tmp/kubernetes/downloads" # /opt folder will return permission error
logs_to_events "AKS.CSE.installKubeletKubectlAndKubeProxy.extractKubeBinaries" extractKubeBinaries ${KUBERNETES_VERSION} $registry_url false ${K8S_DOWNLOADS_TEMP_DIR_FROM_REGISTRY}
# no egress traffic, default install will fail
# will exit if the download fails

#TODO: remove the condition check on KUBE_BINARY_URL once RP change is released
if (($(echo ${KUBERNETES_VERSION} | cut -d"." -f2) >= 17)) && [ -n "${KUBE_BINARY_URL}" ]; then
elif (($(echo ${KUBERNETES_VERSION} | cut -d"." -f2) >= 17)) && [ -n "${KUBE_BINARY_URL}" ]; then
logs_to_events "AKS.CSE.installKubeletKubectlAndKubeProxy.extractKubeBinaries" extractKubeBinaries ${KUBERNETES_VERSION} ${KUBE_BINARY_URL} false
fi
fi
Expand Down
1 change: 1 addition & 0 deletions parts/linux/cloud-init/artifacts/cse_main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ if [[ -n "${OUTBOUND_COMMAND}" ]]; then
retrycmd_if_failure 50 1 5 $OUTBOUND_COMMAND >> /var/log/azure/cluster-provision-cse-output.log 2>&1 || exit $ERR_OUTBOUND_CONN_FAIL;
fi

logs_to_events "AKS.CSE.setCPUArch" setCPUArch
source /etc/os-release

if [[ ${ID} != "mariner" ]] && [[ ${ID} != "azurelinux" ]]; then
Expand Down
Loading

0 comments on commit 0515c7a

Please sign in to comment.