Merge "update feature-gates for specific k8s version"

This commit is contained in:
Zuul 2022-12-07 05:07:28 +00:00 committed by Gerrit Code Review
commit 2ffcbeed18

View File

@ -4,11 +4,22 @@
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
# This will run during a k8s upgrade as a part of the control-plane upgrade of # This will run during k8s upgrades as a part of the control-plane upgrade of
# the first master. It updates the kubeadm-config configmap to edit the # the first master. It updates the kubeadm-config configmap to edit the
# manifests and remove the 'feature-gates' lines. # manifests and updates feature-gates as required for the specific k8s version
# it is upgrading to.
#
# The script updates feature gates for versions 1.22 and 1.24.
#
# It removes below feature gates from kube-apiserver configmap while upgrading
# k8s 1.21.8 to 1.22.5: SCTPSupport=true, HugePageStorageMediumSize=true
# and TTLAfterFinished=true and removes RemoveSelfLink=false while upgrading
# 1.23.1 to 1.24.4.
# #
# Background: # Background:
# HugePageStorageMediumSize is deprecated in Kubernetes 1.22
# SCTPSupport blocks kube-apiserver pod to spawn after control-plane upgrade.
# TTLAfterFinished value defaults to true from k8s 1.21
# Kubernetes 1.24 no longer allows setting kube-apsierver feature-gate # Kubernetes 1.24 no longer allows setting kube-apsierver feature-gate
# RemoveSelfLink=false. All the other feature gates we were using now default # RemoveSelfLink=false. All the other feature gates we were using now default
# to true so we don't want to specify them anymore. # to true so we don't want to specify them anymore.
@ -28,34 +39,36 @@ function ERROR {
# Cleanup and exit # Cleanup and exit
function cleanup_and_exit { function cleanup_and_exit {
rm -v -f "${KUBEADM_CONFIGMAP_TMPFILE}" rm -v -f "${KUBEADM_CONFIGMAP_TMPFILE}" 2>/dev/null
exit "${1:-0}" exit "${1:-0}"
} }
# Update the configmap for kubeadm function get_kubeadm_configmap {
function update_apiserver_configmap {
LOG "Retrieving kubeadm configmap: ${KUBEADM_CONFIGMAP_TMPFILE}" LOG "Retrieving kubeadm configmap: ${KUBEADM_CONFIGMAP_TMPFILE}"
counter=0 local counter=0
RETRIES=10 local RETRIES=10
RC=0 RC=0
until [ $counter -gt $RETRIES ]; do until [ ${counter} -gt ${RETRIES} ]; do
kubectl --kubeconfig=/etc/kubernetes/admin.conf -n kube-system get \ kubectl --kubeconfig=/etc/kubernetes/admin.conf -n kube-system get \
configmap kubeadm-config -o yaml > "${KUBEADM_CONFIGMAP_TMPFILE}" configmap kubeadm-config -o yaml > "${KUBEADM_CONFIGMAP_TMPFILE}"
RC=$? RC=$?
if [ "$RC" = "0" ] ; then if [ "${RC}" == "0" ] ; then
LOG "Kubeadm configmap retrieved." LOG "Kubeadm configmap retrieved."
break break
((counter+=1))
fi fi
ERROR "Failed to retrieve kubeadm configmap, retrying..." ERROR "Error retrieving kubeadm configmap, retrying..."
sleep 5 sleep 5
((counter+=1)) counter=$(( counter+1 ))
done done
if [ $counter -gt $RETRIES ]; then if [ ${counter} -gt ${RETRIES} ]; then
ERROR "Failed to retrieve kubeadm configmap with error code [$RC]". ERROR "Failed to retrieve kubeadm configmap with error code [${RC}]".
cleanup_and_exit $RC cleanup_and_exit ${RC}
fi fi
}
# Update feature gates for version 1.24
function update_feature_gates_v1_24 {
if grep -q 'RemoveSelfLink=false' "${KUBEADM_CONFIGMAP_TMPFILE}"; then if grep -q 'RemoveSelfLink=false' "${KUBEADM_CONFIGMAP_TMPFILE}"; then
LOG "Updating kube-apiserver feature-gates in retrieved kubeadm-config" LOG "Updating kube-apiserver feature-gates in retrieved kubeadm-config"
@ -63,36 +76,98 @@ function update_apiserver_configmap {
if ! grep -q 'RemoveSelfLink=false' "${KUBEADM_CONFIGMAP_TMPFILE}"; if ! grep -q 'RemoveSelfLink=false' "${KUBEADM_CONFIGMAP_TMPFILE}";
then then
LOG "Successfully updated retrieved kubeadm-config" LOG "Successfully updated retrieved kubeadm-config"
if kubectl --kubeconfig=/etc/kubernetes/admin.conf replace -f \
"${KUBEADM_CONFIGMAP_TMPFILE}"; then
LOG 'Successfully replaced updated kubeadm configmap.'
else
RC=$?
ERROR "Failed to replace updated kubeadm configmap with error code: [$RC]"
cleanup_and_exit $RC
fi
else else
ERROR 'Failed to update kube-apiserver feature-gates with an unknown error' ERROR 'Failed to update kube-apiserver feature-gates with an unknown error'
cleanup_and_exit 1 cleanup_and_exit 1
fi fi
else else
RC=$? RC=$?
ERROR "Failed to update ${KUBEADM_CONFIGMAP_TMPFILE} with error code: [$RC]" ERROR "Failed to update ${KUBEADM_CONFIGMAP_TMPFILE} with error code: [${RC}]"
cleanup_and_exit $RC cleanup_and_exit ${RC}
fi fi
else else
LOG "Kubeadm configmap was already updated with RemoveSelfLink=false removed. Nothing to do." LOG "Kubeadm configmap was already updated with RemoveSelfLink=false removed. Nothing to do."
fi fi
} }
# Update kube-apiserver configMap only for k8s 1.23.1 # Update feature gates for version 1.22
K8S_VERSION_FROM='v1.23.1' function update_feature_gates_v1_22 {
LOG "Updating kube-apiserver feature-gates in retrieved kubeadm-config"
# Update api-server feature-gates
sed -i \
's/^\( *\)feature-gates:\s.*RemoveSelfLink=false/\1feature-gates: RemoveSelfLink=false/g' \
"${KUBEADM_CONFIGMAP_TMPFILE}"
RC=$?
if [ "${RC}" == "0" ]; then
LOG "Successfully updated kube-apiserver feature-gates in retrieved kubeadm-config"
else
ERROR "Failed to update kube-apiserver feature-gates in retrieved kubeadm-config with error code: [${RC}]"
cleanup_and_exit ${RC}
fi
# update controller-manager feature-gates
sed -i \
'/feature-gates: TTLAfterFinished=true/d' "${KUBEADM_CONFIGMAP_TMPFILE}"
RC=$?
if [ "${RC}" == "0" ]; then
LOG "Successfully updated controller-manager feature-gates in retrieved kubeadm-config"
else
# we need not gracefully exit here as failing to update this does not
# make any difference to the k8s cluster functions as default value of
# TTLAfterFinished is true
ERROR "Failed to update controller-manager feature-gates in retrieved kubeadm-config with error code: [${RC}]"
fi
}
function replace_configmap {
output=$(kubectl --kubeconfig=/etc/kubernetes/admin.conf replace -f "${KUBEADM_CONFIGMAP_TMPFILE}" 2>&1)
RC=$?
if [ "${RC}" == "0" ]; then
LOG 'Successfully replaced updated kubeadm configmap.'
else
# LP-1996546. kubectl replace expects replacing object to be latest version.
# Although there is low chance that kubeadm-configmap is modified by other
# process in between calls get_kubeadm_configmap and replace_configmap,
# we should still check for that error. If it is the case, then we retry
# modifying and replacing the newer version.
if [[ ${output} == *"the object has been modified; please apply your changes to the latest version and try again" ]]; then
LOG "kubeadm configmap is not the newest version."
else
ERROR "Failed to replace updated kubeadm configmap with error code: [${RC}]"
cleanup_and_exit ${RC}
fi
fi
return ${RC}
}
K8S_VERSION=$(kubectl version --output=yaml| grep -m1 -oP 'gitVersion: \K(\S+)') K8S_VERSION=$(kubectl version --output=yaml| grep -m1 -oP 'gitVersion: \K(\S+)')
if [[ "${K8S_VERSION}" == "${K8S_VERSION_FROM}" ]]; then LOG "k8s version: ${K8S_VERSION}"
LOG "k8s version ${K8S_VERSION} matches ${K8S_VERSION_FROM}" counter=0
update_apiserver_configmap RETRIES=3
else # Most errors during script execution result in exiting the script except one error.
LOG "k8s version ${K8S_VERSION} does not match ${K8S_VERSION_FROM}, skip update" # If kubeadm-configmap is modified by external process after it is
fi # retrieved in function get_kubeadm_configmap and before it is modified
# and replaced in the function replace_configmap, we should retry modifying
# and replacing the latest version.
until [ ${counter} -gt ${RETRIES} ]; do
get_kubeadm_configmap
if [[ "${K8S_VERSION}" == "v1.21.8" ]]; then
update_feature_gates_v1_22
elif [[ "${K8S_VERSION}" == "v1.23.1" ]]; then
update_feature_gates_v1_24
else
LOG "No update required for kubeadm configmap"
break
fi
replace_configmap
if [ "$?" == "0" ]; then
break
else
LOG "Retrying to update the configmap..."
counter=$(( counter+1 ))
fi
done
cleanup_and_exit 0 cleanup_and_exit 0