Notice
Recent Posts
Recent Comments
Link
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

ssuperjun 님의 블로그

[스터디1] Docker 본문

인턴

[스터디1] Docker

ssuperjun 2026. 1. 25. 15:59

Docker란?

도커(Docker)는 애플리케이션을 격리된 환경(컨테이너, Container)에 패키징하여, 어느 환경에서도 동일하게 실행할 수 있게 하는 오픈 소스 소프트웨어 플랫폼

 

Docker(Container)의 필요성

하나의 서버에서 여러 애플리케이션을 띄우는 경우, 버전 충돌 문제 발생

Docker로 애플리케이션을 격리시키면, 버전 충돌 문제 해결

 

서비스마다 다양한 하드웨어에 따른 다양한 소프트웨어 종류 버전 요구
한 앱이 여러 환경에 호환 or 한 환경이 여러 앱에 호환되는 것 필요
컨테이너를 사용하면 개발 및 배포 과정에서 환경이 일관되게 유지됨
어떤 환경에서도 버전을 맞춰 애플리케이션이 동일하게 실행되도록 함

 

요청 많아지면 scale out(작업 처리할 어플리케이션 공간 늘리기) 하기에도 용이하다.

*scale out(수평적 증가): 트래픽 및 작업 부하 증가 시 시스템 리소스를 추가 -> 성능 유지

*scale up(수직적 증가): 시스템 리소스를 업그레이드(gpu, ram 등 추가 혹은 개선) -> 성능 유지

 

컨테이너란? 도커 이미지란?

컨테이너: 애플리케이션을 실행하는 데 필요한 모든 종속성을 포함하는 경량 소프트웨어 패키지

종속성: 시스템 라이브러리, 외부 코드 패키지 및 기타 운영 체제 수준 애플리케이션 등이 있지만, 컨테이너에 포함된 종속성은 운영 체제보다 고수준인 편

이미지: 소스코드, 라이브러리, 기타 파일(애플리케이션 실행에 필요한 모든 파일)을 모아놓은 불변(immutable) 파일

요약하면 이미지 파일 = 프로그램을 실행하는 데 필요한 모든 파일을 포함

이미지를 실행시켜 인스턴스화 한 것이 컨테이너이다.

빌드로 이미지 만들고, 다른 환경에서 이미지 실행하면 배포 완료

 

Virtual Machine vs. Container

Virtualization 예시: Virtualbox

한 하드웨어 위에 VM 설치해 여러 OS 운영 가능

각 VM이 사용자라고 가정하면

여러 사용자가 하나의 물리적 컴퓨팅 자원을 효율적으로 나눠쓸 수 있음

사용자는 VM을 통해 논리적으로 분리되어 독립적으로 운영할 수 있음

하이퍼바이저는 여러 게스트os를 분리하고 리소스를 할당함
virtualization은 migration에 이점이 있음 - 사용자가 기존 피지컬 머신이 바뀐줄도 모르게 migration 가능
그래서 유지보수 및 시스템 리소스 최적화
자원 할당 시 time sharing으로 효율적 할당 가능 - 더 쓰는 애 더 주고 덜 쓰는 애 덜 주고
유연함
각 사용자별 독립성 보장 - 보안
같은 피지컬 컴퓨터를 공유하기 때문에 부하 예측 실패 시 성능 저하
가상화는 분리 통합 이주에 유리
os 구동에 시간 소요
io 오버헤드 발생 - 하나의 하이퍼바이저 거쳐야 하므로

 

Container

하나의 물리적 컴퓨팅 자원 위에 여러 앱 구동

한 피지컬 하드웨어, os 공유, 독립성 보장
container engine이 각 앱에 리소스 할당


컨테이너 분리 위한 2가지 기술
namespace - 한 os 시스템을 분할
cgroup - infrastructure(피지컬 컴퓨터)의 리소스 관리. 여러 프로세스가 한 피지컬 컴퓨터에 접근할 때 리소스 충돌 방지

 

단점

호스트 os 공유하므로 os 손상 시 모든 컨테이너가 문제 발생
모든 컨테이너가 동일 커널 공유하므로 보안 문제 존재
VM에 비해 자원이 완벽히 독립적으로 통제되지 않을 수 있음(상대적인 것일 뿐이지, 컨테이너도 충분히 독립성 보장됨)

 

쿠버네티스 = 항해사 그리스어
여러 container랑 도커들 orchestration
웹 복잡성 증가에 따른 수많은 요청 효율적인 처리 필요
동일 설정 가진 여러 서버 관리 어려워짐
모든 컨테이너 관리 중요 - 오류 디버깅 모니터링
오토 스케일링, 리소스 제어, 확장성, 휴대성
컨테이너 - 다양한 소프트웨어 한 서버에서 효율적으로 동작 가능
도커 - 컨테이너 관리. 앱들 컨테이너화해 배포 및 실행 가능
쿠버네티스 - 여러 서버에 걸쳐있는 도커 컨테이너들을 조율 자동화

 

