딸기말차
[MSA] 4. Docker 활용, Image Build 본문
엔코아 플레이데이터(Encore Playdata) Backend 2기 백엔드 개발 부트캠프 (playdata.io)
백엔드 개발 부트캠프
백엔드 기초부터 배포까지! 매력있는 백엔드 개발자 포트폴리오를 완성하여 취업하세요.
playdata.io
1. 컨테이너 명령어
# 도커 버전 확인
docker -v
# 도커 컨테이너 생성
docker run -it ubuntu:14.04
# 이름을 붙여 도커 컨테이너 생성
docker run -it --name test1 ubuntu:14.04
# 실행중인 도커 컨테이너 목록 보기
docker ps
# stop 상태인 모든 도커 컨테이너까지 보기
docker ps -a
# 도커 컨테이너 이름 변경
docker rename [현재이름] [변경할이름]
# 도커 컨테이너 시작
docker start [컨테이너이름 or 컨테이너ID]
# 실행 중인 도커 컨테이너 정지
docker stop [컨테이너이름 or 컨테이너ID]
# 도커 컨테이너 삭제 (정지 상태인 컨테이너만)
docker rm [컨테이너이름 or 컨테이너ID]
# 실행중인 컨테이너 삭제
docker rm -f [컨테이너이름 or 컨테이너ID]
# 컨테이너의 ID 값을 모두 출력
docker ps -a -q
# 모든 도커 컨테이너 정지
docker stop $(docker ps -a -q)
# 모든 도커 컨테이너 삭제
docker rm $(docker ps -a -q)
2. 도커 네트워크
# 상대의 네트워크 확인
ping [ip addr]
* ping은 ICMP 라는 프로토콜을 사용한다.
# 브릿지 네트워크 만들기
docker network create --driver bridge [네트워크이름]
# net 옵션을 통해 브릿지 네트워크와 연결
docker run -it --name mynetwork --net mybridge ubuntu:14.04
* 일반적으로 컨테이너를 만들 때 docker0 를 통해서 만들지만,
이와같이 새로운 브릿지를 사용해 컨테이너를 만들면 해당 브릿지 네트워크에 종속되어 있기 때문에
기존 docker0를 통해 만든 컨테이너와 통신을 할 수 없다. 즉, 네트워크를 분리사용하고 싶을 때 사용하면 된다.
# 네트워크 브릿지 장비 보기
docker network ls
# 네트워크 상세 정보 보기
docker network inspect [네트워크이름]
# 서브넷, 게이트웨이, ip 할당범위 등을 임의로 설정한 네트워크 생성
docker network create --driver=bridge --subnet=172.72.0.0/16 --ip-range=172.72.0.0/24 --gateway=172.72.0.1 my_custom_network
# 도커 내부 네트워크망이 아니라 호스트 네트워크를 바로 연결해서 쓰고 싶다
docker run -it --name network_host --net host ubuntu:14.04
이렇게하면 포트를 열지 않아도 된다. 호스트의 포트를 그대로 가져다 쓰기 때문. 권장하지는 않는다.
왜냐하면 컨테이너가 따로 네트워크 영역을 할당 받는 것이 아니라 호스트 자체를 가져다 쓰기 때문에
호스트에서 어플리케이션을 외부에 노출하는 것과 같기 때문이다.
# 브릿지 네트워크와 --net-alias
docker network create --driver bridge --subnet 172.200.1.0/24 --ip-range 172.200.1.0/24 --gateway 172.200.1.1 netlb
도커 컨테이너의 ip는 유동이기 때문에 컨테이너를 내렸다 올릴 때마다 ip가 달라진다.
때문에 alias를 통해 요청한다. -> dns 서버 사용
# DNS 확인
dig inner-dns-test
* 해당 코드가 에러날 시
apt update
apt install dnsutils
3. Load Balance
로드 밸런싱은 부하 분산을 위한 필수 네트워크 기술로, 처리해야하는 작업을 분산해 처리하는 것을 의미한다.
즉, 클라이언트의 요청이 많은 경우 이를 여러대의 동일 웹 서버 등에 분산 시켜 요청을 처리해 리소스의 활용도를 최적화하고 처리량을 최대화해 지연 시간을 줄이는 작업으로, 이를 통해 안정적인 시스템 운영에 도움을 준다.
이를 테스트해보기 위해 nginx를 호스트 운영체제에 설치하고, nginx를 proxy 역할로 구성을 변경하여 nginx로 들어오는 패킷을 연결된 컨테이너에 upstream 하여, 요청을 처리하는 실습을 진행하였다.
# 호스트 운영체제에 nginx 설치하고 데몬 구동
sudo apt update
sudo apt install nginx -y
sudo service nginx start
# host의 80번 포트 확인
sudo netstat -nlp | grep 80
# phpserver:1.0 으로 도커 빌드, 이미지 생성
docker build -t phpserver:1.0 .
# 만든 이미지 찾기
docker images | grep php
# 만든 이미지 실행
docker run -itd -p 5001:80 -h nginx-lb01 -v ./lb01:/var/log/apache2 -e SERVER_PORT=5001 --name=nginx-lb01 phpserver:1.0
docker run -itd -p 5002:80 -h nginx-lb02 -v ./lb02:/var/log/apache2 -e SERVER_PORT=5001 --name=nginx-lb02 phpserver:1.0
docker run -itd -p 5003:80 -h nginx-lb03 -v ./lb03:/var/log/apache2 -e SERVER_PORT=5001 --name=nginx-lb03 phpserver:1.0
# 파일 복사
docker cp index.php3 nginx-lb01:/var/www/html/index.php
docker cp index.php3 nginx-lb02:/var/www/html/index.php
docker cp index.php3 nginx-lb03:/var/www/html/index.php
* itd : background에서 실행
* ./lb01 : 호스트의 lb01 폴더와 로그를 공유
이 상태에서 새로고침을 하면, lb02를 통해 요청을 처리하는 것을 확인할 수 있다.
이렇게 여러 컨테이너를 사용하다보면, 해당 컨테이너를 모니터링 해야하는 경우가 생기는데, 구글에서 이를 편하게 해줄 수 있는 프로그램을 지원해준다.
# cAdvisor 설치 (구글에서 배포하는 컨테이너 모니터링 프로그램)
docker run --volume=/:/rootfs:ro --volume=/var/run:/var/run:rw --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --publish=9000:8080 --detach=true --name=cadvisor google/cadvisor:latest
해당 프로그램의 기본 포트는 8080 이지만, 이는 스프링부트 기동 시 톰캣의 기본포트와 중복되기 때문에,
--publish=9000:8080 옵션을 통해 포트를 9000 으로 변경 후 실행하였다.
4. DataBase
# 실행중인 도커 컨테이너로 들어가기
docker exec -it encoredb bash
# 컨테이너 내 DB에 SQL 파일 복원
cd ~
mysql -uroot -pencore stock < master.sql
# view 생성
CREATE VIEW stock_data
AS
SELECT * FROM stock WHERE stock_code = 'A005930' ORDER BY date DESC;
# 특정 데이터만 가지고 VIEW 생성
CREATE VIEW master_2
AS
SELECT `ISU_SRT_CD` FROM master;
# 특정 데이터에 CONCAT을 통해 단어 추가 후 VIEW 생성
CREATE VIEW master_3
AS
SELECT CONCAT('A', `ISU_SRT_CD`) FROM master;
# 특정 데이터들을 골라 VIEW 생성
CREATE VIEW master_view
AS
SELECT CONCAT('A', `ISU_SRT_CD`), ISU_ABBRV, MKT_TP_NM FROM master;
# 생성한 VIEW DROP
DROP VIEW master_view
# CONCAT 을 사용해 테이블을 만들면 컬럼명에 CONCAT 이 포함되는게 불편해서 alias
CREATE VIEW master_view
AS
SELECT CONCAT('A', `ISU_SRT_CD`) as code_, ISU_ABBRV, MKT_TP_NM FROM master;
5. Key 설정
# rsa 방식으로 키 생성
ssh-keygen -t rsa
# .ssh 폴더로 이동, 파일목록 확인
cd ~/.ssh && ls
# Ubuntu 내에서 공개키를 통해 authorized_keys 파일 생성, 권한 변경
cat id_rsa.pub > authorized_keys
chmod 600 authorized_keys
# git bash를 통해 window쪽 공개키 확인
vim id_rsa.pub
해당 공개키의 내용을 Ubuntu의 authorized_keys에 복사 후 저장하면 된다.
6. Git 연동 및 Docker Image 생성
기존에 프로젝트 시 Git을 연동하고 사용했을 때는, GitHub에서 Repository를 생성 후 git bash나 intellij IDE 같은 곳에서 연동해 사용하였다.
반면 이번에 연동할 때는 GitHub의 Repository가 아닌 Ubuntu 내에 Git Repository를 생성 후 연동하는 작업을 진행하였고,
git bash에서 push 한 작업 파일을 Ubuntu 내의 Git Repository에 저장하였다.
이 후 Docker Image를 빌드할 디렉토리를 만들어 Git 연동에 필요한 데이터를 가지고 있는 known_hosts 와 id_rsa 파일을 copy 해 가져오고, 빌드에 필요한 Dockerfile을 작성 후 Ubuntu 내의 Git Repository에서 작업 파일을 Clone, 빌드를 진행하였다.
# mkdir repos
1. Ubuntu 내에 Git Repository로 사용할 디렉토리 생성
# git init ...
2. 작업한 파일이 있는 폴더에서 git bash를 통해 Ubuntu 내의 Git Repository와 연동
# git push origin master
3. 연동 후 작업파일 commit, push -> Ubuntu 내 repos 디렉토리에 작업파일이 push 된다.
# mkdir temp5
4. 도커 이미지를 빌드할 디렉토리 생성으로, 윈도우 내에서 폴더를 하나 생성 후 Github에서 파일을
clone해 오는 것과 거의 동일한 작업이다. 해당 디렉토리 내에 필요한 파일은 다음과 같다.
- 작업파일, Dockerfile, Dockerfile 내 Git Clone에 필요한 known_hosts, id_rsa
# git clone ssh://lhs@172.20.194.122:/home/lhs/repos/
5. Ubuntu 내의 Git Repository 인 repos 디렉토리에서 작업파일을 clone 해온다.
# cp ~/.ssh/known_hosts ./
# cp ~/.ssh/id_rsa ./
6. git 연동에 필요한 정보를 copy 해온다.
# vim Dockerfile
7. 도커 이미지 빌드에 필요한 Dockerfile을 작성한다.
# docker build -t restapi:1.0 .
8. 도커 이미지를 빌드한다.
1. Ubuntu 내 Git Repository 생성
# 사설 git 공간 만들기
sudo apt install openssh-server
sudo service ssh start
ifconfig
ifconfig | grep 192 or 172
mkdir ~/repos && cd ~/repos
git init --bare .
2. 윈도우 작업폴더 내에서 git bash를 통해 Git 연동, commit & push
git init
git remote add origin ssh://lhs@172.20.194.122:/home/lhs/repos/
git add .
git commit -m "stock-service"
git push origin master
3. Ubuntu 내 도커 빌드용 디렉토리 생성 및 빌드에 필요한 파일 생성
# 도커를 빌드할 디렉토리 생성 및 필요한 파일생성
cd ~
mkdir temp5
git clone ssh://lhs@172.20.194.122:/home/lhs/repos/
cp ~/.ssh/known_hosts ./
cp ~/.ssh/id_rsa ./
# 연결 확인
ssh localhost
4. 도커 이미지 빌드에 필요한 Dockerfile 작성
# Dockerfile 생성
vim Dockerfile
FROM openjdk:11
LABEL maintainer="encore"
# install required packages
RUN apt-get update \
&& apt-get install -y --no-install-recommends git \
&& apt-get install -y --no-install-recommends ssh \
&& rm -rf /var/lib/apt/lists/
# make bitbucket as a known host
RUN mkdir -p -m 0600 /root/.ssh
ADD known_hosts /root/.ssh/known_hosts
# ADD SSH Key into Docker container
# local의 .ssh/id_rsa 파일을 Dockerfile과 동일한 디렉토리에 복사해놓자.
ADD id_rsa /root/.ssh/id_rsa
RUN git clone ssh://lhs@172.20.194.122:/home/lhs/repos/
WORKDIR repos/stock-service
RUN chmod 700 gradlew
RUN ./gradlew clean build -x test
RUN mv build/libs/stock-service-0.0.1-SNAPSHOT.jar /opt/app-in-image.jar
WORKDIR /opt
ENTRYPOINT [ "java", "-jar", "app-in-image.jar" ]
5. 도커 이미지 빌드
# Docker build
docker build -t restapi:1.0 .
6. 도커 이미지를 사용해 컨테이너 생성
위에선 이미지 이름을 restapi로 빌드를 진행하였지만, 현재 사용하려는 이미지 파일 이름은 stock-service이다.
# Docker image run
docker run -d --name stock-service -p 9001:8080 stock-service:1.0
이 때 포트가 겹치는걸 막기 위해, 9001번 포트를 통해 접근할 수 있도록 하였다.
6. 51일차 후기
실습 중 직접 만든 API를 Ubuntu 내 Git Repository에 push하고, push 한 내용을 통해 배포를 위한 도커 이미지를 빌드해보았다.
필자는 gradle을 사용해 빌드를 진행했는데, 이 과정에서 test 쪽 디렉토리에서 DB 에러가 나는 것을 발견 후 임시로 Dockerfile 내에서
-x test 옵션을 통해 test 쪽 빌드를 제외하고 도커 이미지를 생성하였다.
해당 부분에 대해 왜 test 쪽에서만 DB 에러가 나는지 좀 더 찾아 수정해야할 부분이라 생각했고, 이번엔 gradle을 통해 빌드를 진행했지만 다음에는 maven을 사용한 빌드도 해봐야겠다는 생각이 들었다.
'Bootcamp > MSA' 카테고리의 다른 글
[MSA] 6. Docker 활용, SQL 예제 (0) | 2023.10.12 |
---|---|
[MSA] 5. Docker 활용, Compose (0) | 2023.10.11 |
[MSA] 3. Network (1) | 2023.10.05 |
[MSA] 2. Docker Image, Container (0) | 2023.09.27 |
[MSA] 1. Ubuntu, Docker (1) | 2023.09.26 |