반응형
  • 모델 소스코드가 파일크기가 너무커서... 자체 GitLab을 만들기로 했다 (LFS용)

 

Resource Name / Desc
OS amazon-linux 2 (ARM64)
Computing t4g.medium
Storage gp3 ( 100GB ) 

 

Gitlab Install

sudo yum update -y

sudo yum install curl \
policycoreutils-python \
openssh-server \
openssh-clients \
perl \
posfix -y

sudo systemctl enable sshd
sudo systemctl start sshd

sudo systemctl enable postfix
sudo systemctl start postfix

## 필요한 경우 (X)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash

## 실제 도메인으로 변경 (domain 로 구성) - gitlab 설치
sudo EXTERNAL_URL="http://domain..." yum install -y gitlab-ce

 

Gitlab 설정

sudo vi /etc/gitlab/gitlab.rb
# 다음 설정들을 필요에 따라 수정:
# external_url 'http://Domain...'
# gitlab_rails['gitlab_shell_ssh_port'] = 22
# postgresql['shared_buffers'] = "256MB" # RAM에 따라 조정

# 설정 적용
sudo gitlab-ctl reconfigure
# 8GB swap memory 설정
sudo dd if=/dev/zero of=/swapfile bs=1M count=8192
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# 부팅시 자동 마운트
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# 백업 디렉토리 생성
sudo mkdir -p /var/opt/gitlab/backups
sudo chmod 700 /var/opt/gitlab/backups

# 백업 설정 (gitlab.rb에 추가)
sudo vi /etc/gitlab/gitlab.rb

# 다음 라인 추가:
# gitlab_rails['backup_path'] = "/var/opt/gitlab/backups"
# gitlab_rails['backup_keep_time'] = 604800 # 7일

# 설정 적용
sudo gitlab-ctl reconfigure
sudo cat /etc/gitlab/initial_root_password ## 초기설정 시 비밀번호 확인

# /etc/gitlab/gitlab.rb에 추가
postgresql['shared_buffers'] = "2GB"  # RAM의 25%
nginx['worker_processes'] = 4         # CPU 코어 수만큼
nginx['worker_connections'] = 2048

# /etc/gitlab/gitlab.rb에 추가
gitlab_rails['env'] = {
  'MALLOC_ARENA_MAX' => 2
}

 

Gitlab SMTP + AWS SES 설정

// /etc/gitlab/gitlab.rb
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "email-smtp.ap-northeast-2.amazonaws.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "SES에서 생성한 SMTP 사용자 이름"
gitlab_rails['smtp_password'] = "SES에서 생성한 SMTP 비밀번호"
gitlab_rails['smtp_domain'] = "SES에서 설정한 도메인"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_tls'] = true
gitlab_rails['smtp_force_ssl'] = true

# 발신자명을 설정하고 싶다면 다음을 추가
gitlab_rails['gitlab_email_from'] = '발신자 이메일 도메인'

// 저장 후 설정 - 재부팅
sudo gitlab-ctl reconfigure

 

Gitlab Status 확인

sudo gitlab-ctl status | cat
반응형
반응형

개요

  • ECS가 뭔데?
  • Kubernetest가 정답인가?
  • 그럼에도 왜 ECS Fargate를 사용하는가?
  • ECS Fargate 를 잘 활용하는 방법

 


ECS 가 뭔데?

 

간단하다. ECS ( Elastic Container Service )

Container 기반 서비스를 AWS 내 쉽게 띄우기 위한 하나의 시스템이다.

어쩌면 Docker 기반의 구성된 서비스를 굉장히 쉽게 만들어서 Cloud 시스템에 구축할 수 있겠는가? -> 그게 바로 ECS라고 생각한다

 


ECS를 사용하면 뭐가 좋은가?

보통 ECS를 얘기하면, 매번 나오는게 EKS와 비교하게 된다.

하지만 그전에 간단하게 Docker 기반 시스템을 구축하기 위한 서비스를 어느정도 나열해보면 아래와 같다.

 

Layer로 나눠본 Container 기반 시스템 구성


Layer 1. Docker를 쓴다 - EC2에 올려서 쓴다

뭐... 굉장히 심플하다

Dockerfile을 구성하든, docker-compose를 구성하든 그 자체로 EC2에 올려서 서비스를 한다.

정말 간단하다는 말 외에는 따로 할 말이 없다

