赣州新闻网

首页 / 科技

谷歌将发布全球用户位置信息 监测社交距离

2020-04-04 · 赣州新闻网 · 科技

一文告诉你如何调试运行在Docker容器中的远程Node.js应用程序

作者 | Terence Shin

翻译 | 天道酬勤,责编 | Carol

出品 | CSDN云计算(ID:CSDNcloud)


你知道吗?


如果你想要调试已运行在远程计算机上Docker容器内的Node.js应用程序,并且希望无需修改命令参数(启用调试模式),其实并不需要向全世界开放远程Node.js调试器代理端口来实现。

或许你原本不知道这o k *真的可以实现,也不知道该如何实现。不过当你看完本文,就会Get 到一些新奇的知识点,话不多说,往下看吧!


一文告诉你如何调试运行在Docker容器中的远程Node.js应用程序

TdodoMVC演示应用程序


作者将使用TodoMVCO L , 7 ( K 1 Node.js应用程序的一个Github分支(由Gleb Bahmutov创建)f J 2 W 9 M . !作为本文的演示应用程序,可以随意克隆并使用此代码库:https://github.com/al# ! T 2 Jexei-led/todomvc-express。

下面是添加的用于TodoMVC应用程序的Dockerfile,它允许在Docker容器中运行TodoMVC应用程序。

FROM alpi& g 2 ) qne:3.5
# install node
RUN apk add --no-cache nodejs-current tini
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Build time argument to set NODE_ENV (‘production’’ bydefault)
ARG NODE_ENV
ENV NODE_ENV ${NODE_ENV:-production}
# install npm pg - k O d | P ~ackages: clean obs2 ^ Q : 1olete files
COPY package.json /usr/src/app/
RUN npm config set depth 0 && \\
npm install && \\
npm cache clean &y @ T c /amp;& \\
rm -rf /tmp/*
# copy source files
COPY . /usr/src/N _ Yapp
EXPOSE 3000
# Set tini as entrypoint
ENTRYPOINT
CMD
# add VCS labels for code sync and nice reports
ARG VCS_REF=”local”
LABEL org.label-schema.vcs-ret t a C hf=$VCS_REF \\
org.label-scu i Zhema.vcs-url=\"https://github.com/alexei-led/todomvc-expret l o 7 ss.git\"


一文告诉你如何调试运行在Docker容器中的远程Node.js应用程序

在Docker容器中构建和运行TodoMVC

要为TodoMVC应用程序构建新的Docker映像,请运M $ v _ R j b行docker build命令。

$ # build Docker image; set VCS_REF tocurrent HEAT : H [ K * JD commit (short)
$ docker build -t lf i Vocal/todomvc --build-argVCS_REF=`git rev-parseb E 0 3 7 = _ O ---short HEAD` .
$ # run TodoMVC in a Docker container
$ docker run -d -p 3000:3000 --name todomvclocal/todomvc node src/start.js
一文告诉你如何调试运行在Docker容器中的远程Node.js应用程序


一文告诉你如何调试运行在Docker容器中的远程Node.js应用程序

计划

最终目标:作者希望能够将Node.js调试器添加到AWS云中的远程主机上Docker容器中已经启动并运行的Node.js应用程序上,而无需修改应用程序、容器、容器配置E | & c Q t ? X或使用其他调试标) G | ; J g ; f志重新启动它。


想象一下,该应用程序正在运行,但是现在发生o t s了一些问题。作者想使用调试器连接O Z y L到该应用程序并开始查看问题。

因此,# 5 u作者需要一个计划一个逐步的流程,这将有助于实现0 B i d m v f g最终目标。下面让我们来探索操作流程。& * B N s , l

在服务器(AWS EC2 VM)机器上,有一个运行在DX P *ocker容器中的Node.js应用程序。在客户端(笔记本电脑)上,使用L D J b W w A一个IDE(Visual Studio Code),Node.js应用程序代码(git pull /clone)和一个Node.js调试器。下面是计划清单:


  • 将已经运行的应用程序设置为调试模式
  • 公开一个新的Node.js调试器代理端口,以安全的方式启用远程调试
  • 同步客户端-服务器代码:两X p J Y 4 B g者都应在git树中的相同的提交上
  • 将本地Node.js调试器添加到远程服务器上的Node.js调试器代理端口,并以安全的@ 1 X y * V ! M方式进行
  • 如果一切正常,应该能够执行常规的调试任务,例如设置断点、检查变量和暂停执行等。


步骤1:将已经运行的Node.js应用程序设置为调试模式


通过使用debug. D * L 1 l ` k命令行标志启动Node) , y或使用SIGUSR* # 4 m z u1通知现有的Node进程,可以启用和访问V8 0 H %VC应用程序的Node.js进程。注意它运行在Docker容器中。我们可以使用什么命令将过程信号发送到在Docker容器中运行的应用程序呢?

作者选择docker killcommand,该命令实际上并没有杀死在Docker容器中运行的X X & F 8 6PID 1进K K q F {程,而是向其发送Unix信号(默认情况下,它会发送SIG* P 8KILL)。

1)将TodoMVC设置为调试模式


下面要做7 N P y d h的就是将SIGUSR1发送到在todomvcDocker容器中运行的TodoMVC应用程序。有两种方法可以做到这一点:


  • 使用docker kill --signal命令将SIGUSR1发送到在Docker容器中运行的PID 1进程,如果它是正确的(正确完成信号转发1 ? h ! i V E ;)初始化应用程序(如tini),那么它将起作用;
  • 或者在已经运行的Docker容器中执行kill -s SIGUSR1,将SIGUSR1信号发送到主Node.js进程。
$ # senH i j ( Wd SIGUSR1 with! } P docker kill (ifv L L N _ I B Y usingproper init process)
$ docker kill --signal SIGUSR1 toH x q - / L K Adomvc
$ # OR run kill command for node processinside todomvc container
$ docker exec -it todomvc sh -c ‘kill -sE = d JSIGUSR1 $(pidof/ % D n = -s node)l # Z’

让我们确认Node应用程序已设置为调试模式。

$ dockn q [  p 2 . w量都将被路由到监听1p ~ D27.0.0.1:5858的Node.js调试器代理。 4848端口可以接受来自任何IP的流量。还可以使用IP范围来限制到socat侦听端口的连接,添加ranF q s p r u tge = <ANY IP RANGE>选项。

3)公开Docker容器的W * # | # { +Node.js调试器端口

在大多数情况下,我们都想调试在远程计算机(例如,AWSk 9 c h X v : EC2实例)上运行的应U J x 8用程序。我们也不想将x g 8 a p 0 u _ M不受保护的Node.js调试器代理端口公a O } L ~开给全世界。一种可行且可行的解决方案是使用SSH隧道访问此T ? ? + &端口。

$ # Open SSH Tunnel to gain access to serversport 5858.
$ # SetX $ G x V `SSH_KEY? X ; 2_FILE` to ssh key locatim 5 7 8 5 n ~ Qon oradd it to ssh-agent
$ #
$ # open an ssh tu! ! ~nnel, send it to the` Y 3 6 m , b e % 2 ig, andwait 20 secoJ X 2 u C 7nds
$ # for connections, once all connections areclosed
$ # after 20 seconds then clV L = P o 8 Cose the tunnel
$ ssh -i ${SSH_KEY_FILE} -f -oExitOnForwardFailure=yes \\
-L 5858:127.0.0.1:5858ec2_user@some.ec2.host) n e , V ( y J A.com s

现在,所有到localhost:5858的流量都将通$ ? { = 0 Y 6 &过SSH隧道传输到远程Docker主机,并经过一些socat2 Y G t 5 i :转发到运行在j s ; / | ! ?todomvc容器中的Node.js调试器代e } f R 0 g F K j理上。


一文告诉你如何调试运行在Docker容器中的远程Node.js应用程序


步骤3:同步相同的代码提交

为了能够调试远程应用程序,你需要确保在IDE中L V Z G 5 V % 1使用的代码与在远程服务器上运行的代码相同。作者也将尝试使这一步骤自动化,还记得在TodoMVC] P w u V U $ ] D Dockerfile中使用过的LABEL命令吗?这些标签可帮助我们识别git存储库并提交应用程序Docker映像:


  • org.label-| / H e ; J =schema.vcs-ref——包含用于HEAD提交的短SHA
  • org.l I !label-schema.vcs-url——包含一个应用程序git存储库URL(可在git clone/pull中使用)


作者使用的是(标签架构约定) X Ubel-schema.org/rc1/],因为它很有用,你也可以选择其他任何约定。


这种% b D i } _方法可以为每个正确标记的Docker映像标识应用程序代码存储库以及创建该存储库的提交。


$ # get git repos) + M ) ! 7 #itory uH p g l G { M f nrl form Docker image
$ GIT_URL=$(2 ! 0 # | D Q | 7docker inspect local/todomvc
| jq -r‘..ContainerConfig.Labels.”org.label-schema.vcs-url”’)
$ # get git commit from Docker image
$ GIT_COMMIT=$(F & 5 - s 8docker insL 0 % 8 ~pect local/todomvc
| jq -r ‘..ContainerConfig.Label| d % i p V e ns.”o{ H j ~ W ! O W arg.label-schema.vcs-ref”’)
$
$ # clone git repository, if needed
$ git clone $GIT_URL
$ # set HEAD to same commit as server
$ git checkout $GIT_COMMIT


现在,本地开发环境和远程应用程序都在同一个git commit上了,我们可以开始调试代码了。

步骤4:将本地Node.js调试器添加到调试器代理端口

需要配置IDE才能开始调h z Q l试,作者= c + n使用的是Visual Studio Code,这里需要添加一个新的Launch配置。

此启动配置指定远程调试器服务器和要添加的w R 7 u 4端口以及应用程序源文件的远程位置,这些位置应与本地文件同步(请参见上一步)。L | } w h W A W (

$ # get git rc P D c mepository url form Docker image
$ GIT_URL=$(docker inspect local/t! ? 5 T w & 6 vodomvc
| jqd l e Q + -r‘..Containee P y v # frConfigo - + h [ ( U I.Labels.”org.label-schema.vcs-url”’)
$ # getR g 8 ? git commit from Docker image
$ GIT_COMMIT=$(docker inspeE C / + w Wct log | { # d * Tcal/todomvc
| jq -r ‘..ContainerConx N q ! A h 1fig.Labels.”org.label-schema.vcs-ref”’)
$
$ #R ~ ^ s K : clone git repository, if nV w B ] 6 q xeeded
$ git clone $GIT_URL
$ # set HEAD to same commit as server
$ gv . n 9 Nit checkout $GIT_COMMIT
一文告诉你如何调试运行在Docker容器中的远程Node.js应用程序

总结


通过以上步骤可以实现计划的目标:可以将Node.js调试器添加到已经在远程计算机上的Docker容器中运行的Node.js| y ! ] ` P i t -应用程序。g 1 H f F m找到合适的解决方案需要很长时间,但是在找到合适的解决方案之后,该过程看起来并不复杂。

弄清楚之后,一旦在环境中遇到新问题,就可以轻松地将Node.js调试器添加到正在运行的应用程序,并开始研究该问题,这样非q I E [ 常方便。

作者录制了一部短片,只是为了证明所演示的步[ d ? = a ~ ? x d骤与本文中所描述的所有步骤一样都很顺利。

希望这篇文章对你有用,欢迎评论区和我们讨论!

确保工作赣州信息发布全球距离用户谷歌