- 리눅스 한 학기 살기 - 5주차2025년 04월 13일 11시 08분 44초에 업로드 된 글입니다.작성자: kugorang
들어가며
라즈베리파이에 우분투와 도커를 얹다 지난 주까지 우분투 서버에 대한 환경 설정은 어느 정도 마무리한 것 같아, 본격적으로 이 친구를 서버로 사용하기 위한 준비를 진행하고자 한다. 현재 졸업프로젝트 때문에 WebRTC용 서버가 하나 필요한데, 이 녀석을 서버로 삼아 Docker를 설치하고, Jenkins와 WebRTC를 컨테이너로 실행해볼까 한다.
이 글은 라즈베리파이 5 하드웨어에서 Ubuntu 24.04 LTS ("Noble Numbat") 데스크톱 버전을 실행하는 환경에 Docker Engine을 설치하는 포괄적인 단계별 가이드 제공을 목적으로 한다. 라즈베리파이 5는 ARM64 아키텍처를 사용하므로, 이 가이드의 모든 절차는 해당 아키텍처에 맞춰져 있다. 설치 과정은 Docker에서 공식적으로 권장하는 APT 리포지토리 설정 방식을 따른다.
공식 Docker 리포지토리 사용의 중요성
운영 체제 배포판(예: Ubuntu)은 자체 패키지 관리 시스템을 통해 docker.io와 같은 이름으로 Docker 패키지를 제공할 수 있다. 그러나 Docker는 빠르게 발전하는 기술이므로, 배포판에서 제공하는 패키지는 최신 기능이나 중요한 보안 패치가 누락된 구버전일 수 있다. Docker의 공식 APT 리포지토리를 사용하면 Docker 팀이 직접 제공하는 최신 안정 버전(docker-ce, docker-ce-cli 등)을 설치하고 시기적절한 업데이트 및 보안 패치를 받을 수 있다. 이는 최신 기능을 활용하고 안정적이며 보안이 강화된 Docker 환경을 유지하는 데 필수적이다. 따라서 이 가이드에서는 공식 리포지토리를 통한 설치 방법을 상세히 안내한다.
이 글의 절차는 라즈베리파이 5 하드웨어에서 Ubuntu 24.04 LTS (Noble Numbat) 운영 체제가 설치된 ARM64 (aarch64) 아키텍처 환경을 대상으로 한다.
사전 요구 사항 및 시스템 준비
운영 체제 및 아키텍처 확인
설치를 진행하기 전에, 현재 시스템이 대상 환경과 일치하는지 확인하는 것이 중요하다. 다음 명령어를 터미널에서 실행하여 Ubuntu 버전과 시스템 아키텍처를 확인할 수 있다.
Ubuntu 버전 확인:
lsb_release -a
출력에서 Distributor ID: Ubuntu, Release: 24.04, Codename: noble과 같은 정보를 확인한다.
아키텍처 확인:
uname -m
라즈베리파이 5 환경에서는 aarch64 또는 arm64가 출력되어야 한다.
이 가이드의 나머지 단계는 위의 조건이 충족되었다고 가정하고 진행된다.
시스템 패키지 목록 업데이트
새로운 소프트웨어를 설치하거나 기존 소프트웨어를 업데이트하기 전에, 시스템이 사용 가능한 패키지의 최신 목록을 인지하도록 로컬 패키지 인덱스를 업데이트하는 것이 좋다. 이는 이후 단계에서 설치할 의존성 패키지들이 최신 버전으로 설치되도록 보장한다.
sudo apt update
이전 또는 비공식 Docker 버전 제거
시스템에 이전에 설치된 Docker 관련 패키지가 있다면, 공식 Docker Engine 설치 전에 이를 제거하는 것이 중요하다. Ubuntu의 기본 리포지토리에서 제공하는 docker.io, 구버전의 docker-ce, 또는 podman-docker와 같은 호환성 패키지들은 공식 설치 과정과 충돌하거나 예기치 않은 동작을 유발할 수 있다. 깨끗한 상태에서 설치를 시작하는 것이 권장된다. 다음 명령어를 사용하여 잠재적으로 충돌할 수 있는 패키지들을 제거한다.
sudo apt remove docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc
위 명령 실행 후, 더 이상 필요하지 않은 의존성 패키지들을 정리하기 위해 다음 명령을 실행하는 것이 좋다.
sudo apt autoremove
참고: apt remove 명령은 일반적으로 Docker 이미지, 컨테이너, 볼륨, 네트워크와 같은 사용자 데이터 및 구성 파일을 /var/lib/docker/ 디렉토리에 남겨둔다. 만약 완전히 새로운 상태에서 시작하고 싶다면, 이 디렉토리를 수동으로 삭제해야 할 수 있다 (예: sudo rm -rf /var/lib/docker). 단, 이 경우 모든 기존 Docker 데이터가 영구적으로 삭제되므로 주의해야 한다.
리포지토리 관리를 위한 필수 의존성 설치
새로운 외부 APT 리포지토리(이 경우 Docker 공식 리포지토리)를 안전하게 추가하고 사용하기 위해서는 몇 가지 보조 도구가 필요하다. 이 도구들은 APT가 HTTPS를 통해 리포지토리에 접근하고, 다운로드한 패키지의 진위 여부를 GPG 키를 사용하여 검증할 수 있도록 지원한다.
다음 명령어를 실행하여 필요한 의존성 패키지들을 설치한다.
sudo apt install ca-certificates curl gnupg
각 패키지의 역할은 다음과 같다:
- ca-certificates: HTTPS 서버(예: Docker 리포지토리 서버)의 SSL/TLS 인증서를 검증하는 데 필요한 루트 인증 기관(CA) 인증서를 제공한다.
- curl: 명령줄 유틸리티로, 여기서는 Docker의 GPG 키를 웹에서 다운로드하는 데 사용된다.
- gnupg: GNU Privacy Guard 유틸리티로, Docker 패키지에 서명하고 이를 검증하는 데 사용되는 암호화 GPG 키를 처리하는 데 필수적이다.
이 패키지들을 미리 설치함으로써, 시스템은 다음 단계에서 Docker의 GPG 키를 추가하고 리포지토리를 설정할 준비를 갖추게 된다. 참고로, 최신 Ubuntu 버전(24.04 포함)에서는 apt-transport-https 패키지가 일반적으로 기본 포함되어 apt에 의해 암묵적으로 처리되므로 명시적인 설치가 필수는 아니지만, 포함해도 문제는 없다.
Docker 공식 APT 리포지토리 설정
이제 시스템에 Docker의 공식 APT 리포지토리를 추가하여, apt 패키지 관리자가 Docker 패키지를 찾고 설치할 수 있도록 설정한다. 이 과정은 두 단계로 나뉜다: Docker의 GPG 키 추가 및 APT 소스 설정.
Docker 공식 GPG 키 추가
목적: GPG(GNU Privacy Guard) 키는 APT가 Docker 리포지토리에서 다운로드하는 패키지가 실제로 Docker에서 배포한 것이며 전송 중에 변조되지 않았음을 암호학적으로 검증하는 데 사용된다. 이는 소프트웨어 공급망 보안의 중요한 요소이다.
명령어: 다음 명령어들을 순서대로 실행하여 Docker의 GPG 키를 다운로드하고 시스템이 인식할 수 있도록 저장한다.
GPG 키를 저장할 디렉토리 생성:
최신 APT 방식에서는 각 서드파티 리포지토리의 키를 별도의 파일로 관리하는 것이 권장된다. /etc/apt/keyrings 디렉토리가 없다면 생성하고 적절한 권한을 설정한다.sudo install -m 0755 -d /etc/apt/keyrings
install 명령어는 디렉토리를 생성하고 지정된 모드(소유자 읽기/쓰기/실행, 그룹 및 기타 읽기/실행)를 설정한다.
Docker GPG 키 다운로드 및 저장:
curl을 사용하여 Docker의 공식 GPG 키를 다운로드하고, gpg --dearmor를 통해 APT가 사용할 수 있는 바이너리 형식으로 변환한 후, 앞서 생성한 디렉토리에 저장한다.curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
curl의 -fsSL 옵션은 실패 시 조용히 종료하고(-f), 오류를 표시하며(-s), 리다이렉션을 따르고(-L), SSL을 사용(-S)하여 안전하게 키를 다운로드한다. 파이프(|)를 통해 sudo gpg --dearmor로 전달되어 키 형식을 변환하고 -o 옵션으로 지정된 파일 경로에 저장한다. sudo는 루트 권한이 필요한 디렉토리에 쓰기 위해 사용된다.
GPG 키 파일 권한 설정:
APT 프로세스(일반적으로 _apt 사용자)가 키 파일을 읽을 수 있도록 모든 사용자에 대해 읽기 권한을 부여한다.sudo chmod a+r /etc/apt/keyrings/docker.gpg
이 과정을 통해 시스템은 Docker 리포지토리의 신뢰성을 검증할 준비가 완료된다. /etc/apt/keyrings 디렉토리와 signed-by 옵션을 사용하는 것은 과거의 전역 키 관리 방식보다 더 안전하고 체계적인 접근 방식이다.
APT 리포지토리 소스 설정
목적: 이 단계는 APT 패키지 관리자에게 Docker 패키지를 어디서 찾아야 하는지 알려주는 설정 파일을 생성한다. 이 설정에는 시스템 아키텍처(ARM64)와 운영 체제 버전(Ubuntu 24.04)에 맞는 올바른 리포지토리 경로와 앞서 추가한 GPG 키 정보가 포함된다.
명령어: 다음 명령어를 실행하여 Docker 리포지토리 정보를 시스템의 소스 목록에 추가한다.
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
명령어 분석:
- echo "...": 리포지토리 설정 라인 문자열을 생성한다.
- deb: 바이너리 패키지 리포지토리를 의미한다.
- [arch=$(dpkg --print-architecture)]: 시스템의 아키텍처를 동적으로 확인하여(라즈베리파이 5에서는 arm64로 평가됨) 명시적으로 지정한다. 이를 통해 해당 아키텍처용 패키지만 고려하도록 한다.
- signed-by=/etc/apt/keyrings/docker.gpg]: 이 리포지토리의 패키지를 검증하는 데 사용할 GPG 키 파일의 경로를 지정한다. 이는 특정 키와 리포지토리를 명확하게 연결하여 보안을 강화한다.
- https://download.docker.com/linux/ubuntu: Docker의 Ubuntu용 공식 리포지토리 기본 URL이다.
- $(. /etc/os-release && echo "$VERSION_CODENAME"): 시스템의 /etc/os-release 파일에서 OS 코드명(Ubuntu 24.04의 경우 noble)을 동적으로 읽어와 삽입한다. 이를 통해 OS 버전에 맞는 리포지토리를 사용하게 된다.
- stable: 사용할 Docker 릴리스 채널을 지정한다. 일반적으로 안정 버전(stable) 사용이 권장된다.
- | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null: 생성된 설정 라인을 파이프(|)를 통해 tee 명령어로 전달한다. sudo tee는 루트 권한으로 /etc/apt/sources.list.d/ 디렉토리 안에 docker.list라는 새 파일을 생성하고 그 안에 설정 라인을 기록한다. 서드파티 리포지토리는 이처럼 별도의 파일로 관리하는 것이 표준적인 방식이며, 관리가 용이하다. > /dev/null은 tee 명령어가 화면에 내용을 출력하는 것을 방지한다.
이 명령어는 시스템의 아키텍처와 OS 버전을 자동으로 감지하고, 특정 GPG 키를 사용하도록 강제함으로써, 정적 설정보다 오류 가능성을 줄이고 보안성과 유지보수성을 높이는 견고한 리포지토리 설정 방식이다.
728x90Docker Engine 설치
Docker 리포지토리가 시스템에 성공적으로 추가되었으므로, 이제 실제 Docker Engine 및 관련 구성 요소들을 설치할 수 있다.
패키지 인덱스 다시 업데이트
새로운 Docker 리포지토리를 추가한 후에는, APT가 해당 리포지토리에서 사용 가능한 패키지 목록을 인지하도록 패키지 인덱스를 다시 한번 업데이트해야 한다. 이전 섹션(2단계)에서 실행한 apt update는 기본 Ubuntu 리포지토리만 알고 있었지만, 이제는 새로 추가된 docker.list 파일에 정의된 Docker 리포지토리의 정보까지 가져와야 한다.
sudo apt update
이 명령을 실행하면 APT는 /etc/apt/sources.list 및 /etc/apt/sources.list.d/ 내의 모든 소스를 확인하고, Docker 리포지토리에서 제공하는 docker-ce, docker-ce-cli 등의 패키지 정보를 로컬 인덱스에 반영한다. 이 업데이트 없이는 다음 단계에서 Docker 패키지를 찾을 수 없다.
Docker 패키지 설치
이제 Docker의 핵심 구성 요소들을 설치할 준비가 되었다. 여기에는 Docker 데몬(엔진), 명령줄 인터페이스(CLI), 컨테이너 런타임(containerd), 그리고 이미지 빌드(buildx) 및 다중 컨테이너 애플리케이션 관리(compose)를 위한 필수 플러그인이 포함된다.
다음 명령어를 실행하여 권장되는 Docker 패키지들을 설치한다.
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
이 명령은 최신 안정 버전의 Docker 스택을 설치하여 사용자가 즉시 Docker를 활용할 수 있도록 한다. 각 패키지는 Docker 생태계에서 중요한 역할을 담당한다.
설치된 Docker 패키지 및 구성 요소
다음 표는 위 명령으로 설치된 주요 패키지와 각 구성 요소의 역할을 요약하여 보여준다. 이는 단순히 설치 명령을 실행하는 것을 넘어, 설치된 Docker 스택의 구조를 이해하는 데 도움을 줄 수 있다.
패키지 이름 구성 요소 역할 설명 docker-ce Docker Engine (데몬) 컨테이너, 이미지, 네트워크, 볼륨 등을 관리하는 서버 측 구성 요소. docker-ce-cli Docker CLI 사용자가 명령어를 통해 Docker Engine과 상호 작용하기 위한 클라이언트 측 도구. containerd.io 컨테이너 런타임 컨테이너 생명 주기(시작, 중지 등)를 관리하는 저수준 구성 요소. Docker Engine이 사용함. docker-buildx-plugin Buildx 플러그인 docker build 기능을 확장하여 멀티 플랫폼 빌드, 향상된 캐싱 등 제공. (ARM 환경에서 유용) docker-compose-plugin Docker Compose 플러그인 docker compose 기능을 Docker CLI에 직접 통합하여 다중 컨테이너 애플리케이션 관리 지원. (예: docker compose up) 이 패키지들을 함께 설치함으로써, 사용자는 현재 Docker의 패키징 및 사용 권장 사항에 부합하는 완전한 기능의 통합 Docker 환경을 갖추게 된다.
Docker 설치 확인
Docker Engine이 성공적으로 설치되고 서비스가 정상적으로 실행 중인지 확인하는 것은 중요하다. 가장 간단하고 표준적인 방법은 hello-world 테스트 컨테이너를 실행하는 것이다.
다음 명령어를 터미널에서 실행한다.
sudo docker run hello-world
이 명령을 실행하면 다음과 같은 과정이 진행된다:
- Docker CLI가 Docker 데몬(Engine)과 통신한다.
- Docker 데몬은 로컬 시스템에 hello-world 이미지가 있는지 확인한다.
- 이미지가 없다면, Docker Hub(기본 레지스트리)에서 시스템 아키텍처(ARM64)에 맞는 hello-world 이미지를 다운로드한다.
- 다운로드한 이미지를 사용하여 새 컨테이너를 생성하고 시작한다.
- 컨테이너는 간단한 메시지를 출력하고 종료된다.
- 출력된 메시지가 터미널에 표시된다.
예상 출력:
성공적으로 실행되면 다음과 유사한 메시지가 출력된다.Hello from Docker! This message shows that your installation appears to be working correctly. ... (추가 설명 메시지)...
이 메시지가 보이면 Docker CLI, Docker 데몬, 이미지 가져오기, 컨테이너 실행 등 핵심 기능이 모두 올바르게 작동하고 있음을 의미한다. 이는 전체 Docker 설치 파이프라인에 대한 포괄적인 기본 테스트 역할을 한다.
비-루트 사용자를 위한 Docker 설정 (설치 후 작업)
기본적으로 Docker 데몬은 Unix 소켓(/var/run/docker.sock)을 통해 통신하며, 이 소켓은 root 사용자 및 docker 그룹의 멤버만 접근할 수 있도록 보호된다. 따라서 일반 사용자가 docker 명령을 실행하려면 매번 sudo를 사용해야 한다. 이 섹션에서는 편의를 위해 sudo 없이 docker 명령을 실행할 수 있도록 현재 사용자를 docker 그룹에 추가하는 방법을 설명한다.
보안 관련 중요 경고
사용자를 docker 그룹에 추가하는 것은 해당 사용자에게 시스템에 대한 루트 수준의 권한을 부여하는 것과 동일한 효과를 가진다. 이는 docker 그룹 멤버가 다음과 같은 작업을 수행할 수 있는 컨테이너를 쉽게 실행할 수 있기 때문이다:
- 호스트 시스템의 루트 파일 시스템을 컨테이너 내부에 마운트 (docker run -v /:/host...) 하여 호스트의 모든 파일을 읽고 수정.
- 호스트 시스템에 소프트웨어를 설치하거나 시스템 설정을 변경.
- 네트워크 트래픽을 조작하거나 다른 민감한 작업을 수행.
따라서 이 단계를 진행하기 전에 이러한 심각한 보안 위험을 완전히 이해해야 한다. 보안이 중요한 환경에서는 이 방법을 사용하지 않는 것이 좋다. 대안으로는 Docker Rootless 모드를 설정하거나, sudo 권한을 신중하게 관리하는 방법이 있지만, 이는 본 가이드의 범위를 벗어난다. 보안 위험을 감수하고 편의성을 위해 진행하기로 결정했다면 다음 단계를 따르면 된다.
docker 그룹 생성 (필요한 경우)
일반적으로 Docker Engine 설치 과정에서 docker라는 이름의 Unix 그룹이 자동으로 생성된다. 하지만 만약을 위해 다음 명령을 실행하여 그룹이 존재하는지 확인하고, 없다면 생성할 수 있다.
sudo groupadd docker
그룹이 이미 존재한다면, 명령은 그룹이 이미 있다는 메시지를 출력하며 이는 정상이다.
현재 사용자를 docker 그룹에 추가
다음 명령은 현재 로그인된 사용자(환경 변수 $USER로 참조됨)를 docker 그룹에 추가한다.
sudo usermod -aG docker $USER
여기서 사용된 옵션의 의미는 다음과 같다:
- -a (append): 사용자를 기존의 보조 그룹 목록에서 제거하지 않고, 지정된 그룹에 추가한다.
- -G (Groups): 사용자가 속할 보조 그룹 목록을 지정한다. 여기서는 docker 그룹을 지정한다.
그룹 변경 사항 적용
Linux 시스템에서 사용자의 그룹 멤버십 변경은 일반적으로 사용자가 새로운 세션을 시작할 때 적용된다. 즉, usermod 명령을 실행한 현재 셸 세션에서는 즉시 변경 사항이 반영되지 않는다. 변경된 그룹 멤버십을 적용하려면 다음 옵션 중 하나를 선택해야 한다.
- 로그아웃 후 다시 로그인: 가장 확실하고 권장되는 방법이다. 시스템에서 완전히 로그아웃했다가 다시 로그인하면, 새로운 세션은 업데이트된 그룹 멤버십으로 시작된다.
- newgrp docker 명령어 사용: 이 명령은 현재 사용자의 그룹 멤버십에 docker 그룹을 포함시킨 새로운 셸 세션을 시작한다. 이 새 셸에서는 sudo 없이 docker 명령을 사용할 수 있다. 하지만 원래 셸이나 다른 기존 세션에는 영향을 미치지 않는다. exit를 입력하면 이 새 셸을 종료하고 이전 셸로 돌아간다.
이러한 조치가 필요한 이유는, 실행 중인 프로세스(현재 셸 포함)는 해당 프로세스가 시작될 때의 사용자 및 그룹 자격 증명을 상속받기 때문이다. usermod는 시스템 데이터베이스(/etc/group)를 업데이트하지만, 이미 실행 중인 프로세스의 자격 증명을 실시간으로 변경하지는 않는다. 따라서 업데이트된 그룹 정보를 인식하는 새 프로세스(예: 새 로그인 셸 또는 newgrp으로 시작된 셸)가 필요하다.
비-루트 접근 확인
그룹 변경 사항이 적용된 후 (예: 다시 로그인했거나 newgrp docker 셸을 사용 중인 경우), sudo 없이 Docker 명령이 작동하는지 확인한다.
docker run hello-world
이제 sudo 없이도 hello-world 컨테이너가 성공적으로 실행되어야 한다. 만약 "permission denied"와 유사한 오류가 발생한다면, 그룹 변경 사항이 현재 세션에 올바르게 적용되었는지 다시 확인하면 된다 (로그아웃/로그인 또는 newgrp 사용).
마치며
이 글에서는 라즈베리파이 5 하드웨어와 Ubuntu 24.04 LTS (ARM64) 환경에서 Docker의 공식 APT 리포지토리를 사용하여 Docker Engine을 설치하는 전체 과정을 단계별로 안내했다. 시스템 요구 사항 확인 및 준비, 필수 의존성 설치, Docker GPG 키 및 APT 리포지토리 설정, Docker Engine 및 관련 구성 요소 설치, 그리고 hello-world 컨테이너를 이용한 설치 확인까지 다루었다. 추가적으로, 보안 관련 고려 사항과 함께 sudo 없이 Docker 명령을 사용하기 위한 비-루트 사용자 설정 방법도 설명했다.
Docker가 성공적으로 설치되었으므로, 이제 다음과 같은 다양한 작업을 탐색해 볼 수 있다.
- 기본 Docker 명령어 익히기: docker ps (실행 중인 컨테이너 보기), docker images (로컬 이미지 목록 보기), docker pull <이미지이름> (이미지 다운로드), docker build. (Dockerfile로 이미지 빌드) 등.
- Docker Hub에서 애플리케이션 이미지 찾고 실행하기: 다양한 사전 빌드된 애플리케이션 이미지를 검색하고 실행해 볼 수 있다.
- Docker Compose 학습: 여러 컨테이너로 구성된 애플리케이션을 정의하고 실행하기 위한 도구인 Docker Compose 사용법을 익힌다 (docker compose up, docker compose down).
- Docker 볼륨 사용: 컨테이너가 삭제된 후에도 데이터를 영구적으로 보존하기 위해 Docker 볼륨을 사용하는 방법을 알아본다.
- Docker 공식 문서 참조: 더 많은 고급 기능, 네트워킹, 보안 설정 등에 대한 자세한 정보는 Docker 공식 문서를 참조하는 것이 좋다.
이 글을 보는 분들이 라즈베리파이 5에서 Docker를 시작하는 데 유용한 기반이 되기를 바라며 글을 마친다.
728x90'프로그래밍' 카테고리의 다른 글
게임 산업의 주요 운영 체제 (1) 2025.04.13 리눅스 한 학기 살기 - 4주차 (0) 2025.04.09 게임·VR·게이미피케이션 분야의 애자일 도입 사례 (0) 2025.04.02 리눅스 한 학기 살기 - 3주차 (0) 2025.04.01 Unity Engine의 C#과 Unreal Engine의 C++ 비교 (0) 2025.03.31 다음글이 없습니다.이전글이 없습니다.댓글