Post

검색과 추천 - (사이드 플젝) 데이터 다운로드 및 전처리 micro app 개발 (1)

데이터 다운로드 및 전처리 micro app 개발

python 개발 환경 구축 - docker container 생성 및 docker network 연동

먼저 대상 데이터셋 Amazon Berkeley Objects (ABO) 데이터셋abo-listings.tar 파일을 다운로드 하고, 적절한 전처리를 수행할 것입니다. 그 전에 이를 수행하는 코드를 python 스크립트로 작성해 실행할 것입니다. 따라서 python 환경을 독립적인 docker container로 만들고, 이를 앞서 만들어 놓은 환경에 integration을 시켜놓으려 합니다. 이를 위해서 아래와 같이 아주 간단하게 Dockerfile을 작성합니다. 이를 통해 제가 원하는 python 환경을 독립적으로 구성하고, 여러가지 필요한 library들을 설치해 사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
FROM python:3.9-slim

# 작업 디렉토리 설정
WORKDIR /usr/src/app

# 프로젝트 파일 복사
COPY . .

# 필요 라이브러리 설치
RUN pip install -r requirements.txt

# 기본 명령어를 bash로 설정
CMD ["/bin/bash"]

그리고 앞서 구축해놓은 elastic, kafka-net이라는 docker network에 해당 python 컨테이너를 연결하기 위해, docker-compose.yml을 업데이트 합니다.

version: '3.8'

services:
  zookeeper:
    image: bitnami/zookeeper:latest
    container_name: zookeeper
    environment:
      - ALLOW_ANONYMOUS_LOGIN=yes  # 익명 로그인을 허용하여 Zookeeper가 시작되도록 설정
    ports:
      - "2181:2181"
    networks:
      - kafka-net

  kafka:
    image: bitnami/kafka:latest
    container_name: kafka
    environment:
      - KAFKA_BROKER_ID=1
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - KAFKA_LISTENERS=PLAINTEXT://:9092
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092
      - ALLOW_PLAINTEXT_LISTENER=yes
    ports:
      - "9092:9092"
    depends_on:
      - zookeeper
    networks:
      - kafka-net

  python-app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: python-app
    ports:
      - "8000:8000"  # 예: 웹 서버를 위한 포트 매핑
      - "8888:8888"  # 예: Jupyter Notebook을 위한 포트 매핑
    networks:
      - elastic
      - kafka-net
    depends_on:
      - kafka
      - zookeeper

networks:
  kafka-net:
    driver: bridge
  elastic:
    external: true  # 이미 존재하는 elastic 네트워크를 사용

docker-compose.yml의 내용 중 “python-app” 부분의 내용을 업데이트 했습니다. 관련 네트워크를 elastic, kafka-net을 명시함으로써, 그리고 Dockerfile도 적어줘 앞서 세팅한 elasticsearch, kafka, spark와 같은 기존 서비스들과 python 3.9환경이 충돌하지 않으면서 유연하게 연동할 수 있게 될 것입니다.

한가지 특이사항은 ‘networks’ 설정 부분 입니다. kafka-netelastic이 각각 다르게 설정이 되어 있습니다.

kafka-netelastic 네트워크 설정이 다르게 된 이유는 다음과 같습니다

  1. kafka-net:
    • kafka-netdocker-compose.yml 파일에서 내부적으로 생성되는 네트워크입니다.
    • driver: bridge를 통해 kafka-net 네트워크를 새롭게 생성하고, Kafka와 Zookeeper 컨테이너가 이 네트워크를 통해 서로 통신할 수 있게 합니다.
    • driver: bridge는 기본적인 네트워크 드라이버로, 동일한 네트워크에 연결된 컨테이너들 간의 통신을 가능하게 합니다.
    • 이 설정은 docker-compose up을 실행할 때 자동으로 네트워크가 생성되도록 하려는 목적입니다.
  2. elastic:
    • elastic 네트워크는 external: true로 설정되어 있습니다.
    • 이는 이 네트워크가 이미 수동으로 생성되어 있으며, docker-compose가 이 네트워크를 새로 생성하지 않고, 기존의 네트워크를 사용하도록 명시하는 것입니다.
    • external: true로 설정하면 docker-compose는 이 이름의 네트워크가 존재하는지 확인하고, 있다면 이를 사용합니다. 만약 네트워크가 존재하지 않으면 오류를 발생시킵니다.
    • 이 설정은 이미 존재하는 네트워크(여기서는 elastic 네트워크)를 사용하여 Elasticsearch와 Python 애플리케이션 컨테이너를 연결하려는 목적입니다.

종합하면..

  • kafka-net: docker-compose.yml에서 내부적으로 생성되는 네트워크이며, Kafka와 Zookeeper의 통신을 위해 사용됩니다.
  • elastic: 이미 수동으로 생성된 네트워크를 사용하여 Python 애플리케이션이 기존의 Elasticsearch와 통신할 수 있도록 합니다.