하지만 그 간단함 때문에 -> 많은 부분들이 고민이 되는 부분이다

모니터링, 로그, 배포, Self Healing, Rollback 모든 부분에서 손수 수작업을 진행해야 한다.


 Layer 2. Orchestration Tool을 사용하되, EC2를 사용한다

보통 production 즉, 회사내에서 서비스를 운영하는 단계라면 Layer 2 에서 시작하는 것 같다.

기본적인 Orchestration 을 사용하되, ECS , EKS 를 EC2를 host로 사용한다.

물론 나쁘진 않다. 하지만 나는 Serverless 더 선호한다. ( 비용 및 효율성 측면에서 어쩔 땐 EC2 기반이 좋을 때가 존재함 )


Layer 3. Serverless 형태로 사용한다

Serverless...

마법의 단어다. 대부분의 고민거리를 해결해준다.

물론 Serverless 가 모든 고민거리, 기술적 이슈들을 해결해주진 않는다.

Serverless 이기에 겪는 문제도 있고, 여전히 손수 수작업으로 해줘야 할 부분도 존재한다.

그럼에도 불구하고 관리하기 편하기때문에 Devosp Engineer 입장에서는 업무 시간에 다른부분을 더 강화할 시간을 벌게된다.

 


Kubernetes가 정답인가?

대부분의 회사에서 사용하는 스택이나, 개발자 취업 사이트를 보면 Kubernetes를 사용한다. 

거의 무조건 사용하고, 사용 / 활용할 수 있는 사람을 뽑는다.

왜 그럴까? ECS 보다 Kubernets가 더 좋은 점은 무엇일까? (경험기반...)

 


EKS는 자유롭다

EKS 만큼 자유로운 시스템은 또 없다.

여기서 자유롭다라는 뜻은, 따로 vendor에 구애 받지 않는다는 얘기다.

 

K8S 는 GCP, AWS, Azure Multi Cloud내에 GKE, EKS, AKE 여러개로 불리기도하고, 온프레미스에서도

동작방식이 같아 흔히 Cloud Lock In 현상을 줄일 수 있다.

 

ECS만 봐도 AWS에서만 사용가능하고,

GCP에서는 Cloud Run, App Engine 같은 기능을 써야하기 때문에 그것의 비해서는 자유롭다.

 


배포 전략이 자유롭다 (CNCF)

ECS는 기본적인 Rolling Update, Code Deploy를 사용해서 Blue/Green, Canary 배포방식을 사용할 수 있다.

하지만 좀더 트래픽을 세밀하게 조절해서 배포하는 방안들의 대해서는 굉장히 많은 노력이 필요하다.

 

그에 반해, K8s 같은 경우에는 Traffic Splitting 같은 배포전략을 Istio로 한다거나, ArgoCD 같은 Tool로 굉장히 

다양한 방법의 배포 / Rollback 기능을 활용할 수 있다.

 


AutoScaling 시, 세부적으로 Control 이 가능하다

ECS도 이건 가능하다. 불가능하지는 않다.

간단하게 CPU, Memory 기반으로도 AutoScaling 가능하고

CloudWatch를 연동해서 SQS, SNS, ALB의 지표등을 확인해서 다양한 AutoScaling 전략을 사용할 수 있다.

 

하지만 K8s 같은 경우에는 더 세밀하게 조정이 가능한데 HPA & VPA 을 사용하면 CPU, Memory 기반으로 자동확장이 더 유연하다.

그리고 애초에 Node , Pod 기반으로 동작하기 때문에 당연한 얘기기도 하다

 

추가적으로 Karpenter 이놈을 쓰면 굉장히 도움이 많이 때문에 좀 부럽긴하다.

나중에 Kaprenter 기능을 Deep 하게 공부해서 글써보면 도움이 많이 될지도...

 


Addons가 너무 훌륭하다 (CNCF)

사실 이 부분은 넘사벽이라고 생각하는데,

ECS도 AWS 내부서비스와 조합은 훌륭하다.

하지만 K8s는 CNCF 내 오픈소스와 다양한 툴링이 가능하다.

 

어떤것이 좋다. 어떤것이 있다. 하나하나 세부적으로 얘기하지 않아도 

정말 좋은 오픈소스나 툴이 있다고 하면 대부분 K8S 를 기반으로 만들어져 있다.

 


그럼에도 왜 ECS Fargate 를 사용하는가?

