在 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
而不是简单的 pip
或 pip3
。如果机器 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'
我按照文档 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
而不是简单的 pip
或 pip3
。如果机器 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 会话中失败(尽管在主线程中工作)
- 我必须创建一个服务代理(在 Cloud Console 中,如果不信任此 link,请转到 service accounts page 或键入 gcloud 服务帐户)
具有以下授权:(对不起,如果不是我必须从我的语言翻译的确切标签)
- 第三节:烧瓶服务器(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'