πŸ³λ„μ»€(Docker) 톺아보기

Neo-RenaissanceΒ·2025λ…„ 4μ›” 6일
post-thumbnail

🐳 "λ„μ»€λž€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ 개발, 배포 및 μ‹€ν–‰ν•˜λŠ” 데 ν˜μ‹ μ μΈ 방식을 μ œκ³΅ν•˜λŠ” μ»¨ν…Œμ΄λ„ˆ ν”Œλž«νΌ"

λ„μ»€μ˜ κΈ°λ³Έ κ°œλ…

μ»¨ν…Œμ΄λ„ˆμ™€ μ΄λ―Έμ§€λž€ 무엇인가?

λ„μ»€μ—μ„œ κ°€μž₯ μ€‘μš”ν•œ 두 κ°€μ§€ κ°œλ…μ€ '이미지'와 'μ»¨ν…Œμ΄λ„ˆ'μž…λ‹ˆλ‹€.

도컀 μ΄λ―Έμ§€λŠ” μ»¨ν…Œμ΄λ„ˆλ₯Ό λ§Œλ“œλŠ” 데 μ‚¬μš©λ˜λŠ” 읽기 μ „μš©(Read-only) ν…œν”Œλ¦Ώ μž…λ‹ˆλ‹€. μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 싀행에 ν•„μš”ν•œ μ½”λ“œ, λŸ°νƒ€μž„, 라이브러리, ν™˜κ²½ λ³€μˆ˜ 및 μ„€μ • 파일 λ“± λͺ¨λ“  것을 ν¬ν•¨ν•©λ‹ˆλ‹€.

도컀 μ»¨ν…Œμ΄λ„ˆλŠ” 이미지λ₯Ό μ‹€ν–‰ν•œ μƒνƒœλ₯Ό λ§ν•©λ‹ˆλ‹€. μ»¨ν…Œμ΄λ„ˆλŠ” μ΄λ―Έμ§€μ˜ λͺ©μ μ— λ§žλŠ” 파일 μ‹œμŠ€ν…œκ³Ό 격리된 μ‹œμŠ€ν…œ μžμ› 및 λ„€νŠΈμ›Œν¬λ₯Ό μ‚¬μš©ν•  수 μžˆλŠ” λ…λ¦½λœ κ³΅κ°„μž…λ‹ˆλ‹€.

"이미지와 μ»¨ν…Œμ΄λ„ˆμ˜ 관계λ₯Ό μŒμ‹μ— λΉ„μœ ν•˜λ©΄, μ΄λ―Έμ§€λŠ” '도넛 λ ˆμ‹œν”Ό'이고 μ»¨ν…Œμ΄λ„ˆλŠ” 'κ·Έ λ ˆμ‹œν”Όλ‘œ λ§Œλ“  도넛'이라고 생각할 수 μžˆμŠ΅λ‹ˆλ‹€. ν•˜λ‚˜μ˜ λ ˆμ‹œν”Ό(이미지)둜 μ—¬λŸ¬ 개의 도넛(μ»¨ν…Œμ΄λ„ˆ)을 λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€."

λ„μ»€μ˜ μ•„ν‚€ν…μ²˜μ™€ λ‚΄λΆ€ ꡬ쑰

λ„μ»€μ˜ ꡬ성 μš”μ†Œ

λ„μ»€λŠ” 크게 λ‹€μŒκ³Ό 같은 ꡬ성 μš”μ†Œλ‘œ 이루어져 μžˆμŠ΅λ‹ˆλ‹€.

Docker 데λͺ¬(dockerd)

λ°±κ·ΈλΌμš΄λ“œμ—μ„œ μ‹€ν–‰λ˜λŠ” μ„œλΉ„μŠ€λ‘œ, 도컀 API μš”μ²­μ„ μ²˜λ¦¬ν•˜κ³  μ»¨ν…Œμ΄λ„ˆ, 이미지, λ„€νŠΈμ›Œν¬ λ“±μ˜ 도컀 객체λ₯Ό κ΄€λ¦¬ν•©λ‹ˆλ‹€.

이미지 λΉŒλ“œ, μ»¨ν…Œμ΄λ„ˆ 생성, κ΄€λ¦¬μ˜ λͺ¨λ“  μž‘μ—…μ„ λ‹΄λ‹Ήν•©λ‹ˆλ‹€.

Docker ν΄λΌμ΄μ–ΈνŠΈ(docker)

