Amazon ECS 에 λŒ€ν•΄μ„œ 쑰금 더 μ•Œμ•„λ³΄λ„λ‘ ν•˜μž.

νƒœμŠ€ν¬ awsvpc λ„€νŠΈμ›Œν¬ λͺ¨λ“œμ™€ 탄λ ₯적 λ„€νŠΈμ›Œν¬ μΈν„°νŽ˜μ΄μŠ€(ENI)

Fargate와 EC2 μΈμŠ€ν„΄μŠ€ λͺ¨λ‘ awsvpc λ„€νŠΈμ›Œν¬ λͺ¨λ“œμ—μ„œλŠ” 프라이빗 IP μ£Όμ†Œκ°€ ENI둜 ν• λ‹Ήλœλ‹€. μΈμŠ€ν„΄μŠ€ μœ ν˜•μ— 따라 μ΅œλŒ€ ENI ν• λ‹Ή κ°œμˆ˜κ°€ μ œν•œλ˜λ―€λ‘œ μ£Όμ˜ν•΄μ•Όν•œλ‹€. μ΄λ•Œ, ECS μ„œλΉ„μŠ€ 계정 μ„€μ •μ—μ„œ awsVpcTrunkingλ₯Ό ν™œμ„±ν™”ν•˜λŠ” 경우 EC2 μΈμŠ€ν„΄μŠ€μ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” ENI 개수 μ œν•œμ΄ λŠ˜μ–΄λ‚œλ‹€.

aws ec2 describe-instance-types \
    --filters "Name=instance-type,Values=c6g.*" \
    --query "InstanceTypes[].{ \
        Type: InstanceType, \
        MaxENI: NetworkInfo.MaximumNetworkInterfaces, \
        IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" \
    --output table

----------------------------------------
|         DescribeInstanceTypes        |
+----------+----------+----------------+
| IPv4addr | MaxENI   |     Type       |
+----------+----------+----------------+
|  50      |  15      |  c6g.16xlarge  |
|  10      |  3       |  c6g.large     |
|  15      |  4       |  c6g.xlarge    |
|  30      |  8       |  c6g.12xlarge  |
|  4       |  2       |  c6g.medium    |
|  50      |  15      |  c6g.metal     |
|  30      |  8       |  c6g.8xlarge   |
|  30      |  8       |  c6g.4xlarge   |
|  15      |  4       |  c6g.2xlarge   |
+----------+----------+----------------+

EC2 μΈμŠ€ν„΄μŠ€μ™€ λ‹€λ₯΄κ²Œ Fargate μ—μ„œλŠ” ENI ν™•μž₯을 μ§€μ›ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

νƒœμŠ€ν¬ bridge λ„€νŠΈμ›Œν¬ λͺ¨λ“œμ™€ 동적 포트 맀핑

Amazon ECS 곡식 λ¬Έμ„œμ—μ„œλŠ” EC2 μΈμŠ€ν„΄μŠ€μ—μ„œλ„ awsvpc λ„€νŠΈμ›Œν¬ λͺ¨λ“œλ₯Ό ꢌμž₯ν•©λ‹ˆλ‹€. EC2 μΈμŠ€ν„΄μŠ€μ˜ bridge λ„€νŠΈμ›Œν¬ λͺ¨λ“œμ—μ„œλŠ” 호슀트 포트λ₯Ό μ§€μ •ν•˜μ§€ μ•Šλ„λ‘ ν•˜μ—¬ 동적 포트 맀핑(Dynamic port mapping)이 κ°€λŠ₯ν•˜λ―€λ‘œ λ™μΌν•œ 포트λ₯Ό μ‚¬μš©ν•˜λŠ” μ„œλ‘œ λ‹€λ₯Έ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μš΄μ˜ν•˜λŠ”λ° 도움이 될 것 κ°™λ‹€.

동적 맀핑을 κ΅¬μ„±ν•˜λ €λŠ” 경우 EC2 μΈμŠ€ν„΄μŠ€κ°€ κ°€μ§€λŠ” λ³΄μ•ˆ 그룹이 μž„μ‹œ 포트 λ²”μœ„(49153-65535 와 32768-61000)에 λŒ€ν•œ μΈλ°”μš΄λ“œ νŠΈλž˜ν”½μ„ ν—ˆμš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.

