회고모음

SK OOO AWS 프로젝트를 마치며

악분 2022. 5. 15. 15:33
반응형

2022. 4월 파견간 곳이 계약이 임시만료되어 SK OOO 프로젝트에 긴급투입되었습니다. 4.18 ~ 5.2동안 프로젝트를 수행하여 무사히 완료되었습니다. 프로젝트 주제는 IDC로 운영하고 있는 데이터 파이프라인과 애플리케이션을 AWS클라우드로 마이그레이션 하는 작업이었습니다. 

AWS잘 모르는데 빨리 끝내야하는 프로젝트에 투입된 ... 

 

프로젝트를 진행하면서 기억에 남는 내용을 정리하려고 합니다.

 

1. 계정별 네트워크 분리와 연결

SK OOO 보안규정으로 네트워크 망을 계정별로 분리하고 연결시켰습니다.

 

보안팀 개발팀 운영팀의 의견 다툼이 있었던 부분이었습니다. 개발, 운영팀은 한 계정안에 VPC로 환경을 분리하고 싶었지만 보안팀은 내부규정때문에 환경별로 계정분리를 원했습니다. 결과적으로 보안을 준수해야하므로 개발, 운영별로 계정을 분리하고 랜딩존은 별도 계정으로 분리했습니다.

개발환경과 운영환경은 통신이 안되도록 분리했어야 했고 아래 글에서 어떻게 분리했는지 설명합니다.

 

1.1. Transit Gateway를 이용한 교차계정 네트워크 연결

