검색과 추천 - (사이드 플젝) 데이터 다운로드 및 전처리 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-net
과 elastic
이 각각 다르게 설정이 되어 있습니다.
kafka-net
과 elastic
네트워크 설정이 다르게 된 이유는 다음과 같습니다
kafka-net
:kafka-net
은docker-compose.yml
파일에서 내부적으로 생성되는 네트워크입니다.driver: bridge
를 통해kafka-net
네트워크를 새롭게 생성하고, Kafka와 Zookeeper 컨테이너가 이 네트워크를 통해 서로 통신할 수 있게 합니다.driver: bridge
는 기본적인 네트워크 드라이버로, 동일한 네트워크에 연결된 컨테이너들 간의 통신을 가능하게 합니다.- 이 설정은
docker-compose up
을 실행할 때 자동으로 네트워크가 생성되도록 하려는 목적입니다.
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 접속 상태 유지), 해당 명령어를 입력해야 합니다.