기본적으로 Reverse Proxy
를 기반으로 동작한다.
1) Nginx
오픈소스 소프트웨어
특정 알고리즘은 Nginx Plus에서만 사용이 가능하다.
2) HAProxy
오픈소스 소프트웨어
여러 로드밸런싱 기능을 지원한다.
https://velog.io/@mooh2jj/docker-jenkins-github-%EB%B0%B0%ED%8F%AC
이 블로그를 기반으로 다음을 진행했습니다.
Nginx는 리버스 프록시, 로드밸런싱을 위해 서버를 감추기 위한 웹서버입니다. 실습을 위해서 nginx 인스턴스
를 따로, jenkins
로 배포할 원격 ssh 인스턴스 3개
를 가지고 진행하겠습니다.
# ubuntu 기준
sudo apt-get install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx
ps -ef | grep nginx ( nginx 프로세스 상태 확인 )
sudo systemctl restart nginx
sudo systemctl reload nginx
restart
서버를 shutdown 한 뒤 재 기동, 즉 서버가 운영되지 않는 시간이 존재
설정 파일에 문법적 에러가 존재할 경우, 서버는 죽게 된다.
reload
새로운 설정 파일을 반영할 때 서버는 살아서 동작한다.
설정 파일에 문법적 에러가 존재할 경우, reload는 실패하지만 서버는 기존 설정을 기반으로 정상적으로 동작한다.
sudo docker run --name webserver -d -p 80:80 nginx
[설치 ip주소]:80
or [설치 ip주소]
을 치면 화면에 나오는지 확인합니다.
로컬에서 설치했다면 http://localhost:80
으로 확인합니다.
# ngnix 중지
sudo docker stop [nginx containerID] or webserver
# ngnix 시작
sudo docker start [nginx containerID] or webserver
이제 로드밸런싱 확인을 위해 Jenkins 인스턴스로 돌아가는 SSH 인스턴스 3개를 준비합니다.
Jenkins 인스턴스가 SSH 인스턴스를 접속하게 만드는 방법은 다음 블로그를 참조하였습니다.
https://velog.io/@mooh2jj/JeinkinsDocker-명령어로-AWS-EC2서버-publish-over-ssh-배포하기
각 SSH 인스턴스에는 docker 명령어가 내려지니
# ec2 인스턴스 재시작 이후에도 docker 연결이 될 수 있음!
sudo usermod -aG docker ${USER}
# 그룹에 대한 변경 사항을 활성화
newgrp docker
# docker 재시작 -> 안해도 됨!
# sudo systemctl restart docker
or
# 2) /var/run/docker.sock 접근 권한 허용
sudo chmod 666 /var/run/docker.sock (비추)
이 명령어로 Permission 문제를 해결해주면 됩니다.
그리고 SSH 서버를 n개 이상 더 추가할려면 Jenkins 홈페이지 > Jenkins 관리 > 환경설정 > Publish over SSH
에 가면 SSH 서버 Add
버튼을 누르고 jenkins 공개키를 등록한 SSH 인스턴스 네임, ip주소 를 넣어주어 추가해줘야 됩니다.
그다음 Item 프로젝트
> 구성
에서
SSH서버
와execute shell
또 추가해주어야 합니다.
자 nginx 인스턴스에 가서 리버스 프록시 설정과 로드밸런싱 설정을 위한 conf 파일을 열어 봅니다.
vim /etc/nginx/nginx.conf
docker exec -it {nginx docker container ID} bash
## 기존 default nginx conf 파일 삭제
sudo rm -rf /etc/nginx/sites-enabled/default
bash
에 들어가서 vi 편집기 설치
cat /etc/issue
# 데비안 확인
apt-get upgrade
apt-get update
apt-get install vim
# load-balancing.conf는 새로 만들어준다.
sudo vi /etc/nginx/conf.d/load-balancing.conf
이렇게 아래 내용으로 바꿔줍니다.
upstream cpu-bound-app { ## cpu-bound-app이라고 네임을 지정할 수 있다.
## 기본: 라운드 로빈
server {instance_1번의_ip}:{지정한 포트번호};
server {instance_2번의_ip}:{지정한 포트번호};
server {instance_3번의_ip}:{지정한 포트번호};
}
server {
listen 80;
location / {
proxy_pass http://cpu-bound-app; ## 지정 네임으로 요청하기
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr; ## 클라이언트의 호스트 설정
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
이로써,
round-robin(디폴트) - 그냥 돌아가면서 분배한다.
hash - 해시한 값으로 분배한다 쓰려면 hash <키> 형태로 쓴다. ex)hash $remote_addr <- 이는 ip_hash와 같다.
ip_hash - 아이피로 해싱해서 분배한다.
random - 그냥 랜덤으로 분배한다.
least_conn - 연결수가 가장 적은 서버를 선택해서 분배, 근데 가중치를 고려함
least_time - 연결수가 가자 적으면서 평균 응답시간이 가장 적은 쪽을 선택해서분배
sudo systemctl restart nginx
그리고 실제 nginx ip주소로 애플리케이션이 실행되는지 확인합니다.
url : {nginx ip주소}:80
ps -ef | grep nginx
netstat -antup | grep LISTEN
80포트가 정상적으로 열렸는지 확인
# nginx 문법 테스트 명령어
sudo nginx -t
# Nginx error log 확인 tail -f 는 끝까지 log를 보는 리눅스 명령어
sudo tail -f /var/log/nginx/error.log
배포를 하는 동안 인스턴스가 내려가기 때문에 사용자가 502에러
같은 사이트 중단을 경험할 수 있습니다. 그래서 사이트가 내려가지 않는 무중단 배포를 해야 하는데 여러가 지 방법이 있지만 인스턴스 사이에 딜레이를 주는 방법인 sleep
을 이용해 보겠습니다.
SSh 인스턴스2번과 3번 Exec commaned
에 30초 정도 딜레이를 줄 수 있게 sleep 30
을 추가 하겠습니다.
# 인스턴스 2번, 3번에 추가
sleep 30
sudo docker rm -f $(sudo docker ps -aq)
sudo docker rmi -f mooh2jj/docker-test
sudo nohup docker run -p 8080:8080 mooh2jj/docker-test > /dev/null 2>&1 &
이러면 사용자가 배포하는 동안에 사용자의 요청에도 사이트가 502에러가 나는 상황을 막을 수 있었습니다.