如何正确收缩已部署的Kubernetes应用
需求
有时候我们需要对已经部署在Kubernetes的应用进行清理(比如:节省资源或是资源不足的情况下),同时又可能在某个心血来潮的时间来恢复它,在这种不确定的场景下,我们就不能使用delete
、uninstall
。
此时我们可以将已部署的应用副本收缩为0
,恢复时将副本收缩前的数量还原即可。
操作步骤
记录副本数量
获取控制器的副本数量,同时将信息追加至annotate
# kubectl -n <命名空间> get deploy -o jsonpath='{range .items[*]}{"kubectl -n <命名空间> annotate --overwrite deploy "}{@.metadata.name}{" previous-size="}{@.spec.replicas}{" \n"}{end}' | sh
# kubectl -n <命名空间> get sts -o jsonpath='{range .items[*]}{"kubectl -n <命名空间> annotate --overwrite sts "}{@.metadata.name}{" previous-size="}{@.spec.replicas}{" \n"}{end}' | sh
副本收缩
正式将控制器的副本数量设置为0
- deployment
# export namespace=demo-dev
kubectl -n $namespace scale --replicas=0 $(kubectl -n $namespace get deploy -o name)
- statefulset
# export namespace=demo-dev
kubectl -n $namespace scale --replicas=0 $(kubectl -n $namespace get sts -o name)
也可以将以上2条命令合并如下:
# export namespace=demo-dev
kubectl -n $namespace scale --replicas=0 $(kubectl -n $namespace get deploy,sts -o name)
应用恢复
此时我们有副本数量的信息,就可以随时将应用恢复到副本收缩前的状态。
- deployment
kubectl -n <命名空间> get deploy -o jsonpath='{range .items[*]}{"kubectl -n <命名空间> scale deploy "}{@.metadata.name}{" --replicas="}{.metadata.annotations.previous-size}{"\n"}{end}' | sh
- statefulset
kubectl -n <命名空间> get sts -o jsonpath='{range .items[*]}{"kubectl -n <命名空间> scale sts "}{@.metadata.name}{" --replicas="}{.metadata.annotations.previous-size}{"\n"}{end}' | sh
脚本整合
SHELL脚本内容
#!/usr/bin/env bash
# 文件名: pod-scale.sh
# 功 能: 快速将指定命名空间的pod资源进行收缩/还原脚本
# 作 者: Qiu<shuhui@vqiu.cn>
# 定义终端颜色
txtbld=$(tput bold) # 加粗
bldred=${txtbld}$(tput setaf 1) # 红
bldgre=${txtbld}$(tput setaf 2) # 绿
bldylw=${txtbld}$(tput setaf 3) # 黄
txtrst=$(tput sgr0) # 复位
err=${bldred}ERROR${txtrst}
info=${bldgre}INFO${txtrst}
warn=${bldylw}WARNING${txtrst}
# 获取当前命名空间
namespace=$(kubectl config get-contexts | grep -e "^\*" | awk '{print $5}')
function print_info() {
# 输出操作信息
cat<< EOF
`printf " ============= ${bldred}操作确认${txtrst} ===============\n"`
`printf " - 命令空间: ${bldgre}${namespace}${txtrst}"`
`printf " - 操作行为: ${bldgre}$1${txtrst}"`
`printf " - 当前时间: ${bldgre}$(date +%F' '%T)${txtrst}"`
`printf " ======================================"`
`printf ""`
EOF
read -p "确认无误,请按Enter键继续..."
}
case $1 in
shrink|s )
print_info 副本收缩
for name in $(kubectl -n $namespace get deploy,sts -o name);
do
# 获取当前控制器副本数量
current_replicas=$(kubectl get $name -o=jsonpath='{.spec.replicas}')
if [[ "${current_replicas}" != "0" ]]
then
kubectl -n $namespace annotate $name --overwrite previous-size=${current_replicas} >/dev/null
kubectl -n $namespace scale --replicas=0 $name >/dev/null && printf "$info: [ ${txtbld}$name${txtrst} ] 已收缩.\n"
else
printf "$warn: [ ${txtbld}$name${txtrst} ] 已收缩,无须处理.\n"
fi
done
;;
recovery|r )
print_info 副本还原
for name in $(kubectl -n $namespace get deploy,sts -o name);
do
replicas=$(kubectl get $name -o=jsonpath='{.metadata.annotations.previous-size}' 2>/dev/null)
if [[ "$replicas" != "" ]]
then
kubectl -n $namespace scale --replicas=$replicas $name >/dev/null && printf "$info: [ ${txtbld}$name${txtrst} ] 副本数量已恢复为 ${bldgre}$replicas${txtrst}.\n"
else
printf "$err:[ ${txtbld}$name${txtrst} ] 恢复失败.\n"
fi
done
;;
*)
echo """
用法: $(basename $0) [选项]
选项:
shrink 资源副本收缩
recovery 资源副本还原
${txtbld}使用案例${txtrst}
示例1. 将当前命名空间 deploy,sts 资源副本收缩
# ${bldgre}$(basename $0) shrink${txtrst}
示例2. 将当前命名空间 deploy,sts 资源副本还原
# ${bldgre}$(basename $0) recovery${txtrst}
示例3. 将middleware命名空间 deploy,sts 资源副本收缩
# ${bldgre}kubectl config set-context --current --namespace=middleware && $(basename $0) shrink${txtrst}
示例4. 将middleware命名空间 deploy,sts 资源副本还原
# ${bldgre}kubectl config set-context --current --namespace=middleware && $(basename $0) recovery${txtrst}
"""
esac