在 googlecloud 启动脚本中启动 tmux 会话

start tmux sessions in googlecloud startup-script

我按照文档 here 中的建议在我的 google 云实例的元数据中添加了一个启动脚本条目 这个问题对我没用。 我的启动脚本代码是:

    #! /bin/bash
    tmux start-server
    tmux new -d -s data_vis_pfs 'pachctl mount /var/data_vis/pfs' 
    tmux new -d -s data_vis_server 'cd /var/data_vis/server/ && python ./index.py' 
    tmux new -d -s data_vis_client 'cd /var/data_vis/client/ && npx serve -l 3001 -s build'

我也试过了:

    #! /bin/bash
    tmux start \; \
         new -d -s data_vis_pfs 'pachctl mount /var/data_vis/pfs' \; \
         new -d -s data_vis_server 'cd /var/data_vis/server/ && python ./index.py' \; \
         new -d -s data_vis_client 'cd /var/data_vis/client/ && npx serve -l 3001 -s build'

当我做的时候sudo journalctl -u google-startup-scripts.service;机器启动后我得到:

    Aug 24 12:20:40 work1-cpu systemd[1]: Starting Google Compute Engine Startup Scripts...
    Aug 24 12:20:42 work1-cpu GCEMetadataScripts[506]: 2021/08/24 12:20:42 GCEMetadataScripts: Starting startup scripts (version 20201214.00).
    Aug 24 12:20:42 work1-cpu GCEMetadataScripts[506]: 2021/08/24 12:20:42 GCEMetadataScripts: Found startup-script in metadata.
    Aug 24 12:20:42 work1-cpu GCEMetadataScripts[506]: 2021/08/24 12:20:42 GCEMetadataScripts: startup-script exit status 0
    Aug 24 12:20:42 work1-cpu GCEMetadataScripts[506]: 2021/08/24 12:20:42 GCEMetadataScripts: Finished running startup scripts.
    Aug 24 12:20:42 work1-cpu systemd[1]: google-startup-scripts.service: Succeeded.
    Aug 24 12:20:42 work1-cpu systemd[1]: Started Google Compute Engine Startup Scripts.

所以这应该是一场胜利(状态 0)

但是我的代码似乎没有激活(python 服务器没有启动,front 和 pachctl mount 都没有)。 top 命令也不会显示它们。

我知道我不应该看到 root 运行 的会话,我可以通过 Socket 解决这个问题,但我暂时不关心:我只需要要启动的代码。 有人知道我遗漏了什么吗?

首先 - 根据您 运行 您的机器的图像 - 它必须 tmux 安装。如果是装有 Debian 10 的新机器,您需要在启动脚本的开头放置 sudo apt install tmux -y 来安装它。

要检查脚本 运行 是否在开头,您可以在末尾添加 touch /tmp/testfile1.txt 并在 VM 启动时检查文件是否存在。这是最简单的方法(而且不是很可靠的方法来判断脚本是否 运行)。

我不熟悉 tmux 但我发现服务器服务将在没有创建会话的情况下退出,在我看来它就像在建立新会话之前服务器退出。您可以尝试使用 sleep 1 suggested here 来解决您的问题。

我按原样尝试了 运行 你的脚本,但结果与你相同,但我进行了我提到的调试并且一切正常;

我在脚本中添加了一些“调试”行,运行 它:

apt update && sudo apt install tmux -y &>> /tmp/debug1.txt
tmux start-server  &>> /tmp/debug1.txt && echo "--- Line 1 OK" >>/tmp/debug1.txt
tmux new -d -s data_vis_pfs 'pachctl mount /var/data_vis/pfs'  &>> /tmp/debug1.txt && echo "--- Line 2 OK" >>/tmp/debug1.txt
tmux new -d -s data_vis_server 'cd /var/data_vis/server/ && python ./index.py'  &>> /tmp/debug1.txt && echo "--- Line 3 OK" >>/tmp/debug1.txt
tmux new -d -s data_vis_client 'cd /var/data_vis/client/ && npx serve -l 3001 -s build' &>> /tmp/debug1.txt && echo "--- Line 4 OK" >>/tmp/debug1.txt