이 차이는 새로운 네트워크를 생성할 필요가 있는지, 아니면 기존의 네트워크를 재사용해야 하는지에 따라 결정됩니다. kafka-net은 새로 생성하고자 했고, elastic은 기존 네트워크를 그대로 사용하고자 했기 때문에 설정이 다르게 된 것입니다.

1
docker-compose up -d --build

위 명령을 통해 python container를 구동합니다.

최종적으로 아래와 같이 elasticsearch, kafka, python docker container가 생성 완료된 것을 확인할 수 있습니다.

1
2
3
4
5
6
7
js.kim@vm:~/search$ sudo docker ps -a
CONTAINER ID   IMAGE                                                  COMMAND                  CREATED          STATUS                      PORTS                                                                                  NAMES
72f6871fc9a0   search-python-app                                      "/bin/bash"              36 seconds ago   Exited (0) 35 seconds ago                                                                                          python-app
340ecc7abc58   bitnami/kafka:latest                                   "/opt/bitnami/script…"   8 minutes ago    Up 8 minutes                0.0.0.0:9092->9092/tcp, :::9092->9092/tcp                                              kafka
ea4c89bba233   bitnami/zookeeper:latest                               "/opt/bitnami/script…"   8 minutes ago    Up 8 minutes                2888/tcp, 3888/tcp, 0.0.0.0:2181->2181/tcp, :::2181->2181/tcp, 8080/tcp                zookeeper
09bfb819b030   docker.elastic.co/kibana/kibana:8.15.0                 "/bin/tini -- /usr/l…"   28 hours ago     Up 28 hours                 0.0.0.0:5601->5601/tcp, :::5601->5601/tcp                                              kibana
4b78c6355980   docker.elastic.co/elasticsearch/elasticsearch:8.15.0   "/bin/tini -- /usr/l…"   28 hours ago     Up 28 hours                 0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp   elasticsearch

살펴보니 python-app이라는 container가 ‘exited(0)’ 되어 있습니다. ‘exited(0)’은 정상적으로 종료되어 있는 상태라는 의미입니다. 아래와 같은 명령어를 실행해 container를 다시 구동합니다.

1
2
3
4
5
6
7
8
9
10
11
12
docker run -it \
  -v /home/js.kim/search:/usr/src/app \
  -p 8000:8000 \  # 웹 서버를 위한 포트 매핑
  -p 8888:8888 \  # Jupyter Notebook을 위한 포트 매핑
  --network elastic \
  search-python-app /bin/bash

# RUN, 생성
sudo docker run -it -v /home/js.kim/search:/usr/src/app -p 8000:8000 -p 8888:8888 --network elastic search-python-app /bin/bash

# 접속
sudo docker exec -it "CONTAINER ID" /bin/bash
  • -it: 대화형 모드로 터미널에 연결된 상태로 컨테이너를 실행합니다.
  • -v /home/js.kim/search:/usr/src/app: 호스트의 디렉토리를 컨테이너의 /usr/src/app 디렉토리로 마운트하여, 파일을 공유합니다.
  • -p 8000:8000: 컨테이너의 8000 포트를 호스트의 8000 포트로 노출하여, 웹 서버에 접근할 수 있도록 합니다.
  • -p 8888:8888: 컨테이너의 8888 포트를 호스트의 8888 포트로 노출하여, Jupyter Notebook에 접근할 수 있도록 합니다.
  • --network elastic: 컨테이너를 elastic 네트워크에 연결하여 Elasticsearch와 통신할 수 있게 합니다.
  • /bin/bash: 컨테이너가 시작되면 bash 쉘로 진입하여 대화형으로 명령어를 실행할 수 있습니다.

앞서 docker network는 elastic뿐만 아니라 kafka-net도 설정했었습니다. 컨테이너가 실행된 후, kafka-net 네트워크에도 연결하려면 다음 명령어를 실행합니다:

1
docker network connect kafka-net python-app

이렇게 하면 python-app 컨테이너가 elastic 네트워크와 kafka-net 네트워크 모두에 연결되어, 두 네트워크 내의 서비스와 통신할 수 있게 됩니다. 이 설정을 통해 컨테이너를 실행한 후, 호스트의 http://localhost:8000에서 웹 서버를, http://localhost:8888에서 Jupyter Notebook에 접근할 수 있습니다.

  • 단, docker network connect kafka-net python-app 명령은 container 진입 후 펼쳐지는 shell에서 입력하면 작동하지 않습니다. container 내부에는 docker가 설치되어 있지 않기 때문입니다. 따라서 새로 terminal을 하나 키고(기존 terminal은 container 내부 shell 접속 상태 유지), 해당 명령어를 입력해야 합니다.
This post is licensed under CC BY 4.0 by the author.