Gitlab CI CD - Docker 에서 aws cli 사용하기

2023. 11. 20. 00:00DevOps/GitLab CI CD

반응형

https://yogingang.tistory.com/455

 

Gitlab CI CD - Docker 에서 host 의 aws 설정 사용하기

IAM 계정 만들기 aws cli 설치 및 설정 # 설치파일 다운로드 curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" # unzip 파일 unzip awscliv2.zip # install sudo ./aws/install aws configure 설정 aws configure s

yogingang.tistory.com

이전 강좌에서 aws 를 docker image 에 설치하지 않고 host  에 설치한 aws 설정을 공유하는 방법에 대해 알아봤다. 이걸 하면서 실제 aws cli 가 설치된 폴더도 공유해서 docker container 실행시 aws cli 명령도 사용하게 하려했다.

 

하지만 문제가 생겼다. aws cli 를 실행 하려 하니 오류가 난다. 

왜 이러한 문제가 생겼는지 확인해 보고 이제부터 이 문제를 해결해 보자.

 

먼저 이전 강좌에서 aws 의 profile (credential) 을 공유한 내용을 확인해 보자

이미지에서 보면 -v ~/.aws:/root/.aws 가 바로 그것이다. volume 연결을 해서 host 의 directory 를 공유하고 있다.

그런데 그 밑에 보면 /usr/local/bin 관련해서도 volume 연결을 해서 사용하고 있다. 

먼저 이 gitlab ci cd 를 이용해 배포한 container 에 접근해 볼것이다. 

실행되고 있는 docker container 에 sh 로 접근 하겠다. (alphine 이라... bash 가 없다.)

# api-server-container 는 자신의 container 명을 적도록 하자
docker exec -it api-server-container sh

# 접속되면 다음과 같이 실행하자
cd /usr/local/bin
ls -al

아래와 같이 표시될 것이다. 

저 빨간 것이 보이는가? 그렇다. 

aws -> 어쩌구 저쩌구 빨강이!!!

 

aws 는 symbol link 라는 것이고 이것은 윈도우에서 바로가기와 비슷하다 

즉 /usr/local/bin 아래에는 aws 라는 바로가기 아이콘이 있고 실제 파일은 뒤쪽 빨강이 부분에 있다는 것이다. 

 

우리는 volume 연결을  symbol link 만 했고 실제 파일이 있는 위치는 않했기 때문에

aws cli 를 사용할 수 없었던 것이다. 

이제 exit 를 하고 host 로 복귀하자

이제  /usr/local/aws-cli/v2/current/bin/ 으로 이동해서 aws 가 실제 파일인지 확인하자

짜잔... 아니다...

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

상위 폴더인 ../dist/aws 가 실제 파일이다.

자 이제 volume 을 어떻게 연결할지 생각해 보자

내 생각엔 /usr/local/aws-cli 전체를 해주는게 좋을것 같은 느낌이다.

 

이제 기존 docker file 을 수정하자

FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine AS build
WORKDIR /source
COPY . .

WORKDIR /source/ApiServer
RUN dotnet publish -r linux-musl-x64 -c release --no-self-contained -p:PublishReadyToRun=true -o /publish

FROM mcr.microsoft.com/dotnet/aspnet:7.0-alpine AS runtime
WORKDIR /publish
COPY --from=build /publish ./
RUN chmod +x entrypoint.sh &&\
    mkdir ~/.aws 2> /dev/null || true &&\
    mkdir /usr/local/bin 2> /dev/null || true &&\
    mkdir /usr/local/aws-cli 2> /dev/null || true

ENTRYPOINT ["./entrypoint.sh"]

docker image 에는 /usr/local/aws-cli 가 없기 때문에 빈 파일인 형태로 연결해 준 것이다. 

2> /dev/null || true  는 이미 folder 가 있을경우 오류가 나는데 그 오류를 무시하고 정상처리로 인식하게 한다.

 

자 이렇게 하고 실행하면!!

짜잔.. 하고 되었으면 좋겠다....

하지만 안된다. 

여전히 aws not found 라는 문구가 뜨고 실제적으로 symbol link 가 다 연결되어 있어도 안된다. 

즉 위와 같은 방식으로는 안된다는 이야기이다...

뭔가 다른 문제가 있는것 같다. 

 

그리고 또하나 share 하려는 이유가 잘못되었다. 

share 는 profile 즉 credential 만 할 것이다. 

aws cli 는 target os 별로 다른 dependency 를 갖는다.

이말은 alphine 에서 host 의 (우리는 ubuntu) dependency 와 다르기 때문에

설사 실행 가능한 상태가 되어도 오동작을 할 것이란 말이다. 

 

생각해보면 ... 당연한 것 같기도 하다.

우리가 저런 dependency 문제를 해결하고 격리환경을 만들려고 docker 를 만든 것이다. 

그런데 그걸다시 되돌리려고 하다니... 편리함을 추구하다가 더 큰 문제를 만들뻔 했다. 

 

자 이쯤해서 생각을 바꿀 때이다. 

때로는 생각을 깊히 오래 해야 할 때도 있지만 

어떨때는 빠르게 다른 방식을 생각해 봐야 할 때도 있다. 

 

자이제 alpine linux 에다 aws cli 를 설치하고

credential 은 그대로 host 것을 공유하자..

(accesskey 와 secret key 를 노출하지 않기 위해서다)

 

그럼 ci, cd pipeline 을 조금 수정해야 하고

dockerfile 도 수정해야 한다. 

 

but 이제 더 이상 여러분들의 시간을 낭비하게 하지 않겠다.

결론만 말하자면 이건 안된다. 

 

사실상 저 alpine linux 에서 실행되게 하려면

여러 c 관련 library 와 python3 , openssl 등의 package 를 깔아야 한다. 

문제는 저런 작업을 하고 나면 docker image 의 크기는 1G 가 넘거나 비슷하게 된다. 

alpine 을 쓰는 이점이 전혀 없어진다는 것이다. 

(aws 어휴... cli 를 무슨 발가락으로 만들었나...??)

 

자 이쯤 되서 cli 를 가지고 구현 하려면 alpine 이 아닌 온전한 linux 를 설치 해서 aws package 를 사용하면 된다. 

이제 이전 Dockerfile 을 다음과 같이 수정하자

FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine AS build
WORKDIR /source
COPY . .

WORKDIR /source/ApiServer
RUN dotnet publish -r linux-musl-x64 -c release --no-self-contained -p:PublishReadyToRun=true -o /publish

# alpine 이 아닌 full version 을 받자
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
WORKDIR /publish
COPY --from=build /publish ./
ENV DEBIAN_FRONTEND=noninteractive
RUN chmod +x entrypoint.sh &&\
    mkdir ~/.aws &&\
    apt update &&\
    apt install -qq curl unzip -y &&\
    curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" &&\
    unzip awscliv2.zip &&\
    ./aws/install
ENTRYPOINT ["./entrypoint.sh"]

 

그리고 entrypoint.sh 도 수정해 주자

shell 에서 bash 로 수정해야 한다. 

#!/bin/bash
chmod +x efbundle.exe
./efbundle.exe --connection ${CONNECTION_FROM_ENV}
dotnet ApiServer.dll

상단에 #!/bin/sh 에서 #!/bin/bash 로 수정되었다. 

이제 docker exec 를 통해 접근한 후 aws configure list 를 실행해 보면 정상 동작 하는 것을 확인 할 수 있다. 

 

 

 

관련영상

https://youtu.be/nDpquh_QjBc

 

 

반응형