通過shell執行kubectl exec並在對應pod容器內執行shell命令
阿新 • • 發佈:2018-12-14
問題描述:
由於服務部署在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 命令,但後續的一些操作並沒有在容器內執行,而是在本地執行了。執行結果如下:
[email protected]:~/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
[email protected]:~/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