μ‚¬μš©μžκ°€ 도컀 λͺ…λ Ήμ–΄λ₯Ό μž…λ ₯ν•˜λ©΄, 이λ₯Ό 도컀 데λͺ¬μ—κ²Œ μ „λ‹¬ν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€.

CLI(Command Line Interface) ν˜•νƒœλ‘œ 제곡되며, μ‚¬μš©μžμ™€ 도컀 데λͺ¬ κ°„μ˜ 톡신 μΈν„°νŽ˜μ΄μŠ€ 역할을 ν•©λ‹ˆλ‹€.

Docker λ ˆμ§€μŠ€νŠΈλ¦¬

도컀 이미지λ₯Ό μ €μž₯ν•˜λŠ” μ €μž₯μ†Œμž…λ‹ˆλ‹€.

Docker HubλŠ” κ°€μž₯ 유λͺ…ν•œ 곡개 λ ˆμ§€μŠ€νŠΈλ¦¬λ‘œ, 기본적으둜 λ„μ»€λŠ” μ—¬κΈ°μ„œ 이미지λ₯Ό μ°ΎμŠ΅λ‹ˆλ‹€.

개인 λ˜λŠ” 기업은 자체 프라이빗 λ ˆμ§€μŠ€νŠΈλ¦¬λ₯Ό μš΄μ˜ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

도컀 μ΄λ―Έμ§€μ˜ 계측 ꡬ쑰 심측 이해

도컀 μ΄λ―Έμ§€λŠ” μ—¬λŸ¬ 읽기 μ „μš© λ ˆμ΄μ–΄λ‘œ κ΅¬μ„±λ˜λ©°, 각 λ ˆμ΄μ–΄λŠ” Dockerfile의 λͺ…령어에 μ˜ν•΄ μƒμ„±λ©λ‹ˆλ‹€.

Layer 4: CMD ["node", "app.js"] - μ‘μš© ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ λͺ…λ Ή
Layer 3: COPY . /app - μ†ŒμŠ€ μ½”λ“œ 볡사
Layer 2: RUN npm install - μ˜μ‘΄μ„± μ„€μΉ˜
Layer 1: FROM node:14 - 베이슀 이미지

μœ λ‹ˆμ˜¨ 파일 μ‹œμŠ€ν…œ(Union File System)

λ„μ»€λŠ” μ΄λŸ¬ν•œ λ ˆμ΄μ–΄λ₯Ό ν•˜λ‚˜μ˜ 파일 μ‹œμŠ€ν…œμœΌλ‘œ ν†΅ν•©ν•˜μ—¬ λ³΄μ—¬μ£ΌλŠ” μœ λ‹ˆμ˜¨ 파일 μ‹œμŠ€ν…œμ„ μ‚¬μš©ν•©λ‹ˆλ‹€.

μƒμœ„ λ ˆμ΄μ–΄μ—μ„œ νŒŒμΌμ„ μˆ˜μ •ν•  경우, ν•˜μœ„ λ ˆμ΄μ–΄μ˜ 원본 νŒŒμΌμ€ κ·ΈλŒ€λ‘œ μœ μ§€λ˜λ©°(Copy-on-Write 방식), λ³€κ²½λœ λ‚΄μš©μ€ μƒˆ λ ˆμ΄μ–΄μ— μ €μž₯λ©λ‹ˆλ‹€.

이미지 캐싱 λ©”μ»€λ‹ˆμ¦˜

λ™μΌν•œ λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•  λ•Œ λ„μ»€λŠ” μΊμ‹œλœ λ ˆμ΄μ–΄λ₯Ό μž¬μ‚¬μš©ν•˜μ—¬ λΉŒλ“œ μ‹œκ°„μ„ λ‹¨μΆ•ν•©λ‹ˆλ‹€.

νŠΉμ • λ ˆμ΄μ–΄κ°€ λ³€κ²½λ˜λ©΄, ν•΄λ‹Ή λ ˆμ΄μ–΄μ™€ κ·Έ μ΄ν›„μ˜ λͺ¨λ“  λ ˆμ΄μ–΄λ₯Ό μž¬κ΅¬μ„±ν•©λ‹ˆλ‹€.

λ„μ»€μ˜ 기술적 기반

λ„μ»€λŠ” λ¦¬λˆ…μŠ€ μ»€λ„μ˜ 핡심 기술인 Cgroups와 Namespaceλ₯Ό 기반으둜 ν•©λ‹ˆλ‹€.

