안녕하세요 이번 포스팅에서는 수십 개의 크롤러들을 도커라이징하며 겪었던 문제 및 문제 해결을 했던 과정을 소개 시켜 드리려고 합니다.

( 그 전부터 정리해야지.. 정리해야지.. 하고 미루다가 이제서야 하게 됐네요)

그전에 왜 수십 개의 크롤러들을 도커라이징 고려를 했는지에 대해 말씀드리려 합니다.

 

우선, 기존 사내 서버실 데스크탑에서 주기적으로 실행되는 크롤러 프로세스들은

- 로컬 개발 환경과 배포 서버 환경의 차이로 인한 각종 에러로 인해, 해당 에러를 처리하는 데에만 꽤나 유의미한 시간이 들었습니다.

- 프로세스가 다운 될 정도의 에러가 발생 시 즉각적으로 대응하지 못하는 점.
(해당 상황 발생 시, 대부분은 프로세스를 다시 실행 시키는 정도의 수준으로 대응이 가능했습니다.)

- 크롤러 내부 로직 수정 시, 수동 배포와 같은 반복적인 작업.

위 사항을 비롯해 기존부터 크롤러 관리의 어려움을 느끼고 있어서 해당 부분을 팀원분들과 논의를 마친 후, 도커라이징을 하기로 결정하게 되었습니다.

 

크롤러 "공통" Dockerfile의 대략적인 내용은 아래와 같습니다

# Base image
FROM python:3.9

# Set the working directory in the container
WORKDIR /app

RUN apt-get update && apt-get install -y \
    chromium \
    chromium-driver

# Copy the project files to the working directory
COPY . .

# Install required libraries
RUN pip install -r requirements.txt

# Set the entrypoint command
ENTRYPOINT ["/bin/bash", "-c", "exec \"$@\"", "--"]

 

ENTRYPOINT만 작성한 이유는 해당 도커 이미지의 진입점을 /bin/bash로 설정해놓은 다음

  • 뒤에 오는 CMD 명령을 인자로 받는 다는 뜻이며 , 이는 곧 컨테이너 별로 다르게 실행될 스크립트를 지정해줌으로써 컨테이너 별로 공통 이미지를 가지며 서로 다르게 실행시키기 위함입니다.
  • 컨테이너가 실행될때의 명령을 컨테이너마다 각기 달리 줘야 하기 때문입니다.

 

크롤러 별 도커 컴포즈 구성은 대략적인 내용은 아래와 같습니다.

 

// 도커 컴포즈의 버전을 명시
version: '2'

services:
  crawler1:
    container_name: crawler1
    build: .
    command: python3 -u main.py crawler1
    network_mode: host
  craler2:
    container_name: crawler2
    build: .
    command: python3 -u main.py crawler2
    network_mode: host
  
  ...​

 

 

각 서비스의 컨테이너 별 command는 단일 도커 파일에서 봤을때 다음과 같은 효과가 생기게 됩니다.

  • ENTRYPOINT ["/bin/bash", "-c", "exec \\"$@\\"", "--"]
  • CMD [”python3”, "-u", "main.py", “crawler1”]
더보기

여기서 한가지 궁금점이 생기실 수도 있는데 만약, ENTRYPOINT만 정의되어 있고, 도커 컴포즈 실행시 Command 지시자가 없다면 어떻게 될까?

해당 물음에 대한 자세한 포스팅은 아래 링크를 참조하시면 좋을 것 같습니다.

https://www.popit.kr/%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EC%B2%98%EC%9D%8C-docker-%EC%A0%91%ED%95%A0%EB%95%8C-%EC%98%A4%EB%8A%94-%EB%A9%98%EB%B6%95-%EB%AA%87%EA%B0%80%EC%A7%80/

 

요약하자면, 도커 컨테이너는 가상머신과 같이 하나의 온전한 서버를 제공하는 것이 아닌, 명령을 실행하는 환경만 제공하고, 그 명령을 실행할 뿐입니다. ( 이 이야기에 대해선 다음번에 좀 더 자세히 다루도록 하겠습니다. )

 

AWS EC2 환경에서의 컨테이너

  • 크롤러 EC2 인스턴스(우분투 리눅스)에는 도커만 설치하고, 크롤러 이미지는 따로 도커 허브를 이용하진 않았습니다.
    (테스트 목적이기도 했고, 퍼블릭한 공간에 이미지를 노출하기가 꺼렸습니다. + 프라이빗은 유료..)
  • 버전 관리를 위해 git 으로 필요한 소스코드 파일과 도커 파일, 도커 컴포즈 파일만 호스트에서 이미지를 빌드하고 컨테이너를 실행하게 했습니다.
  • 성공적으로 첫 단계를 밟았다고 생각했으나 문제가 생기게 됩니다.

