Docker의 개념과 핵심 원리
소프트웨어 개발 및 배포 과정에서 흔히 발생하는 문제들—예를 들어 로컬에서는 정상 작동하지만 서버에서는 오류가 나는 환경 차이, 여러 서비스 간의 리소스 경쟁, 급증하는 트래픽에 대한 확장성 부족, 설치 및 설정 비용 등—은 전통적인 배포 방식의 한계를 보여줍니다. Docker는 이러한 문제를 해결하기 위해 등장한 컨테이너 기술로, 애플리케이션과 그 실행에 필요한 모든 종속성을 하나의 격리된 단위인 컨테이너로 묶어 일관된 동작을 보장합니다.
Docker는 2013년 오픈소스로 공개된 이후 급속도로 성장했으며, 초기에는 PaaS 플랫폼 개발 중 핵심 기술로 활용되다 점차 독립적인 컨테이너 런타임으로 자리 잡았습니다. 주요 설계 철학은 다음과 같습니다:
- 표준화: 이미지 형식, 명령어 인터페이스, 네트워크 및 볼륨 관리 등이 통일되어 있어 다양한 환경에서 동일하게 작동합니다.
- 격리: Linux 커널의 namespace와 cgroups 기능을 이용해 프로세스, 네트워크, 파일 시스템 등을 분리하여 서로 간섭하지 않도록 합니다.
- 이식성: "한 번 작성하고 어디서나 실행 가능(Write Once, Run Anywhere)"을 실현하며, 개발 → 테스트 → 운영 환경 간 이식성이 뛰어납니다.
핵심 구성 요소는 다음과 같습니다:
- 이미지(Image): 읽기 전용 템플릿으로, 애플리케이션과 라이브러리, 설정 등을 포함합니다.
- 컨테이너(Container): 이미지를 기반으로 실행 중인 인스턴스입니다.
- 레지스트리(Registry): 공유 또는 내부 저장소로, 이미지를 업로드하고 다운로드할 수 있습니다 (예: Docker Hub, Harbor).
Docker 설치 및 기본 명령어
CentOS 기반 시스템에 Docker를 설치하는 절차는 다음과 같습니다:
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast && yum install -y docker-ce
systemctl enable docker && systemctl start docker
docker run hello-world
설치 후 hello-world 이미지를 실행하면 설치 성공 여부를 확인할 수 있습니다.
이미지 관리
- 이미지 가져오기:
docker pull nginx:alpine - 로컬 이미지 목록 조회:
docker images - 이미지 삭제:
docker rmi <IMAGE_ID> - 이미지 저장 및 복원:
docker save -o backup.tar nginx:alpine docker load -i backup.tar
컨테이너 생명주기 관리
- 컨테이너 실행 (백그라운드 + 포트 매핑):
docker run -d -p 8080:80 --name web-server nginx:alpine - 실행 중인 컨테이너 확인:
docker ps - 모든 컨테이너 보기:
docker ps -a - 로그 확인:
docker logs -f web-server - 컨테이너 내부 접근:
docker exec -it web-server sh - 중지 및 삭제:
docker stop web-server && docker rm web-server
볼륨(Volume)을 이용한 데이터 영속화
컨테이너는 일시적이라 재생성 시 데이터가 유실될 수 있으므로, 외부 디렉터리 또는 볼륨을 마운트하여 데이터를 보존합니다.
# 사용자 정의 볼륨 생성
docker volume create app-data
# 볼륨 마운트하여 컨테이너 실행
docker run -d -p 8080:8080 -v app-data:/usr/local/tomcat/webapps tomcat:8-jre8
또는 직접 호스트 경로를 지정하는 방식도 가능합니다:
mkdir -p /opt/app/webapps
docker run -d -p 8080:8080 -v /opt/app/webapps:/usr/local/tomcat/webapps tomcat:8-jre8
이 경우 호스트의 /opt/app/webapps에 파일을 추가하면 컨테이너 내부에서도 실시간 반영됩니다.
사용자 정의 이미지 빌드
Dockerfile을 통해 자체 이미지를 생성할 수 있습니다. 예를 들어 SSM 웹 애플리케이션을 포함한 Tomcat 이미지를 만들려면:
# Dockerfile
FROM daocloud.io/library/tomcat:8.5.16-jre8
COPY ssm1.war /usr/local/tomcat/webapps/
빌드 명령:
docker build -t myapp/ssm-tomcat:1.0 .
docker run -d -p 8081:8080 --name ssm-app myapp/ssm-tomcat:1.0
Docker Compose를 이용한 멀티 컨테이너 앱 관리
여러 컨테이너(MariaDB, Tomcat 등)를 동시에 관리하려면 docker-compose.yml을 사용합니다. 먼저 Docker Compose 바이너리를 설치하고 실행 권한을 부여합니다:
# 다운로드 후 설치
curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
예시 구성 파일 (docker-compose.yml):
version: '3'
services:
db:
image: mysql:5.7
container_name: mysql-db
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
TZ: Asia/Shanghai
ports:
- "3306:3306"
volumes:
- db-data:/var/lib/mysql
web:
image: myapp/ssm-tomcat:1.0
container_name: web-app
restart: always
ports:
- "8080:8080"
depends_on:
- db
volumes:
db-data:
관리 명령어:
- 전체 서비스 시작:
docker-compose up -d - 서비스 중지 및 제거:
docker-compose down - 재시작:
docker-compose restart - 로그 모니터링:
docker-compose logs -f
CI/CD 파이프라인 기초: GitLab을 이용한 지속적 통합
코드 변경 시 자동으로 빌드, 테스트, 배포를 수행하는 CI/CD 환경을 마련하기 위해 GitLab을 도커로 설치할 수 있습니다.
version: '3'
services:
gitlab:
image: twang2218/gitlab-ce-zh:11.1.4
container_name: gitlab-server
hostname: gitlab.example.com
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://192.168.199.110'
gitlab_rails['time_zone'] = 'Asia/Shanghai'
gitlab_rails['gitlab_shell_ssh_port'] = 22
ports:
- "80:80"
- "443:443"
- "22:22"
volumes:
- ./config:/etc/gitlab
- ./data:/var/opt/gitlab
- ./logs:/var/log/gitlab
restart: always
이 설정을 통해 내부망에 Git 저장소와 CI/CD 기능을 갖춘 DevOps 플랫폼을 구축할 수 있습니다.