도커 설치 명령어 모음

sudo apt-get update

 

도커 실행 명령어 모음

# sudo 없이 docker 실행하기
sudo usermod -aG docker {username}
# docker 실행
sudo service docker run start
# docker 중단
sudo service docker stop

 

도커 명령어 종류

# 이미지 리스트
docker images

# 실행
docker run
# 예시: docker run –it –-name webserver –p 80:80 rmkuma/oss_week9:0.1 /bin/bash
# -t : 특정 이미지를 지정하는 옵션
# -i : 현재 터미널 창에 attach하여 상호작용할 수 있게 만드는 옵션 (-it 로 같이 사용함)
# -d : detach한 상태로 실행하여 background에서 container를 실행하는 옵션
# --name : 생성되는 container의 이름을 정할 수 있는 옵션
# --cpu-shares, --gpus, --memory : container가 사용할 수 있는 하드웨어를 제한하는 옵션
# =v : volume(현재 서버의 특정 디렉토리)를 연결하여 container 내부에서 접근하는 옵션
# -p : 호스트의 네트워크 포트를 container 내부의 port와 연결해주는 옵션
# -net : 특정 네트워크를 사용하여 container 사이의 통신을 가능하게 해주는 옵션

# 컨테이너 리스트
docker ps

# 도커파일 사용해 빌드
docker build

# docker hub 사이트 이용
docker pull
docker commit
docker push

 

도커 volume: 호스트 내에 연결할 컨테이너 공간을 할당. 호스트 내 파일은 도커 컨테이너 파일과 연결되어 있음(얕은복사 느낌 - 여기서 수정하면 저기서도 반영됨)

도커 네트워크: 호스트(서버)와 컨테이너를 포트 지정해서 연결

데이터 영속성 = 컨테이너가 중지되거나 삭제되어도 데이터 유지되도록 도커 볼륨으로 연결

볼륨 마운트하는 노드들이 많아지면, 의존성 높아지고 관리해야 될 게 많아짐

모든 걸 루트 권한으로 수행하도록 하면 안됨 - 데이터 삭제 작업 유의

 

도커 파일의 필요성

도커 이미지는 용량도 많고, 수정하기도 어려움

→ 몇kb짜리 도커 파일로 도커 빌드하면 도커 이미지가 뚝딱 생성됨

수정과 배포의 편의성

 

도커파일 기본 명령어

FROM: 기본이 되는 Docker Image를 지정
ADD & COPY: Host의 파일(src)이나 디렉토리를 Docker 이미지 내부의 파일 시스템(dest)으로 복사
ARG: Build 시에 사용될 variable을 넘겨 받는다.
CMD: 컨테이너가 시작될 때 실행할 명령을 지정(ex. “/bin/bash”)
ENTRYPOINT: 컨테이너가 시작될 때 항상 실행되어야 하는 명령을 설정(CMD보다 우선시)
ENV: 환경변수 지정
EXPOSE: Docker 내부에서 특정 port로 listen할 때 사용됨, 기본 protocol은 TCP
# 그러나, 어차피 docker run 시 –p를 통해 host의 port와 mapping 해야 하기 때문에 (덮어짐) 실효성은 없고, Dockerfile의 가시성(무슨 port, protocol)을 위한 명령어
RUN
WORKDIR: docker가 실행되는 디렉토리 경로
VOLUME: 볼륨(workspace) 생성

도커파일을 만들 땐, 컨테이너를 임시로 실행하고 내부에서 필요한 명령어들을 하나씩 시험하는 식으로 인터랙티브하게 도커파일을 구성하는 게 중요하다. 이미지를 한번 빌드하고 실행하는 데 많은 시간이 소요되기 때문

 

Docker Compose: 여러 개의 컨테이너를 한번에 묶어서 띄울 수 있다.

예를 들어 Apache Hadoop 다중 노드 클러스터(Master + 3 Worker)를 구축할 때 docker compose를 사용할 수 있다.

docker run은 명령어가 길다.

 

docker-compose.yml 예시

version: '3.3'

services:
  hadoop:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: hadoop-single-node-container
    ports:
      - "9870:9870"   # HDFS NameNode 웹 UI 포트
    volumes:
      - ./hadoop-data/dfs/name:/opt/hadoop_tmp/dfs/name
      - ./hadoop-data/dfs/data:/opt/hadoop_tmp/dfs/data
    tty: true # bash 셸 접근

 

