我找到了这个 systemd 服务文件来启动 autossh 以保持 ssh 隧道:https : //gist.github.com/thomasfr/9707568
[Unit]
Description=Keeps a tunnel to 'remote.example.com' open
After=network.target
[Service]
User=autossh
# -p [PORT]
# -l [user]
# -M 0 --> no monitoring
# -N Just open the connection and do nothing (not interactive)
# LOCALPORT:IP_ON_EXAMPLE_COM:PORT_ON_EXAMPLE_COM
ExecStart=/usr/bin/autossh -M 0 -N -q -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -p 22 -l autossh remote.example.com -L 7474:127.0.0.1:7474 -i /home/autossh/.ssh/id_rsa
[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)
有没有办法将 systemd 配置为在一个服务中启动多个隧道。
我不想创建N个系统服务文件,因为我想避免复制+粘贴。
除了“remote.example.com”将替换为其他主机名之外,所有服务文件都将相同。
我大约在 1.5 年前问过这个问题。
我的想法变了。是的,这很好,你可以用 systemd 做到这一点,但我将来会使用配置管理。
为什么 systemd 应该实现模板语言并替换 %h?..我觉得没有意义。
几个月后,我认为这个循环和模板应该在不同的层次上解决。我现在会使用 Ansible 或 TerraForm。
Gre*_*egL 51
好吧,假设每个单元文件唯一改变的是remote.example.com
零件,您可以使用实例化 服务。
从systemd.unit
手册页:
可选地,单元可以在运行时从模板文件中实例化。这允许从单个配置文件创建多个单元。如果 systemd 查找单元配置文件,它将首先在文件系统中搜索文字单元名称。如果没有成功并且单元名称包含“@”字符,systemd 将查找共享相同名称但删除了实例字符串(即“@”字符和后缀之间的部分)的单元模板。示例:如果请求服务 getty@tty3.service 并且没有找到该名称的文件,则 systemd 将查找 getty@.service 并在找到时从该配置文件中实例化服务。
基本上,您创建一个单元文件,其中包含一个变量(通常是%i
),其中出现差异,然后在您“启用”该服务时将它们链接起来。
例如,我有一个名为的单元文件/etc/systemd/system/autossh@.service
,如下所示:
[Unit]
Description=AutoSSH service for ServiceABC on %i
After=network.target
[Service]
Environment=AUTOSSH_GATETIME=30 AUTOSSH_LOGFILE=/var/log/autossh/%i.log AUTOSSH_PIDFILE=/var/run/autossh.%i.pid
PIDFile=/var/run/autossh.%i.pid
#Type=forking
ExecStart=/usr/bin/autossh -M 40000 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC %i
[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)
然后我启用了
[user@anotherhost ~]$ sudo systemctl enable autossh@somehost.example.com
ln -s '/etc/systemd/system/autossh@.service' '/etc/systemd/system/multi-user.target.wants/autossh@somehost.example.com.service'
Run Code Online (Sandbox Code Playgroud)
并且可以互动
[user@anotherhost ~]$ sudo systemctl start autossh@somehost.example.com
[user@anotherhost ~]$ sudo systemctl status autossh@somehost.example.com
autossh@somehost.example.service - AutoSSH service for ServiceABC on somehost.example
Loaded: loaded (/etc/systemd/system/autossh@.service; enabled)
Active: active (running) since Tue 2015-10-20 13:19:01 EDT; 17s ago
Main PID: 32524 (autossh)
CGroup: /system.slice/system-autossh.slice/autossh@somehost.example.com.service
??32524 /usr/bin/autossh -M 40000 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC somehost.example.com
??32525 /usr/bin/ssh -L 40000:127.0.0.1:40000 -R 40000:127.0.0.1:40001 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC somehost.example.com
Oct 20 13:19:01 anotherhost.example.com systemd[1]: Started AutoSSH service for ServiceABC on somehost.example.com.
[user@anotherhost ~]$ sudo systemctl status autossh@somehost.example.com
[user@anotherhost ~]$ sudo systemctl status autossh@somehost.example.com
autossh@somehost.example.com.service - AutoSSH service for ServiceABC on somehost.example.com
Loaded: loaded (/etc/systemd/system/autossh@.service; enabled)
Active: inactive (dead) since Tue 2015-10-20 13:24:10 EDT; 2s ago
Process: 32524 ExecStart=/usr/bin/autossh -M 40000 -NR 5000:127.0.0.1:5000 -i /opt/ServiceABC/.ssh/id_rsa_ServiceABC -l ServiceABC %i (code=exited, status=0/SUCCESS)
Main PID: 32524 (code=exited, status=0/SUCCESS)
Oct 20 13:19:01 anotherhost.example.com systemd[1]: Started AutoSSH service for ServiceABC on somehost.example.com.
Oct 20 13:24:10 anotherhost.example.com systemd[1]: Stopping AutoSSH service for ServiceABC on somehost.example.com...
Oct 20 13:24:10 anotherhost.example.com systemd[1]: Stopped AutoSSH service for ServiceABC on somehost.example.com.
Run Code Online (Sandbox Code Playgroud)
如您所见,%i
单元文件中的所有实例都被替换为somehost.example.com
.
不过,您可以在单元文件中使用更多的说明符,但我发现%i
在这种情况下效果最好。
rad*_*tek 25
这是一个python示例,这正是我要找的。将@
在该服务名让你开始数处理:
$ cat /etc/systemd/system/my-worker@.service
[Unit]
Description=manages my worker service, instance %i
After=multi-user.target
[Service]
PermissionsStartOnly=true
Type=idle
User=root
ExecStart=/usr/local/virtualenvs/bin/python /path/to/my/script.py
Restart=always
TimeoutStartSec=10
RestartSec=10
Run Code Online (Sandbox Code Playgroud)
启用各种计数,例如:
启用 30 个工人:
sudo systemctl enable my-worker\@{1..30}.service
Run Code Online (Sandbox Code Playgroud)启用 2 个工人:
sudo systemctl enable my-worker\@{1..2}.service
Run Code Online (Sandbox Code Playgroud)然后一定要重新加载:
sudo systemctl daemon-reload
Run Code Online (Sandbox Code Playgroud)
现在您可以通过各种方式启动/停止:
开始 1:
sudo systemctl start my-worker@2.service
Run Code Online (Sandbox Code Playgroud)启动多个:
sudo systemctl start my-worker@{1..2}
Run Code Online (Sandbox Code Playgroud)停止多个:
sudo systemctl stop my-worker@{1..2}
Run Code Online (Sandbox Code Playgroud)检查状态:
sudo systemctl status my-worker@1
Run Code Online (Sandbox Code Playgroud)更新:要将实例作为一项服务进行管理,您可以执行以下操作:
/etc/systemd/system/some-worker@.service:
[Unit]
Description=manage worker instances as a service, instance %i
Requires=some-worker.service
Before=some-worker.service
BindsTo=some-worker.service
[Service]
PermissionsStartOnly=true
Type=idle
User=root
#EnvironmentFile=/etc/profile.d/optional_envvars.sh
ExecStart=/usr/local/virtualenvs/bin/python /path/to/my/script.py
TimeoutStartSec=10
RestartSec=10
[Install]
WantedBy=some-worker.service
Run Code Online (Sandbox Code Playgroud)
/usr/bin/some-worker-start.sh:
#!/bin/bash
systemctl start some-worker@{1..10}
Run Code Online (Sandbox Code Playgroud)
/etc/systemd/system/some-worker.service:
[Unit]
Description=manages some worker instances as a service, instance
[Service]
Type=oneshot
ExecStart=/usr/bin/sh /usr/bin/some-worker-start.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)
现在您可以管理所有实例 sudo systemctl some-worker (start|restart|stop)
这是您的一些样板script.py
:
#!/usr/bin/env python
import logging
def worker_loop():
shutdown = False
while True:
try:
if shutdown:
break
# Your execution logic here.
# Common logic - i.e. consume from a queue, perform some work, ack message
print("hello world")
except (IOError, KeyboardInterrupt):
shutdown = True
logging.info("shutdown received - processing will halt when jobs complete")
except Exception as e:
logging.exception("unhandled exception on shutdown. {}".format(e))
if __name__ == '__main__':
worker_loop()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
70991 次 |
最近记录: |