ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Amazon ECR 와 PrivateLink
    CloudEngineering (AWS)/EKS 2022. 2. 12. 19:37

    "우리 Onprem에 있는 Jenkins 서버에서 ECR을 접근해야 하는데 접근이 안되네요 왜 그런 거죠?" 이 고객사는 Jenkins 서버를 VPN이 연결되어 있는 Onprem에 위치해 놓았다. 그리고 외부 통신은 제한을 해 둔 것이다. 외부 통신이 제한된 환경에서 왜 ECR에 접근되지 않을까?

    ECR 접근

    ECR에 대해 Docker 클라이언트를 인증할 때의 커맨드이다.

    aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ************.dkr.ecr.ap-northeast-2.amazonaws.com

    위의 커맨드 중 ****. dkr.ecr.ap-northeast-2.amazonaws.com는 서울 리전에 있는 리포지토리 주소이다. 개인 계정 ID와 리전으로 이루어져 있다. ECR 주소와 통신할 때 무엇과 통신하는지 궁금하다. nslookup으로 던져보자.

    $ nslookup ************.dkr.ecr.ap-northeast-2.amazonaws.com
    Server:         10.129.0.2
    Address:        10.129.0.2#53
    
    Non-authoritative answer:
    ************.dkr.ecr.ap-northeast-2.amazonaws.com       
    canonical name = nlb3-3c964******a0f79.elb.ap-northeast-2.amazonaws.com.
    Name:   nlb3-3c964******a0f79.elb.ap-northeast-2.amazonaws.com
    Address: 13.***.118.***

    CNAME으로 구성한 적도 없는 NLB DNS 주소가 반환되는 것을 확인할 수 있다. 아래의 사진은 아무런 구성을 하지 않고 VPC 내부에서 ECR을 접근할 때의 네트워크 흐름이다. ECR은 계정에서 만들기 때문에 계정 내에 종속한다고 착각할 수 있지만 계정 밖의 AWS 내부에서 리소스를 별도로 관리한다고 생각하면 된다. ECR도 엄연한 서버이기 때문에 Internet Gateway를 통해서 ECR에 접근할 때 AWS내부적으로 NLB를 통해 데이터를 수신받는 것이다.

     

    https://aws.amazon.com/ko/blogs/korea/setting-up-aws-privatelink-for-amazon-ecs-and-amazon-ecr/

    위에서 말한 것처럼 기존 구성은 Internet Gateway로 외부 통신하여 ECR에 인증받는 방식인데 IGW가 없는 환경이라면 어떻게 해야 할까? ECR과 통신을 할 수 없으니 사용을 할 수 없는 것일까? 아래를 보자.

    https://aws.amazon.com/ko/blogs/korea/setting-up-aws-privatelink-for-amazon-ecs-and-amazon-ecr/

    위의 구조처럼 AWS PrivateLink를 사용하여 ECR에 내부 통신하여 접근이 가능하다. AWS PrivateLink는 퍼블릭 인터넷에 트래픽을 노출하지 않고도 VPC, AWS 서비스 및 온프레미스 네트워크 간에 안전한 비공개 연결을 제공하는 서비스이다. 즉, AWS 서비스인 ECR을 프라이빗하게 연결하도록 도와주는 서비스인 것이다.

    PrivateLink

    엔드포인트 생성

    ecr.api에 대한 엔드포인트를 생성한다. ECR에 접근하기 위해서 인증 토큰을 검색하고 레지스트리에 대해 Docker 클라이언트를 인증하는 과정이 필요하다.

     

    위의 설정 값 외의 정책이나 SG로 엔드포인트에 접근할 수 있는 IP나 사용자를 세부적으로 컨트롤할 수 있다. 자세한 부분은 아래를 문서를 참고하면 될 것이다.

     

    Control access to services with VPC endpoints - Amazon Virtual Private Cloud

    Control access to services with VPC endpoints When you create an interface or gateway endpoint, you can attach an endpoint policy to it that controls access to the service to which you are connecting. Endpoint policies must be written in JSON format. Not a

    docs.aws.amazon.com

    private 서브넷에 엔드포인트를 생성한 뒤에 vpc 내부에서 도커 레지스트리가 어떻게 resolve 되는지 확인해 보았다. ecr.dkr 엔드포인트와 ecr.api 엔트포인트 간에 구분이 명확하게 가지 않을 수 있다.

    ecr.dkr은 push 및 pull과 같은 Docker 클라이언트 명령에 사용하는 엔드포인트이며 ecr.api엔드포인트는 ECR API에 대한 호출로 AWS CLI 또는 AWS SDK를 사용할 때 기본 값이다. 

     

    ECR Docker 클라이언트 인증

    aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ************.dkr.ecr.ap-northeast-2.amazonaws.com

    위의 명령어를 보자 앞서 AWS CLI를 이용한 get-login-password는 기본적으로 api.ecr.ap-northeast-2.amazonaws.com 엔드포인트를 통해 인증을 받을 것이다. 그렇다면 privateLink를 생성했으니 내부 통신이 가능하게 된 것인지 확인해보자.   

    $ nslookup api.ecr.ap-northeast-2.amazonaws.com
    Server:         10.129.0.2
    Address:        10.129.0.2#53
    
    Non-authoritative answer:
    Name:   api.ecr.ap-northeast-2.amazonaws.com
    Address: 10.129.253.51
    Name:   api.ecr.ap-northeast-2.amazonaws.com
    Address: 10.129.184.152

    VPC 내부 서버에서 확인 결과 엔드포인트가 로컬 IP를 반환하는 것을 확인할 수 있었다.

     

    Onprem에서 ECR 인증

    하지만 VPN이 연결된 Onprem 서버에서는 api.ecr.ap-northeast-2.amazonaws.com 엔드포인트에 대한 resolve가 로컬 IP를 반환하지 않을 것이다. 엔드포인트는 VPC 내부에서만 적용되기 때문에 VPN이 연결되었다고 해도 로컬 IP를 반환해 주진 않는다. 엔드포인트를 생성하면 기존의 엔드포인트 외에 다른 DNS를 별도로 생성해준다. 아래와 같은 형식인데 Onprem이나 VPC 외부, local에서도 동일한 로컬 IP를 반환해주는 DNS이다. 

    $ nslookup vpce-*****************-55ubbw4e.api.ecr.ap-northeast-2.vpce.amazonaws.com
    Server:         10.129.0.2
    Address:        10.129.0.2#53
    
    Non-authoritative answer:
    Name:   vpce-*****************-55ubbw4e.api.ecr.ap-northeast-2.vpce.amazonaws.com
    Address: 10.129.184.152
    Name:   vpce-*****************-55ubbw4e.api.ecr.ap-northeast-2.vpce.amazonaws.com
    Address: 10.129.253.51

    그렇다면 Onprem에 위치한 Jenkins 서버에서 ECR에 인증하기 위한 명령어는 어떻게 될까? aws ecr 명령어에 --endpoint-url 값을 별도로 지정하는 인자 값이 있다. 아래와 같은 형식으로 Jenkins 서버에서 aws cli를 사용해 ECR에 로그인할 수 있으니 참고해서 사용하면 될 것이다.

    aws ecr get-login-password --region ap-northeast-2 --endpoint-url https://vpce-*****************-55ubbw4e.api.ecr.ap-northeast-2.vpce.amazonaws.com | docker login --username AWS --password-stdin ************.dkr.ecr.ap-northeast-2.amazonaws.com

    마치며


    이 외에도 외부 통신이 제한된 Onprem에서 VPN 만으로 ECR에 접근하는 방식은 꽤나 번거로울 것이다. Amazon EKS는 사용하나 CI/CD 는 Onprem에서 적용되어 있을 경우 EKS의 엔드포인트 또한 로컬 통신으로 잡아주어야 하는데 EKS는 PrivateLink가 별도로 없기 때문에 서버의 hosts 파일에 맵핑해주던가 하는 방식의 적용이 필요할 것이다. 언제나 네트워크 통신에 대한 고민은 항상 존재하는 것 같다. 다음에는 교차 계정의 ECR 접근 방식에 대해 포스팅해보려고 한다.

    'CloudEngineering (AWS) > EKS' 카테고리의 다른 글

    Cluster Autoscaler (CA)  (0) 2021.12.03
    EKS 환경에서 kubeconfig 적용하기  (0) 2021.11.05
    Custom AMI 로 EKS NodeGroup 배포  (0) 2021.09.04
    EKS 환경에서 RBAC 적용하기  (1) 2021.07.21
    EKS Pod 수 제한  (2) 2021.07.16

    댓글

Designed by Tistory.