Docker compose를 사용해 그라파나 프로메테우스와 CD를 해보자

Featured image

진행상황

전의 프로젝트에서 도커를 띄웠을때는 그냥 도커파일만을 가지고 띄웠으면 됐었는데 이번에는 프로메테우스 그라파나 node expoter도 함께 빌드를 해야하기 때문에 컴포즈를 기본적으로 써야 했다 그리고 나중에 어차피 소켓 서버 분리하고 체결서버 분리하고 그렇게 진행이 되서 도커 컴포즈를 써야했다

사전 준비

기존에는 organization 에서 사용했지만 이번에는 실패할수도 있어서 내꺼 깃허브 레포지토리에서 진행하기로 했다

시크릿을 저장해준다

도커 파일 만들기

각 도커 이미지당 도커 파일을 만들어야 한다

  1. 그라파나용 도커 파일
  2. 프로메테우스용 도커 파일
  3. node expoter용 도커 파일
  4. 메인 프로젝트용 도커 파일 왜 굳이 이미지를 안쓰고 도커 파일을 만들어서 빌드를 하는 이유 설정파일을 깃액션으로 빌드하는데 로컬에서는 도커 컴포즈 파일이 있어서 그냥 up하니까 괜찮은데 깃액션을 사용하게 되면 도커 컴포즈 파일에서 빌드되어 푸시된다

그후 ec2에서 받을때는 하나하나 따로 이미지를 받는거라 도커 컴포즈 업을 하면 도커 컴포즈 파일이 없어서 컴포즈 업이 안됨

뭐 설정할거 없을때는 깃 액션 파일에 그냥 바로 pull 하고tag붙여서 이미지 푸시하면 다음에 풀받아 사용할 수 있는데 이러면 설정 파일을 못바꿈

설정파일에 포트번호 말고도 프로메테우스 설정파일은 어디서 매트릭을 수집할지가 들어가는데 그게 없으면 매트릭 못받아옴

#Dockerfile
#부모 이미지 지정
FROM node:alpine
#도커 내부의 디렉토리를 생성
WORKDIR /app

# 외부 패키지 설치를 위해 package.json과 yarn.lock 파일 복사
COPY ./docker-compose.yml .
COPY main/package.json .
COPY main/yarn.lock .

# 패키지 설치
RUN  yarn install

# 메인 폴더의 내용을 전부 복사 
COPY main .
# 현재 디렉터리에 있는 파일들을 이미지 내부 /app 디렉터리에 추가함

ADD     . /app
#로컬 빌드이기때문에 안의 .env파일이 있어 arg와 env로 사용할 필요 없음
# ARG로 빌드 시점 변수를 선언
ARG DATABASE_URL
ARG PORT
ARG DATABASE_HOST
ARG DATABASE_PORT
ARG DATABASE_NAME
ARG DATABASE_USERNAME
ARG DATABASE_PASSWORD
ARG JWT_SECRET
ARG PASS
ARG USER
ARG GOOGLE_ID
ARG GOOGLE_SECRET
ARG NAVER_ID
ARG BACKEND_URL
ARG FRONTEND_URL
ARG NAVER_SECRET
ARG KAKAO_ID

ENV DATABASE_URL=$DATABASE_URL 
ENV PORT=$PORT 
ENV DATABASE_HOST=$DATABASE_HOST 
ENV DATABASE_PORT=$DATABASE_PORT 
ENV DATABASE_NAME=$DATABASE_NAME 
ENV DATABASE_USERNAME=$DATABASE_USERNAME 
ENV DATABASE_PASSWORD=$DATABASE_PASSWORD 
ENV PASS=$PASS 
ENV USER=$USER 
ENV NAVER_ID=$NAVER_ID
ENV BACKEND_URL=$BACKEND_URL
ENV FRONTEND_URL=$FRONTEND_URL
ENV NAVER_SECRET=$NAVER_SECRET
ENV KAKAO_ID=$KAKAO_ID
ENV GOOGLE_ID=$GOOGLE_ID 
ENV GOOGLE_SECRET=$GOOGLE_SECRET 
ENV JWT_SECRET=$JWT_SECRET
RUN yarn prisma generate

