定义一个启停 k8s 指定命名空间中所有服务的脚本

1,216 阅读3分钟

这是我参与更文挑战的第 1 天,活动详情查看: 更文挑战

一、概述

在使用 k8s 的时候可能遇到这样一个需求,为了充分利用资源,在晚上的时候(通常1:00 - 6:00)用户访问服务比较少,需要将一个命名空间的所有服务实现一键启停,让这些省下来的资源运行一些比较耗费资源的定时任务。如何实现这个需求呢?对于很多服务我们不可能手动去启停服务,通常需要写一个脚本实现,这个对于熟悉 shell 脚本的小伙伴来说,完全没有什么挑战,这里将简单记录一下自己的实现脚本,希望对不熟悉的小伙伴提供一些帮助。

二、一个启停 k8s 命名空间的脚本

脚本内容如下:

#! /bin/bash

echo "当前集群的命名空间如下:"
kubectl get ns | awk 'NR != 1 {print $1}'

read -p "请输入命名空间:"  namespace

if [ "$namespace" == "kube-system" ];then
        echo "不能修改$namespace中的应用"
        exit -1
fi

echo "你输入的命名空间是:$namespace"

read -p "设置pod副本的数量(目前只能设置 1 和 0):"  num


deploys=`kubectl get deploy -n $namespace | awk 'NR != 1 {print $1}'`
case $num in
1)
    for deploy in  $deploys;do

            echo $deploy
            echo `kubectl patch deployment $deploy -p '{"spec":{"replicas":1}}' -n $namespace`
    done
    ;;
0)
    for deploy in  $deploys;do

            echo $deploy
            echo `kubectl patch deployment $deploy -p '{"spec":{"replicas":0}}' -n $namespace`
    done
    ;;
*)
    echo "只能输入 1 和 0"
    ;;
esac


三、批量创建 configmap

#! /bin/bash

echo "当前集群的命名空间如下:"
kubectl get ns | awk 'NR != 1 {print $1}'

read -p "请输入命名空间:"  namespace

if [ "$namespace" == "kube-system" ];then
        echo "不能修改$namespace中的应用"
        exit -1
fi

echo "你输入的命名空间是:$namespace"

deploys=`kubectl get deploy -n $namespace | awk 'NR != 1 {print $1}'`

for deploy in  $deploys;do
	echo $deploy
        echo `kubectl create configmap $deploy --from-file=application.yaml  -n $namespace`
done


脚本中的命令说明:

# 查看集群的命名空间
kubectl get ns

# 使用 awk 输出除了第一行的第一列
awk 'NR != 1 {print $1}'

# 使用 read 命名读取控制台输入,并将输入信息保存到 namespace 变量
read namespace

# 查看命名空间下的所有 deployment 资源对象
kubectl get deploy -n 命名空间

# 使用 patch 命令更新 k8s 资源的副本数
kubectl patch deployment deployment的名字 -p '{"spec":{"replicas":1}}' -n 命名空间

对不熟悉 shell 脚本的小伙伴来说,上面的 case in 语句可能有一些不清楚,下面对 shell 脚本 case in 语句进行详细说明:

shell 脚本中case in 的基本格式如下:


case expression in
    pattern1)
        statement1
        ;;
    pattern2)
        statement2
        ;;
    pattern3)
        statement3
        ;;
    ……
    *)
        statementn
esac

caseinesac 都是 Shell 关键字,expression 表示表达式,pattern 表示匹配模式。

  • expression 既可以是一个变量、一个数字、一个字符串,还可以是一个数学计算表达式,或者是命令的执行结果,只要能够得到 expression 的值就可以。

  • pattern 可以是一个数字、一个字符串,甚至是一个简单的正则表达式。 case 会将 expression 的值与 pattern1、pattern2、pattern3 逐个进行匹配:

  • 如果 expression 和某个模式(比如 pattern2)匹配成功,就会执行这模式(比如 pattern2)后面对应的所有语句(该语句可以有一条,也可以有多条),直到遇见双分号;;才停止;然后整个 case 语句就执行完了,程序会跳出整个 case 语句,执行 esac 后面的其它语句。

  • 如果 expression 没有匹配到任何一个模式,那么就执行*)后面的语句(表示其它所有值),直到遇见双分号;;或者esac才结束。*)相当于多个 if 分支语句中最后的 else 部分。

除最后一个分支外(这个分支可以是普通分支,也可以是*)分支),其它的每个分支都必须以;;结尾,;;代表一个分支的结束,不写的话会有语法错误。最后一个分支可以写;;,也可以不写,因为无论如何,执行到 esac 都会结束整个case in语句。