배경

회사 폐쇄망에서 virtual box로 개발 환경을 설정해야 하는 일이 있었는데, rocky 8.4 OS 이미지만 주어진 상태였다. 그래서 docker 설치를 위해 패키지 rpm 파일을 반입해야 했다. 집에 있는 인터넷망에서 완전히 동일한 환경(virtual box)를 준비하고 그에 맞는 파일들을 다운받기로 했다. 

 

온라인 환경 설정

Virtual box 생성

우선 rocky OS 부터 다운받는다. 공식 사이트에서 "아카이브된 릴리즈 버전"을 선택하고, 원하는 환경에 맞는 폴더를 선택한다. 내 경우 https://dl.rockylinux.org/vault/rocky/8.4/Minimal/x86_64/iso/ 경로의 Rocky-8.4-x86_64-minimal.iso 파일을 받았다. 사실 나도 정확히 뭔지 모르고 일단 다운부터 받아봤는데, 다행히 잘 진행됐다. 

 

virtual box를 설치한 후 새로 만들기 버튼을 통해 위에서 받은 ISO 이미지를 선택해주면 된다. 

 

이제 해당 머신이 사용할 네트워크 설정이 필요한데, 네트워크 설정은 머신이 종료된 상태에서만 변경이 가능하다. 나는 NAT 네트워크로 설정해 주었다. 

 

참고로, NAT 네트워크 사용 시 네트워크 관리자 창에서 포트포워딩 등의 설정도 가능하다. 나는 인터넷망은 아니고, 회사의 폐쇄망에서 SSH 접속을 위해 게스트 IP와 port(22)를 입력하여 putty로 세션을 저장하여 사용했다. 

 

네트워크 설정

기본적인 설정이 완료한 후 머신을 시작하면 계정 생성 등의 절차를 진행한 뒤 터미널에 접속할 수 있게 된다. 이제 이 터미널에서 도커 설치에 필요한 파일들을 받기 위한 명령어를 실행하면 된다. 그런데 나는 호스트가 인터넷에 연결되어 있기 때문에 머신 내에서도 자연스럽게 사용할 수 있을 줄 알았는데, 내 경우에는 별도 설정이 필요했다, 

sudo nmcli connection show
sudo nmcli connection up enp0s3
ping 8.8.8.8 -c 4  # 정상 연결 테스트

 

nmcli를 통해 현재 커넥션을 조회해보니 enp0s3이 내려가 있어서, 연결 설정을 해준 뒤 ping을 통해 정상적으로 인터넷이 동작하는지 확인해줬다. 

 

폴더 마운트 설정

머신 내에서 도커 파일을 받고 나면 이를 외부(호스트)로 반출할 방법이 필요한데, 나는 호스트의 경로를 마운트하여 빼내기로 했다. USB를 연결하는 방법도 있는데, 왜인지 나는 계속 USB 인식이 안돼서 이 방법을 택했다. 우선 사진과 같이 마운트를 원하는 경로를 지정한다. 나는 호스트의 workspace/VM/share라는 폴더와, 머신 내부의 /home/share라는 폴더가 마운트되도록 설정했다. 

 

아래 명령어로 필수 패키지를 설치한 후, 메뉴 탭의 장치 > Guest Additions CD 이미지 삽입(게스트 확장 CD 이미지 삽입)을 선택한다. 

sudo dnf install -y epel release
sudo dnf groupinstall -y Development Tools"
sudo dnf install -y kernel-devel kernel-headers dkms gcc make perl bzip2

 

 

CD 이미지가 정상적으로 삽입이 됐다면 다음 명령어로 마운트 경로를 설정한다.  

sudo mount /dev/cdrom /mnt
cd /mnt
sudo ./VBoxLinuxAdditions.run
sudo reboot
lsmod | grep vboxguest

sudo mkdir -p /home/share
sudo mount -t vboxsf share
ls /home/share  # 마운트된 호스트 경로의 파일들이 보임

 

만약 패키지 버전과 OS 버전이 "정확하게" 일치하지 않는다면 위 과정에서 에러가 발생할 수 있다. 이 경우 다음 명령어를 실행한 후 위 작업을 다시 시도한다. 정상적으로 마운트가 완료되었다면, 호스트의 파일을 머신에서 볼 수 있고 머신의 파일을 호스트에서 볼 수 있게 된다. 

