这是我的/etc/systemd/system/proxy.service
文件:
[Unit]
Description=proxy
After=system.slice multi-user.target
[Service]
Type=forking
User=root
StandardOutput=stdout
StandardError=stderr
SyslogIdentifier=root
ExecStart=/usr/bin/bash /root/proxy/proxy.sh
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
当我运行时systemctl status proxy
,我发现它没有运行,并且我在我的网站中看到此错误:
An error occurred: Failed to connect to api.domain.com port 9999: Connection refused
/root/proxy/proxy.sh
但是如果我在终端中手动运行,连接api.domain.com:9999
将持续并且工作正常。这是systemctl status proxy
:
● proxy.service - proxy
Loaded: loaded (/etc/systemd/system/proxy.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Sat 2022-01-22 17:02:40 +0330; 5min ago
Process: 1830 ExecStart=/usr/bin/bash /root/proxy/proxy.sh (code=exited, status=0/SUCCESS)
Jan 22 17:02:40 server.domain.com root[1830]: IPv4 address for veth-srv-proxy: 192.0.2.2
Jan 22 17:02:40 server.domain.com root[1830]: IPv4 address for wg0: 10.7.0.1
Jan 22 17:02:40 server.domain.com root[1830]: * Super-optimized for small spaces - read how we shrank the memory
Jan 22 17:02:40 server.domain.com root[1830]: footprint of MicroK8s to make it the smallest full K8s around.
Jan 22 17:02:40 server.domain.com root[1830]: https://ubuntu.com/blog/microk8s-memory-optimisation
Jan 22 17:02:40 server.domain.com root[1830]: 5 updates can be applied immediately.
Jan 22 17:02:40 server.domain.com root[1830]: 5 of these updates are standard security updates.
Jan 22 17:02:40 server.domain.com root[1830]: To see these additional updates run: apt list --upgradable
Jan 22 17:02:40 server.domain.com root[1830]: *** System restart required ***
Jan 22 17:02:40 server.domain.com systemd[1]: Started proxy.
我看到它成功退出(在服务器登录时),但按照人的逻辑它不起作用。
我应该怎么做才能保持持久连接?
我应该说一下我尝试过这链接和这在我的命令中,但它无法保持其持久性。
更新 1
内容/root/proxy/proxy.sh
:
ssh -L 127.0.0.1:9999:api.domain.com:443 remote-server
答案1
首先,basicssh
默认会启动一个交互式 shell 会话。一旦该 shell 到达“文件末尾”(当无法从 stdin 读取更多输入时),它就会退出。由于服务不输入可用时,交互式 shell 将立即退出。
对于服务来说,该ssh -N
选项更为合适:它不会尝试启动任何 shell 会话,也不会尝试启动批处理命令,而是创建一个纯粹用于隧道的连接。
其次,Type=forking
期望相关程序将“守护进程化”或“进入后台”。如果它不这样做 - 例如,您从终端运行它并且它继续占用该终端 - 那么它不是 Type=forking,它只是 Type=simple/Type=exec。
(Systemd 并不关心服务是否将使用 fork();Type= 专门用于初始进程是否会 fork然后退出即在启动期间“守护进程”。)
使用 ssh 时,该ssh -f
选项(即,ssh -fN
在本例中)将使其 Type=forking。如果没有,则-f
在您的情况下将是 Type=simple/exec(尽管在给出短时间运行的命令的情况下,它也可能是 Type=oneshot)。
(虽然中间bash
过程可能会使事情变得有点混乱。如果您想要的只是运行 1 个命令,那么这是不必要的 - 只需将该命令直接放入 systemd 服务中即可。)
把所有东西放在一起:
我更喜欢使用“forking”模式,因为它允许 systemd 清楚地区分仍在“启动”的服务与已完全“启动”的服务。
[服务] 类型=分叉 ExecStart=/usr/bin/ssh-f -N-L 127.0.0.1:9999:api.domain.com:443 远程服务器
但在某些情况下,“简单”就足够了:
[服务] 类型=简单的 ExecStart=/usr/bin/ssh-N-L 127.0.0.1:9999:api.domain.com:443 远程服务器