如何通过kubectl非交互式执行Shell脚本?解决脚本中途退出中断问题
问题根源分析
你的脚本核心问题在于交互式容器登录打断了脚本执行流程:
kubectl exec -it keycloak-0 bash会启动容器内的交互式shell,脚本后续的mkdir、export命令、exit都会被作为容器内shell的输入执行。- 当你执行
exit退出容器后,kubectl exec命令结束,加上你用了set -e(命令失败即终止脚本),再配合ssh的-t参数分配的伪终端关闭,导致整个远程ssh会话直接终止,后续的kubectl cp等命令根本没机会在远程主机上执行。
解决方案
修改脚本逻辑,用非交互式方式执行容器内命令,避免进入交互式shell,同时调整流水线命令确保后续复制操作正常执行。
修改后的export.sh脚本
#!/bin/bash set -x set -e # 清理远程主机临时目录 rm -rf /tmp/realm-export # 检查是否有导出进程在运行(用pgrep更简洁可靠) if pgrep -f "keycloak.migration.action=export" > /dev/null; then echo "Another export is currently running" exit 1 fi # 非交互式执行容器内的导出操作 kubectl -n keycloak exec keycloak-0 -- bash -c ' mkdir -p /tmp/export /opt/jboss/keycloak/bin/standalone.sh -Dkeycloak.migration.action=export -Dkeycloak.migration.provider=dir -Dkeycloak.migration.dir=/tmp/export -Dkeycloak.migration.usersExportStrategy=DIFFERENT_FILES -Djboss.socket.binding.port-offset=100 rm -f /tmp/export/master-* ' # 从容器复制文件到远程主机 kubectl -n keycloak cp keycloak-0:/tmp/export /tmp/realm-export
调整后的流水线执行命令
把scp从远程脚本移到本地流水线中,确保由本地发起文件复制请求:
ssh ubuntu@example1.com 'bash' < export.sh && scp ubuntu@example1.com:/tmp/realm-export/* ./configuration2/realms/
关键优化点说明
- 替换交互式容器登录:用
kubectl exec [pod] -- bash -c '命令串'的方式,直接在容器内批量执行命令,无需进入交互式shell,执行完成后自动回到远程主机的shell环境继续后续操作。 - 去掉ssh的
-t参数:不需要分配伪终端,避免容器退出后直接终止ssh会话。 - 分离本地与远程操作:
scp是本地到远程的文件拉取,应该在本地流水线中执行,而不是放在远程脚本里(远程主机无法直接访问本地的./configuration2/realms/目录)。 - 优化进程检查:用
pgrep替代ps + grep的组合,逻辑更简洁且避免误判。
内容的提问来源于stack exchange,提问作者Zheer Ardalan
相关产品推荐
相关产品推荐

