AWS EC2实例在使用Docker和GitLab CI/CD时不停崩溃

5

我有一台 AWS EC2 微型实例(Ubuntu 服务器),在其中托管了几个 Web 应用程序和一个 API 服务器。我使用 Docker 和 GitLab CI/CD 部署使用 Node 编写的 API 服务器。每当我尝试运行构建操作时,它就会崩溃,并且所有托管的应用程序都无法访问。

Dockerfile 如下:

FROM node:12.3.1
LABEL maintainer Venkatesh A <av1998av@gmail.com>
WORKDIR /www/techdoc-api
ARG db_username
ARG db_password
ARG port
ARG jwt_secret
ARG jwt_expiry
ARG link_text
ARG app_link_text
ARG NODE_ENV
ARG redis_host
ARG redis_port
ARG razorpay_id
ARG razorpay_key
RUN npm install pm2 -g
RUN npm install babel-cli -g
RUN apt-get update && apt-get install -y \
  vim
ADD package.json /www/techdoc-api
RUN npm install --production
ADD . /www/techdoc-api
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
RUN cd /www/techdoc-api
RUN rm -f .env
RUN touch .env
RUN echo "port=$port \n\
redis_port=$redis_port \n\
redis_host=$redis_host \n\
razorpay_id=$razorpay_id \n\
razorpay_key=$razorpay_key \n\
db_username=$db_username \n\
db_password=$db_password \n\
link_text=$link_text \n\
app_link_text=$app_link_text \n\
jwt_secret=$jwt_secret \n\
jwt_expiry=$jwt_expiry \n\
NODE_ENV=$NODE_ENV" >> ./.env
EXPOSE 3000
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]

Docker Compose文件如下:
version: '2.2'
services:
    mysql:
        build: ./config/docker_db_config
        environment:
            - MYSQL_ALLOW_EMPTY_PASSWORD=yes
        healthcheck:
            test: "exit 0"
        restart: always
    redis:
        image: 'redis'
        ports: 
            - "6379:6379"
    api:
        build: .
        depends_on:
            mysql:
                condition: service_healthy
        entrypoint:
            - /usr/local/bin/docker-entrypoint.sh
        restart: always
        ports:
            - "3000:3000"

gitlab-ci.yml 如下:

image: docker:stable

services:
  - docker:dind

stages:
  - build
  - deploy

cache:
  paths:
    - node_modules/

build_app:
  stage: build
  script:
    - docker-compose build mysql
    - docker-compose build redis
    - docker-compose build --build-arg db_username="${db_username}" --build-arg db_password="${db_password}" --build-arg  jwt_secret="${jwt_secret}" --build-arg  NODE_ENV="${NODE_ENV}" --build-arg port="${port}" --build-arg redis_port="${redis_port}" --build-arg redis_host="${redis_host}" --build-arg jwt_expiry="${jwt_expiry}" --build-arg razorpay_key="${razorpay_key}" --build-arg razorpay_id="${razorpay_id}" --build-arg link_text="${link_text}" --build-arg app_link_text="${app_link_text}" api
    - echo "Build successful."
    - docker-compose up -d
    - echo "Deployed!!"  
  only: 
    - master
    

在运行新的任务之前,我应该删除旧的容器吗?我应该将节点模块缓存到某个地方吗?我应该确保在运行任务之前有足够的空间吗?

对以上设计提出建议和更改。

(注:通过“崩溃”,我指的是除非重新启动服务器,否则无法通过ssh登录到服务器且托管的Web应用程序不可访问)

2个回答

4
(注意:所谓“崩溃”,是指我无法通过ssh登录服务器,除非我重启它,而托管的Web应用程序也无法访问)
以下是三个正在运行的服务,它们足以使您的微型实例崩溃:
- Redis - MySQL - Node.js
t2.micro
RAM 1GB 
VCPU 1

因此,您可能需要一个更大的实例或更好的实例来构建实例外的应用程序。

您可以在部署过程中使用以下命令轻松检查这三个服务所消耗的内存: docker stats

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
f2ebb9370858        node                0.00%               9.078MiB / 15.54GiB   0.06%               6.6kB / 0B          29.1MB / 0B         11
7f5b2daf3a22        redis               0.19%               18.62MiB / 15.54GiB   0.12%               9.94kB / 0B         13MB / 0B           5
378dcc2af8a9        mysql               0.87%               364MiB / 15.54GiB     2.29%               23.8kB / 0B         471kB / 328MB       37

这些服务全部处于空闲状态,不执行任何操作,但内存消耗量约为 500MB

因此可能是其中一个容器占用了所有内存,您可以在部署过程中使用 docker stats 进行调试。

我应该在运行任务之前确保有足够的空间吗?

最好清理所有进程并停止所有容器,以便为部署腾出一些空间。安装节点模块的过程与构建相比不占用太多资源。


所以这个实例太小了,无法处理这些...最好我升级一下。 - Venkatesh A
是的,但在升级到更高规格的实例之前,请调查部署过程中的问题,使用 ssh 进入服务器并运行部署命令,不断观察 docker 状态 ,你会得到一些有价值的见解。 - Adiii

3
(Note: By 'crashing' I mean that im not able to ssh into the server unless i reboot it and the hosted web apps are unreachable)

从您的这句话来看,我认为您的CPU或内存存在问题。

我们需要实时排除服务器故障。

  1. 保持登录到服务器
  2. 运行流水线
  3. 使用top/htop监测EC2资源以及磁盘

我认为您的实例过小,无法处理您的工作请求。


那么您的意思是最好的方法是扩大实例规模吗?感谢您的快速回复... - Venkatesh A
当然可以,但如果您按照上述步骤操作,就能知道您的问题是CPU还是内存。 - Sergio Tanaka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接