컨테이너 초기화 후 재시작 명령어

# 모든 컨테이너 정리
docker-compose down -v # -v 옵션은 컨테이너 내 영속 데이터 삭제
sudo rm -rf {볼륨 마운트된 디렉토리 경로}
docker image prune -f
docker volume prune -f
docker network prune -f
docker system prune -af # 이건 docker images, ps 다 없애버리는 명령

# 빌드
docker-compose build 혹은 docker-compose build --no-cache
docker-compose up --build -d # 빌드와 실행 한번에

# 실행
docker-compose up -d # 백그라운드로 실행

# 마스터 컨테이너 접속(컨테이너 잘 동작하나 확인)
docker exec -it master /bin/bash

Hadoop 다중 노드 클러스터 구축, HDFS 및 MapReduce 실습 당시 도커파일 구성 순서 예시

임시로 실행한 컨테이너 내부에서 필요한 명령어들을 하나씩 시험하고, 성공한 명령어들만 도커파일에 반영함

 

1단계: 작업 디렉토리 설정

cd /softeer/data_engineering_course_materials/missions/W3/M1
mkdir hadoop-docker && cd hadoop-docker

 

2단계: 임시 Ubuntu 기반 컨테이너 띄우기

docker run -it --name temp-hadoop ubuntu:20.04 /bin/bash

 

3단계: 컨테이너 내부에서 필요한 패키지 설치

apt update && apt upgrade -y
apt install -y openjdk-11-jdk wget ssh rsync net-tools vim curl iputils-ping

 

4단계: Hadoop 설치 및 환경 설정 (컨테이너 내부)

#Hadoop 다운로드

wget https://downloads.apache.org/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz

#압축 해제 및 이동

tar -xzf hadoop-3.3.6.tar.gz
mv hadoop-3.3.6 /opt/hadoop

#환경 변수 설정
echo 'export HADOOP_HOME=/opt/hadoop' >> ~/.bashrc #Hadoop이 설치된 디렉토리 경로를 지정. Hadoop 명령어들이 어디에 설치되었는지 시스템이 앎.
echo 'export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64' >> ~/.bashrc #Java 11이 설치된 경로를 설정
echo 'export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin' >> ~/.bashrc #기존 PATH에 Hadoop의 실행파일 경로들을 추가해 터미널 어디서든 hadoop, start-dfs.sh 같은 명령어 실행
source ~/.bashrc #.bashrc 파일을 즉시 적용해 현재 터미널 세션에 반영

#정상 작동 테스트
hadoop version

 

5단계: Hadoop 설정파일 구성

cd /opt/hadoop/etc/hadoop/
core-site.xml 설정: Hadoop의 전반적인 기본 설정을 정의합니다. 특히, 파일 시스템의 기본 주소를 지정합니다.
hdfs-site.xml 설정: HDFS(Hadoop Distributed File System)의 데이터 저장 위치와 복제 정책 등을 설정합니다.
mapred-site.xml 설정: MapReduce 프레임워크에 대한 실행 방식을 설정
yarn-site.xml 설정: YARN (Yet Another Resource Negotiator)의 기본 구성을 설정. 즉, Hadoop 클러스터의 자원 할당과 실행 방식 설정

 

6단계: namenode 포맷

hdfs namenode -format

 

7단계: 서비스 수동 실행 테스트

테스트 환경이므로 start-dfs.sh 대신 수동으로 데몬 실행

hdfs --daemon start namenode
hdfs --daemon start datanode
start-dfs.sh

#컨테이너 내부에서 ssh 서버를 구동해야 함
#jps 명령어로 프로세스 확인 (namenode, datanode 떠야 정상)

jps
#예시 출력:
#12345 NameNode
#12346 DataNode

 

8단계: 컨테이너 종료 후 Dockerfile 구성

[고려사항]

설치 시 asia/seoul 부분 자동 선택되게 수정
root로도 실행하도록 환경변수 지정
$HADOOP_HOME/etc/hadoop/hadoop-env.sh 파일을 열고, JAVA_HOME을 명시적으로 설정

설정파일 4개 core-site.xml, hdfs-site.xml, mapred-site.xml, yarn-site.xml 파일 생성
entrypoint.sh 생성해서, 초기 설정(namenode 포맷) + 데몬 실행

Dockerfile

FROM ubuntu:20.04

#환경 설정

ENV DEBIAN_FRONTEND=noninteractive
ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
ENV HADOOP_VERSION=3.3.6
ENV HADOOP_HOME=/opt/hadoop
ENV PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

#패키지 설치 및 시간대 설정

