如何在kubectl exec执行的命令中传递Shell变量?
解决kubectl exec中传递Shell变量到Cassandra cqlsh的问题
问题背景
需要自动化重复连接Cassandra Pod执行CQL查询的流程,手动操作正常,但脚本中通过kubectl exec获取的Pod IP变量传递给cqlsh时出现主机名解析错误,直接写死IP则可成功执行。
原脚本
#!/bin/bash CASS_IP=$(kubectl exec pod/my-app-cassandra-pod-name -it --namespace myns -- /usr/bin/hostname -i) echo $CASS_IP # 输出正常IP,例如192.168.79.208 # 执行失败的命令 kubectl exec pod/my-app-cassandra-pod-name -it --namespace myns -- /opt/cassandra/bin/cqlsh $CASS_IP -u myuser -p 'mypass' -e 'SELECT now() FROM system.local;' # 执行成功的命令(写死IP) kubectl exec pod/my-app-cassandra-pod-name -it --namespace myns -- /opt/cassandra/bin/cqlsh 192.168.79.208 -u myuser -p 'mypass' -e 'SELECT now() FROM system.local;'
错误输出
192.168.79.208 Warning: Timezone defined and 'pytz' module for timezone conversion not installed. Timestamps will be displayed in UTC timezone. Traceback (most recent call last): File "/opt/cassandra/bin/cqlsh.py", line 2357, in <module> main(*read_options(sys.argv[1:], os.environ)) File "/opt/cassandra/bin/cqlsh.py", line 2326, in main encoding=options.encoding) File "/opt/cassandra/bin/cqlsh.py", line 463, in __init__ load_balancing_policy=WhiteListRoundRobinPolicy([self.hostname]), File "/opt/cassandra/bin/../lib/cassandra-driver-internal-only-3.25.0.zip/cassandra-driver-3.25.0/cassandra/policies.py", line 425, in __init__ File "/opt/cassandra/bin/../lib/cassandra-driver-internal-only-3.25.0.zip/cassandra-driver-3.25.0/cassandra/policies.py", line 426, in <listcomp> File "/usr/lib64/python3.6/socket.py", line 745, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags): socket.gaierror: [Errno -2] Name or service not known command terminated with exit code 1
解决方案
1. 清理IP变量中的空白字符
问题根源是hostname -i的输出可能包含换行、多余空格等不可见字符,导致变量CASS_IP并非纯IP字符串。修改IP获取命令,去除空白字符:
# 方法1:用tr删除所有空白字符 CASS_IP=$(kubectl exec pod/my-app-cassandra-pod-name --namespace myns -- /usr/bin/hostname -i | tr -d '[:space:]') # 方法2:用xargs自动去除首尾空白并压缩中间空格 CASS_IP=$(kubectl exec pod/my-app-cassandra-pod-name --namespace myns -- /usr/bin/hostname -i | xargs)
注意:去掉-it参数,非交互式执行不需要分配tty,避免输出干扰。
2. 验证变量有效性
执行以下命令确认变量无多余空白:
echo "|$CASS_IP|"
正常输出应为|192.168.79.208|,无额外空格或换行。
3. 优化cqlsh执行命令
执行cqlsh时同样去掉-it(非交互式场景不需要),并给变量加双引号,避免特殊字符拆分:
kubectl exec pod/my-app-cassandra-pod-name --namespace myns -- /opt/cassandra/bin/cqlsh "$CASS_IP" -u myuser -p 'mypass' -e 'SELECT now() FROM system.local;'
4. 更简洁的替代方案(避免外部变量传递)
直接将IP获取和cqlsh执行逻辑放到Pod内部的Shell中执行,完全跳过外部变量传递:
kubectl exec pod/my-app-cassandra-pod-name --namespace myns -- /bin/bash -c '/opt/cassandra/bin/cqlsh $(hostname -i) -u myuser -p "mypass" -e "SELECT now() FROM system.local;"'
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