DB ETIMEDOUT 문제

  • EC2 인스턴스 내의 프로젝트 폴더에서 직접 코드를 실행했을 때는 잘 되었지만
  • 도커 컴포즈로 컨테이너를 실행시켰을 때, 로그에 DB ETIMEDOUT이라는 에러가 발생하여, 컨테이너가 종료되는 에러가 발생했습니다.
  • 당시의 문제점 파악으로는, 우선 네트워크 문제를 고려했습니다. ( 해당 문제가 아닐 수도 있습니다. )
  • 정리하자면, EC2 인스턴스에서의 크롤러 프로세스는 호스트 네트워크를 사용해 DB와 연결을 하고 데이터를 받아와 크롤링을 합니다.
  • 하지만, 컨테이너는 도커가 부여해준 가상 인터페이스를 가지고 외부로 나가 DB와 연결을 하기에 모종의 이유로 타임아웃이 발생할거라 생각했습니다.
더보기

💡 Docker 네트워크는 bridge, host, overlay 등 목적에 따라 다양한 종류의 네트워크 드라이버(driver)를 지원하는데요.

  • bridge 네트워크는 하나의 호스트 컴퓨터 내에서 여러 컨테이너들이 서로 소통할 수 있도록 해줍니다.
  • host 네트워크는 컨터이너를 호스트 컴퓨터와 동일한 네트워크에서 컨테이너를 돌리기 위해서 사용됩니다.
  • overlay 네트워크는 여러 호스트에 분산되어 돌아가는 컨테이너들 간에 네트워킹을 위해서 사용됩니다.

따라서, EC2 인스턴스의 네트워크 인터페이스를 그대로 활용하기 위해 위의 도커 컴포즈 파일의 네트워크 모드를 호스트로 설정해주었습니다.

 

컨테이너 헬스 체크 과정

  • 호스트 네트워크 모드를 사용해 성공적으로 크롤러들을 실행시키는데 성공했습니다.
  • 그러나, 크롤러가 작동할수록 서버의 CPU 사용량(4vCPU, 8GB)이 무지막지하게 늘어났고(아마 브라우저를 계속 생성해서 그런 거 같음)
    • 추후에 생각난건데, 네트워크 I/O 부분도 고려하지 못한게 아쉽다고 생각이 드네요
  • 그 후엔 컨테이너는 정상 실행 상태지만 내부에서는 파이썬 프로세스가 exit가 되어버리며 크롤링이 되지 않는 상황이 발생했습니다.
  • 따라서 적절한 헬스체크 방식이 필요했으며 헬스체크 실패 시 , 컨테이너를 다시 띄우려고 시도 했습니다.

CloudWatch

EC2 서버에 AWS에서 제공하는 CloudWatch를 사용하여 CPU 사용량을 주기적으로 모니터링 했습니다.

  • 크롤러 컨테이너들을 실행하고 CPU 사용량을 관측한 결과, 평균 CPU 사용률이 7~80%를 왔다갔다 했었습니다.
  • 이후로, 파이썬 프로세스가 컨테이너 내부에서 종료 됐을 시에는 CPU 사용률이 2~30%를 왔다갔다 했었습니다.
  • 그래서 위 지표를 토대로 CloudWatch의 CPU 사용률이 30%보다 아래일 때, 크롤러 컨테이너들이 종료됐다고 판단하고,
    이것을 트리거 삼아 AWS SNS에 이벤트를 게시하게 하였습니다.

SimpleNotificationService ( SNS )

AWS SNS는 말그대로 알림을 전송해주는 서비스이며, 위 사진과 같이 여러 엔드포인트에 대하여 알림을 제공할 수 있다.

  • 위 서비스의 새로운 주제를 생성해, 엔드 포인트를 람다 함수로 설정하여, (나름의) 헬스 체크 실패 시 다시 컨테이너를 띄울 수 있는 방식을 택했습니다.

AWS Lambda

