논문을 읽고 코드를 실행시키다 보니 어떤건 우분투 18 어떤건 20 어떤건 22
어떤건 gcc7.5 어떤건 9.5 CMake는 뭘 쓰고 어쩌고 저쩌고
환경설정하다 정신이 나가버려서 결국 docker를 써보기로 했습니다.
요즘 황금방패가 점점 더 세지는 느낌인데 울고싶네요.
저는 아나콘다 환경을 사용하는걸 선호합니다. 사실 아나콘다로 대부분의 문제는 해결 가능했거든요
Docker와 Anaconda(특히 conda env)는 모두 독립적인 환경을 제공하는 도구입니다.
그러나 주요 사용 사례와 방식에는 중요한 차이점이 있습니다.
목적:
범위:
격리 수준:
요약하면, Docker는 "코드와 모든 의존성을 포함하는 컨테이너"를 제공하여, 어디에서나 동일하게 실행할 수 있게 합니다. 이는 마치 "컴퓨터 안의 작은 컴퓨터"와 같은 개념입니다. 반면, Anaconda의 conda env는 특정 Python 환경을 격리하여 관리하는 데 중점을 둡니다.
그니까 docker로 만든 이미지로 컴퓨터를 쓰면 기존 컴퓨터에서 사용하고 있던 폴더는 사용 못합니다.
컴퓨터 안에 따로 image를 써서 docker로 컴퓨터 os를 하나 더 만든거거든요
핵심은 컴퓨터 안에 작은 컴퓨터라는 개념인데 그럼 여기서 의문이 생깁니다.
이거 왜 안쓰는데?
가상머신이라는 좋은거 냅두고 굳이 도커를 쓰는건 이유가 있습니다.
Docker와 전통적인 가상 머신(VM)은 모두 애플리케이션을 격리된 환경에서 실행하는 데 사용되지만, 접근 방식과 특징에는 여러 차이점이 있습니다.
이제 주요 차이점과 Docker의 장점을 살펴보겠습니다:
경량성:
시작 시간:
간편함:
관리 및 유지 보수:
리소스 효율성:
보안:
결론적으로, Docker는 경량성, 빠른 시작 시간, 간편함, 효율적인 리소스 사용 등의 장점을 제공합니다.
이러한 이유로, 특히 마이크로서비스 아키텍처, CI/CD 파이프라인, 개발-테스트-배포의 일관성 유지 등의 사용 사례에서 Docker가 널리 선호되고 있습니다.
Docker는 애플리케이션과 그 의존성을 컨테이너라는 격리된 환경에 패키징하여 일관된 방식으로 실행할 수 있게 해주는 플랫폼입니다.
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
Dockerfile은 Docker 이미지를 생성하기 위한 스크립트입니다.
FROM ubuntu:18.04
MAINTAINER yourname@email.com
RUN apt-get update
CMD ["echo", "Hello World"]
WORKDIR /app
ENV MY_VARIABLE=value
EXPOSE 80
VOLUME /data
EXPOSE: Dockerfile의 EXPOSE
명령어는 이미지가 런타임에 지정된 네트워크 포트에서 수신 대기해야 함을 나타냅니다. 그러나 EXPOSE
만으로는 포트를 실제로 열지 않습니다.
예: EXPOSE 80
은 컨테이너가 포트 80에서 수신 대기해야 함을 나타냅니다.
-p 플래그: docker run
명령어의 -p
플래그를 사용하여 호스트와 컨테이너 간의 포트 매핑을 지정할 수 있습니다.
예: docker run -p 8080:80 image_name
은 호스트의 8080 포트를 컨테이너의 80 포트에 매핑합니다.
-P 플래그: docker run
명령어의 -P
플래그를 사용하면 Docker가 자동으로 호스트의 사용 가능한 포트를 컨테이너의 EXPOSE
로 지정된 포트에 매핑합니다.
포트 충돌: 동일한 호스트 포트에 여러 컨테이너를 매핑하려고 하면 포트 충돌이 발생할 수 있습니다. 이 경우, 다른 호스트 포트를 사용해야 합니다.
포트 범위: 범위를 사용하여 여러 포트를 한 번에 EXPOSE하거나 매핑할 수 있습니다.
예: EXPOSE 7000-8000
또는 docker run -p 7000-8000:7000-8000 image_name
포트는 컴퓨터 네트워크에서 특정 프로세스나 서비스가 네트워크 서비스를 제공하기 위해 사용하는 엔드포인트입니다.
우분투의 telnet
과 같은 도구를 사용하여 특정 포트가 열려 있는지 확인할 수 있습니다.
Docker에서 포트는 두 가지 주요한 목적으로 사용됩니다:
컨테이너 내부의 서비스 접근: 컨테이너 내부에서 실행되는 서비스 (예: 웹 서버, 데이터베이스 서버 등)는 특정 포트에서 수신 대기합니다. 이 포트를 통해 서비스에 접근할 수 있습니다.
호스트와 컨테이너 간의 포트 매핑: Docker는 호스트 시스템의 포트와 컨테이너 내부의 포트를 매핑하는 기능을 제공합니다. 이를 통해 외부에서 호스트의 특정 포트로 요청을 보내면 그 요청이 컨테이너의 특정 포트로 전달됩니다.
예를 들어, 컨테이너 내부에서 웹 서버가 포트 80에서 실행되고 있을 때, docker run -p 8080:80 image_name
명령어를 사용하여 호스트의 8080 포트와 컨테이너의 80 포트를 매핑하면, 외부에서 호스트의 8080 포트로 웹 요청을 보내면 그 요청이 컨테이너의 웹 서버로 전달됩니다.
이렇게 포트 매핑을 사용하면 여러 컨테이너가 동일한 서비스 (예: 웹 서버)를 제공하더라도 각 컨테이너에 대해 다른 호스트 포트를 사용하여 접근할 수 있습니다.
다음은 간단한 예제입니다.
# 베이스 이미지 설정
FROM ubuntu:20.04
# 작업 디렉토리 설정
WORKDIR /app
# 의존성 설치
RUN apt-get update && apt-get install -y python3
# 애플리케이션 코드 추가
COPY . /app
# 포트 설정
EXPOSE 80
# 컨테이너 실행 시 실행될 명령어 설정
CMD ["python3", "app.py"]
# 이미지 빌드
docker build -t myapp:latest .
# 이미지 실행 (컨테이너 생성 및 시작)
docker run -d -p 80:80 myapp:latest
# Docker Hub에 이미지 푸시
docker login
docker push myapp:latest
Docker에서 컨테이너를 사용하고 관리하는 방법에 대해 간략하게 설명하겠습니다.
Docker 이미지를 기반으로 컨테이너를 실행합니다.
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
예시:
docker run -d -p 8080:80 nginx
이 명령은 nginx
이미지를 기반으로 컨테이너를 백그라운드(-d
)에서 실행하며, 호스트의 8080 포트와 컨테이너의 80 포트를 연결(-p 8080:80
)합니다.
docker ps
모든 컨테이너(실행 중이지 않은 컨테이너 포함)를 보려면:
docker ps -a
실행 중인 컨테이너에 bash 셸로 접속하려면:
docker exec -it [CONTAINER_ID or CONTAINER_NAME] /bin/bash
예시:
docker exec -it my_container /bin/bash
docker stop [CONTAINER_ID or CONTAINER_NAME]
docker restart [CONTAINER_ID or CONTAINER_NAME]
컨테이너를 삭제하기 전에 먼저 중지해야 합니다.
docker rm [CONTAINER_ID or CONTAINER_NAME]
docker logs [CONTAINER_ID or CONTAINER_NAME]
컨테이너에서 호스트로 파일 또는 디렉토리를 복사하려면:
docker cp [CONTAINER_ID or CONTAINER_NAME]:[CONTAINER_PATH] [HOST_PATH]
예시:
docker cp my_container:/app/data.txt ./data.txt
docker cp /path/to/local/file container_id:/path/to/container/directory
여기서:
/path/to/local/file
는 호스트 시스템에서 파일의 경로입니다.container_id
는 파일을 복사하려는 대상 컨테이너의 ID 또는 이름입니다./path/to/container/directory
는 컨테이너 내에서 파일을 저장할 경로입니다.예를 들어, 로컬의 Dockerfile
을 mycontainer
라는 이름의 컨테이너의 /app
디렉토리로 복사하고 싶다면 다음과 같이 명령을 실행합니다:
docker cp Dockerfile mycontainer:/app
이 명령을 실행하면 Dockerfile
이 컨테이너의 /app
디렉토리로 복사됩니다.
Docker 컨테이너의 이름을 변경하려면 기존 컨테이너를 중지하고 새 이름으로 새 컨테이너를 생성해야 합니다. Docker는 직접적으로 실행 중인 컨테이너의 이름을 변경하는 기능을 제공하지 않습니다. 하지만, 컨테이너를 중지한 후에 이름을 변경할 수 있습니다.
다음 단계를 따라 컨테이너의 이름을 변경할 수 있습니다:
기존 컨테이너를 중지합니다.
docker stop festive_cori
컨테이너의 이름을 변경합니다.
docker rename festive_cori f2nerf
필요하다면, 새 이름으로 컨테이너를 다시 시작합니다.
docker start f2nerf
이제 컨테이너의 이름이 f2nerf
로 변경되었습니다. docker ps -a
명령어를 사용하여 변경된 이름을 확인할 수 있습니다.
Docker에서 GPU를 사용하려면 NVIDIA GPU 드라이버와 NVIDIA Container Toolkit을 설치해야합니다.
NVIDIA GPU 드라이버 설치: NVIDIA 공식 웹사이트에서 호환되는 드라이버를 다운로드하고 설치합니다.
NVIDIA Container Toolkit 설치:
sudo apt-get install nvidia-docker2
sudo systemctl restart docker
Docker 실행 시 --gpus all
옵션을 추가하여 GPU를 활성화합니다.
docker run --gpus all image-name
nvidia-docker run -it --shm-size 100g --name '容器名称' -v /data0/用户名/:/workspace -v /data0/dataset/:/datasets emernerf:latest