我的结果是(我在安装 tmux 时删除了一些行):

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
  libevent-2.1-6 libutempter0

...... removed some lines for better readability ......


Processing triggers for man-db (2.8.5-2) ...
Processing triggers for libc-bin (2.28-10) ...
--- Line 1 OK
--- Line 2 OK
--- Line 3 OK
--- Line 4 OK

结论:您的脚本 运行 在 VM 启动时。 您只需要弄清楚如何启动 tmux 会话和服务器,然后将其用作启动脚本。

出现各种错误。感谢 Wojtek_B 他详细的回答让我找到了方向。

1 - 第一个问题:依赖关系

我必须在脚本开始时安装所有需要的依赖项,在我的例子中:

1.1 - 系统:

sudo apt update 
sudo apt install -y tmux pachctl nodejs npm python3-setuptools python3.7-dev 

1.2 - python :

python3 -m pip install {all packages here....}

由于 pip3 list 在登录时检索到要安装的软件包列表 请注意 python3 -m pip 而不是简单的 pippip3。如果机器 gcloud 默认使用 2.x 中有 python 2.x,则使用此选项,因此此安装不起作用(事件 pip3 install)。无论如何,这个 python3 -m pip install ... 有效,我会建议。

1.3 - 节点

npm install -g npx

2 - Tmux :

tmux start \; \
  new -d -s sleep 'sleep 1'\;  \
  new -d -s data_vis_pfs 'export KUBECONFIG=/var/data_vis/.kub/config && gcloud auth activate-service-account pfsmounter@{PROJECT}.iam.gserviceaccount.com --key-file=/var/data_vis/sa_cred.json &>> /tmp/pfs_log.txt && gcloud container clusters get-credentials {CLUSTER_NAME} --zone={ZONE_NAME} &>> /tmp/pfs_log.txt &&  kubectl config current-context &>> /tmp/pfs_log.txt && pachctl list repo && pachctl mount /var/data_vis/pfs --verbose &>> /tmp/pfs_log.txt' \; \
 new -d -s data_vis_server 'sleep 1 && ls /var/data_vis/pfs/ &>> /tmp/debug1.txt && cd /var/data_vis/server/ && python3 ./index.py &>> /tmp/server_log.txt' \; \
  new -d -s data_vis_client 'cd /var/data_vis/client/ && npx serve -l 3001 -s build &>> /tmp/client_log.txt'
  • 第一次会话休眠:在我的情况下没有用,但似乎是为了让脚本不会过早关闭的好习惯
  • 第二节厚皮动物:
    • 我必须创建一个服务代理(在 Cloud Console 中,如果不信任此 link,请转到 service accounts page 或键入 gcloud 服务帐户) 具有以下授权:(对不起,如果不是我必须从我的语言翻译的确切标签)
      • Reader 集群 Kubernetes Engine
      • Kubernetes Engine 服务代理
      • Reader Kubernetes 引擎
    • 注意 {CLUSTER_NAME} {ZONE_NAME}(通过 gcloud container clusters list 找到它们)和 {PROJECT} 替换为您自己的值。我必须手动执行 export KUBECONFIG=/var/data_vis/.kub/config 否则它会在 tmux 会话中失败(尽管在主线程中工作)
  • 第三节:烧瓶服务器(python):没什么特别的,我睡了一觉以防万一
  • 第四节:前台申请:没什么特别的

最终代码:

sudo apt update 
sudo apt install -y tmux pachctl nodejs npm python3-setuptools python3.7-dev 