Layers 구성

  • 처음 람다 함수를 실행할 때, 필요한 모듈을 import를 했어야 했는데
  • docker, slack, 인스턴스에 명령을 전달하기 위해 인스턴스와 연결하는 boto3 모듈 가 import가 되지 않았습니다.
  • 람다 공식 문서를 잘 살펴보니 함수를 실행하기 위한 특정 모듈들은 직접 .zip파일로 만들어서 업로드를 해줘야 동작을 할 수 있었습니다.
    • 그래서 필요한 모듈들을 직접 pip3를 이용해 설치하고,
    • 모듈들이 설치된 파일을 .zip파일로 압축시켜 신규 Layers를 생성한 뒤, 해당 Layer를 추가 해주었습니다.

Lambda 코드

import boto3
import os
import docker
import time
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

# ssm-client 계정 엑세스 키
access_key = os.environ['access_key']
secret_key = os.environ['secret_key']
region = os.environ['region']
instance_id = os.environ['instance_id']
slack_token = os.environ['slack_token']
slack_channel = os.environ['slack_channel']
container_list = os.environ['container_list']
remove_command = os.environ['remove_command']
compose_up_command = os.environ['compose_up_command']


ec2_client = boto3.client(
       "ec2",
       aws_access_key_id=access_key,
       aws_secret_access_key=secret_key,
       region_name=region
   )

# ssm_client를 사용하기 위해선 해당 인스턴스에 ssm_agent가 설치 되어 있어야 하며,
# 해당 access_key를 사용자의 권한에 위의 사진과 같은 권한을 설정해주었다.
ssm_client = boto3.client(
       "ssm"
       aws_access_key_id=access_key,
       aws_secret_access_key=secret_key,
       region_name=region
   )

# 도커 데몬의 기본 포트인 2375를 이용해 람다에서 명령을 실행해주기 위함
res = ec2_client.describe_instances(InstanceIds=[instance_id])
docker_host = "tcp://" + res["Reservations"][0]["Instances"][0]["PublicIpAddress"] + ":2375"

docker_client = docker.DockerClient(base_url=docker_host)
slack_client = WebClient(token=slack_token)


# 실행될 메인 람다 함수 이며 , 필수 파라미터로 event와 context가 있다.
# 이게 왜 필수냐면 트리거가 발동 되거나, 어떠한 이벤트 발생 후, 람다에 전달할때 람다에서 해당 event를 매개변수로 받아 사용해야 하기 때문.
# 근데 여기선 트리거 발생시, 실행중인 컨테이너를 전부 삭제하고 새롭게 띄우는 방식으로 설계 했기 때문에 매개변수는 따로 사용하지 않았다.
def lambda_handler(event,context):
    containers = docker_client.containers.list()

    send_slack_message('크롤러 중지 감ji')
            
    message2 = '크롤러 재실행'
    send_slack_message(message2)
            
    remove_containers()
    docker_compose_up()
            
    message3 = '크롤러 재실행 complete'
    send_slack_message(message3)
                
    return

def remove_containers():
    ssm_client_command(remove_command)
    
def docker_compose_up():    
    # docker-compose up 실행
    project_dir = '/home/ec2-user/Overware_crawler'
    compose_file = [f'{project_dir}/docker-compose.yml']
    project_name = 'my_project'

    options = {'--project-directory': project_dir, '--project-name': project_name}
    docker_client.api.compose.up(
        compose_file=compose_file,
        detach=True,
        options=options,
        timeout=60,
    )

def ssm_client_command(command):
    response = ssm_client.send_command(
        InstanceIds=[ec2_instance],
        DocumentName="AWS-RunShellScript",
        Parameters={
            "commands": [command],
        }
    )
    return

def send_slack_message(message):
    try:
        slack_client.chat_postMessage(channel=slack_channel, text=message)
    except SlackApiError as e:
        slack_client.chat_postMessage(channel=slack_channel, text=str(e))

 

여기까지 위에 열거한 문제 (컨테이너는 정상 실행 상태지만 내부에서는 파이썬 프로세스가 exit) 를 해결 하기 위해 했던 과정들입니다.

 

예전에 제가 개인적으로 따로 과정을 정리 해두었지만 글이 너무 중구난방한 상태였고, 해당 문제를 다시 복기하며 보니 개선점이 꽤나 보이네요 ..ㅎㅎㅎ;;

 

과정들을 겪고나니 이제서야 도커 스웜, 쿠버네티스 같은 컨테이너 오케스트레이션을 이유가 좀 더 와닿는 것 같습니다.

 

아쉬운 점은,

  1. 하나의 컨테이너가 이상이 발생해도, 정상 실행중인 컨테이너 모두를 내리고 다시 실행해야 하는 점
  2. 컨테이너의 내부 프로세스 상태를 확인 할 수 있는 방법을 모색하지 못한 점
  3. 왜 호스트의 CPU 사용률이 8~90%까지 되었는지 정확한 원인 파악을 못한 점 ( 추정 정도만 ..)
  4. 좀 더 Best Practice에 다가가지 못한 점

