인프라 구성 포스팅에서 나름 비용을 줄였다고 생각했으나, 생각보다 비용이 많이나와 다시한번 구성을 간소화했다.
대략적으로 VPC와 EC2-기타 항목에서 예상보다 큰 지출이 발생하는것을 확인할 수 있었다.
각 서비스의 어느부분에서 비용이 크게 발생했는지 청구내역을 확인한다.
VPC 에서는 Endpoint(private link), EC2에서는 (NAT Gateway)가 문제였다.
데이터 사용량이 문제가 아니라 단순 사용시간에 대한 청구비용이었다.
위 기능들은 ecs 컨테이너들을 private subnet에 배포하여 보안을 강화하기 위한 수단이다.
위와같이 구성하면 외부(혹은 aws의 특정 서비스)와 통신하기위해 추가적인 설정이 필요하다. public ip를 할당받지 않았기때문에 외부와 통신할 수 없어 배포나 서비스 이용이 불가능한 상태가된다.
예를들어, 컨테이너 배포를 위해 도커 이미지를 가져와야한다. 하지만 ECR과 통신하기 위해서는 외부 인터넷과 통신(NAT Gateway를 통해 외부로 요청가능)할 수 있거나 Endpoint를 사용해야한다.
위와같은 상황이라 필요한 Endpoint를 (4개)사용하고 있었고, NAT Gateway도 (1개)사용하고 있었다.
개발환경인데 비용이 너무 과하다는 생각이 들었고 간소화를 시도했다.
위 두 서비스(Endpoint, NAT Gateway)를 이용하지 않기 위해서는 ecs 컨테이너가 public subnet에 public ip를 할당받아 배포되어야한다. 하지만 이 경우 서버가 공개되어있고 api gateway나 alb를 타지않고 직접 요청도 가능하다.
보안그룹에서 alb를 통해서만 요청이 들어올 수 있게 inbound를 설정했다. 그리고 Endpoint와 NAT Gateway를 제거했고, 정상적으로 배포 - 동작하는것을 확인했다.
위와같이 수정하고 CodePipeline 에서 에러가 발생한다. CodeBuild 에서 DOWNLOAD_SOURCE 단계에서
...
CLIENT_ERROR: error while downloading key daepyo_staging_pipel/SourceArti/DUoCOv5, error: RequestError: send request failed caused by: Get "https://codepipeline-ap-northeast-2-620045473331.s3.ap-northeast-2.amazonaws.com/daepyo_staging_pipel/SourceArti/DUoCOv5": dial tcp 52.219.146.47:443: i/o timeout for primary source and source version arn:aws:s3:::codepipeline-ap-northeast-2-620045473331/daepyo_staging_pipel/SourceArti/DUoCOv5
...
위와같은 에러가 발생했다. 확인해보니 인터넷에 연결되지 않아 발생하는 문제라고한다.
CodeBuild 환경 설정에 private subnet 만 설정하면 별 문제가 없을 줄 알았는데 다시한번 확인해보니 NAT Gateway 사용을 권장한다는 내용들을 확인할 수 있었다.
Amazon Virtual Private Cloud와 함께 AWS CodeBuild 사용
NAT Gateway 재생성, 라우팅테이블 재설정, CodeBuild의 서브넷 재설정 후 다시 테스트해보니 정상적으로 동작한다.
프록시 서버와 함께 AWS CodeBuild 사용 에서 프록시 서버를 사용해 NAT Gateway를 사용하지 않고도 CodeBuild를 사용하는 방법에 대해 안내하고있다. 추후 반영 할 예정이다.
NAT Gateway 비용이 너무 많이나와 다른 대안을 시도했다.
nat용 free-tier ec2 인스턴스를 생성해서 public subnet에 배치하고 라우팅 테이블에 private subnet -> public subnet(NAT Instance located) 설정했다.
private subnet 에 테스트용 ec2 인스턴스(public ip 할당되지 않음)를 생성하고, 해당 인스턴스에서 외부 인터넷으로 ping 테스트를 해봤는데 정상적으로 ping을 주고받는것을 확인할 수 있었다.
설정을 마치고 CodePipeline 배포를 시도했으나 빌드에서 에러가 발생했다.
CodeBuild -> 빌드 프로젝트 -> 프로젝트 명 -> 환경
에서
code build 를 보면 VPC 설정을 검증할 수 있는데, 인터넷 연결이 제대로 되지 않았다고 나온다.
이 문제에대한 해결책은 결국 찾지 못했고, 다른 방법을 적용시키기로 했다.
NAT Gateway를 사용해야했던 이유를 생각해보면 CodePipeline 을 사용해 자동배포를 구성하기 위해서였다. CodePipeline은 반드시 private subnet을 이용해야하고 외부 인터넷과의 통신이 필요하기 때문에 NAT Gateway를 사용하게 되었다. (NAT Instance 실패)
즉, CodePipeline -> Jenkins 로 툴을 바꾸면 위 문제를 해결할 수 있다.
하지만 jenkins 를 사용할때도 몇가지 문제점이 있었다.
t2.micro
인스턴스는 vCpu 1, member 1GB 자원을 가진다. 하지만 이 인스턴스에는 jenkins와 redis가 배포되어야하고, 빌드를 해야한다.
특히, 빌드에 필요한 자원으로는 많이 모자란 느낌이 있었다. swap 메모리 4gb를 설정하고 파이프라인을 실행시켰는데 첫 jar 빌드에 1시간
이 걸렸다.
코드, 의존성 변경 후 빌드시간을 다시 확인해봐야 할 것 같다.
우선, 변경사항없이 계속 진행했다.
jenkins를 사용하기때문에 외부(anywhere)에서 접속을 가능하게 설정했다.
작업환경이 일정하지 않기 때문에(ip 바뀜) jenkins가 완전 public 하게 운영되어 발생하는 보안문제들이 있을 수 있다.
CodePipeline 대신 Jenkins를 사용하기로 했다. 실제 운영이 아니라 개발환경이기 때문에 비용절감을 가장 우선시되었다.
aws ecs로 service-update 실행 시 이전 이미지로 배포된다면, ecs의 태스크 정의에 image_uri를 확인해야한다. latest가 아니라, 특정 tag를 가리키고 있을 가능성이 높다.