컨테이너가 서로 데이터를 주고받을 수 있도록 경로를 제공하며, 네트워크 격리를 통해 보안을 강화합니다.
실제 비즈니스 애플리케이션을 컨테이너화할 때, 여러 개의 컨테이너가 서로 협력해야 목표를 달성할 수 있어요. 그래서 각각의 컨테이너가 서로 소통할 수 있는 방법이 필요하죠. 이를 위해 컨테이너들 사이에서 데이터 패킷을 주고받을 수 있는 경로, 즉 네트워크를 설정해야 해요. 도커에서는 이런 네트워크를 쉽고 효율적으로 구축할 수 있도록 도와주는 간단한 네트워크 모델을 만들었어요. 이 모델을 컨테이너 네트워크 모델(CNM)이라고 부른답니다. 이 모델은 컨테이너 네트워크를 구현할 때 필요한 기본 요건들을 정해줘요.
2. Docker Network 개념
구성 요소
설명
샌드박스
컨테이너를 외부 세계와 격리하며, 네트워크 요청을 안전하게 처리.
엔드포인트
샌드박스와 네트워크를 연결하는 접점으로, 데이터를 주고받는 역할.
네트워크
엔드포인트 간 데이터를 전달하는 경로로, 여러 컨테이너가 소속될 수 있음.
하나의 네트워크 샌드박스 안에는 여러 개의 엔드포인트가 있을 수 있어요. 즉, 하나의 샌드박스 안에 있는 컨테이너는 네트워크에 전혀 연결되지 않거나, 여러 네트워크에 동시에 연결될 수 있어요. 가령, 세 개의 샌드박스 중 하나는 엔드포인트를 통해 두 개의 네트워크에 동시에 연결된 상태일 수 있죠.
이 네트워크 모델은 꽤 범용적이에요. 개별 컨테이너가 네트워크에서 어디에서 작동하는지는 정하지 않아요. 모든 컨테이너가 한 호스트에서 실행될 수도 있고(로컬), 여러 호스트에 걸쳐 있을 수도 있어요(글로벌).
물론 CNM은 그냥 네트워크가 어떻게 작동하는지 설명하는 모델일 뿐이에요. 실제로 네트워크를 사용하려면 CNM을 구현해야 해요. 로컬이든 글로벌이든, CNM을 구현하는 여러 방법이 있답니다.
각 네트워크는 외부에서 오는 권한 없는 접근으로부터 리소스를 보호해서 더 많은 보안을 제공해요. 그래서 애플리케이션을 만들고 운영할 때 여러 네트워크를 사용하는 게 좋아요. 그리고 서로 꼭 통신해야 하는 서비스들만 같은 네트워크에 두는 거죠. 방금 본 예제에서는 웹 API가 데이터베이스와 직접 통신할 필요가 없으니까, 이 둘을 다른 네트워크에 두었어요. 이렇게 하면 만약 해커가 웹 API를 해킹해도, 제품 카탈로그 서비스를 먼저 해킹하지 않고서는 데이터베이스에 접근하기 어렵게 됩니다.
3. Docker Network 종류
종류
설명
특징
브리지 네트워크
Docker의 기본 네트워크로, 단일 호스트 내에서 컨테이너 간 통신 가능.
IP 자동 할당, 포트 매핑으로 외부 연결 가능.
호스트 네트워크
컨테이너가 호스트 머신의 네트워크를 직접 사용.
높은 성능 제공, 네트워크 격리 불가.
오버레이 네트워크
다중 호스트 간 컨테이너를 연결하는 네트워크.
Swarm 모드 또는 Kubernetes에서 사용, 분산 애플리케이션에 적합.
사설 네트워크
사용자 정의 네트워크로, 특정 컨테이너만 연결 가능.
격리된 환경 제공, 보안 강화.
macvlan 네트워크
컨테이너가 물리적 네트워크 인터페이스에 직접 연결.
고유 IP 주소 제공, 네트워크 트래픽의 격리 가능.
4. 실제와 유사한 사례
예제: API, 카탈로그, 데이터베이스 서비스 네트워크
목표:
API는 카탈로그와 통신하지만, 데이터베이스와는 통신하지 않음.
카탈로그는 두 네트워크 모두 연결.
구현 코드
# 네트워크 생성docker network create --driver=bridge back
docker network create --driver=bridge front
# 컨테이너 생성 및 실행docker run --name=webapi -itd --net=front ubuntu:14.04docker run --name=catalog -itd --net=back ubuntu:14.04docker run --name=database -itd --net=back ubuntu:14.04# catalog 컨테이너를 front 네트워크에 추가 연결docker network connect front catalog
# 각 컨테이너에서 네트워크 상태 확인docker exec webapi route
docker exec catalog route
docker exec database route
# 네트워크 정보 확인docker network inspect front
docker network inspect back
# 네트워크 통신 테스트docker exec -it webapi bash
ping -c 1 catalog
ping -c 1 database # 불가능
exitdocker exec -it catalog bash
ping -c 1 webapi
ping -c 1 database
exit# 네트워크 및 컨테이너 정리docker network disconnect front catalog
docker stop webapi catalog database
docker rm webapi catalog database
docker network rm back front
5. Docker Network 명령어
명령어
설명
docker network create <이름>
사용자 정의 네트워크 생성.
docker network ls
현재 생성된 네트워크 리스트 확인.
docker network inspect <이름>
특정 네트워크의 상세 정보 확인.
docker network connect <네트워크> <컨테이너>
컨테이너를 네트워크에 연결.
docker network disconnect <네트워크> <컨테이너>
컨테이너를 네트워크에서 분리.
docker network rm <이름>
네트워크 삭제. 컨테이너가 연결된 네트워크는 삭제 불가.
6. Docker Network 사용 이유
이유
설명
컨테이너 간 통신
여러 컨테이너가 데이터를 주고받으며 협력 가능.
보안 강화
네트워크 격리를 통해 외부 및 불필요한 통신 차단.
구조적 연결
서비스 간 통신 구조를 체계적으로 설계 가능.
다중 호스트 지원
오버레이 네트워크를 활용해 여러 호스트에 분산된 컨테이너 연결.
7. Docker Network의 장단점
장점
단점
네트워크 격리로 보안 강화.
복잡한 네트워크 설정 시 추가 학습 필요.
컨테이너 간 효율적 데이터 전송.
여러 네트워크 드라이버 사용 시 성능 차이 발생 가능.
다중 호스트에서도 네트워크 연결 가능.
Swarm 모드 또는 Kubernetes 설정 필요.
8. 부가적으로 알아야 할 정보
Bridge와 Host 네트워크 차이:
브리지 네트워크는 컨테이너 간 독립적 IP와 네트워크 격리 제공.
호스트 네트워크는 컨테이너가 호스트의 네트워크를 직접 사용해 높은 성능 제공.
오버레이 네트워크:
Swarm 클러스터에서 여러 호스트를 연결할 때 사용.
분산 애플리케이션과 마이크로서비스 환경에서 필수적.
macvlan 네트워크:
고유 IP 주소를 컨테이너에 직접 제공해 외부 네트워크와의 원활한 통신 가능.
# back, front 네트워크 생성
docker network create --driver=bridge back
docker network create --driver=bridge front
# 각 서비스를 생성 및 실행
docker run --name=webapi -itd --net=front ubuntu:14.04
docker run --name=catalog -itd --net=back ubuntu:14.04
docker run --name=database -itd --net=back ubuntu:14.04
# catalog 서비스는 기본 back 네트워크 뿐만 아니라 front 네트워크에도 연결
docker network connect front catalog
# webapi 의 라우팅 테이블
docker exec webapi route
# catalog 의 라우팅 테이블
docker exec catalog route
# database 의 라우팅 테이블
docker exec database route
docker network inspect front # webapi / catalog
docker network inspect back # catalog / database
docker exec -it webapi bash
# 머신 안에서
ping -c 1 catalog # 가능
ping -c 1 database # 연결 불가능exit#
docker exec -it catalog bash
# 머신 안에서
ping -c 1 webapi
ping -c 1 database
# 리소스 정리
docker network disconnect front catalog
docker stop webapi catalog database
docker rm webapi catalog database
docker network rm back
docker network rm front
# 1. 볼륨 생성docker volume create datavol
# 2. 볼륨 리스트 확인
docker volume ls
# 3. Alpine 컨테이너에서 볼륨 사용
docker container run -ti --rm -v datavol:/data alpine
# 4. 컨테이너 내부에서 파일 생성
echo "볼륨 데모" > /data/demo.txt
exit
# 5. 볼륨 데이터 확인
docker container run --rm -v datavol:/data ubuntu cat /data/demo.txt
# 6. 호스트 머신에서 디렉토리 구조 확인
sudo apt update; sudo apt install -y tree
sudo tree -a /var/lib/docker/volumes/datavol
볼륨 정보 확인
docker volume inspect datavol
2. 암시적 볼륨 마운트 실습
예제 코드
# 1. MySQL 컨테이너 실행
docker run -d --name mysqltest -v /var/lib/mysql mysql:latest
# 2. 컨테이너 정보 확인
docker inspect mysqltest | jq .[].Mounts
# 3. 볼륨 리스트 확인
docker volume ls
3. Bind Mount 실습
디렉토리 마운트
# 1. 호스트 머신에서 디렉토리 생성cd ~
mkdir test-app
cd test-app
touch run.sh
chmod +x ./run.sh
# 2. Bind Mount 컨테이너 실행
docker run -ti --rm -v .:/app alpine
# 3. 컨테이너 내부에서 파일 확인cd /app
ls -ahlvF
Read-Only 및 Read-Write 마운트
# 1. Read-Only 및 Read-Write 디렉토리 생성
mkdir ~/readonly
mkdir ~/readwrite
# 2. 컨테이너 실행
docker run -ti \
-v ~/readonly:/readonly:ro \
-v ~/readwrite:/readwrite:rw \
ubuntu
# 3. 컨테이너 내부에서 파일 쓰기 테스트
echo "test" > /readonly/readonly.txt # 파일 쓰기 불가
echo "test" > /readwrite/readwrite.txt # 파일 쓰기 가능
exit
# 4. 호스트 머신에서 파일 확인
cat ~/readwrite/readwrite.txt
# 1. 컨테이너 내부에서 MySQL 접속
docker exec-ti mysqltest /bin/bash
mysql -h localhost -u root -p
# 2. MySQL 명령 실행
show databases;
use mysqltest;
createtable mysqltest(id int, name varchar(50));
insertinto mysqltest values(1, 'testname');
select*from mysqltest;
# 3. 데이터 확인 후 종료
exit
데이터 파일 확인
# 1. 컨테이너 내부 데이터 확인
ls -ahlvF /var/lib/mysql/mysqltest
# 2. 호스트 머신에서 데이터 확인
ls -ahlvF ~/mysqldata/mysqltest
다른 컨테이너에서 동일 데이터 사용
# 1. 기존 컨테이너 중지dockerstop mysqltest
# 2. 새 컨테이너 실행dockerrun -ti --rm -d \
--name mysqltest2 \
-e MYSQL_ROOT_PASSWORD=123! \
-e MYSQL_DATABASE=mysqltest \
-v ~/mysqldata:/var/lib/mysql \
mysql:latest
# 3. 새 컨테이너에서 데이터 확인dockerexec -ti mysqltest2 /bin/shmysql-h localhost -u root -pusemysqltest;select* from mysqltest;
services:
app:
image: myapp:latest
ports:
- "8080:8080"
logging:
driver: 'json-file'
options:
max-size: '10m' # 로그 파일 최대 크기 10MB
max-file: '10' # 최대 10개의 로그 파일 유지
FROM python:3.10
RUN pip install pipenv
WORKDIR /app
ADD . /app/
RUN pipenv --python 3.10
RUN pipenv run pip install poetry
RUN pipenv sync
RUN pipenv run pip install certifi
ARG STAGE
RUN sh -c 'echo "STAGE=$STAGE" > .env'
RUN sh -c 'echo "PYTHONPATH=." >> .env'
# ENV PYTHONPATH=/app
RUN chmod +x ./scripts/run.sh
RUN chmod +x ./scripts/run-worker.sh
# ENV PYTHONPATH=/app
CMD ["./scripts/run.sh"]
📌 Dockerfile은 컴퓨터에서 돌아가는 앱을 만들기 위한 레시피라고 보면 된다. 이 레시피대로 하면 Docker 이미지라는 걸 만들 수 있다. Docker 이미지는 앱을 실행하는 데 필요한 모든 것을 담고 있다.
Dockerfile을 사용하는 이유
1. 환경 일관성
문제: 애플리케이션은 다양한 환경(OS, 라이브러리 버전, 설정)에 따라 다르게 동작할 수 있습니다.
Dockerfile의 역할:
Dockerfile을 통해 운영체제, 소프트웨어 버전, 라이브러리 등을 명시적으로 정의.
개발, 테스트, 운영 환경에서 동일한 컨테이너 이미지를 사용하므로 환경 차이로 인한 문제를 방지.
"개발 환경에서 잘 동작하는데 프로덕션에서는 오류가 발생하는 문제"를 해소.
2. 자동화된 이미지 생성
문제: 매번 애플리케이션을 설치하거나 빌드하는 과정을 수동으로 처리하면 시간이 낭비되고 오류가 발생할 수 있습니다.
Dockerfile의 역할:
Dockerfile은 애플리케이션 빌드 및 설치 과정을 자동화.
docker build 명령어로 간단히 이미지를 생성할 수 있음.
변경 사항이 생길 경우 Dockerfile만 업데이트하여 쉽게 새로운 이미지를 생성 가능.
3. 이식성(Portability)
문제: 다른 플랫폼(OS)에서 애플리케이션을 배포하려면 추가 설정과 조정이 필요할 수 있습니다.
Dockerfile의 역할:
Docker 이미지는 한 번 생성하면 어떤 환경에서든 동일하게 동작.
컨테이너를 실행할 수 있는 곳이라면(로컬, 클라우드, 서버 등) 어디서나 배포 가능.
운영 환경에 상관없이 안정적인 배포 보장.
4. 확장성과 모듈화
문제: 복잡한 시스템은 여러 애플리케이션이나 서비스가 상호작용하며 구성됩니다.
Dockerfile의 역할:
Dockerfile을 사용해 애플리케이션별 컨테이너를 생성하고, 이를 조합하여 마이크로서비스 아키텍처를 구현.
각 서비스는 독립적으로 배포, 확장 가능.
5. 버전 관리 및 재현성
문제: 애플리케이션 업데이트나 변경이 과거 버전과 충돌하거나 재현이 어려울 수 있음.
Dockerfile의 역할:
Dockerfile 자체를 소스 코드와 함께 버전 관리(Git 등)할 수 있음.
특정 시점의 Dockerfile로 언제든지 동일한 이미지를 재생성 가능.
6. 배포 자동화(CI/CD와 통합)
문제: 애플리케이션 배포 과정을 수동으로 처리하면 효율성이 떨어지고 오류가 발생할 수 있음.
Dockerfile의 역할:
CI/CD 파이프라인에서 Dockerfile을 사용해 자동으로 이미지를 생성하고 테스트, 배포 가능.
GitHub Actions, Jenkins, GitLab CI/CD 등과 쉽게 통합 가능.
7. 리소스 격리
문제: 하나의 서버에서 여러 애플리케이션을 실행하면 서로 충돌할 가능성이 있음.
Dockerfile의 역할:
컨테이너화된 애플리케이션은 호스트와 격리된 상태로 실행.
리소스(CPU, 메모리, 네트워크)를 독립적으로 관리 가능.
8. 경량성
문제: VM(가상 머신)은 운영체제와 함께 많은 리소스를 소모.
Dockerfile의 역할:
컨테이너는 운영체제를 포함하지 않으므로 VM에 비해 가볍고 빠름.
Dockerfile로 필요한 최소 구성만 정의해 경량화된 이미지를 생성.
요약: Dockerfile 사용하는 이유
이유
설명
환경 일관성
개발, 테스트, 운영 환경 간 차이를 없애 동일한 애플리케이션 동작 보장.
자동화
애플리케이션 빌드 및 설정 과정을 자동화.
이식성
어디서나 동일하게 실행 가능한 이미지를 제공.
확장성
마이크로서비스 아키텍처 및 독립적인 서비스 확장을 지원.
재현성
버전 관리를 통해 특정 시점의 동일 환경을 재생성 가능.
CI/CD 통합
자동화된 빌드와 배포를 지원하여 DevOps 환경에 최적화.
격리 및 안전성
컨테이너 간 리소스 격리로 안정성 향상.
경량성
VM보다 적은 리소스 사용으로 효율적.
Dockerfile 사용법
Dockerfile 예제
# Dockerfile
FROM ubuntu:latest # 베이스 이미지를 Ubuntu 최신 버전으로 설정
MAINTAINER Your Name <your-email@example.com> # 이미지 제작자 정보# 필요한 패키지 업데이트 및 Nginx 설치
RUN apt-get update && apt-get install -y nginx
# index.html 파일을 Nginx의 기본 HTML 디렉토리로 복사
COPY index.html /usr/share/nginx/html
# 컨테이너가 노출할 포트를 설정
EXPOSE 80# 컨테이너 실행 시 Nginx를 실행하고 데몬 모드를 비활성화
CMD ["nginx", "-g", "daemon off;"]
Dockerfile 명령어 설명
명령어
설명
FROM
베이스 이미지를 설정 (컨테이너의 기반 OS 또는 환경).
MAINTAINER
이미지를 제작한 사람의 이름과 이메일 주소를 설정.
RUN
컨테이너 이미지를 빌드할 때 실행할 명령어 (예: 패키지 설치).
COPY
로컬 파일을 컨테이너 이미지로 복사.
EXPOSE
컨테이너가 외부에 노출할 포트를 지정.
CMD
컨테이너가 실행될 때 기본으로 실행할 명령어를 설정.
Docker 이미지 생성 명령어
Docker 이미지를 생성하는 명령:
docker buildx build -t my-nginx:latest .
-t: 이미지에 태그를 설정 (예: my-nginx:latest).
.: 현재 디렉토리에서 Dockerfile을 찾음.
buildx: 빌드 실행 도구. 일반적인 빌드 명령은 docker build를 사용.
Docker 컨테이너 실행 명령어
컨테이너 실행 명령:
docker run -d -p 80:80 my-nginx:latest
-d: 컨테이너를 백그라운드에서 실행.
-p 80:80: 호스트의 80번 포트를 컨테이너의 80번 포트에 매핑.
my-nginx:latest: 생성한 Docker 이미지를 기반으로 컨테이너 실행.
Docker 컨테이너 관리
컨테이너 종료:
my-nginx: 실행 중인 컨테이너 이름 또는 ID.
docker stop my-nginx
컨테이너 재시작:
docker start my-nginx
실행 중인 컨테이너 확인:
docker ps
중지된 컨테이너 포함 확인:
docker ps -a
Docker 이미지 공유
Docker 레지스트리:
Docker 이미지를 공유하고 저장하는 서비스.
예: Docker Hub, AWS ECR, Google Container Registry 등.
이미지 업로드 명령:
username/my-nginx:latest: Docker Hub에 업로드할 이미지 이름.
# Python 3.11 베이스 이미지 사용FROM python:3.11# pipenv 설치RUN pip install pipenv
# 작업 디렉토리 설정WORKDIR /app
# 로컬 파일을 컨테이너로 복사ADD . /app/
# pipenv 환경 설정RUN pipenv --python 3.11RUN pipenv run pip install poetry
RUN pipenv sync
RUN pipenv run pip install certifi
# 빌드 시 입력 가능한 변수 설정ARG STAGE
RUN sh -c 'echo "STAGE=$STAGE" > .env'
RUN sh -c 'echo "PYTHONPATH=." >> .env'
# 실행 스크립트에 실행 권한 부여RUN chmod +x ./scripts/run.sh
RUN chmod +x ./scripts/run-worker.sh
# 컨테이너 시작 시 실행할 명령어 설정CMD ["./scripts/run.sh"]
Dockerfile 예제 2: Nginx 웹 서버
Dockerfile
# Ubuntu 22.04 베이스 이미지 사용
FROM ubuntu:22.04# 작성자 정보
MAINTAINER your-name <your-email@example.com>
# 이미지 메타데이터 추가
LABEL purpose=Web Server
# Nginx 설치
RUN apt-get update && apt-get install -y nginx
# Nginx 설정 파일 복사
COPY nginx.conf /etc/nginx/nginx.conf
# 컨테이너 실행 시 Nginx 시작
CMD ["nginx", "-g", "daemon off;"]
Nginx 설정 파일 (nginx.conf):
user nginx;
worker_processes1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfileon;
keepalive_timeout65;
gzipon;
gzip_disable"msie6";
include /etc/nginx/conf.d/*.conf;
}
📌 GitHub Actions는 GitHub에 내장된 CI/CD 도구로, 소스 코드 저장소 내에서 코드 테스트, 빌드, 배포 등의 작업을 자동화합니다. GitHub Actions는 별도의 CI/CD 서버 구축 없이 GitHub와 쉽게 통합되며, 사용자가 YAML 형식의 워크플로 파일을 통해 간단하게 자동화 작업을 설정할 수 있습니다.
주요 특징
GitHub 통합: GitHub와 완벽히 통합되어, 저장소 내 이벤트(push, pull request 등)를 기반으로 자동화 실행.
서버리스: CI/CD 서버를 별도로 운영할 필요 없이 GitHub에서 바로 실행.
무료 제공 범위:
스토리지: 500MB
실행 시간: 월 2,000분 (무료 사용자 기준)
YAML 기반 설정:
워크플로는 반드시 .github/workflows 디렉토리에 저장.
YAML 파일을 작성해 자동화 작업 정의.
GitHub Actions의 CI (Continuous Integration)
개념
CI in GitHub Actions:
코드 병합 시 자동 테스트 및 빌드를 실행.
테스트 통과된 코드만 develop, main 브랜치로 병합되도록 설정.
코드 품질 유지 및 안정적인 배포 보장.
활용 예시
develop 브랜치에 병합 시:
gradle test 실행.
feature/* 브랜치에 push 시:
테스트 실행 후 알림(Slack, 이메일 등) 전송.
샘플 CI 워크플로
# 워크플로 이름을 설정 (GitHub Actions UI에서 표시됨)
name: CI
# 워크플로가 트리거되는 조건 정의
on:
push: # push 이벤트 발생 시 실행
branches:
- develop # develop 브랜치에 push되었을 때 실행
- feature/** # feature 하위 브랜치에 push되었을 때 실행
# 작업(Job) 정의 시작
jobs:
ci: # Job의 이름 정의
runs-on: ubuntu-latest # 실행 환경으로 최신 버전의 Ubuntu를 사용
# Job에서 실행할 작업 단계 정의
steps:
# 1. 리포지토리 코드를 체크아웃 (clone)
- name: Checkout repository # 단계 이름
uses: actions/checkout@v4 # GitHub Actions의 공식 체크아웃 액션 사용
# 2. Java 환경 설정
- name: Setup Java # 단계 이름
uses: actions/setup-java@v3 # Java 설정을 위한 액션 사용
with:
java-version: '17' # Java의 버전을 17로 설정
# 3. Gradle을 사용해 테스트 실행
- name: Run Gradle tests # 단계 이름
run: ./gradlew clean test # Gradle 명령어를 실행하여 테스트 수행
GitHub Actions의 CD (Continuous Deployment)
개념
CD in GitHub Actions:
main 브랜치에 병합된 코드를 자동으로 배포.
배포 작업에 필요한 빌드, 테스트, 배포 프로세스를 YAML로 정의.
활용 예시
main 브랜치에 병합 시:
테스트 실행 후 JAR 파일 생성.
생성된 JAR 파일을 AWS, GCP, Heroku 등으로 배포.
샘플 CD 워크플로
# 워크플로 이름을 설정
name: CD
# 워크플로 트리거 조건 설정
on:
push: # push 이벤트 발생 시 실행
branches: [ main ] # main 브랜치에 push되었을 때만 실행
# 작업(Job) 정의 시작
jobs:
cd: # Job의 이름 정의
runs-on: ubuntu-latest # 실행 환경으로 최신 버전의 Ubuntu를 사용
# Job에서 실행할 작업 단계 정의
steps:
# 1. 리포지토리 코드 체크아웃
- name: Checkout repository # 단계 이름
uses: actions/checkout@v4 # GitHub Actions의 공식 체크아웃 액션 사용
# 2. Java 환경 설정
- name: Setup Java # 단계 이름
uses: actions/setup-java@v3 # Java 설정을 위한 액션 사용
with:
java-version: '17' # Java의 버전을 17로 설정
# 3. Gradle 테스트 실행
- name: Run Gradle tests # 단계 이름
run: ./gradlew clean test # Gradle 명령어를 실행하여 테스트 수행
# 4. Heroku에 배포
- name: Deploy to Heroku # 단계 이름
uses: akhileshns/heroku-deploy@v3.12.12 # Heroku 배포를 위한 액션 사용
with:
heroku_api_key: ${{secrets.HEROKU_API_KEY}} # Heroku API 키를 GitHub Secrets에서 가져옴
heroku_app_name: "sampleapp-github-actions" # Heroku 앱 이름 (고유해야 함)
heroku_email: "user@example.com" # Heroku 계정 이메일
GitHub Actions의 장단점
장점
단점
통합성
GitHub와 완벽히 통합되어 추가 도구 없이 자동화 가능.
GitHub 플랫폼에 종속적.
사용 편의성
YAML 형식으로 간단히 워크플로 설정 가능.
복잡한 파이프라인 구성 시 설정 파일이 복잡해질 수 있음.
비용 효율성
무료 플랜으로 소규모 프로젝트에 적합.
대규모 프로젝트에서는 추가 비용 발생 가능.
확장성
다양한 오픈소스 액션 지원(GitHub Marketplace)으로 손쉬운 확장 가능.
커스텀 요구사항에 맞는 액션은 직접 작성해야 함.
자동화 수준
CI/CD 전 과정 자동화 가능.
실행 환경 제한(특정 OS/환경에서의 실행은 복잡).
GitHub Actions의 사용 이유
빠르고 간단한 설정: .github/workflows에 YAML 파일을 작성해 바로 사용 가능.
GitHub와의 높은 호환성: Pull request, Push 등 GitHub 이벤트와 밀접하게 연동.
비용 절감: 무료 플랜으로 소규모 프로젝트에서 부담 없이 사용 가능.
강력한 커뮤니티와 확장성:
GitHub Marketplace에서 다양한 Actions 활용 가능.
DevOps 문화에 적합한 자동화 도구 제공.
정리
GitHub Actions CI
GitHub Actions CD
목적
코드 변경 사항의 빌드 및 테스트 자동화
코드 변경 사항의 자동 배포
주요 작업
- Gradle, Maven 등 빌드 도구 테스트- 코드 품질 보장
- AWS, Heroku 등 클라우드 서비스로 배포
트리거
- Push- Pull Request
- Main 브랜치로의 병합
사용 예시
- 브랜치별 테스트- 테스트 실패 시 알림 전송
- 빌드된 파일 배포- 프로덕션 환경 배포
필요 도구
Java, Gradle, Docker, Slack
Heroku, AWS, Docker
장점
빠른 피드백, 품질 유지
배포 시간 단축, 자동화된 릴리스
부가적으로 알아야 할 정보
GitHub Secrets:
API 키, 데이터베이스 비밀번호 등 민감한 정보를 안전하게 관리.
secrets.변수명으로 워크플로에서 참조 가능.
GitHub Marketplace:
다양한 오픈소스 액션 제공(테스트, 배포, 코드 분석 등).
사용자가 만든 커스텀 액션을 공유하거나 활용 가능.
모니터링 및 디버깅:
GitHub Actions에서 제공하는 로그를 통해 워크플로 실행 과정을 모니터링 및 디버깅.
Github Actions 뜯어보기
Workflow
최상위 개념
여러 Job으로 구성되고, Event에 의해 트리거될 수 있는 자동화된 프로세스
Workflow 파일은 YAML으로 작성되고, Github Repository의 .github/workflows 폴더 아래에 저장됨
event
Github Repository에서 발생하는 push, pull request open, issue open, 특정 시간대 반복(cron) 등의 특정한 규칙
workflow 를 실행(trigger)함
runner
Github Action Runner app이 설치된 VM
Workflow가 실행될 instance로, 각각의 Job 들은 개별적인 runner에서 실행
배포 자동화: Docker, Kubernetes와 같은 컨테이너 및 오케스트레이션 툴을 활용한 배포 관리.
모니터링 및 피드백: Prometheus, Grafana, ELK 스택 등을 사용하여 문제를 조기에 탐지.
CI/CD의 상세 장단점
장점
단점
CI
- 변경 사항에 대한 빠른 피드백 - 코드 품질 유지 - 병합 충돌 감소 - 자동화로 생산성 향상
- 설정 복잡 (빌드 서버, 테스트 환경 구축 필요) - 테스트 커버리지 부족 시 문제 탐지 어려움
Continuous Delivery
- 코드 배포 준비 시간 단축 - 안정적인 릴리스 프로세스 구축 - 수동 배포 시 위험 최소화
- 릴리스 승인 절차로 인해 배포 지연 가능 - 추가적인 테스트와 검증 단계가 필요
Continuous Deployment
- 실시간 사용자 피드백 수집 가능 - 업데이트 빈도가 높아짐 - 운영비용 절감 및 시장 대응력 강화
- 초기 설정 및 유지보수 복잡 - 충분히 자동화된 테스트가 없을 경우 문제 발생 가능
CI/CD 사용 이유
품질 개선:
코드 병합 시 자동으로 테스트를 수행해 결함을 사전에 발견.
코드 리뷰 프로세스와 통합하여 개발 표준을 준수.
효율성 증가:
반복적이고 수동적인 작업을 자동화하여 개발자 생산성 향상.
릴리스 주기를 단축해 시간 및 인력 비용 절감.
리스크 감소:
변경 사항이 점진적으로 배포되므로 대규모 릴리스로 인한 문제 발생 가능성 감소.
롤백 자동화로 문제 발생 시 신속한 복구 가능.
팀 협업 강화:
병합 시 충돌을 최소화하고, 투명한 코드 공유를 통해 팀 간 협력 향상.
DevOps 문화를 활성화하여 개발과 운영의 경계를 허물음.
CI/CD 프로세스 상세 표
Continuous Integration
Continuous Delivery
Continuous Deployment
목적
코드 변경 사항 병합 후 자동 빌드 및 테스트
배포 준비 상태를 자동화
변경 사항을 자동으로 프로덕션에 배포
주요 활동
- 소스 코드 병합- 자동 빌드- 자동 테스트
- 자동화된 테스트- 릴리스 패키지 생성- 승인 대기
- 완전 자동화된 배포- 문제 시 자동 롤백
자동화 수준
테스트 및 빌드 자동화
테스트 및 배포 준비 자동화
완전 자동화
필요한 도구
Git, Jenkins, Maven, JUnit
Ansible, Terraform, Docker
Kubernetes, Helm, ArgoCD
적용 사례
소규모 프로젝트, 개발 단계
중간 규모 이상의 프로젝트
대규모 서비스, 빈번한 업데이트 환경
Docker+CI/CD
Docker와 CI/CD를 결합하면 개발, 테스트, 배포 프로세스를 표준화하고, 애플리케이션의 이식성과 안정성을 크게 향상할 수 있습니다.
Docker와 CI/CD의 결합 개념
Docker: 컨테이너화를 통해 애플리케이션과 모든 종속성을 하나의 이미지로 패키징. 어떤 환경에서도 동일하게 동작하도록 보장.
CI/CD:
CI: Docker 이미지를 생성하고 테스트를 자동화.
CD: Docker 이미지를 사용해 스테이징 또는 프로덕션 환경에 배포.
Docker+CI/CD의 주요 장점
장점
내용
이식성
Docker 이미지를 사용하면 환경 차이에 상관없이 동일한 애플리케이션 동작을 보장.
일관성 유지
모든 개발, 테스트, 배포 환경에서 동일한 컨테이너 이미지를 사용하여 일관된 결과를 제공.
자동화된 워크플로우
CI/CD 파이프라인에서 Docker를 활용하여 빌드, 테스트, 배포 과정을 자동화.
신속한 배포
Docker 이미지를 미리 빌드하고 저장소(예: Docker Hub, AWS ECR)에 푸시하여 빠르게 배포 가능.
비용 절감
컨테이너를 사용해 경량화된 환경을 제공하고 리소스를 효율적으로 사용.
Docker와 CI/CD를 활용한 워크플로우
코드 작성 및 변경: 개발자가 소스 코드를 작성하고 Git 저장소에 커밋.
Docker 이미지 생성:
CI 파이프라인에서 Dockerfile을 기반으로 이미지를 빌드.
이미지에 필요한 애플리케이션 코드와 종속성을 포함.
자동화 테스트:
Docker 컨테이너에서 테스트 스크립트를 실행하여 애플리케이션의 동작 검증.
이미지 저장소 푸시:
테스트를 통과한 Docker 이미지를 Docker Hub, AWS ECR, Azure ACR 등에 푸시.
배포 자동화:
CD 파이프라인에서 저장소에 있는 이미지를 스테이징 또는 프로덕션 환경에 배포.
Kubernetes 등 오케스트레이션 도구를 활용해 배포 관리.
모니터링 및 피드백:
배포된 애플리케이션의 성능과 로그를 모니터링하고, 피드백 루프를 구축.
CI/CD 파이프라인에서 Docker 사용 사례
사용 사례
설명
빌드 자동화
Dockerfile을 사용해 CI 과정에서 표준화된 애플리케이션 이미지를 자동 생성.
테스트 환경 표준화
Docker 컨테이너를 활용하여 동일한 테스트 환경을 제공하고, 테스트의 일관성 보장.
멀티 서비스 배포
Docker Compose 또는 Kubernetes를 통해 여러 서비스를 동시에 컨테이너로 배포.
롤백 지원
문제가 있는 배포는 이전 버전의 Docker 이미지를 사용해 신속히 롤백 가능.
블루-그린 배포 및 카나리 배포
Docker를 활용하여 새로운 버전을 점진적으로 배포하거나 테스트 배포 가능.
Docker와 CI/CD를 구현하는 도구
도구
역할
설명
Jenkins
CI/CD 자동화 도구
Docker 플러그인과 통합하여 이미지를 빌드하고 컨테이너에서 테스트 실행.
GitLab CI/CD
GitLab의 내장 CI/CD 도구
Docker 이미지를 빌드하고, 스테이징 및 프로덕션 배포를 자동화.
CircleCI
클라우드 기반 CI/CD 서비스
Docker 이미지 생성 및 컨테이너 기반 테스트 지원.
Docker Hub
Docker 이미지 저장소
Docker 이미지를 관리하고 배포 파이프라인에서 사용.
Kubernetes
컨테이너 오케스트레이션 도구
다수의 Docker 컨테이너를 관리하고, 스케일링 및 업데이트 수행.
간단한 예: GitLab CI/CD + Docker
1. Dockerfile 작성
# 베이스 이미지 설정FROM node:14# 작업 디렉토리 설정
WORKDIR /app
# 패키지 파일 복사 및 설치
COPY package*.json ./
RUN npm install
# 애플리케이션 코드 복사
COPY . .
# 애플리케이션 실행
CMD ["npm", "start"]
2. GitLab CI/CD 설정 (.gitlab-ci.yml)
stages:
- build
- test
- deploy
build:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker build -t my-app .
test:
stage: test
image: docker:latest
script:
- docker run my-app npm test
deploy:
stage: deploy
image: docker:latest
script:
- docker tag my-app my-dockerhub-repo/my-app:latest
- docker push my-dockerhub-repo/my-app:latest