등이 있겠네요..ㅠㅠ

 

긴 글 읽어주셔서 감사합니다.

 

 

'Work Experience' 카테고리의 다른 글

좌충우돌 서비스 모니터링 핀포인트 도입기  (0) 2023.07.25

모니터링의 필요성

프로젝트를 여러 개 해보며, 본인을 포함한 팀원들이 배포된 프로젝트에 대한 모니터링이 잘 되지 않아,

 

수많은 트러블 슈팅에 많은 난항이 있었다.

 

예를 들어, (배포 환경에서) 특정 부분에서 오류가 발생해 서비스가 잘 동작하지 않는 상황에서,

 

  • 개발자 입장에서는 어디서 어떤 함수가 오류를 일으켰는지,
  • DB의 문제인지 코드의 문제인지..등등을 단번에 파악하기란 매우 어려운 일이다

또한, 향후 진행하게 될 프로젝트에 대해(BtoB든 BtoC) 효과적인 모니터링 시스템이 있으면 좋겠다는 생각을 누구나가 했을 터.

 

그러던 중,,, 네이버에서 만든 모니터링 오픈 소스 핀포인트를 발견 했으며 이는 꽤나 엄청났다.

핀포인트 ?

  • 위와 같이 분산환경에서 애플리케이션 모니터링에 최적화된 기능이 많아 매우 유용하게 사용이 가능하다.
  • 응답 코드는 물론 Response가 얼마나 걸렸는지, 자세히 까보면 어느 함수가 불려서 어떤 쿼리가 실행 되었는지도 자세하게 나온다.

실제 모니터링 화면

  • Java 분산 서비스 및 시스템의 지속적인 성능 분석을 제공하며, 오류 발생 가능성에 대한 진단과 추적을 지원하는 플랫폼 서비스.
  • 분산 애플리케이션의 트랜잭션 분석
    • 지금은 애플리케이션이 하나라 대시보드에 하나만 보이지만, 프로젝트와 핀포인트 에이전트를 동시에 구동할 때
      ( java,
      -javaagent:핀포인트에이전트가 설치된 경로,
      DdpointApplicationName=애플리케이션이름,
      DdpointApplicationId=에이전트id,
      -jar,
      애플리케이션.jar)
    • 위의 명령어의 에이전트 id로 애플리케이션이 여러 서버에 분산 되어 있을 때
    • 애플리케이션이름으로 등록된 에이전트 id를 통해 여러 서버에 있는 애플리케이션도 동시에 확인이 가능함

Deep Dive..

핀포인트 개발 동기

과거 인터넷 서비스는 사용자가 적음과 동시에, 구조 자체가 단순했었다.

 

2계층(웹 서버 + 데이터베이스) 또는 3계층(웹 서버, 웹 애플리케이션 서버, 데이터베이스)로 구성해 서비스를 운영이 가능했음.

 

하지만 인터넷 서비스가 발전하면서 3계층을 넘어 n계층 (multitier) 아키텍처로 변경 되어지며, 마이크로서비스 형식의 아키텍처는 이제 현실이 되어가고 있었다.

 

n계층 아키텍처로 변화함에 따라 시스템의 복잡도도 덩달아 증가하며, 장애나 성능 문제가 발생했을 때 해결이 어려워졌다.

 

따라서 이러한 문제점을 해결하기 위해 네이버에서는 n계층 아키텍처를 효과적으로 추적할 수 있는 새로운 플랫폼을 개발하기로 하였다.

핀포인트 특징

  • 분산된 애플리케이션의 메시지를 추적할 수 있는 분산 트랜잭션 추적
  • 애플리케이션 구성 자동 파악해서 대시보드에 뿌려줌
  • 대규모 서버군을 지원할 수 있는 수평 확장성
  • 뛰어난 가시성으로 문제 발생 지점과 병목 구간을 쉽게 발견

분산 트랜잭션 추적 방법

RPC …?

💡 Remote Procedure Call(원격 프로시저 호출)의 약자로,

별도의 원격 제어를 위한 코딩 없이 다른 주소 공간에서 “함수나 프로시저”를 실행할 수 하는 프로세스 간 통신 기술을 말한다.

→ 프로그래머는 함수가 프로그램이 존재하는 로컬 위치에 있든, 원격 위치에 있든 상관없이 동일한 기능을 수행할 수 있음을 의미.

 

