【问题标题】:running server in tmux through ansible通过 ansible 在 tmux 中运行服务器
【发布时间】:2021-08-25 15:41:24
【问题描述】:

(请原谅我发垃圾邮件,我应该调整original question,但感觉在解决问题时遇到了新的障碍)

我设定了一个使用 ansible 运行 Web 服务器的目标:我想我会把它放在一个 tmux 会话中。由于 tmux 掉入了它自己的外壳,我很快就遇到了永远挂起的 ansible play,但在社区的帮助下,目标实现了一半。我可以运行我的服务器,但在盒子上找不到 tmux 会话。

剧本的任务是这样的:

tasks:
    - name: drop into tmux and run gunicorn
      shell:
        cmd: tmux has-session -t api || tmux new-session -d -s api /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000
        chdir: htmshop_parent

,基本上,如果会话 'api' 不存在,则在会话中启动 gunicorn(来自 virtualenv),然后分离。

该剧取得了一定的成功:

TASK [drop into tmux and run gunicorn]
*****************************************
    changed: [44.197.228.14] => {"changed": true, "cmd": "tmux has-session -t api || tmux new-session -d -s api /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000", "delta": "0:00:00.012161", "end": "2021-08-25 14:47:14.284544", "rc": 0, "start": "2021-08-25 14:47:14.272383", "stderr": "no server running on /tmp/tmux-0/default", "stderr_lines": ["no server running on /tmp/tmux-0/default"], "stdout": "", "stdout_lines": []}

tmux 报告 no server is running 错误,这是 has-session 应该做的;然后 || 的第二个子句开始...至少当我在盒子上手动运行此命令时确实。但是剧本让我感到惊讶;进程(gunicorn)确实启动了(为什么是两个?打败我!):

> pgrep -a guni
    6542 /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/python /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000
    6548 /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/python /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000

但是 tmux ls 告诉我 没有服务器在 /tmp/tmux-1001/default 上运行

有趣的是,如果我看一下这样的过程:

± |staging ?:13 ✗| → ps auxw | grep guni
root        6541  0.0  0.3   7536  3616 ?        Ss   15:14   0:00 tmux new-session -d -s api /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000
root        6542  0.0  2.2  30352 22340 pts/2    Ss+  15:14   0:00 /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/python /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000
root        6548  0.0  4.1  52532 41984 pts/2    S+   15:14   0:00 /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/python /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000

,我确实也看到了 tmux(父进程)...但是会话在哪里?如果不是在 tmux 会话中,这匹小马是从什么神奇的 subshel​​l 类东西开始的?或者它可能是某种 tmux 会话,而不是我的 tmux 知道的会话? ¯_(ツ)_/¯

感谢大家的宝贵时间...

【问题讨论】:

  • 嗯。会话只是服务器中的一个内部数据结构。 tmux 应该立即退出;我不确定为什么没有。服务器可能运行在与您的手册 tmux 尝试连接的不同的套接字上;它是由其他用户启动的吗?检查任何其他/tmp/tmux-* 目录。
  • 对于可重现的部署,您可能希望明确指定要使用的套接字,使用tmux-L-S 选项,或TMUX_TMPDIR 环境变量。
  • gunicorn 正在使用伪终端pts/2 运行,该伪终端由tmux 服务器管理(作为api 会话的一部分),而不是由您的终端模拟器管理。
  • gnunicorn 可能出于某种原因分叉了自己。
  • 会话是伪终端的集合。对这些伪终端的访问是通过链接到会话的窗口(及其组成窗格)进行调解的。会话具有 活动 窗口的概念,这是您的客户端在附加到会话时首先显示的内容。

标签: ansible tmux subshell


【解决方案1】:

不是真正的答案,而是充实一些关于 tmux 工作原理的背景。

当您运行tmux 时,它会尝试连接(或在必要时创建)在特定 Unix 套接字上运行的服务器。默认情况下,该套接字的路径类似于/tmp/tmux-$USERID/default。您可以使用-L 选项或TMUX_TMPDIR 环境变量更改目录。你可以忽略这两个使用-S 来指定你自己的确切路径的人。

例如,

$ tmux -L ~/foo ...   # Talks to a server via ~/foo/default
$ tmux -S ~/foo/bar   # Talks to a server via ~/foo/bar

您的 playbook 可能在与交互式 shell 不同的用户 ID 下执行,因此 tmux 在这种情况下尝试与两个不同的服务器通信。我建议在您的剧本中明确说明,以便毫无疑问 Ansible 将创建/与之对话的服务器。类似的东西

- name: Gunicorn in tmux
  environment:
    TMUX_TMPDIR: /tmp/my/ansible/tmux/session
  tasks:
    - name: drop into tmux and run gunicorn
      shell:
        cmd: tmux has-session -t api || tmux new-session -d -s api /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000
        chdir: htmshop_parent

看到tmux new-session -d 仍在运行, as it should have exited immediately after creating the session (or rather, asking the server to create the session). The gunicornprocesses are indeed running in this session. When a session is created, a new window for the session is created as well, and according to your output, this window is associated with the pseudoterminal/dev/pts/2`,我有些惊讶。

如果您稍后尝试附加到此会话,命令tmux attach-session -t api 将向服务器发送一个请求,询问它(非常粗略地说)哪个伪终端与命名会话的当前活动窗口相关联。然后tmux 客户端将与该伪终端通信,提供一种瘦终端仿真。

所以除了tmux new-session ... 继续在后台运行之外,一切看起来都应该如此。

【讨论】:

  • 不得不说,与大多数(如果不是全部)在线搜索结果相比,您更加强调 tmux 真正 是什么。猜想他们将真实的东西(服务器和窗口)隐藏在会话后面,让像我这样的人认为他们是一流的......虽然他们是一个用户界面神器,嗯
  • 我希望这能帮助您解决问题:)
  • "您的 playbook 可能在与交互式 shell 不同的用户 ID 下执行,因此在这种情况下 tmux 正在尝试与两个不同的服务器进行通信。" - 哦,伙计,就是这样。多么菜鸟的错误; playbook 确实以 root 身份运行 - 并且在我看到我的会话的盒子上下降到 root,没有魔法,只是血腥的 linux 基础......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 2012-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
相关资源
最近更新 更多