我正在编写一个下属 charm,它将使用 打开特定端口Charmhelpers.core.hookenv.open_port
。现在我想将同一个下属 charm 部署到同一台机器上的另一个 charm。我遇到的问题是,我想要打开的端口已被另一个下属 charm 打开,所以我的 charmhelpers 给了我一个错误:
subprocess.CalledProcessError: Command '['open-port', '8080/TCP']' returned non-zero exit status 1
我无法在同一台机器上两次打开同一个端口,这是有道理的,但Charmhelpers.core.hookenv
我找不到任何可以列出所有打开端口的方法。有没有办法让我在我的 charm 中检查我的端口是否已经打开?
答案1
回答标题中提出的问题:是的!
用 Python 编写的 Charms
该charmhelpers
库包含您所需的功能:
from charmhelpers.core.hookenv import opened_ports
opened_ports()
将为您提供开放的端口范围和协议的列表:
>>> opened_ports()
['80/tcp', '8081-8083/tcp', 'icmp']
该icmp
协议很特殊,因为没有端口号。
非 Python 魅力
如果您希望在 Python 之外执行此操作,您的脚本应该执行一个 shell 命令:
open-ports
您需要在钩子处理程序中解释其输出。那么,open-ports
命令实际上提供了什么?您可以通过使用安全 shell 登录到单元并自行运行命令来进行实验。
首先我们用 charm 设置默认模型ubuntu
:
$ juju bootstrap localhost c-testing
$ juju deploy ubuntu
现在我们可以请求 Juju 授予我们直接访问ubuntu
该单元上下文中运行 charm 的机器的权限ubuntu/0
:
$ juju run --unit ubuntu/0 -- opened-ports --help
Usage: opened-ports [options]
Summary:
lists all ports or ranges opened by the unit
Options:
--format (= smart)
Specify output format (json|smart|yaml)
-o, --output (= "")
Specify an output file
Details:
Each list entry has format <port>/<protocol> (e.g. "80/tcp") or
<from>-<to>/<protocol> (e.g. "8080-8088/udp").
只是为了确认一下,我们可以opened-ports
直接从我们所在位置的笔记本电脑上运行我们在云中关心的单元上下文:
$ juju run --unit ubuntu/0 -- opened-ports --format=smart
80/tcp
8081-8083/tcp
icmp
或者如果您更喜欢机器可读的输出:
$ juju run --unit ubuntu/0 -- opened-ports --format=json
["icmp","80/tcp","8081-8083/tcp"]
我们可以从下属组件检查父组件的开放端口吗?
并非毫无痛苦...一旦我找到了一些相对简单的事情,我就会尝试充实答案。
答案2
从文档看来您可以使用打开端口挂钩工具:
https://jujucharms.com/docs/stable/reference-hook-tools#opened-ports
它看起来像是位于这里的 charm-helpers 中:
另一种可能的方法是先关闭要打开的端口,然后再打开它,这样它在技术上就关闭了,可以重新打开。不过,我敢肯定,如果多个下属管理相同的端口,这会引起混淆。