일반적으로 프로세스는 자신의 주소공간 안에 존재하는 함수만 호출하여 실행이 가능함.

 

그러나, RPC의 경우 자신과 다른 주소 공간에서 동작하는 프로세스의 함수를 실행할 수 있게 해주는데,

 

이는 네트워크를 통한 메시징을 수행하기 때문.

 

MSA 구조의 서비스를 만들 때, 언어나 환경에 구애받지 않고, 비즈니스 로직을 개발하는데 집중할 수 있다 !

 

 

Google Dapper의 분산 트랜잭션 추적 방법

분산 트랜잭션 추적의 핵심은 그림처럼 Node1 에서 Node 2로 메시지를 전송했을 때, 분산된 Node1과 Node 2가 처리한 메시지의 관계를 찾아내는 것 !!

 

그러나 , 메시지의 관계를 찾을 때 어려운 점은 Node1이 보낸 N개의 메시지와 Node 2에 도착한 N개의 메시지를 보고,

 

메시지 간의 관계를 엮을 수 있는 방법이 없다는 것이다.

 

즉, Node1에서 X번째 메시지를 보냈을때, Node 2가 받은 N개의 메시지 중 X번째 메시지를 선택할 수가 없다.

 

TCP 프로토콜이나 운영체제의 수준에서 추적하려 했지만 프로토콜마다 별도로 구현해야 해 복잡도가 높고 성능이 좋지 않았다고 한다.

=> 고질적인 문제인 메시지를 정확하게 추적 해결을 하지 못했다고 한다.

 

하지만 Google Dapper팀은 이 문제를 간단한 방법으로 해결했다.

 

메시지 전송 시 애플리케이션 수준에서 메시지를 엮을 수 있는 태그를 추가 한것이다.

 

HTTP를 예로 들면, HTTP 요청 전송 시, HTTP 헤더에 메시지 태그 정보를 넣고 , 이 정보를 메시지 간의 연결 고리로 활용해 메시지를 추적한다.

  • TransacionId(TxId) : 분산된 노드를 거쳐 다니는 메시지의 아이디로, 전체 서버군에서 중복되지 않아야 함.
  • SpanId : RPC 메시지를 받았을 때 처리되는 작업의 아이디를 정의함. RPC가 노드에 도착했을 때 생성.
  • ParentSpanId : 호출한 부모의 SpanId를 나타냄

구성 요소

Pinpoint Agent

  • 애플리케이션의 모니터링 정보를 Collector로 전달
  • 현재 프로젝트에선 해당 Agent는 백엔드 서버 컨테이너가 돌아가는 EC2 서버에 위치한다.
  • EC2에 pinpoint Agent + Spring Project 요렇게 있는 셈.

Pinpoint Collector

  • 위의 Agent 서버에서 받은 정보를 HBase란 곳에 적재 한다.
  • Pinpoint는 코드 수준의 정보를 추적하기 때문에 트래픽이 많으면 많을 수록 데이터의 양이 폭발적으로 증가한다는 단점이 있다.
  • 그래서 핀포인트는 이 정보들을 Hbase에 담아서 활용한다.
Hbase ?
구글의 BigTable을 기반으로 발전한 NoSQL 오픈 소스.

실시간 읽기/쓰기 기능을 제공한다고 한다.

강력하게 일관된 읽기/쓰기고속 카운터 집계와 같은 작업에 매우 적합.

 

현재 프로젝트에서 해당 Collector는 인바운드 규칙이 좀 특이하단 걸 볼 수 있는데, 이는 Agent에서 Collector로 데이터를 보내는 포트가 8000 ~ 9999 번대이기 때문.

Pinpoint Web

  • 적재된 데이터를 웹으로 노출하여 모니터링 제공