sudo dnf install -y kernel-devel-$(uanme -r) kernel-headers-$(uname -r)

docker 다운로드

rpm 파일 다운로드

처음에는 docker 엔진 설치 문서를 참고했는데, 이렇게 진행할 경우 5~8개? 정도의 패키지에 대한 설치 파일만 저장된다. 그런데 내 경우에는 회사에서 사용 중인 OS 이미지가 정말 필수 패키지만 존재하는 상태였기 때문에, 그에 따른 의존성 패키지들도 모두 다운로드할 필요가 있었다. 그래서 repotrack 명령어를 통해 rpm 파일들을 다운받았고, 약 190여 개의 파일들이 저장되었다. 

docker dnf install yum-utils-y
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
repotrack docker-ce docker-ce-cli containerd.io docker-compose-plugin

 

rpm 설치 테스트

회사에 반입하여 테스트하기 전에, 해당 파일들로 docker가 제대로 설치되는지 사전 테스트를 진행해보았다. 우선 rpm 파일은 서로 의존성을 갖고 있어서, 우선적으로 설치되어야 하는 패키지나 버전이 존재한다. 하지만 내가 받은 파일은 모두 190여개에 달했고, 이 파일들의 관계를 모두 파악하기란 현실적으로 불가능하다. 어차피 인터넷망을 통해 필요한 모든 파일들을 받은 것이고, 버전도 그에 맞게 레포지토리에서 가져온 것이므로 문제가 없을 것이라 기대하고 무작정 설치를 진행했다. 

 

우선 그 전에, 최대한 폐쇄망과 동일한 환경을 구성하기 위해 (혹시 몰라) 처음에 설정했던 네트워크 설정을 다시 꺼줬다. 

sudo nmcli connection show
sudo nmcli connection down enp0s3
ping 8.8.8.8 -c 4  # 안되는 것 확인

 

이후 rpm 파일을 모두 설치하는 쉘 파일을 작성했다. 

  • --force: 기존에 설치된 패키지여도 강제로 설치
  • --nodeps: 의존성 무시하고 설치
  • -U: i면 install, u면 update
#!bin/bash

cd "test/docker/rpms" || exit 1

for rpm in *.rpm; do
	rpm -Uvh --nosignature --force --nodeps "$rpm"
done


설치가 완료되면 도커가 정상적으로 실행되는지 확인한다. 

docker -v  # docker-ce-cli 정상 설치 시 표시됨
systemctl start docker  # 이걸 실행해야 엔진이 실행됨
systemctl status docker  # docker-ce, 도커 엔진 정상 설치 시 표시됨
docker ps

 

그런데 사실, 집에서 해봤을 때는 문제가 없었는데, 회사에서 동일한 파일로 테스트했을 때에는 rpm 설치 도중 core dump 에러가 발생했다. 정확히 에러가 발생하는 패키지 대상을 확인했고, rpm 관련 3개 파일에서 문제가 생기는 것을 발견했다. (rpm, rpm-libs, rpm-plugin-selinux) 버전만 조금 상이할 뿐 이미 설치되어 있는 패키지였기 때문에 이 3개를 제외하고 설치를 진행했고, 이후 docker rootless 모드 설정까지 문제없이 모두 진행되어 큰 문제는 없어보였다. 

개념

일반 도커 단점

Docker는 container를 실행시키기 위해서는 Docker daemon을 통한다. 이 때, Docker daemon은 root권한 함께 실행되기 때문에 컨테이너를 실행하기 위해서는 root 권한이 필요하다. 이러한 방식은 컨테이너에서 보안 상의 문제가 발생했을 때, root권한이 탈취될 위험성이 있다.

도커 데몬이란?
도커 시스템에서 중추적인 역할을 하는 백그라운드 프로세스. 도커 데몬은 컨테이너, 이미지, 네트워크, 볼륨 등을 관리하고 사용자의 요청에 따라 도커 엔진의 핵심 작업을 수행한다. 데몬은 시스템이 부팅될 때 자동으로 시작되며, 지속적으로 백그라운드에서 동작하며 도커 관련 명령을 처리한다.

 

 

정의