간단하다...

쉽다...

아주 적은 인원으로, 여러개의 서비스를 구축할 때 이만한건 없는 것 같다.

내가 생각했을 때 굉장히 좋은 시스템이고 Lock In이 걸렸다면 어쩔수 없지만...

당분간 AWS 만 쓸건데, Lock In 정도야 ... 큰 문제일까 싶다.

 


그래도 나름대로 비용 효율성

AWS내에서 K8s를 사용하려면 EKS 옵션이 있는데,

이건 Cluster 비용이 별도로 나간다. 큰 비용은 아니지만 월에 $ 70 ~ 80 발생한다.

하지만 ECS는 Cluster를 여러개 만들어도 공짜이기 때문에 짱짱맨이다.

 


나는 인프라 이런거 모르고 그냥 개발에만 집중할래

딱 이런 사람들에게는 최적의 솔루션이 아닌가 싶다.

ECS Fargate 를 사용하면 정말 많은것을 해준다.

Self Healing도 해주고, Auto Scaling도 너무 쉽고, ALB나 Event Bridge pipe를 사용해서 여러 서비스와 조합도 가능하다.

그리고 Scale-up 하는것도 굉장히 옵션이 다양하기 때문에 GPU 기반이나 LLM을 크게 돌릴것이 아니라면 더할나위 없다.

 

 

ECS Fargate 를 잘 활용하는 방법

솔직히 개인적인 경험으로는 기존 ECS Fargate를 사용해도 큰 문제는 없지만

몇몇 더 잘 사용하면 기존보다 2~3배 가량 더 잘 사용할 수 있다고 생각한다.

 


비용 효율화 (SPOT 인스턴스)

ECS Fargate OS System은 총 2가지로 나뉜다

  • ARM
  • x86_64

이때 x86_64를 사용하게되면 SPOT 인스턴스를 사용할 수 있다.

물론 SPOT 인스턴스 자체가 동작하는 원리는 AWS 내 노는 컴퓨팅을 잠시 빌려써서 다시 임대하는 형식이기 때문에,

가끔은 죽을 수도 있다.

 

그렇기에 개발 / 스테이징 / 데이터 배치 같은 가끔은 죽어도 되는 애들은 SPOT 인스턴스를 고려해보는것도 좋은것같다.


ECS Fargate 가 아닌, EC2 on ECS도 고려해보자

너무 위에서 ECS Fargate 만 얘기했지만,

EC2에 ECS 사용하는 옵션도 굉장히 좋다.

 

GPU, 그외 다른 성격을 가진 Computing 유형도 ECS를 사용해서 편하게 배포하고 구성하고를 사용할 수 있다 (ecs agent)

추가적으로 보통 ECS Fargate 에서는 서비스 당 ENI를 하나씩 가지게된다 (network mode)

 

하지만 EC2 on ECS는 다양한 network mode를 선택 할 수 있다.

network mode 설명
bridge - EC2 내부에 Docker bridge 사용
- Container 간 NAT 통신
host - 컨테이너나 EC2의 네트워크를 직접사용 (IP공유)
- EC2에 바인딩 된 포트 그대로 사용
- 보안이슈가 존재

 

그래서 고성능 네트워크가 필요하다거나, 특정 포트를 컨테이너 내에서 직접 노출한다거나,

로드밸런서가 아닌 EIP로 바로 트래픽을 받는 어느정도 특수한 환경일 경우, 위와같이 처리할 수 있다.

 

결론

정말 대규모의 시스템이나 비용효율적인 방안들을 검토해서 구성을 해야한다면 K8S 가 정답일 수도 있다고 생각한다.

하지만 본인 내지, 회사의 도메인과 서비스를 이해하고 현재 어느수준에 있는지를 파악한다면 어떤 솔루션이 적합한지 한번쯤은 더 생각해볼수 있지 않을까 생각한다.

 

물론 나도 K8S를 하고싶지만, 현재 ECS 를 사용하면서도 회사의 비즈니스는 정말 잘 굴러간다.

그렇다고 ECS -> K8S 갈아탄다고 해서 서비스 안정성이 올라가냐?, 트래픽이 올라가냐? 그건 아니다.

 

하지만 K8S로 마이그레이션하거나 진행해야 할때는 있을거다.

그때를 위해서 공부는 꾸준히 해놓자...

 

 

반응형