CMD [ "node","src/app.js" ]
FROM grafana/grafana:latest
COPY grafana.ini /etc/grafana/grafana.ini
FROM prom/prometheus:latest
COPY prometheus.yml /etc/prometheus/prometheus.yml
FROM prom/node-exporter:latest
version: "3.8"
services:
  stocking:
    build:
      context: .
      args:
        PORT: $PORT
        DATABASE_URL: $DATABASE_URL
        DATABASE_HOST: $DATABASE_HOST
        DATABASE_PORT: $DATABASE_PORT
        DATABASE_NAME: $DATABASE_NAME
        DATABASE_USERNAME: $DATABASE_USERNAME
        DATABASE_PASSWORD: $DATABASE_PASSWORD
        JWT_SECRET: $JWT_SECRET
        GOOGLE_ID: $GOOGLE_ID
        GOOGLE_SECRET: $GOOGLE_SECRET
        USER: $USER
        PASS: $PASS
        AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
        AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
        AWS_REGION: $AWS_REGION
        REMOTE_PRIVATE_KEY: $REMOTE_PRIVATE_KEY
        EC2_HOST: $EC2_HOST
        NAVER_ID: $NAVER_ID
        NAVER_SECRET: $NAVER_SECRET
        KAKAO_ID: $KAKAO_ID
        BACKEND_URL: $BACKEND_URL
        FRONTEND_URL: $FRONTEND_URL
    image: ${ECR_REGISTRY}/stocking:latest
    environment:
      PORT: $PORT
      DATABASE_URL: $DATABASE_URL
      DATABASE_HOST: $DATABASE_HOST
      DATABASE_PORT: $DATABASE_PORT
      DATABASE_NAME: $DATABASE_NAME
      DATABASE_USERNAME: $DATABASE_USERNAME
      DATABASE_PASSWORD: $DATABASE_PASSWORD
      JWT_SECRET: $JWT_SECRET
      NAVER_ID: $NAVER_ID
      NAVER_SECRET: $NAVER_SECRET
      KAKAO_ID: $KAKAO_ID
      BACKEND_URL: $BACKEND_URL
      FRONTEND_URL: $FRONTEND_URL
      GOOGLE_ID: $GOOGLE_ID
      GOOGLE_SECRET: $GOOGLE_SECRET
      USER: $USER
      PASS: $PASS
      AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
      AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
      AWS_REGION: $AWS_REGION
      REMOTE_PRIVATE_KEY: $REMOTE_PRIVATE_KEY
      EC2_HOST: $EC2_HOST
  node-exporter:
    build:
      context: .
      dockerfile: Dockerfile.node-exporter
    image: ${ECR_REGISTRY}/node-exporter:latest
    container_name: node-exporter
    ports:
      - "9100:9100"
  prometheus:
    build:
      context: .
      dockerfile: Dockerfile.prometheus
    image: ${ECR_REGISTRY}/prometheus:latest
    ports:
      - "9091:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    depends_on:
      - node-exporter
  grafana:
    build:
      context: .
      dockerfile: Dockerfile.grafana
    image: ${ECR_REGISTRY}/grafana:latest
    ports:
      - "3001:3001"
    volumes:
      - ./grafana.ini:/etc/grafana/grafana.ini

그 후 설정

  1. 깃액션에 올린 후 로그 확인하기
  2. 로그에서 제대로 4개가 올라왔는지 확인하기
  3. 프로메테우스 서버 열기 (여기서는 9091포트로 바인딩함)
  4. 열고 status에 타겟에 가서 제대로 up인지 확인하기 (여기 연결된 서버수집은 위에 만든 prometheus.yml에서 만들 수 있다 )
prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: "node-exporter"
    static_configs:
      - targets: ["x.xx.xx.xxx:9100"] #자기 아이피 주소 넣기

이거 컨테이너 이름하고 내부 포트써도 되는데 내꺼는 갑자기 안되서 아이피로 넣었더니 되더라 이유를 모르겠다

  1. 연결이 됐으면 그라파나에 가서 데이터 소스에 프로메테우스 누르고 연결 url부분에 http하고 노드컨테이너이름:포트 넣고 savve&test하면 연결 된다

에러잡기

깃액션에서 도커 권한이 없다고 뜨면 pull받을때 sudo를 떼면 된다 이거 있으면 로그인 잘되도 에러나던게 안나더라 그리고 컨테이너 이름은 ec2에서 만들떄 포트 바인딩 부분 다음에 –name 옵션 사용해 지정하기 이 이름을 사용해 통신한다