각각의 컨테이너는 현재 접속 중인 user 또는 group의 권한 만으로도 생성, 실행 및 관리가 가능하며 이러한 컨테이너를 Rootless Container라고 한다. 사용자 네임스페이스 내에서 Docker 데몬과 컨테이너를 실행하여 일반 사용자 권한으로도 docker를 실행할 수 있게 한다. rootless docker를 사용 시 컨테이너에서 보안 상의 문제가 발생하더라도 컨테이너를 실행한 유저의 권한 만을 가질 수 있을 뿐, root권한은 보호할 수 있다. 이를 이용하여 컨테이너를 실행하는 유저에게 최소한의 권한만을 부여함으로써 보안성을 향상시킬 수 있다.

 

특징

  • 보안 안정성: 루트 권한이 없기 때문에 컨테이너가 호스트 시스템에 미치는 영향을 줄임
  • 네임스페이스 분리: 사용자 네임스페이스 활용
  • 특히 여러 사용자가 동일한 서버에서 컨테이너를 실행하거나, 루트 권한을 요구하지 않는 환경에서 적합함

 


rootless 설정

rootless docker는 일반 docker를 먼저 설치하고 rootless 설정을 활성화하면 된다.
Docker rootless 설정 공식 문서

기존 서비스 비활성화

기존에 docker daemon이 실행 중이라면 root 계정으로 다음 명령어를 실행하여 비활성화한다. shutdown/disable을 하지 않는 이상은 도커는 계속해서 rootful로 돌고 있을 것이다. 만약 안된다면 --force 옵션을 사용하라.

  • docker.sock: 도커 데몬과 클라이언트가 통신하기 위해 사용되는 소켓 파일. 기본적으로 도커 데몬 실행 시 생성된다.
systemctl disable --now docker.service docker.socket
rm /var/run/docker.sock

 

docker 서비스 재설치

만약 도커 20.0 버전 이상을 rpm 파일로 설치했다면, /usr/bin/dockerd-rootless-setuptools.sh 파일이 생성되어 있을 것이다. (없다면 docker-ce-rootless-extras 패키지 설치가 필요하다) root가 아닌 일반 계정으로 다음 파일을 실행하여 daemon을 설정한다. 만약 해당 서비스를 제거하고 싶다면 uninstall을 실행하면 된다.

/usr/bin/dockerd-rootless-setuptool.sh install
/usr/bin/dockerd-rootless-setuptool.sh uninstall

 

docker 실행

rootless docker 모드에서는 기본적으로 사용자 계정에 해당하는 ~/.config/systemd/user/docker.service 파일에 시스템 서비스가 설치된다. --user 옵션을 통해 해당 계정이 도커 데몬의 라이프 사이클을 관리하도록 설정하면 도커 데몬이 root가 아닌 사용자 세션에서 실행될 수 있다.

  • docker.service: 도커 데몬을 관리하는 systemd 서비스 유닛 파일. 이 파일에는 도커 데몬을 시작, 중지, 재시작, 상태 점검 등의 작업을 제어하는 명령어와 설정이 포함되어 있음
  • linger 모드 활성화: 해당 명령은 사용자가 로그아웃한 후에도 해당 사용자의 systemd 서비스를 계속 실행하도록 설정하는 옵션이다.
systemctl --user start docker  # 도커 데몬을 현재 세션에서 즉시 시작
systemctl --user enable docker  # 시스템 시작 시 도커 데몬을 자동으로 시작
loginctl enable-linger [일반계정ID]

 

Client 환경 변수 설정

rootless 모드로 변경됨에 따라 사용하는 소켓 파일의 위치도 변경되었다. 해당 환경변수 값을 수정한 뒤 echo를 통해 변경된 값을 확인할 수 있다. 이 경로는 위에서 rootless-setup 설치 시 디폴트로 설정된 위치이다.

  • 소켓 파일 경로
    • 디폴트 경로: $XDG_RUNTIME_DIR/docker.sock
    • $XDG_RUNTIME_DIR는 사용자별 런타임 디렉토리를 지정하는 환경 변수로, 일반적으로 /run/user/$UID로 설정된다. 여기서 unix://는 실제 파일 경로가 아니라 docker가 사용하는 소켓의 URI 형식을 나타낸다.
  • 데이터 디렉토리
    • 디폴트 경로: ~/.local/share/docker
    • docker 이미지, 컨테이너 데이터, 볼륨 등이 저장되는 경로. NFS(Network File System) 상에 위치하면 성능 문제가 발생할 수도 있고, docker와 같은 데몬이 파일 시스템에 빠르게 액세스해야 하는 경우에는 적합하지 않다.
  • 데몬 설정 디렉토리
    • 디폴트 경로: ~/.config/docker
    • 도커 데몬의 설정 파일을 관리하는 경로로, ~/.docker와는 다르다는 점에 주의해야 한다. 이 곳에는 client가 사용하는 설정과 인증 정보를 저장한다.
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
echo $DOCKER_HOST

