imhamburger 님의 블로그
도커(Docker) - 도커 컴포즈로 Nginx 로드밸런서 실행하기 본문
같은 어플리케이션을 도커를 이용해 여러 개의 컨테이너로 생성하여 실행하고 로드밸런서를 이용해 분산시키는 것을 해보려고 한다.
나는 간단하게 웹사이트를 만들었고 도커를 이용해 3개의 컨테이너를 실행한다고 가정해보자.
웹사이트는 Apache httpd 웹 서버 소프트웨어를 이용해 서빙할 것이다. apache httpd 는 도커 이미지를 사용하였다. (httpd 도커)
도커파일은 다음과 같이 설정해주었다.
Dockerfile
ROM httpd:2.4
ARG REPO_URL=https://github.com/hamsunwoo/hamsunwoo.github.io.git
COPY ./my-httpd.conf /usr/local/apache2/conf/httpd.conf
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "vim"]
RUN ["apt-get", "install", "-y", "git"]
RUN git clone ${REPO_URL} /usr/local/apache2/blog
- 만들어놓은 웹사이트 소스코드는 나의 깃허브에서 가져올 것이다.
이제 위의 Dockerfile을 이용하여 빌드하여 실행시켜보자.
$ docker build -t my-apache2 .
$ docker run -dit --name my-running-app -p 8080:80 my-apache2
httpd.conf 에서 DocumentRoot?
httpd.conf 파일에서 DocumentRoot는 Apache HTTP Server가 웹 콘텐츠를 제공하는 기본 디렉토리를 지정하는 지시어.
DocumentRoot에 지정된 디렉토리는 웹 서버가 요청받은 URL과 일치하는 파일을 찾는 기본 위치이다.
예를 들어, DocumentRoot /var/www/html로 설정되어 있다면, 웹 서버는 /var/www/html 디렉토리에서 요청된 파일을 찾는다.
만약, 실행되고 있는 나의 웹 어플리케이션의 html 파일을 컨테이너 안이 아닌 내 컴퓨터로 복사해오고싶다면 다음과 같은 명령어를 사용한다.
$ docker cp my-running-app:/usr/local/apache2/htdocs/index.html index.html
이 명령어를 사용하면 도커 컨테이너 내부의 index.html 파일을 내 컴퓨터로 복사해올 수 있다.
이렇게 함으로써, 내 컴퓨터에서 파일을 수정하거나 백업하는 등의 작업을 할 수 있다.
응용해보기
$ docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf > my-httpd.conf
위 명령어는,
도커허브에 있는 httpd:2.4 이미지에서 httpd.conf 복사파일의 내용이 my-httpd.conf라는 이름의 파일로 호스트의 현재 작업 디렉토리에 저장된다. (--rm: 컨테이너가 종료되면 자동으로 삭제되도록 하는 옵션)
이 방법은 Apache의 기본 설정을 쉽게 가져오고 수정할 수 있는 유용한 방법이다!!
다시돌아와서,
웹 어플리케이션을 실행시키기 전에 나는 내 컴퓨터에서 작업을 계속 하고싶은데, 도커를 다시 빌드하고 실행시키려니 너무 번거로울 것 같다.
따라서, 다음과 같은 명령어로 내 로컬의 작업파일이 바로 도커 컨테이너에도 반영되게끔 하였다.
$ docker run -dit --name my-apache-app -p 8080:80\
-v "$PWD":/usr/local/apache2/blog/ my-apache2
#읽기모드
docker run -dit --name my-apache-app -p 8080:80\
-v "$PWD":/usr/local/apache2/blog/:ro --rm my-apache2
나는 컨테이너 안에 httpd.conf 파일에서 DocumentRoot를 변경하였었는데 이것을 일치하게 명령어를 줘야 에러가 나지 않는다.
:ro 옵션은 이 마운트를 읽기 전용 모드로 설정.
즉, 컨테이너 내에서 호스트의 파일을 수정할 수 없고, 오직 읽기만 가능하다.
웹 어플리케이션 도커 컨테이너는 실행시켜놓았고 이제 nginx 로드밸런서를 이용해 분산시켜보자.
나는 컨테이너들을 blog-1 / blog-2 / blog-3 / blog-4 으로 총 3개를 만들었고 포트번호는 주지않았다.
그리고 로드밸런서 설정을 해주자.
default.conf
upstream blog_servers {
server blog-1:80;
server blog-2:80;
server blog-3:80;
server blog-4:80;
}
server {
listen 80;
location / {
proxy_pass http://blog_servers;
}
}
nginx 를 위한 Dockerfile
FROM nginx:1.25.1
COPY ["default.conf", "/etc/nginx/conf.d/"]
로드밸런서 실행하기
docker run -d --name lb -p 8080:80 \
--link blog-1 --link blog-2 --link blog-3 --link blog-4 --rm lb
결과
이렇게 실행하면 nginx conf도 일일이 수정해줘야하고 명령어를 줄 때도 실행시켜놓은 모든 어플리케이션을 link 해줘야 한다.
그렇지만!!
Docker Compose 를 사용하면 간단하게 모든 것을 실행시킬 수 있다!!
Docker compose
실행시켜놓은 모든 어플리케이션을 모두 중단 및 삭제를 해준다.
그리고 compose.yml 을 만든다. (공식문서 참고)
docker-compose.yml
services:
blog_1:
build: ./docker/httpd
container_name: blog-1
ports:
- 8051:80
blog_2:
build: ./docker/httpd
container_name: blog-2
ports:
- 8052:80
blog_3:
build: ./docker/httpd
container_name: blog-3
ports:
- 8053:80
load_balancer:
build: ./docker/nginx
container_name: blog-lb
ports:
- 8949:80
depends_on:
- blog_1
- blog_2
- blog_3
links:
- blog_1
- blog_2
- blog_3
(참고로 외부 클라이언트가 각 블로그에 직접 접근하려면 포트가 지정해야한다.)
default.conf
upstream blog_servers {
server blog-1:80;
server blog-2:80;
server blog-3:80;
}
server {
listen 80;
location / {
proxy_pass http://blog_servers;
}
}
Docker compose.yml 실행시키기
$ docker compose up -d #실행
$ docker compose -f <yml 파일명> down #중단
결과
아까와 동일하게 잘 나온것을 확인할 수 있다.
하지만, 어플리케이션을 더 늘리고 싶을 때는?
위와 같은 방법을 사용할 시 yml파일에 blog_4를 추가하고 name 지정하고... 번거로운 작업을 해줘야 한다.
그리하여....
--scale 옵션을 활용하여 container 개수를 늘려보자!
Docker-compose.yml
name: ham
services:
blog:
build: ./docker/httpd
ports:
- 80
deploy:
mode: replicated
replicas: 1
environment:
- VIRTUAL_HOST=localhost
- VIRTUAL_PORT=80
load_balancer:
image: nginxproxy/nginx-proxy
container_name: blog-lb
ports:
- 8949:80
depends_on:
- blog
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- nginx 도 바로 도커허브에서 nginxproxy를 가져다 쓰기때문에 별도로 default.conf파일이 필요없다.
- mode: replicated: 복제된 서비스로 설정하여 스케일링이 가능하다.
- replicas: 1: 블로그 컨테이너의 복제본을 1개로 제한. (추후 확장가능)
- VIRTUAL_HOST=localhost: Nginx 프록시가 localhost라는 호스트 이름을 기반으로 이 컨테이너에 트래픽을 전달하도록 설정
- VIRTUAL_PORT=80: 트래픽이 blog 컨테이너의 포트 80으로 라우팅
실행하기
docker compose up -d --scale blog=<개수입력> --build
어플리케이션 컨테이너를 원하는 개수만큼 입력해주면 된다!
이렇게 설정하면 훨씬 간편하다.
부록: Develop 옵션
Docker-compose.yml
services:
blog_1:
build: ./docker/httpd
container_name: blog-1
ports:
- 8051:80
blog_2:
build: ./docker/httpd
container_name: blog-2
ports:
- 8052:80
blog_3:
build: ./docker/httpd
container_name: blog-3
ports:
- 8053:80
load_balancer:
build: ./docker/nginx
container_name: blog-lb
ports:
- 8949:80
depends_on:
- blog_1
- blog_2
- blog_3
links:
- blog_1
- blog_2
- blog_3
develop:
watch:
- action: sync+restart
path: ./docker/nginx/default.conf
target: /etc/nginx/conf.d/default.conf
- watch: 이 키는 특정 파일이나 디렉토리를 감시하는 설정을 포함. 파일의 변경 사항이 감지되면 지정된 동작이 수행.
- sync는 감시 중인 파일의 변경 내용을 특정 위치로 동기화하는 작업
- restart는 Nginx 서버를 재시작하는 작업 (변경된 설정이 즉시 적용)
- path: ./docker/nginx/default.conf는 감시할 파일의 경로를 지정
- target: /etc/nginx/conf.d/default.conf는 동기화된 파일이 Nginx 컨테이너 내에서 위치할 경로 (Nginx가 설정 파일을 읽는 위치)
즉, 이 설정은 ./docker/nginx/default.conf 파일이 수정될 때마다 Nginx 설정 파일이 자동으로 업데이트되고 Nginx 서버가 재시작되어 변경 사항이 적용되도록 하는 것이다.
이를 통해 개발자는 설정을 빠르게 변경하고 결과를 즉시 확인할 수 있다.
'도커(Docker)' 카테고리의 다른 글
도커(Docker) - Docker compose 사용하기 (0) | 2024.10.28 |
---|---|
도커(Docker) - 같은파일인데 도커 이미지 안에서의 결과랑 내 컴퓨터에서 출력되는 결과가 다르게 나오는 오류 (2) | 2024.09.05 |
도커(Docker) - 명령어 모음 (0) | 2024.08.25 |
도커(Docker) - 도커 이해하기 (0) | 2024.07.04 |
도커(Docker) - 가상화 기술과 컨테이너 이해하기 (0) | 2024.07.03 |