【问题标题】:what is the point of using pm2 and docker together?一起使用 pm2 和 docker 有什么意义?
【发布时间】:2018-07-05 12:30:45
【问题描述】:

我们已经非常成功地使用 pm2 在我们的服务器上运行应用程序。我们目前正在迁移到 docker,我们看到了http://pm2.keymetrics.io/docs/usage/docker-pm2-nodejs/

但是实际同时使用两者又有什么意义呢? docker 不提供 pm2 所做的一切吗?

【问题讨论】:

    标签: docker pm2


    【解决方案1】:

    通常在 docker 中使用 pm2 是没有意义的。

    PM2 和 Docker 都是进程管理器,它们都可以进行日志转发、重启崩溃的工作人员和许多其他事情。如果您在 docker 容器内运行 pm2,您将隐藏服务的潜在问题,至少如下:

    1) 如果您使用 pm2 为每个容器运行一个进程,除了增加内存消耗之外,您不会获得太多收益。可以使用带有restart policy 的纯 docker 来完成重新启动。其他基于 docker 的环境(如 ECS 或 Kubernetes)也可以做到。

    2) 如果您运行多个进程,您将更加难以监控。 CPU/内存指标不再直接用于您的封闭环境。

    3) 单个 PM2 进程的健康检查请求将分发给可能隐藏不健康目标的工作人员

    4) pm2 隐藏了 Worker 崩溃。您几乎不会从您的监控系统(如 CloudWatch)中了解它们。

    5) 负载平衡变得更加复杂,因为您实际上将拥有多个级别的负载平衡。

    在 docker 容器内运行多个进程也与 docker 的理念相矛盾,即每个容器保持一个进程。

    我能想到的一种情况是,如果您对 docker 环境的控制非常有限。在这种情况下,运行 pm2 可能是控制工作人员调度的唯一选择。

    【讨论】:

    • 我唯一可以补充的是,“让 Node.js 在 Docker 中保持稳定的四大策略”docker.com/blog/keep-nodejs-rockin-in-docker 还建议不要在 docker 中使用 pm2。
    • 对于#2:PM2没有监控功能吗?对于#3:PM2 不会复活不健康/死掉的进程吗?我打算将一个 PM2-Node.js-cluster 放入一个可以获取所有流量的容器中,这样负载平衡就会变得更加简单。有那么严重吗?
    • 取决于您的环境。如果您打算“直接”公开您的 pm2 集群,那么它可能会起作用。但是,如果你有 ECS + ALB 和 autoscaling 之类的东西,那么使用 pm2 几乎没有意义。
    • 如果您的 Web 应用程序的文件会随时间更改,例如它所依赖的 CSV 文件,那么 Docker 运行时本身不会监控这些文件的更改。当某些用例需要的特定文件发生更改时,Pm2 将重新加载应用程序。
    • 感谢您的解释??
    【解决方案2】:

    更新:

    您可能不赞成在 Docker 中使用 pm2,但有时应用程序要求不同,您可能需要在一个 docker 容器中运行 两个 nodejs 应用程序,以防万一你想运行前端和后端应用程序在同一个容器中,然后在 pm2 运行良好的情况下,然后其他解决方法。

    所以现在我们有了 pm2-runtime,它在 前台 中运行 docker 进程,您的应用程序将使用 pm2 运行前台,您可以期待与在没有 pm2 的情况下运行。

    所以对于 pm2-run time

    • 您可以在 Docker 容器中运行多个节点应用程序
    • 您现在可以在前台运行应用程序
    • 可以与key metrics集成
    • 您生成自定义指标
    • 容器的行为与不使用 pm2 但使用 pm2 时的行为相同。
    • 您现在可以控制重启行为,(如果进程崩溃,pm2 将自动重启,如果禁用,则容器将被终止)
    • 在安装等开发环境中,不需要重启容器,只需重启 pm2 进程 pm2 restart all ,这样可以节省开发时间。
    FROM node:alpine
    RUN npm install pm2 -g
    CMD ["pm2-runtime", "app.js"]
    

    或者如果你想在一个容器中运行多个节点应用程序,那么你可以 process.yml

    FROM node:alpine
    RUN npm install pm2 -g
    CMD ["pm2-runtime", "process.yml"]
    

    process.yml 文件 您还可以创建 YAML 格式的生态系统文件。示例:

    这将允许容器运行多个 nodejs 处理。

    apps:
      - script   : ./api.js
        name     : 'api-app'
        instances: 4
        exec_mode: cluster
      - script : ./worker.js
        name   : 'worker'
        watch  : true
        env    :
          NODE_ENV: development
        env_production:
          NODE_ENV: production
    

    如果您想使用 Keymetrics 运行。

    Keymetrics.io 是建立在 PM2 之上的监控服务,允许 轻松监控和管理应用程序(日志、重启、异常 监控……)。在 Keymetrics 上创建存储桶后,您将获得一个 公钥和密钥。

    FROM node:alpine
    RUN npm install pm2 -g
    CMD ["pm2-runtime", "--public", "XXX", "--secret", "YYY", "process.yml"]
    

    禁用自动重启:

    使用此标志,如果 nodejs 进程由于错误或异常而终止或停止,则容器将被终止。有时我们不会自动重启进程,但我们想重启容器。

    FROM node:alpine
    RUN npm install pm2 -g
    CMD ["pm2-runtime","app.js","--no-autorestart"]
    
    

    没有 pm2 运行时

    根据经验,每个容器只有一个进程。因此,请记住这一点,您可以使用node start server.js 在容器内启动您的进程,就像您在没有 docker 时所做的那样。如果 nodejs 服务器崩溃,这里会发生什么?在这种情况下,您的容器将被杀死。哪一个应该避免这样做。

    每当 nodejs 服务器关闭时,您的容器就会被杀死,因为主进程将关闭,并且该进程应该作为容器的主进程位于前台。

    所以最终有 pm2 来解决这个问题。这就是您可以一起使用 pm2 和 supervisord 来实现这一目标的方法。

    如果您也在寻找示例,这里是 dockerfile 和所需的配置文件。使用 alpine 最轻量级的 2MB 镜像。

    FROM alpine:3.7
    COPY supervisord.conf /etc/supervisord.conf
    #installing nodejs and supervisord
    RUN apk add  --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/v3.7/main/ \
        --repository http://dl-cdn.alpinelinux.org/alpine/v3.7/community/ \  
       sudo supervisor nodejs>=8 
    RUN npm i pm2  -g
    COPY pm2.conf  /etc/supervisord.d/pm2.conf
    

    supervisord.conf

    [unix_http_server]
    file = /tmp/supervisor.sock
    chmod = 0777
    chown= nobody:nogroup
    
    [supervisord]
    logfile = /tmp/supervisord.log
    logfile_maxbytes = 50MB
    logfile_backups=10
    loglevel = info
    pidfile = /tmp/supervisord.pid
    nodaemon = true
    umask = 022
    identifier = supervisor
    
    [supervisorctl]
    serverurl = unix:///tmp/supervisor.sock
    
    [rpcinterface:supervisor]
    supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
    
    [include]
    files = /etc/supervisord.d/*.conf
    

    pm2.conf

        [supervisord]
        nodaemon=true
        
        [program:pm2]
        command:pm2 start pm2_processes.yml --no-daemon
        startretries:5
    
    

    【讨论】:

    • "哪一个应该避免这样做。" Docker Swarm 可以处理这个
    • 是的,你可以忽略它,它与pm2 start server.Js 相同。您可以在此处阅读有关 yml 配置的信息 pm2.keymetrics.io/docs/usage/application-declaration
    • 似乎正确的文件夹是 /etc/supervisor/conf.d/ 而不是 /etc/supervisord.d/ ?? gist.github.com/RoccoHoward/4440d9ac0a375665de0c9c2068a53715
    • 你需要两个文件夹,一个用于全局配置/etc/supervisord.conf,另一个用于应用程序配置`/etc/supervisord.d/pm2.conf`
    • pm2 网站说使用pm2-runtime 而不是pm2。我不确定有什么区别,或者如何让 isnight 进入状态和日志记录。
    猜你喜欢
    • 2011-08-26
    • 2013-09-06
    • 2019-05-26
    • 1970-01-01
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    • 2021-05-01
    • 1970-01-01
    相关资源
    最近更新 更多