AS-IS
현재 구동중인 백엔드 서버의 node 버전은 16버전을 사용하고 있다.
node 16은 지원이 중단되었으며 보안 업데이트도 받을 수 없는 버전에 놓여있기에 최근 lts인 node 20으로 업그레이드를 진행 하고자 한다.
현재 서버 EC2 AMI는 amazon linux 2를 사용 중에 있다.
TO-BE
node 20 버전으로 업그레이드를 진행하기 위해서 Amazon linux 2에서 Amazon linux 2023으로 업그레이드를 진행하고자 한다.
단, 현재 가동 중인 prod 환경에서 다운타임 없이 업데이트를 진행하고자 한다.
이 때의 best pracitce와 더불어 각 인프라를 분석하며 업그레이드를 진행한다.
Node.js Benchmark
State of Node.js Performance 2023
16과 20의 차이는 아주 유의미할 정도의 성능 향상이 있었으며 이제 16버전은 더 이상 지원이 종료되었으며 보안 업데이트를 받지 않는 버전이니 업그레이드의 필요성이 대두 된다.
- V8 Engine Update: Upgraded to V8 version 10.7, which includes the new Intl.NumberFormat API for language-sensitive number formatting .
- node --watch Mode: Experimental feature that allows processes to restart automatically when files are changed, enhancing developer productivity .
- HTTP(S)/1.1 Keep-Alive by Default: Outgoing HTTP(S) connections now use HTTP 1.1 Keep-Alive by default, improving throughput by reusing connections .
- Stable WebCrypto API: The WebCrypto API, excluding certain algorithms, is now stable, providing secure cryptographic operations .
- Enhanced Security Measures: Improved security defaults, vulnerability patching, dependency scanning, and enhanced TLS support .
- Tooling and Developer Experience: Improved developer tools, efficient package management, advanced debugging capabilities, and integrated profiling tools .
- Removed Support for DTrace/SystemTap/ETW: These tracing tools were deprecated due to maintenance complexity .
Node.js 20
- Permissions Model: Node.js 20 introduces an experimental permission model, allowing developers to restrict access to certain resources like file system, child processes, and worker threads .
- Single Executable Applications: This version supports building single executable applications, simplifying deployment and distribution .
- Updated V8 Engine: V8 is updated to version 11.0, bringing performance improvements and new JavaScript features .
- Enhanced Test Runner: The built-in test runner is further enhanced to provide a more robust testing environment .
- WebAssembly System Interface (WASI): Improved support for WASI, enabling better performance and compatibility for running WebAssembly modules outside the browser .
Breaking changes
https://github.com/nodejs/node/pull/45526
현재 node 20으로 업그레이드하면서 자바스크립트 런타임 팀에서는 문제를 일으킬 수 있는 변경 사항으로는 url.parse() 부분만 경고되고 있으며 별 다른 breaking points는 없는 것으로 사료된다.
추가적으로 v8.serialize와 같은 메서드로 따로 직렬화 과정을 거치는 로직도 없기에 v8 엔진 버전이 오른다고해서 문제가 될 부분은 없어보인다.
(사실 로컬에서는 이미 node 20버전을 사용하며 지금까지 테스트 및 FE 연동 과정을 거쳐왔기에 우선 로컬에선 적어도 별다른 문제점이 없을 것으로 보인다. 다만 실 배포 환경에서의 충분한 테스트는 필요하다.)
현재 인프라 분석
$ nvm install --lts
node: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by node)
node: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by node)
단, 현재 AWS AMI는 Amzaon linux 2를 사용 중이다.
따라서 현재 AMI로는 node 버전을 업그레이드 할 수 없다.
따라서 Amazon linux 2023(최신) AMI를 써야만 node.js 20 버전을 사용할 수 있다.
AMI upgrade
현재 prod, dev 모두 Amazon linux 2 (arm64)를 사용 중이며 커스텀 AMI로 구성되어있는데 이유는 cloudwatch, codedeploy agent 설치를 위함이다.
현재 구동 중인 서버의 다운타임 없이 마이그레이션 과정을 거쳐야한다.
어떻게 하면 좋을까? Best practice를 생각해보자.
Best practice
우선 현재 ASG를 사용하고 있으므로 이전 인스턴스 + Amazon linux 2023 AMI 버전 사용 및 node 20 업그레이드 과정을 거친 인스턴스를 동시에 띄우고 그 이후에 old 인스턴스를 terminate하면 될 것 같다.
- Amazon linux 2023 AMI를 이용한 시작 템플릿 새로운 버전 생성
- ASG 시작 템플릿 latest 버전으로 인스턴스 1개 실행
- 아래 스크립트 들 모두 입력 후 CodeDeploy, Cloudwatch agent 설치
- 정상 작동 확인 및 cloudwatch 로그 수집 정상 확인
- AMI 생성 및 기본 AMI 변경 (시작 템플릿 기본 버전 업그레이드)
- 이전 인스턴스 terminate
#!/bin/bash
set -e
sudo yum update -y
sudo yum install -y git htop
curl -o- <https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh> | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh"
nvm install 20.16.0
npm install -g pm2
pm2 install pm2-logrotate
sudo yum install -y amazon-cloudwatch-agent
sudo amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file://opt/aws/amazon-cloudwatch-agent/bin/config.json
sudo yum install -y ruby wget
sudo /opt/codedeploy-agent/bin/codedeploy-agent stop || true
sudo yum erase -y codedeploy-agent
wget <https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install>
chmod +x ./install
sudo ./install auto
sudo service codedeploy-agent status
// sudo vi /opt/aws/amazon-cloudwatch-agent/bin/config.json
{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "root"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
**"file_path": "/home/ec2-user/.pm2/logs/server.log",**
**"log_group_name": "server",**
"log_stream_name": "{instance_id}"
}
]
}
}
},
"metrics": {
"append_dimensions": {
"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
"ImageId": "${aws:ImageId}",
"InstanceId": "${aws:InstanceId}",
"InstanceType": "${aws:InstanceType}"
},
"metrics_collected": {
"mem": {
"measurement": [
"mem_used_percent"
],
"metrics_collection_interval": 60
}
}
}
}
💡 collect_list에 prod 환경에 맞게 file_path, log_group_name 지정!
위와 같은 과정을 진행하면 EC2의 AMI도 업그레이드를 진행하며 CodeDeploy agent, Cloudwatch agent 설치 및 node.js 20으로 업그레이드를 다운타임 없이 진행할 수 있게 되었다.