[분리한 네트워크망끼리 통신하기 위해 연결 설정을 고민했습니다. 후보는 2개가 있었습니다.

  • 1. VPC Peering
  • 2. Transit Gateway

 

장기적으로 네트워크가 커질 것을 생각했기 때문에 Trnaist Gateway를 선택했습니다. 지금 당장은 VPC peering이 더 적합했지만 올해 말까지 다른 서비스들이 이관할 예정이라고 해서, 확장성을 생각하여 Transit Gateway를 선택했습니다.

 

transit gateway이론은 제 블로그 이전 글(https://malwareanalysis.tistory.com/325)에서 볼 수있습니다. 실습은 유투브(https://youtu.be/sN55nRo6eQs)에서 볼 수 있습니다.

 

1.2. 네트워크 사내 보안규정 준수

보안팀의 보안규정은 정말 많았는데요. 암호화 등 대부분 AWS리소스 설정페이지에서 버튼 몇번 클릭하면 쉽게 보안설정할 수 있었습니다. 하지만, 네트워크는 눈에 보이지 않아서 처음 접근할 때 어려웠습니다.

 

여러가지 네트워크 보안설정에서 말씀드리려고 합니다.

 

① 외부에서는 랜딩존만 접속 가능

보안규정으로 개발환경과 운영환경은 외부에서 접근이 불가능했습니다. 모든 것은 랜딩존을 거쳐서 개발 또는 운영환경에 접속해야 했습니다. 별다른 설정 없이 Transit Gateway 라우팅 테이블만 설정하면 쉽게 해결할 수 있었습니다. 랜딩존만 외부와 통신할 수 있도록 Internet Gateway, NAT Gateway를 구축했습니다.

 

개발환경과 운영환경은 Transit Gateway를 이용해서 랜딩존에 있는 NAT Gateway를 사용합니다. 지금 말씀드린 네트워크 트래픽은 AWS공식문서(https://docs.aws.amazon.com/ko_kr/vpc/latest/tgw/transit-gateway-nat-igw.html)에서도 예제로 다루고 있습니다.

 

② 개발환경과 운영환경은 통신 불가하도록 설정

개발환경과 운영환경은 서로 통신이 되지 않아야 했습니다. 반면, 랜딩존→개발환경, 랜딩존→운영환경은 통신이 가능합니다. 처음에 어떻게 막지라고 생각했는데, 사수가 NACL로 막자는 의견을 내서 NACL로 성공적으로 막았습니다.

 

③ WAF도입

랜딩존에 구축한 엔드포인트는 WAF를 이용하여 최소한의 보안 설정을 했습니다. 기밀상 어떤 엔드포인트가 있는지는 밝히지 못한점 이해바랍니다.

 

2. EKS클러스터

대부분의 애플리케이션은 쿠버네티스 클러스터에 배포했습니다. EKS를 사용하요 손쉽게 구축했습니다.

 

2.1 EKS 모니터링

메트릭은 prometheus를 사용했고 애플리케이션 pod로그는 s3에 저장했습니다. fluentbit를 이용하여 컨테이너 로그를 s3에 전송했습니다. 애플리케이션 에러로그는 cloutwatch API를 이용하여 코드단에서 exception, error로그를 별도로 수집했습니다. 로그 뷰어는 grafana를 사용했습니다.

 

2.2 보안규정으로 ingress직접 사용 불가

[챕터 1.2]에서 말씀드린 것처럼 개발/운영 환경에 있는 EKS는 직접 외부에서 접속하면 안됩니다. 그래서 ingress를 사용하지 못했고 랜딩존에 ELB를 구축하여 pod에 연결시켰습니다.

 

2.3 컨테이너이미지 저장소

컨테이너이미지는 ECR을 사용했습니다. 내부 보안규정때문에 랜딩존에 ECR를 구축했습니다. ECR 교차계정 설정으로 개발/운영 EKS가 랜딩존 ECR이미지를 pull할 수 있었습니다. 이미지는 최대 5개 revision만 저장하도록 ECR라이프사이클을 설정했습니다.

 

2.4 기타

여러가지 애플리케이션을 관리하기 위해 쉘스크립트를 만들고 cronjob, daemon set으로 적용했습니다.

 

3. 코드 파이프라인

3.1 파이프라인 구조

codecommit, codebuild, codepipeline을 이용해서 애플리케이션 CI/CD 파이프라인을 만들었습니다. EKS, lambda배포 파이프라인을 만들었는데요. 어려웠던 점은 역시 내부보안규정을 준수하기 위해 랜딩존에 코드파이프라인을 만드는 것이었습니다. assume-role을 이용하여 교차계정 배포 파이프라인을 구축했습니다.

 

3.2 파이프라인 정책

개발자 개발브랜치에 commit하면 자동으로 codepipeline이 동작하도록 설정했습니다. 반면, 운영브랜치에 commit하면 배포관리자가 승인해야 파이프라인이 실행되도록 했습니다.

 

3.3 EKS 파이프라인

kustomize를 이용하여 EKS배포 파이프라인을 구축했습니다. 아직 운영할 애플리케이션이 소수이고 서비스 축적경험이 없기 때문에 helm을 사용하지 않았습니다.

 

3.4 Lambda 파이프라인

Lambda는 SAM을 이용해서 배포했습니다.

 

4. kinesis

데이터 수집과 변환을 위해 AWS Kinesis를 사용했습니다. ingestor는 Kineis Datastream을 사용했고 데이터 변환은 Kineis Firehose와 Lambda, S3를 이용했습니다. 

 

구축만 하고 kinesis는 개발자가 거의 다뤘습니다. 옆에서 같이 모니터링한 결과로는 대규모(초당 몇만건 이상)에서는 Kinesis는 부적합하다고 느꼈습니다. kinesis의 할당량 제약사항이 많아서 application → kinesis흐름에서 오류가 많이 발생했습니다. 차라리 kafaka를 직접 구축해서 개발로 해결하는게 좋은 것 같습니다.

 

5. Snowflake

데이터 웨어하우스(warehouse)는 snowflake를 사용했습니다. 직접 구축한 건 아니고 snowflake엔지니어와 함께 호흡을 맞추면서 구축했습니다. snowflake가 이중 assume-role기능을 아직 지원하지 않아서 snowflake만 예외로 랜딩존을 거치지 않았습니다.

 

6. 교차계정 lambda호출

내부 보안규정으로 람다를 호출할 API Gateway를 랜딩존에 구축했습니다. 다행히 옵션(Link)으로 지원해줘서 교차계정 호출에 성공했습니다.

 

7. 개발 이슈

개발팀이 AWS리소스에 접근하기 위해 AWS SDK를 사용을 많이 했었습니다. 문제는 개발팀은 안된다하고 운영팀은 된다하는 상황이 있었습니다.

 

제가 중계역할을 맡았는데요!. 근본적인 문제원인은 의사소통이었습니다. AWS SDK는 개발자가 별다른 옵션을 설정하지 않으면 디폴트설정으로 SDK가 사용됩니다. 당연히 개발자는 AWS리소스 옵션을 잘 모르기 때문에 별다른 설정을 하지 않았었습니다.


대표적으로 S3 Policy설정입니다. 운영자가 설정한 S3 Policy옵션을 코드단에서 설정하지 않으면 SDK는 에러를 뱉습니다. 관리자 권한을 갖고 있더라도 옵션이 일치하지 않아서 오류가 발생합니다.

 

꼭! 개발자에게 사용할 AWS리소스를 알려줄 때 세부옵션을 알려줘야 합니다.

 

 

반응형