4 min read

如何正确收缩已部署的Kubernetes应用

【封面图片:广州市天河国际乒乓培训中心】如何正确收缩已部署的Kubernetes应用
如何正确收缩已部署的Kubernetes应用

需求

有时候我们需要对已经部署在Kubernetes的应用进行清理(比如:节省资源或是资源不足的情况下),同时又可能在某个心血来潮的时间来恢复它,在这种不确定的场景下,我们就不能使用deleteuninstall

此时我们可以将已部署的应用副本收缩为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

参考引用