IT Share you

AWS 자격 증명을 Docker 컨테이너에 전달하는 가장 좋은 방법은 무엇입니까?

shareyou 2020. 12. 11. 20:56
반응형

AWS 자격 증명을 Docker 컨테이너에 전달하는 가장 좋은 방법은 무엇입니까?


Amazon EC2에서 docker-container를 실행하고 있습니다. 현재 Dockerfile에 AWS 자격 증명을 추가했습니다. 이를 수행하는 가장 좋은 방법을 알려주시겠습니까?


가장 좋은 방법은 IAM 역할을 사용하고 자격 증명을 전혀 처리하지 않는 것입니다. ( http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html 참조 )

자격 증명은 http://169.254.169.254.....개인 IP 주소이므로 EC2 인스턴스에서만 액세스 할 수 있습니다.

모든 최신 AWS 클라이언트 라이브러리는 여기에서 자격 증명을 가져오고, 새로 고치고, 사용하는 방법을 "알고"있습니다. 따라서 대부분의 경우에 대해 알 필요도 없습니다. 올바른 IAM 역할로 ec2를 실행하기 만하면됩니다.

옵션으로는 (예 : 환경 변수로 런타임에 전달할 수 있습니다 docker run -e AWS_ACCESS_KEY_ID=xyz -e AWS_SECRET_ACCESS_KEY=aaa myimage)

터미널에서 printenv를 실행하여 이러한 환경 변수에 액세스 할 수 있습니다.


이 질문이 제기 된 이후 Docker에서 많은 것이 변경되었으므로 여기에 업데이트 된 답변을 시도해 보겠습니다.

첫째, 특히 클라우드 내부에서 이미 실행중인 컨테이너에 대한 AWS 자격 증명을 사용하면 Vor가 제안한 대로 IAM 역할을 사용 하는 것이 정말 좋은 옵션입니다. 그렇게 할 수 있다면 대답에 더하기 1을 더하고 나머지는 건너 뛰십시오.


클라우드 외부에서 작업을 시작하거나 다른 유형의 비밀이있는 경우 비밀 저장 에 대해 권장 하는 두 가지 주요 장소가 있습니다 .

  1. 환경 변수 : 이러한 변수가 컨테이너에 정의되면 컨테이너 내부의 모든 프로세스가 액세스 할 수 있으며 / proc을 통해 볼 수 있으며 앱은 로그에 저장되는 stdout에 환경을 덤프 할 수 있으며 가장 중요한 것은 컨테이너를 검사 할 때 텍스트를 지 웁니다.

  2. 이미지 자체에서 : 이미지는 종종 이미지를 가져 오는 데 필요한 자격 증명 없이도 많은 사용자가 가져 오기 액세스 권한이있는 레지스트리로 푸시됩니다. 한 레이어에서 비밀을 삭제하더라도 같은 일반적인 Linux 유틸리티를 사용하여 이미지를 분해 할 수 있으며 이미지 tar에 처음 추가 된 단계에서 비밀을 찾을 수 있습니다.


그렇다면 Docker 컨테이너의 비밀에 대한 다른 옵션은 무엇입니까?

옵션 A : 이미지 빌드 중에 만이 시크릿이 필요하고 빌드가 시작되기 전에 시크릿을 사용할 수없고 아직 BuildKit에 대한 액세스 권한이없는 경우, 다단계 빌드 가 나쁜 옵션 중 최고입니다. 빌드의 초기 단계에 비밀을 추가하고 거기에서 사용한 다음 비밀없이 해당 단계의 출력을 릴리스 단계에 복사하고 해당 릴리스 단계 만 레지스트리 서버에 푸시합니다. 이 비밀은 여전히 ​​빌드 서버의 이미지 캐시에 있으므로 마지막 수단으로 만 사용하는 경향이 있습니다.

옵션 B : 또한 빌드 시간 동안 18.09에서 출시 된 BuildKit을 사용할 수 있다면 현재 단일 RUN 라인에 대한 볼륨 마운트로 비밀을 주입 할 수있는 실험적 기능 이 있습니다 . 해당 마운트는 이미지 레이어에 기록되지 않으므로 공개 레지스트리 서버로 푸시 될 염려없이 빌드 중에 비밀에 액세스 할 수 있습니다. 결과 Dockerfile은 다음과 같습니다.

# syntax = docker/dockerfile:experimental
FROM python:3
RUN pip install awscli
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials aws s3 cp s3://... ...

그리고 18.09 이상에서 다음과 같은 명령으로 빌드합니다.

DOCKER_BUILDKIT=1 docker build -t your_image --secret id=aws,src=$HOME/.aws/credentials .

