问题描述:
由于服务部署在K8S环境下,在应用层之上有一次cache层,使用的是nginx的缓存,这样每次更新后台服务资源后,cache内的缓存并未及时更新,这时需要人工清除cache,其实只要使用yaml文件拉取nginx镜像重新部署就可以了,但K8s对于镜像tag未变化时并不会重新拉取docker image重新部署服务。
服务部署公司是用jenkins job执行shell脚本来做的CICD,所以cache的清楚也要求是用通过jenkins job来完成。所以要是用shell脚本来执行一些kubectl的命令
网上查了一些资料,先scale instance数为0,然后在scale为默认instance数
kubectl scale deployment <deployment_name> --replicas=0 -n <namespace>
kubectl scale deployment <deployment_name> --replicas=3 -n <namespace>
这样做cache问题会得到解决,但会中断服务的访问,对服务访问频度要求比较高的业务是不允许的。
起初我的脚本是这样:
#!/bin/bash
print_help() {
echo "USAGE: $0 -e <ENV>"
echo "OPTIONS: "
echo "-e : which env cache you want to clear(required): dev, stg, preview, prd"
echo "-h : help"
exit -1
}
while getopts ":e:h" opt; do
case $opt in
e) ENV="$OPTARG"
;;
h) print_help
;;
\?) echo "Option -$OPTARG is not recognized." >&2
print_help
;;
:) echo "Option -$OPTARG requires an argument." >&2
print_help
;;
esac
done
if [ -z ${ENV} ]; then
echo "ENV is required."
print_help
fi
result=`kubectl get pods -o=name -n j7v126xg-vip-${ENV} | sed "s/^.\{5\}//"`
pods=($result)
for pod in ${pods[@]}; do
if [[ $pod == vip-nginx-* ]]; then
echo the pod name is $pod
#echo "kubectl exec -it $pod bash -n j7v126xg-vip-${ENV}"
if kubectl exec -it $pod bash -n j7v126xg-vip-${ENV}; then
cd /tmp/nginx-cache
echo entry the dir
echo `ls` #列出当前目录文件
fi
fi
done
但这样虽然执行了kubectl exec 命令,但后续的一些操作并没有在容器内执行,而是在本地执行了。执行结果如下:
v@NGINX-CACHE:~/nginx-cache/script$ ./clear_nginx_cache.sh -e preview
the pod name is vip-nginx-6f6cd6df44-lp8sm
bash-4.4#
bash-4.4# exit
exit
./clear_nginx_cache.sh: line 40: cd: /tmp/nginx-cache: No such file or directory
entry the dir
clear_nginx_cache.sh parse_json.sh
v@NGINX-CACHE:~/nginx-cache/script$
于是在网上查找了很久,发现kubectl exec可以执行容器命令。
格式:
kubectl exec -it <podName> -c <containerName> -n <namespace> -- shell comand
例如我们创建一个testfile文件:
kubectl exec -it <podname> -c <container name> -n <namespace> -- touch /usr/local/testfile
需要注意的是:
shell命令前,要加 -- 号,不然shell命令中的参数,不能识别
修改后脚本:
#!/bin/bash
print_help() {
echo "USAGE: $0 -e <ENV>"
echo "OPTIONS: "
echo "-e : which env cache you want to clear(required): dev, stg, preview, prd"
echo "-h : help"
exit -1
}
while getopts ":e:h" opt; do
case $opt in
e) ENV="$OPTARG"
;;
h) print_help
;;
\?) echo "Option -$OPTARG is not recognized." >&2
print_help
;;
:) echo "Option -$OPTARG requires an argument." >&2
print_help
;;
esac
done
if [ -z ${ENV} ]; then
echo "ENV is required."
print_help
fi
result=`kubectl get pods -o=name -n j7v126xg-vip-${ENV} | sed "s/^.\{5\}//"`
pods=($result)
for pod in ${pods[@]}; do
if [[ $pod == vip-nginx-* ]]; then
echo the pod name is $pod
if kubectl exec -it $pod -c vip-nginx -n j7v126xg-vip-${ENV} -- rm -rf /tmp/nginx-cache; then
echo cache clear successfully
fi
fi
done