컨테이너 : 가상화 기술
- 애플리케이션을 실행할 수 있는 가상환경 = 독립된 환경에서 실행 가능
= 하나의 어플리케이션을 위한 전용 가상환경 = 여러 개의 가상환경 실행이 가능 = 의존성 문제 해결
: 가상 머신은 아님
: kernel을 가져와 명령어들이 독립적으로 실행될 수 있는 별도의 파티션, 디스크 레이아웃 등을 가질 수 있는 환경
: host 환경에 대비되어 독립적으로 존재하는 것 같은 환경 제공
: host의 프로세스에 영향을 주지 않음
- 애플리케이션의 배포와 실행을 자동화 가능
가상화 기술
: 가상화에 필요한 하드웨어를 구축하고 그 위에 운영체제를 올리는 방식
Docker
- Docker.Inc에서 개발한 소프트웨어
- 컨테이너 기술을 활용한 것 중 하나
- Go 언어로 작성
Docker의 구성
- Docker 데몬
- Docker CLI
Docker 사용 패턴
- Single Machine에 Daemon과 CLI/GUI 설치
- VM 환경에 분리되어 설치 (윈도우 환경일 경우 주로 VM 형태, Docker Desktop 역시 이 형태)
- 서버가 여러 대인 경우(CLI에서 Remote에 있는 Daemon을 제어하는 형태)
>> CLI와 Daemon이 분리되어있는 형태
Docker를 사용하는 과정
1. Dockerfile => Docker의 이미지 생성(build)
2. Docker 이미지 배포(파일 or Docker Registry(Docker hub 등))
3. Docker 이미지를 통해 컨테이너 생성 및 실행(run)
: Docker Daemon이 있는 machine에 전개
리눅스 운영 환경 : 프로세스들의 집합
- Kernel의 역할 : 프로세스 관리 = 프로세스들이 요청하는 자원 관리
- 운영체제는 자원을 확보하는 역할
- 리눅스는 프로세스를 복제를 통해 새로운 프로세스를 생성(fork) = 프로세스를 만드는 개념이 존재하지 않음
> 생성(복제)된 프로세스는 다른 프로그램 코드로 언제든지 실행 가능(exec)
- 최초의 프로세스(Init Process) : 리눅스 운영 체제의 부팅 과정이 끝난 후 실행되는 프로세스(모든 프로세스의 기원)
> 최초의 프로세스 종료 = 시스템 종료
- 상위 프로세스 (기원) <=> 하위 프로세스 (복제)
> 복제된 프로세스들을 관리
> 상위 프로세스가 종료될 때, 하위 프로세스도 종료(기본) : 변경 가능
= 최초 프로세스 종료 시 동작 중인 모든 프로세스가 종료
컨테이너 : 운영 환경의 격리
- 격리된 환경 내에 Init Process가 존재하게 됨
: 격리된 환경의 Init Process가 종료 시 Container가 종료 됨
- 격리된 환경에서의 Init Process와 원래 Linux의 InitProcess는 다른 존재
- 보통 Init Process를 1번 프로세스로 봄 > Container는 격리된 환경의 Init Process가 1번 프로세스
> 컨테이너 내에서 Process를 만드는 행위 = Initial Process를 복제하는 행위
: Initial Process는 하위 프로세스를 관리할 능력만 있으면 됨
결론
- 컨테이너 기술은 새로운 운영 체제를 설치하는 것이 아님
- 운영 환경이라 함은 Init Process에서 만들어진 Process의 집합을 의미
- 컨테이너는 위와 같은 집합을 격리하여 새로운 Initial Process로부터 시작하게 함
Docker 설치
- 환경 구축 (Vagrant로 CentOS 준비)
#디렉토리 생성 및 이동
vagrant init
- Vagrantfile파일 수정
# -*- mode: ruby -*-
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/jammy64"
config.vm.hostname = "container"
config.vm.network "private_network", ip: "192.168.33.20"
config.vm.synced_folder ".", "/home/vagrant/sync", disabled: true
end
vagrant up
vagrant ssh
- Docker 설치 (https://docs.docker.com/engine/install/ubuntu/) 참고
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Docker Daemon의 시작
# SystemD 를 이용한 Docker 데몬 시작
sudo systemctl start docker
# 운영체제 부팅 후에 바로 시작하도록 등록
sudo systemctl enable docker
Docker Version확인
sudo docker version
Docker 계정 권한
- Docker 는 기본적으로 Root 권한으로 동작
- 현재 계정(vagrant) 에 권한 부여
sudo usermod -aG docker vagrant
sudo systemctl restart docker
#logout 후 vagrant ssh 로 다시 접속
Docker의 정보 확인($sudo docker version)
- Client 정보 : Docker CLI
- Server 정보 : Daemon에 대한 정보
Docker CLI 구조
: docker [서브 명령] [서브 명령의 옵션]
Docker Container Life Cycle : 서브 명령
1. run : 배포 / 실행
2. stop : 실행 중인 컨테이너 정지
3. start : 정지 중인 컨테이너 실행
4. rm : 배포한 컨테이너 삭제
Docker Container 제어: 서브 명령
1. exec : 실행 중인 컨테이너에 명령어 실행
2. logs : 컨테이너의 로그(표준 출력/표준 에러) 표시
3. inspect : 컨테이너/이미지의 상세정보 표시
Docker Image 제어: 서브 명령
1. images : Docker Daemon에 있는 이미지 목록 표시 (= image ls)
2. rmi : Docker 이미지 삭제(= image rm)
Docker Image 입출력 : 서브 명령
1. commit : 컨테이너의 상태를 새로운 이미지로 생성
2. tag : 기존 이미지의 새로운 태그(이름) 부여
3. save : 이미지를 파일로 내보내기
4. load : 이미지 파일을 Daemon으로 적재하기
Docker 배포와 실행
: docker run [옵션] 이미지 [명령] [인수 ...]
: 옵션 > docker run 서브 명령의 옵션
: [명령] > 이미지에서 사용 가능한 명령
: [인수] > 명령에 대한 인수
예시
docker run ubuntu cat /etc/lsb-release
> 현재 운영체제는 Ubuntu 22.04.5
> Docker를 통해 구한 Ubuntu 정보 : Ubuntu 24.04.2 LTS
- 특정 이미지 선택(Tag)
docker run ubuntu:20.04 cat /etc/lsb-release
- 다른 이미지 탐색 : docker search [이미지 이름]
> 혹은 Docker Hub 사이트에서 확인 가능(hub.docker.com)
docker search nginx
- Nginx 실행해보기
docker run -d -P nginx
> -d : Daemon으로 실행 (백그라운드 실행)
> -p : Expose 된 Port를 개방 (호스트에서 접근 가능)
- 실행 중인 컨테이너 확인하기
docker ps
: 서브 명령 ps를 통해 확인
: 아래의 사진에서 32768 포트를 통해 접근 가능한 것을 확인
- 임의의 포트 개방
: P 옵션이 아닌 -p 옵션 사용
: -p 8080:80 > 호스트의 8080 Port를 컨테이너의 80Port로 포트포워딩
- 네트워크 상태 확인
: netstat 명령
: Network 정보 확인 (net-tools 패키지에 따로 존재)
sudo apt-get install net-tools
sudo netstat –natp
> t : TCP 프로토콜 확인
> p : 프로세스 정보 확인
- NGINX 접속
curl localhost:32768
- 컨테이너 정지: Stop
> docke stop [옵션] 컨테이너 [컨테이너 ...]
> [옵션] : stop 서브 명령의 옵션
> 컨테이너 : 컨테이너 이름 또는 Hash ID
> docker ps로 컨테이너 id와 이름 확인
docker ps
> hash id로 정지
docker stop f1e7c15e0338
> 정지 후 확인
: docker ps > 실행중인 목록만 나타남
: docker ps -a > -a 옵션을 추가하면 실행 중이지 않지만, 존재하는 모든 컨테이너 목록 표시
- 정지된 컨테이너 실행
: docker start [옵션] 컨테이너 [컨테이너 ...]
: [옵션] > 서브 명령 start의 옵션
: 컨테이너 > 컨테이너의 이름 또는 Hash Id
docker start f1e7c15e0338
- 컨테이너 삭제
: docker rm [옵션] 컨테이너 [컨테이너 ...]
: [옵션] > 서브 명령 rm의 옵션
: -f 옵션 > 실행 중인 컨테이너도 강제로 중지 후 제거
: 여러 개의 컨테이너를 동시에 삭제 가능
docker rm 560343d256b4 2918513a0b69
- 컨테이너에 명령 실행 : Exec
: docker exec [옵션] 컨테이너 명령 [인수 ...]
: [옵션] > 서브 명령 exec 의 옵션
) -t : 터미널 열기
) -i : 상호작용(표준 입출력) 허용
: 컨테이너 > 컨테이너의 이름 또는 Hash Id
: 명령 > 컨테이너 내에 있는 명령어
: 인수 > 명령의 인수
: Nginx의 설정 파일 MD5SUM 구해보기
docker exec f1e7c15e0338 md5sum /etc/nginx/nginx.conf
: Nginx 컨테이너 쉘로 접속해보기
docker exec -i -t f1e7c15e0338 /bin/bash
- 컨테이너 로그 확인 : Logs
: docker logs [옵션] 컨테이너
: [옵션] > 서브 명령 log 의 옵션
) -f : 향후 출력되는 로그를 계속 추적(종료하지 않고 새로운 로그를 대기)
: 컨테이너 > 컨테이너의 이름 또는 Hash Id
docker logs f1e7c15e0338
- 컨테이너 정보 확인 : Inspect
: docker inspect [옵션] 대상 [대상 ...]
: [옵션] > 서브 명령 inspect 의 옵션
: 대상 > 컨테이너의 이름 또는 Hash Id
: Nginx 정보 조회
docker inspect f1e7c15e0338
- 이미지 목록 : Images
: docker images [옵션]
: docker image ls [옵션]
: [옵션] > 서브 명령 images의 옵션
docker images
- 이미지 삭제 : Rmi
: docker rmi [옵션] 이미지 [이미지 ...]
: docker image rm [옵션] 이미지 [이미지 ...]
: [옵션] > 서브 명령 rmi의 옵션
docker rmi bf16bdcff9c9 ubuntu:20.04
'DevOps' 카테고리의 다른 글
#16 Docker2 (0) | 2025.06.12 |
---|---|
#14 ChatOps (1) | 2025.06.11 |
#13 Site Reliability Engineering (0) | 2025.06.11 |
#12 DevOps와 애자일 개발 (3) | 2025.06.11 |
#11 인프라 아키텍쳐 변경 (1) | 2025.06.11 |