Cgroups(Control Groups): ν”„λ‘œμ„ΈμŠ€ 그룹의 λ¦¬μ†ŒμŠ€ μ‚¬μš©λŸ‰(CPU, λ©”λͺ¨λ¦¬, λ„€νŠΈμ›Œν¬ λŒ€μ—­ν­)을 λͺ¨λ‹ˆν„°λ§ν•˜κ³  μ œν•œν•©λ‹ˆλ‹€. ν•œ μ»¨ν…Œμ΄λ„ˆκ°€ 전체 μ‹œμŠ€ν…œ μžμ›μ„ λ…μ ν•˜λŠ” 것을 λ°©μ§€ν•©λ‹ˆλ‹€.

Namespace: ν”„λ‘œμ„ΈμŠ€μ—κ²Œ μ œν•œλœ μ‹œμŠ€ν…œ λ·°λ₯Ό μ œκ³΅ν•˜μ—¬, ν”„λ‘œμ„ΈμŠ€κ°€ μžμ‹ μ˜ λ„€μž„μŠ€νŽ˜μ΄μŠ€ λ‚΄μ—μ„œλ§Œ μ‹œμŠ€ν…œ λ¦¬μ†ŒμŠ€λ₯Ό λ³Ό 수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 파일 μ‹œμŠ€ν…œ, λ„€νŠΈμ›Œν¬, μ‚¬μš©μž ID 등을 각 μ»¨ν…Œμ΄λ„ˆλ§ˆλ‹€ λ…λ¦½μ μœΌλ‘œ 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.

도컀 μ΄λ―Έμ§€μ˜ ꡬ쑰


도컀 μ΄λ―Έμ§€λŠ” λ ˆμ΄μ–΄ 적측식 μ•„ν‚€ν…μ²˜λ₯Ό κ°–μŠ΅λ‹ˆλ‹€. 각 λ ˆμ΄μ–΄λŠ” λ³€κ²½ 사항을 μ €μž₯ν•˜λ©°, 이전 λ ˆμ΄μ–΄ μœ„μ— μŒ“μ΄λŠ” ν˜•νƒœλ‘œ κ΅¬μ„±λ©λ‹ˆλ‹€.

λ³€κ²½λ˜λŠ” λ ˆμ΄μ–΄λŠ” μ΅œμƒμœ„ λ ˆμ΄μ–΄λ‘œ κ΅¬μ„±ν•˜λŠ” 것이 νš¨μœ¨μ μž…λ‹ˆλ‹€. νŠΉμ • λ ˆμ΄μ–΄λ₯Ό μˆ˜μ •ν•˜λ©΄ λ„μ»€λŠ” ν•΄λ‹Ή λ ˆμ΄μ–΄λΆ€ν„° λͺ¨λ“  μƒμœ„ λ ˆμ΄μ–΄λ₯Ό μž¬κ΅¬μ„±ν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

  • μ»¨ν…Œμ΄λ„ˆ μ‹€ν–‰ μ‹œ λ„μ»€λŠ” 읽기/μ“°κΈ° κ°€λŠ₯ν•œ 'μ»¨ν…Œμ΄λ„ˆ λ ˆμ΄μ–΄'λ₯Ό μ΅œμƒλ‹¨μ— μΆ”κ°€ν•©λ‹ˆλ‹€. 이 λ ˆμ΄μ–΄μ— μ»¨ν…Œμ΄λ„ˆ μ‹€ν–‰ 쀑 λ°œμƒν•˜λŠ” λͺ¨λ“  변경사항이 κΈ°λ‘λ©λ‹ˆλ‹€.

κΈ°λ³Έ 도컀 λͺ…λ Ήμ–΄

1. docker run - μ»¨ν…Œμ΄λ„ˆ 생성 및 μ‹€ν–‰

docker run -it --name mycontainer nginx

이 λͺ…λ Ήμ–΄λŠ” nginx 이미지λ₯Ό μ΄μš©ν•΄ 'mycontainer'λΌλŠ” μ΄λ¦„μ˜ μ»¨ν…Œμ΄λ„ˆλ₯Ό μƒμ„±ν•˜κ³  μ‹€ν–‰ν•©λ‹ˆλ‹€.

2. docker ps - μ‹€ν–‰ 쀑인 μ»¨ν…Œμ΄λ„ˆ λͺ©λ‘ 보기

docker ps      # μ‹€ν–‰ 쀑인 μ»¨ν…Œμ΄λ„ˆλ§Œ ν‘œμ‹œ
docker ps -a   # λͺ¨λ“  μ»¨ν…Œμ΄λ„ˆ ν‘œμ‹œ(μ€‘μ§€λœ μ»¨ν…Œμ΄λ„ˆ 포함)