μ  ν‚¨μŠ€ νŒŒμ΄ν”„λΌμΈκ³Ό AWS ECR ν”ŒλŸ¬κ·ΈμΈ

Amazon ECR 프라이빗 λ¦¬νŒŒμ§€ν† λ¦¬λ‘œ 이미지λ₯Ό ν‘Έμ‹œν•  수 μžˆλŠ” IAM κΆŒν•œμ„ λ§Œλ“€κ±°λ‚˜ EC2InstanceProfileForImageBuilderECRContainerBuilds 정책을 κ°€μ§€λŠ” IAM μ‚¬μš©μžλ₯Ό λ§Œλ“€λ©΄ μ  ν‚¨μŠ€μ—μ„œ Amazon ECR λ¦¬νŒŒμ§€ν† λ¦¬λ‘œ λΉŒλ“œλœ 이미지λ₯Ό ν‘Έμ‹œν•  수 μžˆλ‹€.

μ  ν‚¨μŠ€ μ„œλ²„μ— AWS CLIλ₯Ό μ„€μΉ˜ν•΄λ„ λ˜μ§€λ§Œ μ»¨ν…Œμ΄λ„ˆ 기반의 inbound-agent λ˜λŠ” Cloud 둜 docker-agent 둜 λΉŒλ“œ νŒŒμ΄ν”„λΌμΈμ„ μˆ˜ν–‰ν•˜λŠ” 경우 aws-cli κ°€ μ„€μΉ˜λ˜μ§€ μ•Šμ€ μƒνƒœμΌ 수 μžˆλ‹€. λ”°λΌμ„œ, AWS Credentails ν”ŒλŸ¬κ·ΈμΈκ³Ό ν•¨κ»˜ Amazon ECR ν”ŒλŸ¬κ·ΈμΈμ„ μ‚¬μš©ν•˜μ—¬ ECR λ¦¬νŒŒμ§€ν† λ¦¬λ‘œ 이미지λ₯Ό ν‘Έμ‹œν•˜λŠ” νŒŒμ΄ν”„λΌμΈμ„ μž‘μ„±ν•˜λŠ” 것을 ꢌμž₯ν•œλ‹€.

λ‹€μŒμ€ μ  ν‚¨μŠ€ νŒŒμ΄ν”„λΌμΈ μž‘μ„±μ— λŒ€ν•œ μ˜ˆμ‹œμ΄λ‹€.

pipeline {
    agent {
        label 'docker-agent'
    }
    
    tools {
        jdk "JDK17"
    }

    properties {
        string(name: 'buildTag', defaultValue: 'latest', description: 'build version')
    }
    
    environment {
        registry = 'xxxxx.dkr.ecr.ap-northeast-2.amazonaws.com'
        repository = 'xxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/sample-app'
        registryCredential = 'mambo-ecr-builder'
        registryRegion = 'ap-northeast-2' // seoul
        buildImage = ''
        JAVA_HOME = "tool JDK17"
    }

    stages {
        
        stage('Prepare') {
            steps {
                echo 'Cloning Repository'
                git branch: 'main', 
                    credentialsId: 'jenkins-git-token', 
                    url: 'https://github.com/xxx/ecs-demo.git'
            }
            post {
                failure {
                    error 'This pipeline stops here...'
                }
            }
        }
        
        stage('Build Gradle') {
            steps {
                echo 'Build Gradle'

                dir('./sample-app'){
                    sh '''
                        pwd
                        chmod +x ./gradlew
                        ./gradlew build ecsbuild
                    '''
                }
            }
            post {
                failure {
                    error 'This pipeline stops here...'
                }
            }
        }
        
        stage('Build image') {
            steps {
                dir('./sample-app') {
                    script {
                        buildImage = docker.build("sample-app:${buildTag}", "--build-arg BUILD_VERSION=${buildTag} .")
                    }
                }
            }
        }
        
        stage('Push image') {
            steps {
                script {
                    // sh 'docker images'
                    
                    docker.withRegistry("https://${registry}", "ecr:${registryRegion}:${registryCredential}") {
                        buildImage.push()
                    }
                }
            }
        }
        
        stage('Cleanup docker image') {
            steps {
                script {
                    sh '''
                        docker rmi sample-app:latest
                        docker rmi $repository:$buildTag
                    '''
                }
            }
        }

    }
}

