嘿,我正在运行kubernetes集群,我想在属于特定服务的所有Pod上运行命令。
据我所知,kubectl exec只能在Pod上运行,而跟踪我所有的Pod是一件荒谬的工作(这是服务的好处之一)。
是否有任何方法或工具可以让您“广播”服务中的所有Pod?
预先感谢您的帮助!
答案 0 :(得分:4)
正如Bal Chua所写,kubectl无法执行此操作,但是您可以使用bash脚本执行此操作:
#!/usr/bin/env bash
PROGNAME=$(basename $0)
function usage {
echo "usage: $PROGNAME [-n NAMESPACE] [-m MAX-PODS] -s SERVICE -- COMMAND"
echo " -s SERVICE K8s service, i.e. a pod selector (required)"
echo " COMMAND Command to execute on the pods"
echo " -n NAMESPACE K8s namespace (optional)"
echo " -m MAX-PODS Max number of pods to run on (optional; default=all)"
echo " -q Quiet mode"
echo " -d Dry run (don't actually exec)"
}
function header {
if [ -z $QUIET ]; then
>&2 echo "###"
>&2 echo "### $PROGNAME $*"
>&2 echo "###"
fi
}
while getopts :n:s:m:qd opt; do
case $opt in
d)
DRYRUN=true
;;
q)
QUIET=true
;;
m)
MAX_PODS=$OPTARG
;;
n)
NAMESPACE="-n $OPTARG"
;;
s)
SERVICE=$OPTARG
;;
\?)
usage
exit 0
;;
esac
done
if [ -z $SERVICE ]; then
usage
exit 1
fi
shift $(expr $OPTIND - 1)
while test "$#" -gt 0; do
if [ "$REST" == "" ]; then
REST="$1"
else
REST="$REST $1"
fi
shift
done
if [ "$REST" == "" ]; then
usage
exit 1
fi
PODS=()
for pod in $(kubectl $NAMESPACE get pods --output=jsonpath={.items..metadata.name}); do
echo $pod | grep -qe "^$SERVICE" >/dev/null 2>&1
if [ $? -eq 0 ]; then
PODS+=($pod)
fi
done
if [ ${#PODS[@]} -eq 0 ]; then
echo "service not found in ${NAMESPACE:-default}: $SERVICE"
exit 1
fi
if [ ! -z $MAX_PODS ]; then
PODS=("${PODS[@]:1:$MAX_PODS}")
fi
header "{pods: ${#PODS[@]}, command: \"$REST\"}"
for i in "${!PODS[@]}"; do
pod=${PODS[$i]}
header "{pod: \"$(($i + 1))/${#PODS[@]}\", name: \"$pod\"}"
if [ "$DRYRUN" != "true" ]; then
kubectl $NAMESPACE exec $pod -- $REST
fi
done
答案 1 :(得分:1)
这是一个简单的示例,其中包含到xargs的kubectl管道,并打印每个pod的env:
k get pod \
-l {your label selectors} \
--field-selector=status.phase=Running \
-o custom-columns=name:metadata.name --no-headers \
| xargs -I{} kubectl exec {} env
答案 2 :(得分:1)
上面Nick Rack中的脚本有一个小错误。如果要与-m
选项一起使用以限制命令的Pod数量(例如,当您具有多个副本的部署时),则不必按以下方式修改此部分代码:
if [ ! -z $MAX_PODS ]; then
PODS=("${PODS[@]:0:$MAX_PODS}")
fi
答案 3 :(得分:0)
我已经编写了一个简单的kubectl插件,该插件使用Tmux将板载命令“广播”到所有Pod。假设服务中的所有pod均应在其规范中共享相同的标签,例如app=foobar
,则可以使用以下命令
kubectl tmux-exec -l app=foobar bash
该插件可在Github上使用:predatorray/kubectl-tmux-exec。希望对您有帮助!
答案 4 :(得分:0)
还有一个名为kubectl-exec-all
https://github.com/jpdasma/kubectl-exec-all的kubectl插件,做得很好。
不能使用krew索引,但是您可以将https://raw.githubusercontent.com/jpdasma/kubectl-exec-all/master/unix/exec-all.sh的内容保存到/usr/local/bin/kubectl-exec_all
,并且不要忘记通过运行使其成为可执行文件
chmod +x /usr/local/bin/kubectl-exec_all
然后它像这样工作:
kubectl plugin exec-all daemonset docker-daemon -- docker system prune -a -f
答案 5 :(得分:0)
这里:
kubectl -n alex get pods -l app=alex-admin-api -o name | xargs -I{} kubectl -n alex exec {} -- cat alexAdminApi.log >> alex-admin-api_pods.logs