RUN apt update && apt upgrade -y \
&& apt install -y openjdk-11-jdk wget ssh rsync net-tools vim curl iputils-ping tzdata \
&& ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime \
&& dpkg-reconfigure -f noninteractive tzdata

#Hadoop 설치

RUN wget [https://downloads.apache.org/hadoop/common/hadoop-${HADOOP_VERSION}/hadoop-${HADOOP_VERSION}.tar.gz](https://downloads.apache.org/hadoop/common/hadoop-$%7BHADOOP_VERSION%7D/hadoop-$%7BHADOOP_VERSION%7D.tar.gz) \
&& tar -xzf hadoop-${HADOOP_VERSION}.tar.gz \
&& mv hadoop-${HADOOP_VERSION} $HADOOP_HOME \
&& rm hadoop-${HADOOP_VERSION}.tar.gz

#환경변수 설정 파일 내 JAVA_HOME 지정

RUN echo "export JAVA_HOME=$JAVA_HOME" >> $HADOOP_HOME/etc/hadoop/hadoop-env.sh

#Hadoop 설정 파일 복사 (작성자가 따로 준비해야 함)

COPY core-site.xml $HADOOP_HOME/etc/hadoop/core-site.xml
COPY hdfs-site.xml $HADOOP_HOME/etc/hadoop/hdfs-site.xml
COPY mapred-site.xml $HADOOP_HOME/etc/hadoop/mapred-site.xml
COPY yarn-site.xml $HADOOP_HOME/etc/hadoop/yarn-site.xml

#데이터 디렉터리 생성

RUN mkdir -p /opt/hadoop_tmp/dfs/name /opt/hadoop_tmp/dfs/data

#포맷 및 데몬 실행용 기본 스크립트 복사

COPY [entrypoint.sh](http://entrypoint.sh/) /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

 

9단계: Docker 이미지 빌드 및 테스트

docker build -t hadoop-single-node .

docker run -it -p 9870:9870 --name hadoop-single-node-container hadoop-single-node
(docker run -it --name hadoop-single-node-container hadoop-single-node)

#컨테이너에서 나왔다면 다시 접속
docker exec -it hadoop-single-node-container /bin/bash

 

10단계: HDFS 동작 테스트

#디렉토리 생성
hdfs dfs -mkdir -p /user/root

#샘플 파일 업로드
echo "Hello Hadoop" > test.txt
hdfs dfs -put test.txt /user/root/

#업로드 확인
hdfs dfs -ls /user/root/

#파일 읽기
hdfs dfs -cat /user/root/test.txt

#접속 주소
http://localhost:9870/

#HDFS 웹 UI 확인(컨테이너 실행)
docker run -it -p 9870:9870 --name hadoop-single-node-container hadoop-single-node

Docker 기반의 Apache Spark Standalone 클러스터를 구축하고, Spark 작업을 실행하며 그 결과를 검증 - Spark Master 1개, Worker 2개 구성. Spark Web UI를 통한 작업 모니터링. PySpark 기반 π 추정 작업 제출

 

테스트용 컨테이너 생성 (인터랙티브 환경 구축)

docker run -it -p 8080:8080 -p 7077:7077 --name spark-test ubuntu:22.04 /bin/bash
apt update && apt install -y curl wget git build-essential software-properties-common net-tools python3 python3-pip
python3 —version

apt install -y openjdk-17-jdk
java -version

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-arm64
export PATH=$PATH:$JAVA_HOME/bin

cd /opt
wget https://dlcdn.apache.org/spark/spark-4.0.0/spark-4.0.0-bin-hadoop3.tgz
tar -xzf spark-4.0.0-bin-hadoop3.tgz

echo 'export SPARK_HOME=/opt/spark' >> ~/.bashrc
echo 'export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin' >> ~/.bashrc
source ~/.bashrc

# 심볼릭 링크 생성
ln -s /opt/spark-4.0.0-bin-hadoop3 /opt/spark

#Hostname 확인
Hostname

#결과를 worker 실행 시 반영
$SPARK_HOME/sbin/start-master.sh
$SPARK_HOME/sbin/start-worker.sh spark://df31b403bcb3:7077

http://localhost:8080/ 확인

#스파크 예제
$SPARK_HOME/bin/spark-submit --master spark://df31b403bcb3:7077 $SPARK_HOME/examples/src/main/python/pi.py 10

#결과 확인
Pi is roughly 3.137680

#http://localhost:8080/ Web UI의 Completed Applications 섹션에도 작업이 기록됨

 

도커파일 만들고 빌드 및 실행 테스트

docker build -t spark:4.0.0 .
docker run -it -p 8080:8080 -p 7077:7077 --name spark-test2 spark:4.0.0