'Architecture > Computing' 카테고리의 다른 글

self hosted 로 gitlab 설치하기  (0) 2025.03.27
python 앱 빌드시간 단축  (0) 2025.01.12
반응형

개요

  • python 앱 빌드할때 시간이 너무 오래걸린다
  • 빌드 시간 단축하는 방법
  • 결과
  • 추후 고민해야 할 부분

 


python 앱 빌드할때 시간이 너무 오래걸린다

최근 회사내에서 AI 서비스를 운영하면서,

Build 하는시간이 너무 오래걸렸다. (평균 20분)

 

 

이건 뭐... 배포하는데 20분씩 걸리는건 조금... 아주 많이 비효율적이었다.

배포만 20분이지 중간에 실패하면 30~40분씩 걸린다 (... CloudFormation 때문인것도 있음)

 


문제인식

해당 앱의 전체적인 문제점을 파악해보았다.

  • Docker Container Image 용량이 2GB 육박함 (Multi Staging임에도 불구하고)
  • Build 하는 과정에서 python package 버전이 명시되지 않아서 설치하는 과정에서 굉장히 오래걸림
  • docker cache가 제대로 되고 있지 않음

먼저 해결할 수 있는 부분 선택하기

  • Docker Container Image 용량이 2GB 육박함 (Multi Staging임에도 불구하고)
    • 이부분은 dive 를 사용해서 파악해볼 수는 있지만 시간이 꽤 오래걸릴것같아 pass
    • 추후에는 고쳐져야 할 문제, 결국 2GB 데이터의 Data Transfer 비용도 상당할것으로 예상됨
    • https://github.com/wagoodman/dive 
  • Build 하는 과정에서 python package 버전이 명시되지 않아서 설치하는 과정에서 굉장히 오래걸림 (선택됨)
    • package 버전을 명시한다면 빌드시간을 단축할 수 있을 것 같음
  • docker cache가 제대로 되고 있지 않음 (선택됨)
    • docker cache 가 제대로 이뤄지게끔 Docker 명령어를 수정하기로 함

 


빌드 시간 단축하는 방법


Build 하는 과정에서 python package 버전이 명시되지 않아서 설치하는 과정에서 굉장히 오래걸림

사실 난 파이썬 잘 모른다.

그래서 package 버전을 명시하려니... 와... 에러가 너무 많이남

python 자체가 이렇게 버전별로 dependency가 있는지 처음알았음

 

그래서 꼼수를 하나썼음...

"아니... 지금 운영상에 올라가있는 서비스 package 버전을 알면 되잖아" -> correct

 

2가지 방법이 존재한다.

  • 현재 구동중인 서비스는 ECS로 운영중이고, ssm exec 명령어를 사용하여 확인
aws ecs execute-command --profile PROFLE_NAME --region REGION_NAME\
  --cluster CLUSTER_NAME \
  --task TASK_ID \
  --container CONTAINER_NAME \
  --command "/bin/sh" \
  --interactive
  • docker image 를 다운 받아서, exec로 버전 파악하기 (이걸로 함)
## 기존 이미지 다운로드
docker pull [ecr에 올라가있는 image url]:latest

## sleep infinity로 run
docker run [image-url] sleep infinity

## exec로 접근
docker exec -it [container-id] /bin/sh

## package 버전확인
pip show [package]

 

 

나는 2번째 방법을 사용해서, 

전체 package에 대한 버전을 확인하고 명시하였다.

 


docker cache가 제대로 되고 있지 않음

Docker 이미지 구성하는 과정에서 Cache가 잘 되고 있지 않았다. 

물론 Layer Cache가 구성되어있지만, 하루에한번 Action에 잔존되어있는 이미지를 삭제하게된다면

Cache 없이 Image를 Build하였다.

 

그래서 build 명령어에 cache-from 추가하였다.

docker build -t sena -f Dockerfile.sena --cache-from [ecr iamge url] .

 

결과

일단 Build가 5분안에 끝났다. (원래는 10분 ~ 13분 가량 소요되었음)

배포까지 하면 8분안에 끝날듯하다 ... 현재는 다른이슈로 결과창을.... (추후에)

 

추후 고민해야 할 부분

현재 Docker Image가 2GB 정도된다. 

Image 경량화작업을 진행해야 할듯하다... 언제나 작업할건 참 많은것 같다.

반응형

+ Recent posts