🦁멋쟁이사자처럼 백엔드 부트캠프 13기 🦁
TIL 회고 - [72]일차
🚀72일차에는 Docker로 설정파일을 담은 이미지를 직접 만들어 네트워크의 컨테이너 간 통신을 테스트해볼 수 있었다.
학습 목표 : 네트워크 핑 테스트와 컨테이너에 올릴 설정파일 작성 연습
학습 과정 : 회고를 통해 작성
컨테이너 이미지 만들기
- 필요한 애플리케이션들을 컨테이너에 매번 설치해서 직접실행할 필요없이
프로젝트마다 다른 개발환경에 따라 이미지화시켜서 적용하면 개발환경에 맞게 활용 가능 - private 리포지토리를 가져올때
https://아이디:토큰@깃허브저장소주소 - 설정파일에 직접 넣어 이미지를 만들지 않고 환경변수에서 가져다 쓰도록 설정할 것
Dockerfile
# 1. JDK 21을 포함한 OpenJDK 기반 이미지 사용
FROM eclipse-temurin:21-jdk
# 2. 필수 패키지 설치
RUN apt-get update && apt-get install -y git maven && \\
rm -rf /var/lib/apt/lists/*
# 3. 작업 디렉토리 설정
WORKDIR /app
# 4. 실행 스크립트 복사
COPY start.sh /app/.
# 5. 기본 쉘 지정
CMD ["bash"]
- Dockerfile은 이미지를 생성할때 사용하는 파일
docker-compose.yml
version: '3.8'
services:
spring-app:
build: .
container_name: juunb-spring-container
ports:
- "9999:8080"
environment:
- GITHUB_USER=${JUUNB_GITHUB_USER}
- GITHUB_TOKEN=${JUUNB_GITHUB_TOKEN}
command: /bin/bash -c "/app/start.sh"
- 포트를 9999로 지정하여 이미 사용했었던 9090 포트와 겹치치 않도록 함
- command -c : /bin/bash로 /app/start.sh 스크립트 파일을 실행해달라는 의미
윈도우에서 환경변수 추가
- 변수 이름과 변수 값에 적절하게 값을 넣어줌
- cmd창으로 확인했을때의 결과 확인
start.sh
#!/bin/bash
# 1. 프로젝트 디렉토리로 이동
cd /app
# 2. Git 리포지토리 클론 (이미 존재하면 스킵)
if [ ! -d "juunbapp" ]; then
git clone juunbapp
fi
cd juunbapp
# 3. 최신 코드 가져오기
git pull origin main
# 4. gradle 빌드 실행
chmod 755 ./gradlew
./gradlew build -x test
# 5. Spring Boot 애플리케이션 실행
java -jar build/libs/linuxspringexam-0.0.1-SNAPSHOT.jar --server.port=8080
# linuxspringexam-0.0.1-SNAPSHOT.jar
# 빌드 후 JAR 파일 확인
ls -l build/libs/
- if [ ! -d "juunbapp" ]; then
➡️해당 디렉토리 안에 그 app이 있는지를 검사 (juunbapp) - git clone https://$GITHUB_USER:$GITHUB_TOKEN@깃허브저장소주소 juunbapp
➡️지정할 디렉토리명은 가장 뒤에 지정을 해준다 (juunbapp)
docker logs -f juunb-spring-container
➡️-f 옵션
- 컨테이너의 로그가 실시간으로 계속 표시됨 (터미널이 이 상태를 유지)
- 9999 포트로 접속했을때 컨트롤러로 지정한 water URL이 성공적으로 접속되는 것을 확인 가능
jar 파일 자동으로 찾기
기존 코드
# 5. Spring Boot 애플리케이션 실행
java -jar build/libs/linuxspringexam-0.0.1-SNAPSHOT.jar --server.port=8080
# linuxspringexam-0.0.1-SNAPSHOT.jar
- jar파일을 fix하는 것이 아니라 자동으로 jar 파일을 읽어오도록 코드를 수정할 수 있음
수정 코드
# 5. Spring Boot 애플리케이션 실행
# java -jar build/libs/linuxspringexam-0.0.1-SNAPSHOT.jar --server.port=8080
# linuxspringexam-0.0.1-SNAPSHOT.jar
JAR_FILE=$(find build/libs -name "*-0.0.1-SNAPSHOT.jar" ! -name "*-plain.jar" | head -n 1)
if [ -f "$JAR_FILE" ]; then
echo "실행 파일: $JAR_FILE"
java -jar "$JAR_FILE" --server.port=8080
else
echo "실행할 JAR 파일을 찾을 수 없습니다."
exit 1
fi
- 기존코드는 주석처리하고 이렇게 사용할 수 있을 것
- -plain.jar 인 파일은 제외를 해주고, 여러개를 찾았다면 첫번째 파일을 넣어달라는 것
JAR_FILE=$(find build/libs -name "*-0.0.1-SNAPSHOT.jar" ! -name "*-plain.jar" | head -n 1)
- find build/libs
➡️build/libs/ 디렉토리에서 파일을 검색 - name "*-0.0.1-SNAPSHOT.jar"
➡️name 옵션을 사용해 이름 패턴이 -0.0.1-SNAPSHOT.jar인 파일만 찾음 - ! -name "*-plain.jar"
➡️!(NOT) 연산자를 사용해서 -plain.jar 파일을 제외 - | head -n 1
➡️찾은 파일 중 첫 번째 파일만 선택
➡️만약 여러 개의 JAR 파일이 있다면 가장 먼저 찾은 것만 사용
- if [ -f "$JAR_FILE" ]
➡️찾은 JAR 파일이 정말 존재하는지 체크
- echo "실행 파일: $JAR_FILE"
➡️실행할 JAR 파일명을 출력해서 어떤 JAR 파일이 실행되는지 로그 확인 가능 - java -jar "$JAR_FILE" --server.port=8080
➡️찾은 JAR 파일을 실행
➡️Spring Boot 애플리케이션을 8080 포트에서 실행
VM vs 컨테이너 아키텍처
- 가상머신 (VM) : 하이퍼바이저를 통해 물리서버(호스트)위에 여러 독립된 OS를 구동
VM마다 게스트 OS전체가 올라감
장점 : 완전한 OS이므로 높은 보안성 및 호환성
단점 : 통째로 실행하므로 부팅, 구동시간이 길고 자원사용량이 큼 - 컨테이너 : 호스트 커널을 공유하면서 프로세스를 격리하여 독립된 환경을 제공
최소한의 라이브러리만 포함하여 OS 커널 자체는 호스트와 공유
장점 : 경량적인 특징
단점 : 하지만 보안에 있어서 주의가 필요 (ex. 커널공유) - 개발/테스트/운영환경이 동일한 컨테이너 이미지를 유지함으로써 “일관된 환경보장”
레지스트리
- 도커 이미지를 저장하고 공유하기 위한 서버 (저장소)
- 대표적으로 Docker Hub 혹은 사설로 AWS ECR (Amazon Elastic Container Registry)
브릿지
- 도커를 처음 설치하면 기본 브리지 네트워크가 생성
- 호스트와 컨테이너, 컨테이너와 컨테이너 간 통신이 NAT를 걸쳐 이루어짐
- 장점 : 설정 없이도 간단한 네트워크 분리 = 대다수의 개발환경
- 컨테이너끼리의 네트워크가 연결되도록 브릿지를 생성해줄 수 있음 (통신이 가능해짐)
호스트
- 컨테이너가 별도 가상 NIC없이 호스트의 네트워크 스택을 직접 사용
- 따라서 컨테이너 내 80번 포트를 쓰면 호스트 80번 포트가 바로 점유됨
- 컨테이너와 호스트가 동일한 IP/포트를 공유하게됨
- 장점 : NAT 오버헤드 없이 네트워크 성능이 좋을 수 있음
- 단점 : 포트충돌과 보안 주의
- 8888에 접속해보면 nginx로 접속 가능
- -p 옵션으로 내부 80번을 외부 8888로 띄우도록 설정한 것
- nginx1이 아닌 또 다른 nginx2 를 띄워서 도커들간의 통신을 테스트 가능
- 8889 테스트 결과
ping-demo - ping 테스트
services:
container-a:
image: debian
container_name: container-a
command: sleep infinity
networks:
- my-bridge-net
container-b:
image: debian
container_name: container-b
command: sleep infinity
networks:
- my-bridge-net
networks:
my-bridge-net:
driver: bridge
- debian
➡️리눅스의 가볍게 테스트하기 위한 image (ping 테스트 등) - command: sleep infinity
➡️서버를 띄운 다음 입력이 없어도 무한대기로 계속 있어달라는 것 (종료X) - ping으로 container-a, container-b 모두 잘 수행중인 것을 확인 가능
- 컨테이너 간 통신 동일 브리지 네트워크에 있는 컨테이너들은 서로 IP로 직접 통신 (ex. 172.17.0.2↔️ 172.17.0.3 )
- Docker DNS를 통해 컨테이너 이름으로 접근도 가능(단, 같은 네트워크 안이어야 함)
정리하자면
컨테이너↔️컨테이너 : 같은 브리지 네트워크에 있으면 서로 통신 가능.
컨테이너 이름으로 DNS 해석(ex. ping web1 ), 또는 IP 주소 사용
호스트↔️컨테이너 : 호스트에서 컨테이너로 접속은 docker0 인터페이스 또는 포트 매핑으로 가능
컨테이너에서 호스트로의 접속은 호스트의 IP(또는 DNS) 통해 NAT로 이뤄짐
외부↔️컨테이너: 외부(인터넷 등)에서 컨테이너에 접근하려면, -p (포트 매핑) 옵션을 활용하거나
별도 프록시/로드밸런서 설정이 필요
- Bridge 네트워크는 Docker의 기본 네트워킹 방식으로, NAT 기반 격리를 제공
- 기본 bridge (docker) 또는 사용자 정의 브리지를 통해 컨테이너끼리 IP/DNS로 통신 가능
- 포트 매핑( -p host:container )을 통해 호스트 포트에 연결하면 외부에서 컨테이너에 접근 가능
- 개발 시에는 기본 브리지를 자주 사용하고, 여러 애플리케이션을 나눠 격리하려면 사용자 정의 브리지를 만들어 관리
🚀회고 결과 :
이미지의 설정파일을 만드는 과정에 대한 코드 이해가 필요하여 회고를 통해 더 공부를 진행하였다.
아직 컨테이너, 호스트, 외부끼리의 통신흐름에 대한 이해가 더 필요할 것 같다.
향후 계획 :
- 네트워크 통신 흐름, 컨테이너 간 통신 등에 대한 이해 필요
'Recording > 멋쟁이사자처럼 BE 13기' 카테고리의 다른 글
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_74일차_"Docker 로드밸런싱" (0) | 2025.03.26 |
---|---|
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_73일차_"Docker 이미지" (0) | 2025.03.25 |
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_71일차_"Docker + Linux (3)" (0) | 2025.03.21 |
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_70일차_"Docker + Linux (2)" (0) | 2025.03.20 |
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_69일차_"Docker + Linux" (0) | 2025.03.19 |