Author Archives: elegantcoder

ECS – API애플리케이션 – S3 웹리소스 고정아이피 구성

ECS로 구성된 애플리케이션의 웹 리소스의 고정아이피 구성이 필요했다. 가끔 유용하게 활용할 수 있는 사례라 구성도를 따로 그려봤다.

문제정의

  • 애플리케이션 서버는 ECS – Fargate – ALB 환경으로 구축
  • S3에 웹 리소스가 배포됨.
  • 애플리케이션 서버와 웹리소스에 고정아이피 주소 필요
  • 백엔드와의 연결은 HTTP만 사용해도 됨.

해결

  • Network Load Balancer에 고정아이피를 설정
  • NLB는 포트라우팅만 지원하므로 Nginx의 virtual server 설정으로 애플리케이션과 웹리소스 라우팅
  • Task Definition상 Nginx와 애플리케이션 서버를 하나에 둠
  • Nginx는 리버스프록시(localhost)로 애플리케이션 연결, S3와의 연결도 리모트 리버스프록시 사용.
  • S3는 Bucket Policy를 이용해 VPC고정으로 연결

구성도

참고

AWS ALB Target Group의 Draining 이 너무 길다면

최근 ECS를 도입하면서 Rolling Deploy 를 적용했다. 이전에는 EC2인스턴스마다 방문하면서 배포를 했다면 이제는 새로운 Fargate기반 태스크가 생성되면서 기존 태스크는 없애는 방식으로 배포된다.

테스트를 진행하다보니 ALB Target Group에 등록된 아이템이 Draining에 걸리는 시간이 긴 것이 눈에 들어왔다. 기본값으로 이 값은 300초가 주어지기 때문에 트래픽이 많지 않거나 커넥션을 오래 유지할 필요가 없다면 이 시간만큼 Fargate인스턴스를 더 사용하는 셈이다.

타겟그룹의 Draining에 걸리는 시간은 “Deregistration delay”항목에서 수정할 수 있다.

참고: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html#deregistration-delay

Docker Entrypoint와 쉘 함수의 사용

Docker 컨테이너는 Entrypoint를 가지고 있어서, 컨테이너를 하나의 실행파일처럼 동작할 수 있게 해준다.

An ENTRYPOINT allows you to configure a container that will run as an executable.

https://docs.docker.com/engine/reference/builder/#entrypoint

이를 이용해 때때로 활용하는 기법이 있는데, Entrypoint를 쉘 함수로 엮어 사용하는 방법이다.

최근 Jenkins에 AWSCLI v2를 사용해야할 일이 있었다. 이미 aws v1이 시스템 전체에 설치되어 운영되고 있기 때문에 명령어 충돌을 피하기 위해 이 방법을 사용했다.

#!/bin/env bash -x 

docker pull amazon/aws-cli
aws () { docker run --rm amazon/aws-cli [email protected] }

참고로 Interactive Shell에서는 alias를 사용해도 되지만, Non-Interactive 쉘에서 alias를 사용하려면 shopt 설정이 필요하다.

AWS MySQL Aurora 최대 접속수 수정방법

오랜만에 Aurora MySQL의 최대 접속수를 다시 지정했다. 개발용도의 데이터베이스는 사용량은 작지만 여러 프로젝트들이 connection pool 을 생성하니 기본 정의값보다 올려서 사용하는 경우가 종종있다. max_connections를 다시 지정한 파라미터 그룹으로 교체하면 된다. 이건 TIL이라 할 것도 없다.

하지만 글로 남기는건 10분이면 될 일을 1시간이나 헤맸기 때문.

  1. 클러스터 파라미터그룹과 인스턴스 파라미터 그룹 양쪽에 max_connections가 있다.
  2. 파라미터 수정 후 apply immediately로는 동작하지 않아서 reboot 후 적용되었다.

변경된 수치는 다음쿼리로 확인가능하다.

mysql> select @@max_connections;
+-------------------+
| @@max_connections |
+-------------------+
|               300 |
+-------------------+
1 row in set (0.00 sec)

Jenkins 역할기반 전략으로 프로젝트 권한지정하기

Jenkins의 Security Rule 중 Role Based 플러그인을 사용한 사용자 권한 설정을 했다.

Manage Jenkins > Configure Global Security 의 Authorization 에서 Role-Based Strategy를 선택한다.
(Enable security 상태)

Manage Jenkins > Configure Global Security > Authorization

이후  Manage Jenkins > Manage and Assign Roles 화면에서 역할을 추가하고 사용자에 역할을 지정할 수 있다.

Manage Jenkins > Manage and Assign Roles 메뉴
Manage Jenkins > Manage and Assign Roles 화면
Manage Roles역할을 추가, 편집, 삭제한다. 전역(Global)과 프로젝트별 역할이 있다.
Assign RolesManage Roles에서 생성된 역할을 사용자에게 지정한다.

역할에는 Global Roles(전역역할)과 Project Roles(프로젝트 역할)가 있다.
사용자는 기본으로 전역역할 중 하나를 가지고 프로젝트 역할을 별도로 가지게된다.

Manage Roles 지정방법

관리자용 역할(권한이름 admin)과 프로젝트별 역할(권한이름 Developers)을 분리했다고 가정하면 다음과 같이 Global Roles를 설정한다. Developers역할이 최소한 Overall / Read 권한을 가져야 워크스페이스 화면에 접근할 수 있다.

프로젝트 역할은 프로젝트 이름을 패턴으로 매칭한다. 매칭은 정규식패턴이 프로젝트 이름의 전체에 대해 대응해야한다. 작업했던 Jenkins의 프로젝트들은 모두 숫자를 기본으로 가지고 있어서 숫자매칭을 통해 지정했다.

Assign Roles지정

Assign Roles화면에서 Manage Roles에서 추가된 권한들을 확인할 수 있다. (사용자 이름을 추가한 후 확인할 수 있다.) 사용자 이름에 따른 Global roles와 Item roles를 지정할 수 있게 된다.