라즈베리파이로 테스트 서버 구축하기
맥락 공유
Denamu 서비스에 대한 헬스 체크와 로그가 필요했습니다.
vscode로 SSH 접속 후 메모리와 CPU를 100% 점유하는 버그가 있었고, 이외에도 어떤 이유로 서버가 멈출 때 알림의 필요성이 제기되었습니다.
그래서 알림 + 원인 파악을 위한 로그, 2가지의 기능을 도입하기 위해 테스트 서버를 구축하고 해당 내용에 대해 학습, 테스트 한 뒤 배포 중인 서버에 적용할 수 있도록 했습니다.
라즈베리파이 서버 구축 과정
목차
- 라즈비안 설치
- 원격 접속 xrdp 설치(rdp란?)
- SSH 설정
a. ssh-keygen 사용
b. sshd 설정에서 패스워드 사용 OFF 후 SSH key 사용 ON - nvm 설치
a. node 설치
b. db 설치 (mysql 지원 X → maria DB 설치해야 함)
c. nginx 설치
d. pm2 설치
e. HTTPS 설정 - 공유기 포트포워딩
- git 설치
- github actions 시크릿 값 설정
- crontab, 셸 스크립트 작성 → 헬스 체크 연동
라즈비안 설치
라즈베리파이도 엄연한 컴퓨터이기에 OS를 설치할 수 있습니다. 라즈비안이라는 OS인데요, 해당 링크(홈페이지)에서 이미지를 다운받아서 마이크로SD카드에 저장하면 됩니다. 추가적으로 라즈비안은 Debian기반의 OS입니다.
- cf) Debian?
데비안은 데비안 프로젝트에서 개발하는 리눅스 배포판입니다. 우분투를 비롯한 많은 리눅스 배포판이 데비안에 뿌리를 두고 있습니다.
데비안은 안정성을 중시한다는 특징을 가지며, 우분투에서 사용하는 많은 패키지들이 검증을 위해 데비안에서 사용하지 못하는 상황도 발생할 수 있습니다.
2013년의 아티클이긴 하지만, 데비안의 안정성 덕분에 NASA에서 선택된 전적도 가지고 있습니다. (해당 아티클)
xrdp 설치
라즈비안을 설치하고 설정을 좀 편하게 해주기 위해 GUI를 선택했습니다.
그렇게 하기 위해서 RDP를 사용했는데요, RDP는 원격 데스크톱 프로토콜입니다.
RDP를 사용하기 위해 xrdp 오픈소스 소프트웨어를 설치하여 사용합니다.
xrdp는 리눅스/유닉스 시스템에서 Windows RDP 클라이언트로 원격 접속할 수 있게 도와주는 소프트웨어입니다.
sudo apt-get instasll xrdp
입력하시면 됩니다. (저는 xrdp 설치할 때 라즈베리파이에 모니터, 키보드, 마우스를 직접 연결해서 세팅했습니다.)
💡
SSH와 RDP의 차이점이 궁금하실 수도 있을 것 같습니다. SSH는 유닉스 계열에서 주로 사용되며 CLI를 통해 접속하고, RDP는 Windows에 최적화되어 있으며 GUI 전체를 원격 제어할 수 있습니다. 그래서 GUI로 초반 세팅을 편하게 하기 위해 RDP를 사용한 것도 있습니다.
- cf) RDP란?
말 그대로 원격으로 데스크톱에 연결하여 사용하는 기능입니다.
처음에는 MS에서 출시하였으며 대부분 윈도우 계열 OS에서 사용할 수 있습니다.
(MAC에서도 사용할 수 있습니다. 이외에도 ICA, VNC 등 여러 프로토콜을 사용하여 데스크톱을 원격으로 사용할 수 있다고 합니다.) - 원격 데스크톱 액세스와 클라우드 컴퓨팅은 다른 개념입니다.
클라우드 컴퓨팅은 가상화된 리소스에 접근해서 여러 서버와 데이터 센터를 통해 서비스를 이용하는 것인 반면,
원격 데스크톱 액세스는 소프트웨어를 사용할 때 물리적 컴퓨터에 직접 연결하는 방식입니다.
요약하면 RDP는 원격 데스크톱 접속을 위한 것이며, 클라우드는 포괄적인 원격 컴퓨팅 서비스입니다. |
서로 이분법적으로 대비되는 개념이 아니라 서로 목적과 방식이 다를 뿐입니다.
SSH
"xrdp 설치했잖아요. SSH는 왜 설정하는 건가요?"와 같은 의문이 생길 수도 있습니다. 하지만 우리는 서버를 구축해야 합니다.
github actions로 CI/CD를 구축하면서 actions의 컴퓨터(인스턴스)가 SSH 접속을 시도하기 때문입니다.
최근 버전의 라즈베리파이는 SSH 접속을 OS 이미지 설치 단계에서 설정할 수도 있습니다. (참고 링크)
SSH 설정을 위해 ssh-keygen을 사용해줍니다. (keygen 가이드)
패스워드 방식을 사용하지 않는 이유는 보안적으로 RSA key가 더 우수하기 때문입니다.
(비밀번호를 잘못 설정하면 해킹당하고 비트코인 채굴에 사용될 수도 있습니다.)
생성하면 위와 같이 id\_rsa, id\_rsa.pub
파일 2개가 생성됩니다.
클라우드 인스턴스에 접속할 때처럼 id\_rsa
를 가져와서 외부에서 이 라즈베리파이 서버로 SSH 접속할 수 있습니다.
authorized\_key
라는 파일을 볼 수 있는데요, /etc/ssh
디렉토리 내부의 sshd\_config
라는 SSH설정에 필요한 파일입니다.
위 설정 파일에서 PubkeyAuthentication 옵션을 no에서 yes로 수정한 뒤, AuthorizedKeysFile 옵션을 .ssh/authorized\_keys
로 수정해줍니다.
공개키를 저장하는 위치를 명시적으로 설정하는 것입니다.
그래서 authorized\_key
에 id\_rsa.pub
내용을 복사 붙여넣으면 됩니다.
(chmod 600을 통해서 소유자만 읽고 쓸 수 있도록 권한 설정을 해야 합니다.)
마지막으로 PasswordAuthentication 을 no로 설정하시면 끝입니다.
NVM 설치
목차는 NVM 설치지만 node, mysql 등 이 파트에서 필요한 모든 소프트웨어들을 설치할 겁니다.
저도 여기서 정말 많은 에러를 겪었습니다.
NVM 설치
Node.js 공식 페이지에 접속하셔서 하라는 대로 따라하면 됩니다.
curl이 없다면 apt를 이용해서 설치해줍시다.
저는 설치 후 github actions 동작 과정에서 err: bash: line 2: /home/\*\*\*/.nvm/nvm.sh: No such file or directory
라는 에러를 볼 수 있었습니다.
저희 프로젝트에는 ~/.nvm 경로로 설정되어 있는데, 라즈베리파이에 설치하니 .config/nvm 경로로 설정되었습니다. 그래서 actions 스크립트를 수정했습니다. 만약 구축하시는 분이 있다면 설치 경로도 잘 봐야할 것 같습니다.
MySQL 설치
sudo apt install mysql-server 를 입력하면 설치가 안됩니다. 블로그를 찾아보거나 클로드한테 물어가면서 설정해주고 설치하려고 했는데요, 결국 만난건 아래와 같은 에러였습니다.N: Skipping acquire of configured file 'mysql-8.0/binary-arm64/Packages' as repository '<[http://repo.mysql.com/apt/debian](http://repo.mysql.com/apt/debian)\> bookworm InRelease' doesn't support architecture 'arm64'
MySQL 공식 저장소에서 arm64를 지원하지 않는다는 슬픈 말인데요, 라즈베리파이4를 사용하는 저는 arm64 아키텍처를 사용하고 있습니다.
파일을 직접 수정해서 조금 복잡하게 해결할 수도 있지만, 머리가 너무 아팠던 저는 Maria DB를 설치하며 해결했습니다.
Maria DB가 MySQL를 호환할 수 있기 때문에 가능한 일이었습니다.
(설치 문구와 에러가 너무 길어서 분석하기가 힘들어서 이 문제를 해결하는 데 시간이 정말 오래 걸렸습니다. 글로 쓰니까 10줄 안에 모든 내용이 들어가는군요.)
Maria DB를 사용하며 entity.ts 코드에서 수정할 부분이 생겼는데요, ngram이 없기 때문에 QueryFailedError: Function 'ngram' is not defined
라는 에러가 발생합니다.
위와 같이 코드를 수정해서 ngram을 사용하지 않도록 설정해줍니다.
Nginx 설치
이 부분은 어려울 게 없습니다. sudo apt install nginx 를 해주면 대부분 끝인데요, github 저장소에 있는 nginx.conf 파일을 불러서 읽는 정도의 설정만 추가하면 됩니다. /etc/nginx 디렉토리의 nginx.conf 파일을 수정해줍시다.
##
# Virtual Host Configs
##
#include /etc/nginx/conf.d/*.conf;
#include /etc/nginx/sites-enabled/*;
include /var/web05-Denamu/nginx.conf;
위와 같이 기본으로 설정되어 있는 2개를 지우고 Denamu에서 설정한 nginx.conf 파일을 읽어오도록 수정하면 됩니다.
- ps) 저는 로깅 메세지를 점검하기 위해 log 쪽 코드도 수정했습니다.
## # Logging Settings ## log_format custom '$time_local|$remote_addr|$request_method|$request_uri|$status|$request_time|$pid|$http_user_agent|$http_referer|$request_length|$bytes_sent'; log_format custom_spring_style '[$time_local] INFO [PID:$pid] --- [Thread:$connection] $remote_addr: $request_method "$request_uri" $status ($request_time sec) referer="$http_referer" agent="$http_user_agent" bytes=$bytes_sent req_length=$request_length'; access_log /var/log/nginx/access.log custom_spring_style; error_log /var/log/nginx/error.log error;
PM2 설치
여기도 마찬가지로 어려운 부분은 없습니다.
ecosystem.config.js에 담당했던 팀원이 이미 모든 설정을 작성했기 때문에 npm install -g pm2 로 전역 설치만 해주면 끝이었습니다.
PM2 설정을 아직 하지 않았다면 참고 링크1, 참고 링크2를 확인하시면 될 것입니다.
HTTPS 설정
Nginx HTTPS 설정 담당하신 팀원처럼 Let’s Encrypt를 통해서 인증서를 발급 받으려고 했습니다. 에러가 발생하며 실패하길래 로그를 열어서 분석했는데요, 아래와 같은 에러를 확인할 수 있었습니다.
"error": { "type": "urn:ietf:params:acme:error:caa", "detail": "CAA record for \[iptime.org\](<[http://iptime.org/](http://iptime.org/)\>) prevents issuance", "status": 403 },
iptime.org 도메인이 인증서 발급을 차단하고 있으며, iptime.org가 제 서브 도메인에 대한 SSL 인증서 발급을 제한하는 CAA 레코드를 설정해놓았습니다.
그래서 SSL 인증서 발급이 불가능했습니다.
클로드한테 물어보니 해결 방안으로 자체 도메인 구매, 클라우드플레어 등의 서비스 이용, HTTP로만 운영, 3가지를 주었습니다.
테스트 서버이기에 굳이 도메인을 구매하는 등 신경을 쏟을 필요가 없다고 생각하여 HTTP로만 운영하는 마지막 방법을 선택했습니다.
- cf) CAA Record?
참고 링크: https://blog.naver.com/ucert/221084644904
공유기 포트포워딩
공유기 포트포워딩은 참고 링크를 통해서 설정했습니다.
어차피 집에서 테스트용으로 돌릴건데 왜 해야 하냐고 물으신다면, CI/CD 때문입니다.
actions(공유기 외부)에서 ssh 접속을 하려면 네트워크에 있는 컴퓨터 중 어느 녀석으로 접속해야 하는지 알아야 하니까요.
그러면 또 어떤 걸 설정해야 할까요? 네 맞습니다. DDNS 설정을 해야 합니다. (참고 링크)
우리가 NCP나 AWS에서 인스턴스를 생성하면 IP 관해서 뭐를 설정해주나요?
AWS는 elastic ip를 설정할 것입니다. 마찬가지로 NCP에서도 고정 IP를 설정해주고요.
우리가 가정에서 사용하는 IP는 유동 IP로, 주기적으로 IP가 변경됩니다.(참고 링크) 그럴 때마다 매번 github에 등록된 시크릿 값을 매번 바꿔줘야 한다면 너무 귀찮겠죠?
그래서 DDNS 서비스를 통해 변경되는 IP 주소를 자동으로 추적하고 고정된 도메인 이름에 연결합니다.
IPTIME의 경우에는 xxxxx.iptime.org
로 설정할 수 있습니다.
모두 설정이 끝나면 위와 같이 확인할 수 있을겁니다.
(443 포트는 안 열어도 됩니다. 위에서 언급한 것처럼 HTTPS 사용을 하지 않기 때문입니다. 사용하실 분들은 443을 추가하셔도 됩니다.)
Git 설치
이제 거의 끝이 났습니다. 원본 레포지토리로부터 fork를 사용해서 개인 레포지토리에 우리 프로젝트를 복사해옵시다. 아니면 코드만 받아서 새로운 레포지토리로 올려도 됩니다. 그리고 라즈베리파이에 git을 설치합니다. git clone 레포지토리 주소
명령어를 입력하면 라즈베리파이에 레포지토리가 생성됩니다.
⚠️
Git 저장소 권한 문제 err: fatal: detected dubious ownership in repository at '/var/web05-Denamu' 위 에러가 발생할 수 있습니다.
(참고 링크)
Github 시크릿 값 설정
Settings → Secrets and variables → Actions
로 들어오셔서 New repository secret에 해당 값들을 저장하면 끝입니다.
추가적으로 현재 테스트 서버에는 HTTPS가 적용되지 않아 actions 스크립트 및 nginx.conf, client 코드에 수정이 필요했습니다.
헬스 체크 연동 테스트
이제 모든 준비 과정이 끝났고 스크립트를 작성해서 연동 테스트를 하면 끝입니다. 저는 디스코드 웹 훅을 사용했습니다.(참고 링크)
스크립트를 작성해서 CPU, 메모리, 디스크 사용량이 90퍼센트를 넘어가는 등 시나리오를 부하 테스트 해보며 디스코드에 알림이 오는지 테스트 해봤습니다.
'개발 > Denamu 프로젝트' 카테고리의 다른 글
[Denamu 스테이징 서버] DB 조회를 어떻게 최적화할 수 있을까? (0) | 2025.02.02 |
---|---|
NCP 활용 프로젝트 소개 - 🎄Denamu (1) | 2024.12.22 |