컨테이너의 세계로 첫걸음! 도커 설치부터 핵심 명령어 마스터하기 🚀
[들어가며: 왜 도커를 사용할까요? 🤔]
요즘 IT 세상은 그야말로 '컨테이너' 열풍이라고 해도 과언이 아니야. 그 중심에는 바로 **도커(Docker)**가 있지!
- 컨테이너 엔진/플랫폼으로서의 도커: 도커는 애플리케이션을 신속하게 구축, 테스트 및 배포할 수 있게 해주는 소프트웨어 플랫폼이야. 컨테이너라는 표준화된 단위로 프로그램을 패키징해서 어떤 환경에서든 동일하게 실행될 수 있도록 만들어주지.
- 컨테이너 오케스트레이션은 쿠버네티스: 물론, 많은 컨테이너들을 효율적으로 관리하고 조율(오케스트레이션)하는 데는 쿠버네티스 같은 도구가 사용되지만, 그 기본에는 도커와 컨테이너 기술이 깔려있어. 도커는 먼저 시장을 선점하고 높은 점유율을 차지하면서 사실상 표준 기술로 자리 잡았지.
- 마치 경량화된 컴퓨터처럼!: 기존에 운영체제(OS)를 설치하기 위해 "Rocky Linux 배포판 ISO 파일을 다운받아 설치"했다면, 도커는 "미리 잘 만들어진 컨테이너 이미지를 다운받아 바로 실행"하는 방식이야. 그래서 컨테이너는 **"경량화된 가상 컴퓨터"**에 비유되곤 해.
- PID 1의 차이: 일반적인 리눅스 서버의 첫 번째 프로세스(PID 1)는 systemd 같은 초기화 시스템이지만, 컨테이너 내부에서는 애플리케이션 자체가 PID 1이 되는 등 다를 수 있다는 점도 알아두면 좋아.
- CRI와 OCI: 잠깐 용어 정리!
- CRI (Container Runtime Interface): 쿠버네티스가 컨테이너를 실제로 구동할 수 있게 해주는 다양한 '컨테이너 런타임 도구들'과의 인터페이스 표준이야.
- OCI (Open Container Initiative): 컨테이너 이미지 포맷이나 런타임에 대한 개방형 산업 표준을 만드는 곳이야. 도커도 이 표준을 따르고 있지.
[0. 도커 설치 확인! ✅]
실습을 시작하기 전에, 내 컴퓨터(또는 실습용 서버)에 도커가 잘 설치되어 있는지부터 확인해 보자! 터미널(명령 프롬프트)을 열고 아래 명령어를 입력해 봐.
docker -v
# 또는
docker --version
Docker version ... 하고 버전 정보가 잘 나오면 준비 완료! (만약 설치가 안 되어 있다면, 이전 글 "[실습로그] Ansible 플레이북으로 워드프레스 자동 설치 & Docker 제대로 설치하기! 🚀"의 Docker 설치 부분을 참고해서 설치해 줘!)
[1. 도커의 기본 구성 요소 🧱]
도커는 크게 두 가지 핵심 요소로 이루어져 있어.
- 도커 CLI (Command Line Interface): 우리가 터미널에서 docker run, docker pull 같이 직접 명령어를 입력하는 도구야. 사용자와 도커 엔진 사이의 소통 창구지.
- 도커 데몬 (Docker Daemon, dockerd): 실제로 명령을 받아서 이미지, 컨테이너, 네트워크, 볼륨 같은 도커 객체들을 생성하고 관리하는 백그라운드 프로세스야. 도커의 심장이라고 할 수 있지!
[2. 도커 이미지 다루기 🖼️ – 컨테이너의 설계도!]
컨테이너를 만들려면 먼저 그 설계도에 해당하는 **이미지(Image)**가 있어야 해.
- 이미지 검색 (docker search): 어떤 이미지가 있는지 찾아보자. 예를 들어 웹 서버로 유명한 Nginx 이미지를 찾아볼까?검색 결과에는 이미지 이름, 설명, 받은 별점(STARS), 공식 이미지 여부(OFFICIAL) 등이 나와. 별점이 높거나 공식 이미지([OK] 표시)가 좀 더 신뢰할 만하겠지?
-
Bash
docker search nginx - 이미지 내려받기 (docker pull): 마음에 드는 이미지를 찾았다면 내 컴퓨터로 내려받아야 해.
- 이미지 이름 규칙: 보통 이름:태그 형식으로 사용해.
- 예: rockylinux:8, almalinux:9, nginx:latest
- latest 태그는 보통 가장 최신 버전을 의미하지만, 항상 그런 건 아니니 주의! 안정적인 운영을 위해서는 특정 버전 태그를 명시하는 게 좋아.
- 이미지는 **레지스트리(Registry)**라는 원격 저장소에서 다운로드해. 가장 유명한 공개 레지스트리는 **도커 허브(Docker Hub)**야.
- 이미지 이름 규칙: 보통 이름:태그 형식으로 사용해.
-
Bash
docker pull nginx - 이미지와 컨테이너의 관계는?:
- "컨테이너 이미지 → 컨테이너 실행": 이미지는 설계도, 컨테이너는 그 설계도로 지은 집!
- "pull → run": 먼저 이미지를 내려받고(pull), 그걸 실행(run)하는 게 정석.
- "이미지가 있어야 컨테이너를 실행할 수 있어." 마치 "ISO 파일이 있어야 OS를 설치할 수 있는 것"처럼!
- 꿀팁!: 만약 로컬에 이미지가 없는데 docker run 명령을 실행하면, 도커가 똑똑하게 자동으로 해당 이미지를 pull 해 온 다음에 실행해 줘. 편리하지? 😉
[3. 도커 컨테이너 실행하고 관리하기 🏃♂️ – 이제 집을 지어보자!]
자, 이제 이미지를 사용해서 컨테이너를 직접 실행해 볼 시간이야!
- 가장 간단한 컨테이너 실행 (docker run hello-world): 도커 설치 후 가장 먼저 해보는 국민 명령어!이 명령을 실행하면:
- 로컬에 hello-world 이미지가 있는지 확인.
- 없으면 도커 허브에서 자동으로 pull 해 옴.
- 해당 이미지로 컨테이너를 실행.
- 컨테이너가 "Hello from Docker!" 같은 환영 메시지를 화면에 출력.
- 메시지 출력이 끝나면 컨테이너는 자동으로 종료됨.
-
Bash
docker run hello-world - 대화형 컨테이너 실행 (docker run -it ubuntu bash): 이번엔 우분투(Ubuntu) 리눅스 컨테이너를 실행하고, 그 안의 쉘(bash)을 직접 사용해보자.
- docker run: 컨테이너 실행 명령어.
- -i (--interactive): 컨테이너의 표준 입력(STDIN)을 활성화해서 우리가 명령을 입력할 수 있게 해줘.
- -t (--tty): 가상 터미널(pseudo-TTY)을 할당해서 마치 진짜 리눅스 터미널에 접속한 것처럼 만들어줘. -i랑 -t는 보통 함께 써서 -it로 사용해.
- ubuntu: 사용할 이미지 이름. (태그를 생략했으니 ubuntu:latest가 사용될 거야)
- bash: 컨테이너가 실행된 후 그 안에서 실행할 명령어. 여기서는 bash 쉘을 실행하라는 의미.
- 컨테이너 내부에서 OS 정보 확인: cat /etc/os-release 명령으로 현재 컨테이너의 OS 정보를 볼 수 있어.
-
Bash
docker run -it ubuntu bash - 컨테이너의 생명주기 (Lifecycle) – 짧고 굵게!:
- "도커 컨테이너는 내부에 실행된 메인 프로세스가 종료되면, 컨테이너도 함께 종료돼."
- hello-world 컨테이너는 메시지를 출력하는 스크립트가 메인 프로세스였고, 그 스크립트가 끝나니 컨테이너도 바로 멈췄지.
- 위에서 실행한 ubuntu 컨테이너의 bash 쉘에서 exit 명령으로 빠져나오면, bash 프로세스가 종료되면서 컨테이너도 함께 종료될 거야.
- 즉, "컨테이너의 수명은 그 안에서 실행되는 메인 프로세스의 수명과 동일해." 웹 서버처럼 계속 실행되어야 하는 프로그램은 메인 프로세스가 계속 살아있도록 해야겠지.
- 실행 중인 컨테이너 확인 (docker ps): 현재 내 컴퓨터에서 작동 중인 컨테이너들의 목록을 보여줘.
-
Bash
docker ps - 모든 컨테이너 확인 (docker ps -a): 지금까지 만들었던 모든 컨테이너(정지된 것 포함) 목록을 보여줘.
-
Bash
docker ps -a - 컨테이너를 계속 실행시키기: 백그라운드 실행 및 재시작 정책 웹 서버처럼 계속 켜져 있어야 하는 컨테이너는 어떻게 할까?
- -d (--detach): 컨테이너를 백그라운드에서 실행시켜. 터미널에 붙잡혀 있지 않고 바로 다음 명령을 입력할 수 있게 되지.
- --restart <정책>: 컨테이너가 멈췄을 때 어떻게 할지 정하는 옵션.
- no (기본값): 컨테이너가 종료되면 다시 시작하지 않아.
- always: 컨테이너가 어떤 이유로든 종료되면 항상 재시작하려고 시도해.
- on-failure: 컨테이너가 비정상적으로 종료됐을 때만 (예: 오류로 인해) 재시작해. (컨테이너 내부의 메인 프로세스가 정상적으로 작업을 마치고 종료된 경우에는 재시작하지 않아.)
- unless-stopped: 사용자가 docker stop 명령으로 수동으로 멈추기 전까지는 항상 재시작하려고 시도해.
-
Bash
docker run -d --restart always nginx - 포트 포워딩과 이름 지정 – 외부 접속 길 열기! 컨테이너는 자신만의 격리된 네트워크를 가져. 그래서 컨테이너 안의 웹 서버(예: Nginx의 80번 포트)에 외부에서 접속하려면 호스트 PC의 특정 포트와 연결해 줘야 해.
- -p 8080:80: 호스트 PC의 8080번 포트로 들어오는 요청을 컨테이너 내부의 80번 포트로 전달(포워딩)하라는 의미야. 이제 웹 브라우저에서 http://<호스트PC_IP>:8080 또는 http://localhost:8080으로 접속하면 Nginx 초기 화면을 볼 수 있어!
- 네트워크 팁!: 네가 메모해 준 것처럼, 가끔 6000번대 같은 특정 포트들은 방화벽이나 보안 정책 때문에 외부에서 웹 접속이 잘 안 될 수 있어. 그럴 땐 8080, 8888처럼 비교적 자유로운 포트를 사용하는 게 좋아!
- --name my-nginx-server: 컨테이너에 my-nginx-server라는 사람이 알아보기 쉬운 이름을 붙여줘. 이름을 지정하지 않으면 도커가 임의의 재미있는 이름(예: tender_snyder)을 붙여줘.
- -p 8080:80: 호스트 PC의 8080번 포트로 들어오는 요청을 컨테이너 내부의 80번 포트로 전달(포워딩)하라는 의미야. 이제 웹 브라우저에서 http://<호스트PC_IP>:8080 또는 http://localhost:8080으로 접속하면 Nginx 초기 화면을 볼 수 있어!
-
Bash
docker run -d -p 8080:80 --name my-nginx-server --restart always nginx - 컨테이너는 불변 인프라를 지향!: "컨테이너는 변경 불가능한 인프라(Immutable Infrastructure)를 지향해." 이게 무슨 말이냐면, 한번 만들어진 컨테이너의 내부 설정을 직접 바꾸기보다는, 설정이 변경된 새로운 이미지를 만들거나, 설정을 외부에서 주입해서 새 컨테이너를 띄우는 방식을 더 선호한다는 뜻이야. 그래야 환경의 일관성을 유지하고 관리가 쉬워지거든.
[마무리하며 🛠️]
오늘은 도커의 가장 기본적인 명령어들을 실습하면서 이미지와 컨테이너가 무엇인지, 어떻게 다루는지 감을 잡아봤어. pull, run, ps 같은 명령어들이 이제 조금은 익숙해졌기를 바란다!
도커는 정말 강력하고 활용 분야도 넓으니까, 오늘 배운 내용을 바탕으로 더 다양하게 가지고 놀면서 익숙해지면 좋을 거야. 예를 들어 나만의 웹 애플리케이션을 도커 이미지로 만들어본다든지 말이지! 😊
'02. 클라우드 보안 공부 > 실습로그' 카테고리의 다른 글
| ✅ [실습로그] AWS 클라우드 기초부터 네트워크 설계까지 완벽 가이드 ☁️ (1) | 2025.05.28 |
|---|---|
| ✅ [실습로그] 스프링 부트를 도커로! 개발부터 최적화까지 완벽 가이드 🚀 (0) | 2025.05.28 |
| ✅ [실습로그] VLAN과 Trunk로 스마트하게 네트워크 나누고 합치기! 🌐 (feat. 스위치 설정) (0) | 2025.05.23 |
| ✅ [실습로그] Ansible 플레이북으로 워드프레스 자동 설치 & Docker 제대로 설치하기! (1) | 2025.05.22 |
| ✅ [실습로그] Vagrant로 멀티 노드 구성하고 Ansible 자동화 맛보기! 🚀 (feat. 사용자 설정, (1) | 2025.05.21 |