将 shell 变量传递给通过 kubectl exec 执行的命令

Jam*_*mes 1 bash cassandra kubernetes kubectl

我在测试时执行一项重复性任务,需要连接到 cassandra pod 并运行几个 CQL 查询。

这是“手动”方法:

  1. 在集群控制器节点上,我使用 kubectl 在 pod 上执行 shell:
    kubectl exec pod/my-app-cassandra-pod-name -it --namespace myns -- /bin/bash

  2. 进入 pod 后,我执行 cqlsh:,
    cqlsh $(hostname -i) -u myuser
    然后以交互方式输入密码

  3. 我以交互方式执行 cql 查询

现在,我想要一个 bash 脚本来自动执行此操作。我的目的是通过 kubectl exec 直接运行 cqlsh。

我遇到的问题是,显然我无法在 kubectl exec 的“命令”部分中使用 shell 变量。我需要 shell 变量来存储 a) pod 的 IP、b) 作为第一个查询的输入的 id,以及 c) 中间查询结果(后两个尚未添加到脚本中)。

到目前为止,我使用的是虚拟 CQL 查询:

#!/bin/bash

CASS_IP=$(kubectl exec pod/my-app-cassandra-pod-name -it --namespace myns -- /usr/bin/hostname -i)
echo $CASS_IP   # This prints out the IP address just fine, say 192.168.79.208

# The below does not work, errors provided below
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;'

# The below works just fine and returns the CQL query output
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;'
Run Code Online (Sandbox Code Playgroud)

上面的输出如下,其中 IP 被回显,第一个 exec'd cqlsh 中断,第二个成功:

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
Warning: Timezone defined and 'pytz' module for timezone conversion not installed. Timestamps will be displayed in UTC timezone.


 system.now()
--------------------------------------
 e78e75c0-0d3e-11ed-8825-1de1a1b1c128

(1 rows)
Run Code Online (Sandbox Code Playgroud)

有什么想法可以解决这个问题吗?我已经研究这个问题很长一段时间了,但我被困住了......

mda*_*iel 5

这是一个非常非常常见的常见问题解答:kubectl exec正如其名称所示,使用exec(3)vs system(3)——在您的情况下无论如何都行不通,因为$您的会被您的shellkubectl exec解释,而不是pod 的shell

但幸运的是,这两个问题的解决方案是相同的:system(3)通过将命令包装在sh -c调用中来创建您自己的解决方案(或者bash -c如果您有 bash-isms 并且 bash 在 pod 内可用):

kubectl exec pod/my-app-cassandra-pod-name -it --namespace myns -- sh -c '/opt/cassandra/bin/cqlsh $(hostname -i) -u myuser -p "mypass" -e "SELECT now() FROM system.local;"'
Run Code Online (Sandbox Code Playgroud)

与往常一样,请注意“外部”引用与“内部”引用,特别是当您的“mypass”或语句-e包含 shell 元字符时