如何正确收缩已部署的Kubernetes应用
【封面图片:广州市天河国际乒乓培训中心】如何正确收缩已部署的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_rollout.sh
# 功 能: 快速将指定命名空间的pod资源进行收缩/还原脚本
# 作 者: vqiu<shuhui@vqiu.cn>
# 获取当前命名空间
namespace=$(kubectl config get-contexts | grep -e "^\*" | awk '{print $5}')
function print_info() {
# 输出操作信息
cat<< EOF
`echo -e " ============= 操作确认 ==============="`
`echo -e " - 命令空间: ${namespace}"`
`echo -e " - 操作行为: $1"`
`echo -e " - 当前时间: $(date +%F' '%T)"`
`echo -e " ======================================"`
`echo -e ""`
EOF
read -p "确认无误,请按Enter键继续..."
}
case $1 in
shrink|s )
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)
[[ "$replicas" =~ ^[0-9]+$ ]] || kubectl -n $namespace annotate $name --overwrite previous-size=$replicas >/dev/null
kubectl -n $namespace scale --replicas=0 $name >/dev/null && echo "[ $name ] 已收缩."
#kubectl -n $namespace get $name -o yaml | grep "previous-size" >/dev/null 2>/dev/null || kubectl -n $namespace annotate $name --overwrite previous-size=$(kubectl get $name -o=jsonpath='{.spec.replicas}')
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" =~ ^[0-9]+$ ]]
then
kubectl -n $namespace scale --replicas=$replicas $name >/dev/null && echo "[ $name ] 副本数量已恢复 $replicas."
else
echo "[ $name ] 恢复失败."
fi
done
;;
*)
echo """
用法: $(basename $0) [选项]
选项:
shrink 资源副本收缩
recovery 资源副本还原
使用案例
示例1. 将当前命名空间 deploy,sts 资源副本收缩
# $(basename $0) shrink
示例2. 将当前命名空间 deploy,sts 资源副本还原
# $(basename $0) recovery
示例3. 将middleware命名空间 deploy,sts 资源副本收缩
# kubectl config set-context --current --namespace=middleware && $(basename $0) shrink
示例4. 将middleware命名空间 deploy,sts 资源副本还原
# kubectl config set-context --current --namespace=middleware && $(basename $0) recovery
"""
esac
使用案例
示例1. 将当前命名空间 deploy,sts 资源副本收缩
# pod_rollout.sh shrink
示例2. 将当前命名空间 deploy,sts 资源副本还原
# pod_rollout.sh recovery
示例3. 将middleware命名空间 deploy,sts 资源副本收缩
# kubectl config set-context --current --namespace=middleware && pod_rollout.sh shrink
示例4. 将middleware命名空间 deploy,sts 资源副本还原
# kubectl config set-context --current --namespace=middleware && pod_rollout.sh recovery