python - 运行 kubectl port-forward 时子进程意外死亡
问题描述
所以,我正在编写一个 CLI 来与 Elasticsearch 对话(因为我厌倦了冗长的 curl 命令)。一切都很好,除非我想与运行在 Kubernetes 中的集群通信,因为它没有暴露在互联网上。因此我必须手动运行kubectl port-forward
第一个,我觉得它很烦人。
为了“解决”这个问题,我开始实现某种“预命令”,以便在我的 CLI 中的实际命令之前运行。在我的 CLI 配置文件中,我定义了如下内容:
my_cluster:
servers: https://localhost:9200
pre_commands:
- command: "kubectl use-context ..."
wait_for_exit: True
- command: "kubectl port-forward svc/es 9200"
wait_for_exit: False
wait_for_output: "Forwarding from 127.0.0.1:9200"
此配置意味着在与名为“my_cluster”的集群通信时,我想预先运行两个 shell 命令:
kubectl use-context ...
并等待它退出(因为它不是一个长时间运行的命令)kubectl port-forward svc/es 9200
并等待特定的输出:我不想等待这个命令退出,因为它没有。但是,当建立端口转发时,它会在标准输出上打印一些东西,因此我正在等待。
我正在使用悬崖构建命令行,它在名为prepare_to_run_command
and的方法中公开了一些钩子(在此处clean_up
定义):
def _run_shell_subcommand(self, command):
command = command.split(" ")
process = subprocess.Popen(command, stdout=subprocess.PIPE)
return process
def prepare_to_run_command(self, cmd):
for i in range(len(self.context.pre_commands)):
command_block = self.context.pre_commands[i]
process = self._run_shell_subcommand(command_block.get("command"))
if command_block.get("wait_for_exit"):
process.communicate()
elif command_block.get("wait_for_output"):
string_to_look_for = command_block.get("wait_for_output")
pattern = re.compile(string_to_look_for)
while True:
line = process.stdout.readline()
if not line:
break
line = line.decode("utf-8").strip()
match = re.search(pattern, line)
if match is None:
pass
else:
break
self.context.pre_commands[i]["process"] = process
def clean_up(self, cmd, result, err):
for pre_command in self.context.pre_commands:
pre_command.get("process").terminate()
它似乎成功地等待了预期的输出,然后继续执行我想要针对我的 Elasticsearch 集群运行的实际操作。但这就是问题所在:我通常会遇到如下错误:
Traceback (most recent call last):
File "/Users/jeromepin/.asdf/installs/python/3.6.9/lib/python3.6/site-packages/urllib3/connectionpool.py", line 672, in urlopen
chunked=chunked,
File "/Users/jeromepin/.asdf/installs/python/3.6.9/lib/python3.6/site-packages/urllib3/connectionpool.py", line 376, in _make_request
self._validate_conn(conn)
File "/Users/jeromepin/.asdf/installs/python/3.6.9/lib/python3.6/site-packages/urllib3/connectionpool.py", line 994, in _validate_conn
conn.connect()
File "/Users/jeromepin/.asdf/installs/python/3.6.9/lib/python3.6/site-packages/urllib3/connection.py", line 394, in connect
ssl_context=context,
File "/Users/jeromepin/.asdf/installs/python/3.6.9/lib/python3.6/site-packages/urllib3/util/ssl_.py", line 370, in ssl_wrap_socket
return context.wrap_socket(sock, server_hostname=server_hostname)
File "/Users/jeromepin/.asdf/installs/python/3.6.9/lib/python3.6/ssl.py", line 407, in wrap_socket
_context=self, _session=session)
File "/Users/jeromepin/.asdf/installs/python/3.6.9/lib/python3.6/ssl.py", line 817, in __init__
self.do_handshake()
File "/Users/jeromepin/.asdf/installs/python/3.6.9/lib/python3.6/ssl.py", line 1077, in do_handshake
self._sslobj.do_handshake()
File "/Users/jeromepin/.asdf/installs/python/3.6.9/lib/python3.6/ssl.py", line 689, in do_handshake
self._sslobj.do_handshake()
ConnectionResetError: [Errno 54] Connection reset by peer
我最好的猜测是在调用 Elasticsearch 期间端口转发被中断(虽然它不应该),意外终止连接。
如果我在另一个 shell 中手动运行端口转发并发出我的 CLI 命令(没有任何 pre_command),一切都会像魅力一样工作。
如果这不是运行 shell 命令的好方法,我也愿意接受建议。
解决方案
推荐阅读
- angular - Angular 7 和 HTML 选择问题
- java - 如何选择下拉值
- php - 这是在 php 类中使用准备好的语句的不安全方式吗?
- sass - 如何将 mat-tab-group 标签左对齐
- c# - LuisRecognizer 结果在 DateTimeV2 分辨率 Json 中不显示“Value”字段
- jsf - primefaces 微调器的 ValueChangeEvent 为空
- python - 搜索正则表达式时忽略子节点
- javascript - 使用 jquery 或 javascript 运行浏览器工具栏按钮
- powershell - 如何阻止电子邮件签名通过
- ios - 为什么频繁切换CALayer的隐藏属性会导致图形极度退化?