옵션 C :Swarm 모드 또는 기타 오케스트레이션없이 단일 노드에서 런타임에 자격 증명을 읽기 전용 볼륨으로 마운트 할 수 있습니다. 이 자격 증명에 액세스하려면 docker 외부에서 동일한 자격 증명 파일에 대한 것과 동일한 액세스 권한이 필요하므로 Docker가없는 시나리오보다 좋거나 나쁘지 않습니다. 가장 중요한 것은 컨테이너를 검사하거나 로그를 보거나 이미지를 레지스트리 서버로 푸시 할 때이 파일의 내용이 보이지 않아야한다는 것입니다. 이는 모든 시나리오에서 볼륨이 그 범위 밖에 있기 때문입니다. 이를 위해서는 컨테이너 배포와는 별도로 Docker 호스트에 자격 증명을 복사해야합니다. (참고로, Docker API에 대한 액세스는 호스트에서 루트이고 루트가 모든 사용자의 파일을 볼 수 있기 때문에 해당 호스트에서 컨테이너를 실행할 수있는 권한이있는 모든 사용자가 자격 증명을 볼 수 있습니다. 호스트에서 루트가있는 사용자를 신뢰하지 않는 경우 ,

의 경우 docker run다음과 같습니다.

docker run -v $HOME/.aws/credentials:/home/app/.aws/credentials:ro your_image

또는 작성 파일의 경우 다음이 필요합니다.

version: '3'
services:
  app:
    image: your_image
    volumes:
    - $HOME/.aws/credentials:/home/app/.aws/credentials:ro

옵션 D :Swarm Mode 및 Kubernetes와 같은 오케스트레이션 도구를 사용하여 이제 볼륨보다 더 나은 비밀 지원이 제공됩니다. Swarm 모드를 사용하면 파일이 관리자 파일 시스템에서 암호화됩니다 (복호화 키도있는 경우가 많으므로 관리자가 복호화 키를 입력하지 않고도 관리자를 다시 시작할 수 있음). 더 중요한 것은 비밀이 필요한 작업자에게만 전송되고 (해당 비밀을 사용하여 컨테이너를 실행하는) 작업자의 메모리에만 저장되고 디스크에는 저장되지 않으며 tmpfs를 사용하여 컨테이너에 파일로 주입됩니다. 산. swarm 외부의 호스트에있는 사용자는 해당 비밀을 자신의 컨테이너에 직접 마운트 할 수 없지만, docker API에 대한 개방형 액세스를 통해 노드의 실행중인 컨테이너에서 비밀을 추출 할 수 있으므로이 액세스 권한을 가진 사용자를 다시 제한합니다. API. 작성에서이 비밀 주입은 다음과 같습니다.

version: '3.7'

secrets:
  aws_creds:
    external: true

services:
  app:
    image: your_image
    secrets:
    - source: aws_creds
      target: /home/user/.aws/credentials
      uid: '1000'
      gid: '1000'
      mode: 0700

You turn on swarm mode with docker swarm init for a single node, then follow the directions for adding additional nodes. You can create the secret externally with docker secret create aws_creds $HOME/.aws/credentials. And you deploy the compose file with docker stack deploy -c docker-compose.yml stack_name.

I often version my secrets using a script from: https://github.com/sudo-bmitch/docker-config-update

Option E: Other tools exist to manage secrets, and my favorite is Vault because it gives the ability to create time limited secrets that automatically expire. Every application then gets its own set of tokens to request secrets, and those tokens give them the ability to request those time limited secrets for as long as they can reach the vault server. That reduces the risk if a secret is ever taken out of your network since it will either not work or be quick to expire. The functionality specific to AWS for Vault is documented at https://www.vaultproject.io/docs/secrets/aws/index.html


Another approach is to pass the keys from the host machine to the docker container. You may add following lines to the docker-compose file.

services:
  web:
    build: .
    environment:
      - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
      - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
      - AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}

Yet another approach is to create temporary read-only volume in docker-compose.yaml. AWS CLI and SDK (like boto3 or AWS SDK for Java etc.) are looking for default profile in ~/.aws/credentials file.

If you want to use other profiles you just need also to export AWS_PROFILE variable before running docker-compose command

export AWS_PROFILE=some_other_profile_name

version: '3'

services:
  service-name:
    image: docker-image-name:latest
    environment:
      - AWS_PROFILE=${AWS_PROFILE}
    volumes:
      - ~/.aws/:/root/.aws:ro

In this example I used root user on docker. If you are using other user just change /root/.aws to user home directory

:ro - stands for read-only docker volume

It is very helpful when you have multiple profiles in ~/.aws/credentials file and you are also using MFA. Also helpful when you want to locally test docker-container before deploying it on ECS on which you have IAM Roles, but locally you don't.

참고URL : https://stackoverflow.com/questions/36354423/which-is-the-best-way-to-pass-aws-credentials-to-docker-container

반응형