Docker 빌드(3)

뾰족머리삼돌이·2024년 11월 23일

서버

목록 보기
5/10

Build Secrets

이번 포스팅은 Docker 빌드과정에서 SSH나 인증관련 값들의 관리방법에 대해 작성하려고 한다.

앞선 Docker 빌드(2) 에서 소개했던 ARGENV는 빌드과정에서 변수값을 사용할 수 있게 해주지만, 최종 결과물인 이미지에도 값이 남아있기 때문에 민감한 정보를 작성하면 안된다.

이에대한 대안으로 사용할 수 있는 방법이 Secret MountsSSH Mounts, 그리고 원격 Context를 위한 Git Authentication이다.

Secret MountsSSH Mounts에서 Build Secret을 사용하는 것은 2단계의 과정을 거친다.

docker build --secret id=aws,src=$HOME/.aws/credentials .
  1. docker build 과정에서 --secret을 통해 값을 전달
RUN --mount=type=secret,id=aws \
    AWS_SHARED_CREDENTIALS_FILE=/run/secrets/aws \
    aws s3 cp ...
  1. Dockerfile에서 전달받은 secret값 사용
    RUN 지침에서 --mount=type=secret 를 통해 secret값을 사용한다

Secret Mounts

빌드 클라이언트로부터 secret 값을 가져와 빌드과정에 일시적으로 사용하는 방법이다.
빌드과정에서 private artifact 서버나 API와 통신해야하는 경우 유용하다.

파일 혹은 환경변수를 통해 secret 값을 노출하는 방법으로, 일반적으로는 자동으로 감지된다.
특정 방법을 명시적으로 지정하고 싶다면 type=file, type=env를 이용할 수 있다.

docker build --secret id=kube,env=KUBECONFIG .

위 예시처럼, ID와 값의 형식으로 secret 값을 전달할 수 있다.
( 이 경우, env는 Dockerfile의 RUN 지침에 사용된다 )

만약, env 매개변수를 생략한다면 빌드 컨테이너의 /run/secrets/API_TOKEN 에 마운트된다.


Dockerfile을 작성할 때 secret 값은 기본적으로 파일에 마운트되며, 마운트되는 경로는 /run/secrets/<id>다.

RUN --mount=type=secret,id=aws \
    AWS_SHARED_CREDENTIALS_FILE=/run/secrets/aws \
    aws s3 cp ...

예를들어, Dockerfile에서 위 형식으로 작성하면 /run/secrets/aws 경로에 secret값을 마운트한다. (예시에선 해당 경로에 저장된 값을 환경변수에 적용하고있다 )

다른 이름의 파일로 마운트하고 싶다면 --mount=type=secret,id=aws,target=<경로>의 형식으로 원하는 경로의 파일로 마운트할 수 있다.


RUN --mount=type=secret,id=aws-key-id,env=AWS_ACCESS_KEY_ID \
    --mount=type=secret,id=aws-secret-key,env=AWS_SECRET_ACCESS_KEY \
    --mount=type=secret,id=aws-session-token,env=AWS_SESSION_TOKEN \
    aws s3 cp ...

이 외에 환경변수로 secret값을 마운트하고 싶다면 --mountenv 옵션을 사용하면 된다.
targetent를 모두 사용하는 경우에는 파일과 환경변수에 모두 마운트할 수 있다.

SSH Mounts

SSH 소켓이나 key를 빌드 내부에서 사용할 수 있도록하는 방법이다.
일반적으로 빌드과정에서 prvate Git Repository를 가져와야할 때 사용한다.

GitLab에 접근하는 예시를 살펴보자

# syntax=docker/dockerfile:1
FROM alpine
RUN apk add --no-cache openssh-client
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
RUN --mount=type=ssh \
  ssh -q -T git@gitlab.com 2>&1 | tee /hello
# "Welcome to GitLab, @GITLAB_USERNAME_ASSOCIATED_WITH_SSHKEY" should be printed here
# with the type of build progress is defined as `plain`.

Dockerfile에서 RUN --mount=type=ssh 를 이용해 SSH Mounts를 이용하는 예시이다.

  1. ~/.ssh 디렉토리를 생성하고, GitLab의 공개키를 ~/.ssh/known_hosts에 추가한다.
  2. 이후, 빌드 명령에서 제공된 SSH 인증정보를 Docker 컨테이너에 전달하며 GitLab으로의 ssh 연결을 시도한다.
  3. 최종적으로는 ssh 표준출력을 /hello 파일에 저장한다.
eval $(ssh-agent)
ssh-add ~/.ssh/id_rsa
(Input your passphrase here)
docker buildx build --ssh default=$SSH_AUTH_SOCK .

빌드 명령에서 SSH 인증 소켓($SSH_AUTH_SOCK)에 전달하여, 빌드과정에서 SSH 연결을 사용할 수 있게 한다.
즉, SSH 인증 소켓을 전달함으로써 빌드과정에서 빌드플랫폼의 SSH 개인키를 접근할 수 있게 하는 것이다.

원격 Context를 위한 Git Authentication

Build Context는 빌드과정에서 사용할 자료들을 의미한다.

원격 Git Context이나 Private Repository로 빌드할 때 사용할 수 있는 사전정의된 secret 집합을 의미한다.

pre-flight secret이기 때문에 빌드 지침내에서 사용되지는 않지만,
Builder(BuildKit)가 context를 가져오는 데 필요한 자격증명을 제공한다.

BuildKit은 2개의 사전정의된 build secret( GIT_AUTH_TOKEN, GIT_AUTH_HEADER ) 을 지원한다.
원격 Private Repository를 사용해 빌드할 때, HTTP 인증 매개변수 지정에 사용된다.

만약, 빌드과정에서 Repository를 Build Context로 사용하고 싶다면 빌드명령에 인증이 필요하다.

GIT_AUTH_TOKEN=$(cat gitlab-token.txt) docker build \
  --secret id=GIT_AUTH_TOKEN \
  https://gitlab.com/example/todo-app.git

인증에 필요한 토큰값을 GIT_AUTH_TOKEN에 지정하고, 빌드명령에서 --secret id=GIT_AUTH_TOKEN 으로 제공함으로써 인증을 수행할 수 있다.

FROM alpine
ADD https://gitlab.com/example/todo-app.git /src

GIT_AUTH_TOKEN은 Dockerfile에서 ADD 지침을 사용할 때에도 사용된다.

만약, Bearer가 아닌 Basic 인증방식 ( 아이디, 비밀번호 )를 이용하려고 한다면 GIT_AUTH_HEADER 을 사용해야한다.

export GIT_AUTH_TOKEN=$(cat gitlab-token.txt)
export GIT_AUTH_HEADER=basic
docker build \
  --secret id=GIT_AUTH_TOKEN \
  --secret id=GIT_AUTH_HEADER \
  https://gitlab.com/example/todo-app.git

이 경우, GIT_AUTH_TOKEN에는 아이디와 비밀번호가 저장되어 있어야한다.

참고

0개의 댓글