python3 -m pip install adal aiohttp ansiwrap anyio appdirs argcomplete argon2-cffi arrow asn1crypto async-generator async-timeout attrs backcall backports.functools-lru-cache bidict binaryornot black bleach blinker blis bokeh boto boto3 botocore brotlipy bz2file cachetools catalogue certifi cffi chardet charset-normalizer click cloudpickle colorama colorcet confuse cookiecutter cryptography cycler cymem dask datashader datashape debugpy decorator defusedxml distributed docker docker-pycreds entrypoints fastai fastcore fastprogress Flask Flask-Cors Flask-SocketIO fsspec gcsfs gitdb GitPython google-api-core google-api-python-client google-auth google-auth-httplib2 google-auth-oauthlib google-cloud-bigquery google-cloud-bigquery-storage google-cloud-bigtable google-cloud-core google-cloud-dataproc google-cloud-datastore google-cloud-firestore google-cloud-kms google-cloud-language google-cloud-logging google-cloud-monitoring google-cloud-pubsub google-cloud-scheduler google-cloud-spanner google-cloud-speech google-cloud-storage google-cloud-tasks google-cloud-translate google-cloud-videointelligence google-cloud-vision google-crc32c google-resumable-media googleapis-common-protos grpc-google-iam-v1 grpcio grpcio-gcp h11 HeapDict holoviews htmlmin httplib2 idna ImageHash imageio importlib-metadata ipykernel ipython ipython-genutils ipython-sql ipywidgets itsdangerous jedi Jinja2 jinja2-time jmespath joblib json5 jsonschema jupyter-client jupyter-core jupyter-http-over-ws jupyterlab jupyterlab-git jupyterlab-pygments jupyterlab-server jupyterlab-widgets kiwisolver kubernetes llvmlite locket loguru Markdown MarkupSafe matplotlib matplotlib-inline missingno mistune msgpack multidict multimethod multipledispatch murmurhash mypy-extensions nbclient nbconvert nbdime nbformat nest-asyncio networkx  numba numpy oauthlib olefile packaging pandas pandas-profiling pandocfilters panel papermill param parso partd pathspec pathy patsy pexpect phik pickleshare Pillow pip poyo preshed prettytable prometheus-client prompt-toolkit protobuf psutil ptyprocess pyarrow pyasn1 pyasn1-modules pycosat pycparser pyct pydantic Pygments PyJWT pynndescent pyOpenSSL pyparsing pyrsistent PySocks python-dateutil python-engineio python-pachyderm python-slugify python-socketio pytz pyviz-comms PyWavelets PyYAML pyzmq rawpy regex requests requests-oauthlib requests-unixsocket retrying rope rsa ruamel.yaml ruamel.yaml.clib s3transfer scikit-image scikit-learn scipy seaborn Send2Trash setuptools shellingham simple-websocket simplejson six smart-open smmap sniffio sortedcontainers spacy spacy-legacy SQLAlchemy sqlparse srsly statsmodels tangled-up-in-unicode tblib tenacity terminado testpath text-unidecode textwrap3 thinc threadpoolctl tifffile toml tomli toolz torch torchvision tornado tqdm traitlets typed-ast typeguard typer typing-extensions umap-learn umap-learn[plot]  Unidecode uritemplate urllib3 visions wasabi wcwidth webencodings websocket-client Werkzeug wheel whichcraft widgetsnbextension wrapt wsproto xarray yarl zict zipp 

#pip3 list &>> /tmp/debug1.txt
npm install -g npx
#nodejs --version &>> /tmp/debug1.txt

tmux start \; \
  new -d -s sleep 'sleep 1'\;  \
  new -d -s data_vis_pfs 'export KUBECONFIG=/var/data_vis/.kub/config && gcloud auth activate-service-account pfsmounter@{PROJECT}.iam.gserviceaccount.com --key-file=/var/data_vis/sa_cred.json &>> /tmp/pfs_log.txt && gcloud container clusters get-credentials {CLUSTER_NAME} --zone={ZONE_NAME} &>> /tmp/pfs_log.txt &&  kubectl config current-context &>> /tmp/pfs_log.txt && pachctl list repo && pachctl mount /var/data_vis/pfs --verbose &>> /tmp/pfs_log.txt' \; \
  new -d -s data_vis_server 'sleep 1 && ls /var/data_vis/pfs/ &>> /tmp/debug1.txt && cd /var/data_vis/server/ && python3 ./index.py &>> /tmp/server_log.txt' \; \
  new -d -s data_vis_client 'cd /var/data_vis/client/ && npx serve -l 3001 -s build &>> /tmp/client_log.txt'