클라우드 구조도
이번에 프로젝트를 배포하면서 적용한 클라우드 배포와 GitHub Actions를 이용한 CI/CD 파이프라인을 글로 적어보려고 합니다.
NCP에서 솔루션을 사용할때 Classic 과 VPC 버전으로 나뉘어지는데 VPC버전으로 위와같은 구조로 환경을 구축시 월 청구료가 많이 높아져서 Classic 버전으로 구성하게 되었습니다.
VPC
VPC는 Virtual Private Cloud의 약자로, 클라우드 환경에서 가상의 사설 네트워크를 제공
Internet Gateway
인터넷 게이트웨이는 VPC 내부의 리소스가 인터넷과 통신할 수 있도록하는 게이트웨이
Nat Gateway
- 네트워크 주소 변환 게이트웨이는 프라이빗 서브넷 내부의 EC2 인스턴스와 같은 리소스가 인터넷과 통신할 수 있도록 하는 게이트웨이
- 프라이빗 서브넷에 있는 리소스는 NAT 게이트웨이를 통해 외부로 나가는 트래픽을 라우팅 가능
Application Load Balancer
클라이언트로부터의 요청을 받아 배포된 여러 대상 서버로 트래픽을 분산하여 각 서버의 부하를 분산하고, 서버 장애 시 다른 서버로 트래픽을 전환하여 가용성을 보장
Bastion Server
배스천 서버는 외부에서 내부 네트워크로의 보안 접근을 제공하는 서버
Subnet
서브넷은 하나의 VPC 내에서 IP 주소 범위를 정의한 일종의 네트워크 세그먼트이며 Public Subnet과 Private Subnet으로 나뉨
Public Subnet
- 퍼블릭 서브넷은 외부에서 인터넷에 연결된 리소스를 호스팅하기 위해 사용
- 퍼블릭 서브넷은 라우팅 테이블(Route Table)에 인터넷 게이트웨이(Internet Gateway)와 연결되어 있다.
- 인터넷에 직접 액세스할 수 있는 퍼블릭 IP 주소를 가질 수 있다.
- 일반적으로 웹 서버, 로드 밸런서 등의 공개적으로 액세스 가능한 서비스를 호스팅
Private Subnet
- 프라이빗 서브넷은 외부와 격리되어 있는 리소스를 호스팅하기 위해 사용
- 프라이빗 서브넷은 라우팅 테이블에 NAT 게이트웨이(Network Address Translation Gateway) 또는 NAT 인스턴스와 연결되어 있습니다.
- 외부에서 직접 접근할 수 없는 사설 IP 주소를 가집니다.
- 데이터베이스 서버, 애플리케이션 서버 등의 보안이 중요한 서비스를 호스팅하는 데 사용됨
사용되는 서비스
Computer
NetWorking
모든 트래픽을 받을 수 있는 0.0.0.0/0 으로 설정하였지만 본인의 접속 IP별 설정해두시는걸 권장합니다.
WAS
SSH 접속용 22, 클라이언트 트래픽용 8080
DBS
SSH 접속용 22 => DBS의 경우 3306, 6379등을 열지 않은 이유는 조금 이따가 Network Interface 부분에서 설명하도록 하겠습니다.
Load Balance
기본으로 제공해주는 default-acg에 80포트를 추가하였습니다.
ncloud-load-balancer 이름으로 추가하지 않으면 0.0.0.0으로 열어놔도 로드밸런서로 통신이 불가능합니다.
os 선택 (ubuntu 18.04)
Server 설정
인증키 설정
ACG 설정
본인이 아까 만드신 ACG 설정을 추가합니다.
서버 생성 후 화면
Bastion Server에 대해서 아까전 설명을 드렸던것 같은데요 NCP에서는 AWS와 달리 서버 생성후 공인IP를 지급하지 않습니다.
그렇기 때문에 위 사진 우측 하단에 보시면 포트 포워딩 정보를 보실수 있는데요 특정 IP를 통해 다단계접속으로 직접 만든 Server에 접근을 할 수 있게 됩니다. 그러므로 Bastion Server의 역할을 하는 Server가 이미 존재하므로 Bastion Server는 만들지 않도록 하겠습니다.
포트 포워딩 설정 클릭
20002번 포트를 WAS의 22포트로 포워딩
(회색칸에 SSH 접속용 공인IP는 블러처리하였습니다. )
서버 관리 및 설정 변경에서 관리자 비밀번호 확인
위와 똑같은 방식으로 RDS 인스턴스를 똑같이 만들어 주시면 됩니다.
이로써 Private Subnet과 각각의 인스턴스를 연결시켜주었습니다.
그래서 아까 서버 정보로 돌아가보면 방금 네트워크 인터페이스에서 설정한 대역폭이 추가로 제공된걸 확인할 수 있습니다.
Private Subnet의 인스턴스들은 사설 IP대역에서만 통신을 할 수 있다고 하였습니다. 그런데 Git을 설치한다던지 Docker를 설치하려면 인터넷을 통해 다운로드를 받아와야하는데 서버측에서 통신을 보낼 수 있는 Client의 주소와 적용될 서버를 설정하는 부분입니다.
저는 모든 클라이언트에 요청을 보낼 수 있도록 설정을 하였습니다.
네트워크
Public IP로 하는 이유로는 ALB가 앞단에서 요청을 받아야 하기 때문입니다. Private Subnet은 기본적으로 사설망 내에서 폐쇄적인 네트워크 입니다. 트래픽을 받을 수 없는 상태란 건데요 Public Subnet에서 Private Subnet으로 요청 라우팅이 가능함으로써 로드밸런서 => WAS로 순차적으로 라우팅이 되는 것 입니다.
로드밸런서 설정
라우팅 해줘야 하는 서버가 건강한지 헬스체크 요청 설정 부분입니다.
아까 WAS ACG에서 8080포트를 열어놨으니 로드밸런서 공인IP 80포트로 오는 요청을 인스턴스의 8080으로 라우팅 하겠다는 설정입니다.
이렇게 생성을 하고나면 로드밸런서가 활성화가 되며 생성이 되었는데요
하지만 helth check 요청에 대한 반환값을 서빙해줄 서버가 없다보니 로드밸런서는 정지된 상태로 있게 됩니다.
이제 NCP console상 즉 GUI로 설정할 수 있는것은 다 해주었는데요.
여지껏 구성해놓은 클라우드 서버에 접속하여 헬스체크용 서버를 간단하게 배포해서 Load Balance를 활성화 시키고 OS상에서 설정해야하는 몇가지들을 추가적으로 진행해보도록 하겠습니다.
Spring Initalizr 에서 저는 Java 17, gradle 7.6버전에 의존성은 Spring Web 만 추가해서 생성하였습니다.
helth check용 controller만 작성하고 github에 push하였습니다.
@RestController
@RequestMapping("/helth")
public class HelthController {
@GetMapping()
public String check() {
return "helth check success!";
}
}
sudo ssh -i {your-pem-key} {username}@{your-public-ip} -p {your port(예:20002)}
이렇게 엔터를 치면 패스워드를 입력하라는 문구가 뜨는데요 설정 및 변경에서 받은 관리자 번호까지 치고나면 인스턴스로 SSH접속이 됩니다.
필수 소프트웨어 설치
당장 헬스체크용 프로젝트를 배포할때 필요한 필수 소프트웨어를 설치합니다.
여기서 설치를 다루지는 않겠습니다.
Git과 Java가 잘 설치가 되었다? => NAT Gateway설정이 잘 되었다.
Private Subnet에 위치한 인스턴스는 인터넷을 이용한 통신이 안됩니다. 그렇기 때문에 Nat Gateway로 요청을 라우팅하여 보내게 되는데 설치가 잘 되었다는건 아까 구성한 NAT Gateway 설정이 잘 된걸 의미할 수 있습니다.
이제 순서대로
git clone {your-repository-url}
cd {your-repository-dir-name}
./gradlew bootJar
java -jar build/libs/{your-project}-0.0.1-SNAPSHOT.jar
실행을 시키면 이제 /helth 엔드포인트로 Get 요청이 주기적으로 들어오는걸 확인할 수 있습니다. 이제 Load Balance를 확인해보면
상태가 운영중 적용 서버에 연결상태 성공으로 바뀌신걸 확인할 수 있습니다.
이제 마지막으로 하나가 남았는데요 Private Subent내에서 사설 대역간의
통신을 위한 설정과 확인을 마지막으로 진행하겠습니다.
WAS 인스턴스에서 DBS 인스턴스로 Ping을 날려보도록 하겠습니다.
ping {your-DBS-ip}
PING 192.168.128.13 (192.168.128.13) 56(84) bytes of data.
이렇게만 뜨고 화면이 아마 멈춰 계실겁니다. 그 이유로는 아까 NIC(Network Interface)를 생성하였지만 실제로 OS에서도 인터페이스를 설정을 해줘야만이 사설 대역간에 통신이 가능합니다.
ubuntu 18.04를 기준으로 아래 명령어를 치고 들어가시면
vim /etc/network/interfaces
기본 제공된 사설 IP대역만 설정이 되어있게 됩니다. 이제 여기서 사설 네트워크 대역을 추가하겠습니다.
auto eth1: eth1 네트워크 인터페이스가 부팅 시 자동으로 활성화
iface eth1 inet static: 이 줄은 eth1 네트워크 인터페이스를 정적(Static) IP 주소로 구성.
address 192.168.128.12: 이 줄은 eth1 인터페이스에 할당될 IP 주소를 지정
netmask 255.255.255.0: 이 줄은 eth1 인터페이스의 서브넷 마스크를 지정
up route add -net 192.168.0.0 netmask 255.255.255.0 dev eth1:
이 줄은 eth1 인터페이스를 통해 192.168.0.0/24 사설 네트워크로 라우팅하도록 추가, 이 설정은 해당 시스템이 eth1 인터페이스를 통해 192.168.0.0/24 네트워크로 접근할 수 있도록 합니다.
터미널에서 ifconfig 를 치면 eht1이 추가된걸 확인할 수 있습니다.
이제 다시 DBS에 Ping을 날려보도록 하겠습니다.
Private Subnet끼리의 통신도 잘 되는걸 확인할 수 있습니다.
이로써 클라우드 구성부터 배포까지 해보았는데요 다음편에서는 초반에 말했던 기존의 프로젝트를 방금 만든 클라우드에 Github Action을 이용한 CI/CD 파이프라인으로 빌드배포를 진행해 보겠습니다.
여기서 마치고싶지만 클라우드를 구성하면서 여러분들이 의아해 할만한 부분을 몇개 짚고 넘어가도록 하겠습니다.
Private Subnet을 구성할때 NIC(Network Interface)및 OS에서 NIC 설정을 한번 더 해주었는데요 AWS, NCP(VPC)를 이용하시는 분들은 실제로 VPC를 생성하고 IGW(Internet Gateway), Public Subnet, Private Subnet의 라우팅테이블을 생성하는것 만으로 끝내신 경우가 있는걸로 알고 있습니다.
아무래도 저는 Classic으로 구성을 하다보니 classic에서는 라우팅테이블을 서비스하지 않으니 조금더 번거로운 작업을 추가해야 했고 이런 부분들이 조금은 다르다고 생각합니다.
DBS에서 각 DB에서 흔히 사용되는 특정 포트를 오픈하지 않았는데요 사실 Private Subnet 대역폭 안에서는 ACG가 적용되지 않을뿐더러 사설대역간에는 자유롭게 통신이 가능하여서 ACG에서 특정 포트에 대한 InBound 규칙을 정의하지 않았습니다.
사실 저는 클라우드와는 조금 안친한 프로그래밍에 집중하던 개발자 인데요 그래도 직접 클라우드를 구성하고 배포를 해보니 약간 다른 느낌의 성장이 된것 같습니다.
추가적으로 잘못된점이나 더 좋은 방안들은 댓글로 알려주시면 감사하겠습니다.
안녕하세요, 네이버 클라우드 플랫폼입니다.
네이버클라우드의 기술 콘텐츠 리워드 프로그램 '이달의 Nclouder(2월)' 도전자로 초대합니다 :)
네이버 클라우드 플랫폼 서비스와 관련된 모든 주제로 3/7(목) 23시까지 신청 가능합니다. (*2월 작성 콘텐츠 한정 신청 가능)
Ncloud 크레딧을 포함한 다양한 리워드가 준비되어 있으니 많은 관심 부탁드립니다!
자세한 내용은 아래 링크에서 확인부탁드립니다.
https://blog.naver.com/n_cloudplatform/223344999298
신청 링크
https://navercloud.typeform.com/to/lF8NUaCF