3. docker start/stop - μ»¨ν…Œμ΄λ„ˆ μ‹œμž‘/쀑지

docker start mycontainer   # μ»¨ν…Œμ΄λ„ˆ μ‹œμž‘
docker stop mycontainer    # μ»¨ν…Œμ΄λ„ˆ 쀑지
  • docker start λͺ…λ Ήμ–΄λŠ” μ •μ§€λœ μ»¨ν…Œμ΄λ„ˆλ₯Ό μ‹œμž‘ν•©λ‹ˆλ‹€.
  • docker stop λͺ…λ Ήμ–΄λŠ” μ‹€ν–‰ 쀑인 μ»¨ν…Œμ΄λ„ˆλ₯Ό μ •μ§€ν•©λ‹ˆλ‹€.

4. docker create - μ»¨ν…Œμ΄λ„ˆ 생성(μ‹€ν–‰ν•˜μ§€ μ•ŠμŒ)

docker create --name testos centos

이 λͺ…λ Ήμ–΄λŠ” centos 이미지λ₯Ό μ‚¬μš©ν•΄ 'testos'λΌλŠ” μ΄λ¦„μ˜ μ»¨ν…Œμ΄λ„ˆλ₯Ό μƒμ„±ν•˜μ§€λ§Œ μ‹€ν–‰ν•˜μ§€λŠ” μ•ŠμŠ΅λ‹ˆλ‹€.

도컀 이미지 λΉŒλ“œ

Dockerfile μž‘μ„±λ²•

Dockerfile은 도컀 이미지λ₯Ό μƒμ„±ν•˜λŠ” 데 ν•„μš”ν•œ 섀정값을 λ‹΄κ³  μžˆλŠ” 슀크립트 νŒŒμΌμž…λ‹ˆλ‹€.

# κΈ°λ³Έ 이미지 μ§€μ •
FROM node:14

# μž‘μ—… 디렉토리 μ„€μ •
WORKDIR /app

# μ˜μ‘΄μ„± 파일 볡사 및 μ„€μΉ˜
COPY package.json .
RUN npm install

# μ†ŒμŠ€ μ½”λ“œ 볡사
COPY . .

# 포트 μ„€μ •
EXPOSE 3000

# μ‹€ν–‰ λͺ…λ Ήμ–΄
CMD ["node", "server.js"]

μ£Όμš” λͺ…λ Ήμ–΄ μ„€λͺ…:

  • FROM: 베이슀 이미지 μ§€μ •
  • WORKDIR: μž‘μ—… 디렉토리 μ„€μ •
  • RUN: 이미지 λΉŒλ“œ μ‹œμ μ— μ‹€ν–‰ν•  λͺ…λ Ήμ–΄
  • COPY: 호슀트의 νŒŒμΌμ„ μ»¨ν…Œμ΄λ„ˆλ‘œ 볡사
  • EXPOSE: μ»¨ν…Œμ΄λ„ˆκ°€ μ‚¬μš©ν•  포트 μ§€μ •
  • CMD: μ»¨ν…Œμ΄λ„ˆ μ‹€ν–‰ μ‹œ μ‹€ν–‰ν•  λͺ…λ Ήμ–΄

이미지 λΉŒλ“œν•˜κΈ°

docker build -t myapp:latest .

이 λͺ…λ Ήμ–΄λŠ” ν˜„μž¬ 디렉토리(.)의 Dockerfile을 μ‚¬μš©ν•˜μ—¬ 'myapp:latest'λΌλŠ” μ΄λ¦„μ˜ 이미지λ₯Ό λΉŒλ“œν•©λ‹ˆλ‹€.

이미지 μ΅œμ ν™” μ „λž΅

  1. κ²½λŸ‰ 베이슀 이미지 μ‚¬μš©ν•˜κΈ°: κ°€λŠ₯ν•œ κ°€μž₯ μž‘μ€ 베이슀 이미지(예: alpine)λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
  2. λ©€ν‹° μŠ€ν…Œμ΄μ§€ λΉŒλ“œ μ‚¬μš©ν•˜κΈ°: λΉŒλ“œ ν™˜κ²½κ³Ό μ‹€ν–‰ ν™˜κ²½μ„ λΆ„λ¦¬ν•˜μ—¬ μ΅œμ’… 이미지 크기λ₯Ό μ€„μž…λ‹ˆλ‹€.
  3. λ ˆμ΄μ–΄ μ΅œμ†Œν™”ν•˜κΈ°: RUN, COPY λ“±μ˜ λͺ…λ Ήμ–΄λ₯Ό μ΅œμ ν™”ν•˜μ—¬ λ ˆμ΄μ–΄ 수λ₯Ό μ€„μž…λ‹ˆλ‹€.