문제점

  1. 프로젝트가 위치한 서버는 Serverless 컴퓨터 형태인 Fargate 방식임.
    • EC2 백엔드 서버에 Agent를 설치를 해야 하는데, 접속할 서버가 없음 .
    • Fargate 컴퓨팅 서비스는 그냥 컴퓨터 사양 이것저것 안 만들고 그냥 실행할 도커 이미지만 있으면 실행할 수 있도록 설계 되어 있음.
  2. 클러스터내 지원 컴퓨팅
    • 현재 프로젝트 AWS ECS 클러스터는 이런 상황을 염두에 두지 않고, Fargate 컴퓨팅만 실행하도록 되어 있었음
    • 고로, 기존 클러스터를 전부 다 삭제 하고 새로운 클러스터와 EC2 서버를 입맞에 맞게 생성해야함.
      → 프로젝트 규모에 맞게 …
  3. 도커 기반 환경에서 Pinpoint Agent 설치 …
    • 위에서 나열한 문제점은 어찌저찌 해결이 가능했다.
      1. 기존 클러스터를 삭제하고 Fargate 컴퓨팅과 EC2 컴퓨팅이 둘 다 가능한 새로운 클러스터를 만들었다.
      2. 또한 GitActions에서 우리 프로젝트를 빌드하고 서버에 전달해줄 때는 amd64 기반 이미지라
      3. 해당 CPU 아키텍처에 맞춰 다시 만들어 주었음
    • GitActions에서 이미지를 빌드 하고, AWS ECR에 푸쉬하고 EC2 서버에 배포로 변경
      1. 여기서 제일 큰 문제가 발생하는데

        처음에는 핀포인트 에이전트(수집 서버에 전달할 에이전트) 이미지 레이어를 추가시켜

        애플리케이션의 이미지를 빌드하는 과정에 이를 넣는 방식을 사용하려 했다.

        이렇게 한다면 그냥 도커 이미지만 있어도 알아서 핀포인트 에이전트와 애플리케이션이 통째로 포함된 컨테이너가 실행될테니 말이다.

      2. 하지만 위의 방법은 이미지를 빌드 하는데 너무 많은 시간이 걸렸고,

        이미지의 크기도 너무 증가하여

        결과적으로 배포하는 시간이 오래 늘어나게 되었다.
  4. 모니터링 데이터 누적 수집 불가
    1. 핀포인트가 배포할때마다 이미지 내부에 설치 됨.

    2. 배포가 일어날때마다 모니터링 데이터가 아예 초기화가 되버림

    3. 백엔드 서버가 돌아가는 환경에 자체적으로 설정해놓는게 아닌 이상 데이터를 누적 할 수 없음.

해결방안 - 도커 바인드 마운트

바인드 마운트란 ?

호스트의 스토리지를 컨테이너에 직접적으로 연결할 수 있는 방법.

`바인드 마운트`는 호스트 컴퓨터 파일 시스템의 디렉터리를 컨테이너 파일 시스템의 디렉터리로 만든다.

컨테이너 입장에서는 그냥 평범한 디렉터리에 불과하지만, 

도커를 사용하는 입장에서는 컨테이너가 호스트 컴퓨터의 파일에 직접 접근도 가능하고, 

그 반대도 가능하다.

- 바인드 마운트를 사용하면 호스트 컴퓨터의 파일 시스템을 명시적으로 지정해서 컨테이너 데이터로 쓸 수 있다.
- 속도 면에서 뛰어난 SSD 디스크, 네트워크상에서 사용하는 분산 스토리지까지 
- 호스트 컴퓨터에서 접근 가능한 파일 시스템이라면 무엇이든 컨테이너에서도 사용할 수 있다.
  1. 따라서, 호스트에 설치된 핀포인트 에이전트를 컨테이너가 중단되거나,

    실행될 때 영속성을 유지(호스트 서버의 핀포인트 에이전트 관련 환경 설정 파일 등..) 할 수 있어야 했기 때문에 

    컨테이너의 바인드 마운트 기능을 사용하기로 했으며 곧바로 이를 적용하였다.


  2. 프로젝트가 포함된 이미지가 컨테이너에서 실행 시, 호스트에 설치되어 있는 핀포인트 에이전트 경로를 마운트 시킴
    • 해당 폴더에는 핀포인트 에이전트를 실행하기 위한 .jar 파일과 config 파일 등이 있다

    • 로컬에 있는 /home/ec2-user/pinpoint-agent 를 같이 사용하게 됨

  • 볼륨이름을 pinpoint-agent로 설정해주고, 해당 볼륨을 컨테이너 내부에 /app/pinpoint-agent에 생성하도록 했다.

  • 요렇게 실행시점에 실행 서버 환경의 폴더를 마운트를 시켜놓으면 ,
  • 컨테이너 실행 시점에서 위의 명령어들을 사용해 웹 애플리케이션과 핀포인트 에이전트를 같이 구동하게 된다.
  • 서버 환경의 폴더를 그대로 마운트해서 실행되는 것 !

'Work Experience' 카테고리의 다른 글

AWS EC2 크롤러 컨테이너 헬스체크 적용기  (4) 2023.11.17

+ Recent posts