# 환경변수 영구 저장 방법
vi ~/.bashrc
# 파일 하단에 export DOCKER_host=... 동일하게 입력
source ~/.bashrc

 

docker GPU 관련 설정

nvidia-ctk runtime configure --runtime=docker --cinfog=$HOME/.config/docker/daemon.json
systemctl --user restart docker
nvidia-ctk config --set nvidia-container-cli.no-groups --in-place

 


References

배경

회사에서 운영 업무를 맡게 되었는데, 우선 유지보수 시에 필요한 각 관계사별 서버의 스펙을 정리하게 되었다. 우리 솔루션은 AI 모델을 기반으로 서비스되기 때문에 GPU 환경이 필요하다. 이를 위해서는 CUDA, NVIDIA 드라이버의 설치가 추가로 필요하며 GPU 종류에 따라 그 버전이 상이한데, 설치 파일의 크기도 작지 않고 버전 호환성 문제에 민감하기 때문에 잘 체크하는 것이 좋다. 
기존에는 대략적으로 알고 있었던 개념을 이번 기회에 간단히 알아보고, GPU 종류에 맞는 버전을 확인하는 법도 정리해보려 한다. 
 


개념

NVIDIA 드라이버

드라이버는 운영체제(OS)와 하드웨어를 연결하는 통로라고 볼 수 있다. NVIDIA 드라이버는 그 중 GPU를 활용하기 위한 것으로, GPU의 하드웨어 리소스를 최적화하고 그래픽 작업을 처리하기 위해 명령을 전달하는 역할을 수행한다. 그렇기 때문에 GPU 버전에 맞는 드라이버를 설치하는 것이 중요하다.
 

CUDA(Computed Unified Device Architecture)

CUDA는 C/C++ 프로그래밍 언어를 기반으로 하며, GPU에서 병렬 코드를 작성하고 실행할 수 있는 풍부한 라이브러리와 도구를 제공한다. 따라서 딥러닝과 같은 연산량이 방대한 처리를 수행하고자 하는 경우 CUDA의 사용은 필수라고 볼 수 있다. 일반적으로 CUDA를 설치한다는 것은 CUDA Toolkit의 설치를 의미한다. CUDA도 결국 드라이버 위에서 동작하기 때문에 NVIDIA 드라이버의 버전에 따라 호환 가능한 버전이 달라진다. 


호환 버전 확인

버전을 확인하는 방법은 매우 간단하다. NVIDIA 공식 홈페이지에서 찾고자 하는 GPU의 카테고리/시리즈/제품/OS/CUDA 툴킷 버전을 고르면 된다. 내 경우 A40, A100, H100 과 같은 GPU를 사용하고 있었고 아래와 같이 검색했다. 

 
그럼 아래와 같이 해당 GPU에 추천되는 드라이버 버전과 CUDA 툴킷 버전이 나오는 것을 확인할 수 있다. 물론 View More Versions 버튼을 통해 더 다양한 버전을 확인할 수 있다.

 
 앞서 드라이버와 CUDA의 버전 호환성도 중요하다고 말했는데, CUDA의 버전이 올라간다면 드라이버 버전업이 필요할 수도 있다. 엔비디아 드라이버는 하위호환성을 지원한다. 

  • 상위 호환성(지원X): 구버전 드라이버가 새로운 cuda 버전을 지원함
  • 하위 호환성(지원O): 최신 드라이버가 기존 cuda 버전을 지원함

CUDA 툴킷 버전에 따른 드라이버 정보는 공식 홈페이지의 release note에서 찾아볼 수 있다. (CUDA Toolkit Archive)

 


References

'Infra' 카테고리의 다른 글

폐쇄망 docker설치(rpm 파일 다운로드)  (0) 2025.05.14
rootless docker란? 개념 및 설정 방법  (0) 2025.04.20

+ Recent posts