도컀 ν—ˆλΈŒ μ‚¬μš©ν•˜κΈ°

이미지λ₯Ό 도컀 ν—ˆλΈŒμ— μ—…λ‘œλ“œν•˜μ—¬ κ³΅μœ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

1. 도컀 ν—ˆλΈŒ 둜그인

docker login

2. 이미지 νƒœκ·Έ μ§€μ •

docker tag myapp:latest username/myapp:latest

3. 이미지 ν‘Έμ‹œ

docker push username/myapp:latest

이 과정을 톡해 μžμ‹ μ΄ λ§Œλ“  이미지λ₯Ό 도컀 ν—ˆλΈŒμ— μ—…λ‘œλ“œν•˜κ³  λ‹€λ₯Έ μ‚¬λžŒκ³Ό κ³΅μœ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

도컀 컴포즈

λ©€ν‹° μ»¨ν…Œμ΄λ„ˆ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄λž€?

μ‹€μ œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ€ 보톡 μ—¬λŸ¬ μ„œλΉ„μŠ€λ‘œ κ΅¬μ„±λ©λ‹ˆλ‹€(μ›Ή μ„œλ²„, λ°μ΄ν„°λ² μ΄μŠ€, μΊμ‹œ μ„œλ²„ λ“±). μ΄λŸ¬ν•œ μ„œλΉ„μŠ€λ“€μ„ 각각 μ»¨ν…Œμ΄λ„ˆλ‘œ μ‹€ν–‰ν•˜κ³  μ—°κ²°ν•  λ•Œ 도컀 컴포즈λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

docker-compose.yml 파일 μž‘μ„±λ²•

docker-compose.yml νŒŒμΌμ€ YAML ν˜•μ‹μœΌλ‘œ μž‘μ„±λ˜λ©°, μ—¬λŸ¬ μ»¨ν…Œμ΄λ„ˆμ˜ ꡬ성을 μ •μ˜ν•©λ‹ˆλ‹€.

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
    networks:
      - my-network
    depends_on:
      - db
      
  db:
    image: postgres:13
    environment:
      POSTGRES_USER: example
      POSTGRES_PASSWORD: example
      POSTGRES_DB: example_db
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - my-network
      
volumes:
  db-data:
  
networks:
  my-network:

μ£Όμš” μ„Ήμ…˜ μ„€λͺ…:

  • services: 각 μ»¨ν…Œμ΄λ„ˆλ₯Ό μ •μ˜
  • volumes: 데이터 μ˜μ†μ„±μ„ μœ„ν•œ λ³Όλ₯¨ μ •μ˜
  • networks: μ»¨ν…Œμ΄λ„ˆ κ°„ 톡신을 μœ„ν•œ λ„€νŠΈμ›Œν¬ μ •μ˜

μ‹€μ œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ꡬ성 예제

λ‹€μŒμ€ ν”„λ‘ νŠΈμ—”λ“œ, λ°±μ—”λ“œ, λ°μ΄ν„°λ² μ΄μŠ€λ‘œ κ΅¬μ„±λœ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μ˜ˆμ œμž…λ‹ˆλ‹€.

services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    depends_on:
      - backend
      
  backend:
    build: ./backend
    ports:
      - "8080:8080"
    environment:
      - DB_HOST=postgres
      - DB_PORT=5432
      - DB_USER=example
      - DB_PASSWORD=example
      - DB_NAME=example_db
    depends_on:
      - postgres
      
  postgres:
    image: postgres:13
    environment:
      POSTGRES_USER: example
      POSTGRES_PASSWORD: example
      POSTGRES_DB: example_db
    volumes:
      - postgres-data:/var/lib/postgresql/data
      
volumes:
  postgres-data:

도컀 컴포즈 λͺ…λ Ήμ–΄

# 컴포즈 파일둜 μ„œλΉ„μŠ€ μ‹œμž‘
docker-compose up

# λ°±κ·ΈλΌμš΄λ“œμ—μ„œ μ‹€ν–‰
docker-compose up -d

# μ„œλΉ„μŠ€ 쀑지
docker-compose down

# μ„œλΉ„μŠ€ μƒνƒœ 확인
docker-compose ps
profile
if (μ‹€νŒ¨) { λ‹€μ‹œ 도전; } else { 성곡; }

0개의 λŒ“κΈ€