λ§Œμ•½, μ  ν‚¨μŠ€ νŒŒμ΄ν”„λΌμΈμ—μ„œ ERROR: could not find credentials matching ecr:ap-northeast2:aws_credential_id 와 같은 였λ₯˜κ°€ λ‚œλ‹€λ©΄ μ  ν‚¨μŠ€μ— Amazon ECR ν”ŒλŸ¬κ·ΈμΈμ„ μ„€μΉ˜ν–ˆλŠ”μ§€ ν™•μΈν•˜μ‹œκΈ° λ°”λžλ‹ˆλ‹€.

Amazon ECS 와 μΈν„°νŽ˜μ΄μŠ€ VPC μ—”λ“œν¬μΈνŠΈ

μŠ€νƒ€νŠΈμ—… μ—”μ§€λ‹ˆμ–΄μ˜ AWS λΉ„μš© μ΅œμ ν™” κ²½ν—˜κΈ°μ²˜λŸΌ 데브옡슀 μ—”μ§€λ‹ˆμ–΄μ—κ²ŒλŠ” Amazon ECS에 λŒ€ν•œ μš”κΈˆ μ ˆκ°μ€ μ€‘μš”ν•œ 뢀뢄에 해당될 수 μžˆλ‹€. Amazon ECS 곡식 λ¬Έμ„œμ—μ„œλŠ” Amazon ECS κ΄€λ ¨ μΈν„°νŽ˜μ΄μŠ€ VPC μ—”λ“œν¬μΈνŠΈ(PrivateLink)λ₯Ό μ‚¬μš©ν•˜λ©΄ 퍼블릭 μ—”λ“œν¬μΈνŠΈλ‘œμ˜ μš”μ²­μ„ μœ„ν•΄ 인터넷 κ²Œμ΄νŠΈμ›¨μ΄ λ˜λŠ” NAT κ²Œμ΄νŠΈμ›¨μ΄μ— λŒ€ν•œ λΉ„μš©μ„ μ ˆκ°ν•  수 μžˆλ‹€κ³  μ•ˆλ‚΄ν•œλ‹€. κ·ΈλŸ¬λ‚˜, μΈν„°νŽ˜μ΄μŠ€ VPC μ—”λ“œν¬μΈνŠΈλŠ” μ€‘μš”ν•œ 뢀뢄이 μžˆλŠ”λ° Private LinkλŠ” μ„œλΈŒλ„·λ§ˆλ‹€ ENIλ₯Ό ν• λ‹Ήν•˜λ―€λ‘œ μ„œλΈŒλ„· 개수만큼 μ‹œκ°„ μš”κΈˆμ΄ λΆ€κ°€λœλ‹€λŠ” 것이닀.

λ”°λΌμ„œ, ECS와 ECS Agent μ»¨ν…Œμ΄λ„ˆ λ˜λŠ” μ„œλΉ„μŠ€ 연결을 μœ„ν•œ Envoy μ‚¬μ΄λ“œμΉ΄ μ»¨ν…Œμ΄λ„ˆ λ“±μ—μ„œ CloudWatch Logs VPC μ—”λ“œν¬μΈνŠΈλ‘œμ˜ μš”μ²­μ΄λ‚˜ μ—¬λŸ¬κ°€μ§€ λͺ¨λ‹ˆν„°λ§μ„ μœ„ν•œ μ‚¬μ΄λ“œμΉ΄ μ»¨ν…Œμ΄λ„ˆλ‘œ 인해 NAT κ²Œμ΄νŠΈμ›¨μ΄μ— λŒ€ν•œ μš”κΈˆμ΄ 많이 λ°œμƒν•˜λŠ” νŠΈλž˜ν”½ 규λͺ¨κ°€ μ•„λ‹ˆλΌλ©΄ Amazon ECS와 ν•¨κ»˜ NAT κ²Œμ΄νŠΈμ›¨μ΄λ₯Ό μ‚¬μš©ν•˜λŠ”κ²Œ 더 적합할 수 μžˆλ‹€.

Amazon ECS κ΄€λ ¨ 레퍼런슀