Cách tốt nhất để chuyển thông tin đăng nhập AWS vào vùng chứa Docker là cách nào?


102

Tôi đang chạy docker-container trên Amazon EC2. Hiện tại tôi đã thêm AWS Credentials vào Dockerfile. Bạn có thể vui lòng cho tôi biết cách tốt nhất để làm điều này?


2
Còn nếu tôi đang chạy một vùng chứa Docker trên máy tính xách tay của mình được cho là cũng hoạt động kỳ diệu trong ECS ​​khi tôi đẩy nó vào đó? I am gonna đoán tôi sử dụng cờ --volume ... một người nào đó phải đã trả lời ...
Randy L

Câu trả lời:


105

Cách tốt nhất là sử dụng IAM Role và không xử lý thông tin đăng nhập nào cả. (xem http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html )

Thông tin đăng nhập có thể được truy xuất từ http://169.254.169.254..... Vì đây là địa chỉ ip riêng nên chỉ có thể truy cập được từ các phiên bản EC2.

Tất cả các thư viện ứng dụng AWS hiện đại đều "biết" cách tìm nạp, làm mới và sử dụng thông tin xác thực từ đó. Vì vậy, trong hầu hết các trường hợp, bạn thậm chí không cần biết về nó. Chỉ cần chạy ec2 với vai trò IAM chính xác và bạn đã sẵn sàng.

Là một tùy chọn, bạn có thể chuyển chúng trong thời gian chạy dưới dạng các biến môi trường (tức là docker run -e AWS_ACCESS_KEY_ID=xyz -e AWS_SECRET_ACCESS_KEY=aaa myimage)

Bạn có thể truy cập các biến môi trường này bằng cách chạy printenv tại thiết bị đầu cuối.


35
Có cách nào tốt để thực hiện việc này trong quá trình phát triển / thử nghiệm cục bộ mà không ảnh hưởng đến bảo mật trong sản xuất không? Tôi muốn đảm bảo hình ảnh hoạt động mà không cần triển khai đầy đủ.
honktronic

3
một giải pháp thay thế mà tôi đã đăng với các biến môi trường hoạt động tốt trong môi trường dev / local.
Vor

5
Tôi tự hỏi nếu đây là lỗi đánh máy, nhưng tôi cần phải nhập AWS_SECRET_ACCESS_KEY, không phải AWS_SECRET_KEY, dù sao câu trả lời của bạn rất hữu ích. Cảm ơn bạn.
Akavall

14
Nói một cách đơn giản (đối với những người có câu trả lời này giống như cách tôi đã làm); Bộ chứa docker chạy trên EC2 sẽ kế thừa vai trò giống như phiên bản máy chủ. (Tôi cần một "ELI5" như thế này khi lệnh AWS CLI trong container của tôi một cách bí ẩn làm việc mặc dù có không credentials truyền cho họ!)
Adam Westbrook

8
Cách dễ dàng để lấy các giá trị chính từ hồ sơ cục bộ của bạn để gán cho biến môi trường cho mục đích phát triển (như được đề xuất trong cameroneckelberry.co/words/… ): "aws --profile default config get aws_access_key_id"
Altair7852

88

Rất nhiều thứ đã thay đổi trong Docker kể từ khi câu hỏi này được hỏi, vì vậy đây là một nỗ lực để có một câu trả lời được cập nhật.

Đầu tiên, cụ thể là với thông tin đăng nhập AWS trên các vùng chứa đã chạy bên trong đám mây, sử dụng vai trò IAM như Vor đề xuất là một lựa chọn thực sự tốt. Nếu bạn có thể làm điều đó, hãy thêm một cộng một vào câu trả lời của anh ấy và bỏ qua phần còn lại của phần này.


Khi bạn bắt đầu chạy những thứ bên ngoài đám mây hoặc có một loại bí mật khác, có hai nơi chính mà tôi khuyên bạn không nên lưu trữ bí mật:

  1. Các biến môi trường: khi chúng được xác định trên vùng chứa, mọi quy trình bên trong vùng chứa đều có quyền truy cập vào chúng, chúng được hiển thị qua / proc, các ứng dụng có thể kết xuất môi trường của chúng sang stdout nơi nó được lưu trữ trong nhật ký và quan trọng nhất, chúng xuất hiện trong văn bản rõ ràng khi bạn kiểm tra vùng chứa.

  2. Trong chính hình ảnh: hình ảnh thường được đẩy đến các cơ quan đăng ký nơi nhiều người dùng có quyền truy cập kéo, đôi khi không cần bất kỳ thông tin xác thực nào để kéo hình ảnh. Ngay cả khi bạn xóa bí mật khỏi một lớp, hình ảnh có thể được tháo rời bằng các tiện ích Linux phổ biến như tarvà bạn có thể tìm thấy bí mật từ bước nơi nó được thêm vào hình ảnh lần đầu tiên.


Vậy có những lựa chọn nào khác cho những bí mật trong vùng chứa Docker?

Tùy chọn A: Nếu bạn chỉ cần bí mật này trong quá trình xây dựng hình ảnh của mình, không thể sử dụng bí mật trước khi quá trình xây dựng bắt đầu và chưa có quyền truy cập vào BuildKit, thì xây dựng nhiều giai đoạn là một lựa chọn tốt nhất trong số các tùy chọn không tốt. Bạn sẽ thêm bí mật vào các giai đoạn đầu của quá trình xây dựng, sử dụng nó ở đó, sau đó sao chép đầu ra của giai đoạn đó mà không cần bí mật cho giai đoạn phát hành của bạn và chỉ đẩy giai đoạn phát hành đó đến các máy chủ đăng ký. Bí mật này vẫn còn trong bộ nhớ cache hình ảnh trên máy chủ xây dựng, vì vậy tôi có xu hướng chỉ sử dụng điều này như một phương sách cuối cùng.

Tùy chọn B: Ngoài ra trong thời gian xây dựng, nếu bạn có thể sử dụng BuildKit được phát hành vào năm 18.09, hiện có các tính năng thử nghiệm để cho phép đưa các bí mật vào làm giá đỡ âm lượng cho một dòng RUN duy nhất. Gắn kết đó không được ghi vào các lớp hình ảnh, vì vậy bạn có thể truy cập bí mật trong quá trình xây dựng mà không cần lo lắng nó sẽ bị đẩy lên máy chủ đăng ký công khai. Dockerfile kết quả trông giống như sau:

# 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://... ...

Và bạn xây dựng nó bằng một lệnh trong 18.09 hoặc mới hơn như:

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

Tùy chọn C:Trong thời gian chạy trên một nút duy nhất, không có Chế độ Swarm hoặc điều phối khác, bạn có thể gắn thông tin đăng nhập dưới dạng tập chỉ đọc. Quyền truy cập vào thông tin xác thực này yêu cầu cùng một quyền truy cập mà bạn sẽ có bên ngoài docker vào cùng một tệp thông tin xác thực, vì vậy nó không tốt hơn hay tệ hơn so với tình huống không có docker. Quan trọng nhất, nội dung của tệp này sẽ không hiển thị khi bạn kiểm tra vùng chứa, xem nhật ký hoặc đẩy hình ảnh đến máy chủ đăng ký, vì ổ đĩa nằm ngoài vùng chứa đó trong mọi trường hợp. Điều này yêu cầu bạn sao chép thông tin đăng nhập của mình trên máy chủ docker, tách biệt với việc triển khai vùng chứa. (Lưu ý, bất kỳ ai có khả năng chạy vùng chứa trên máy chủ đó đều có thể xem thông tin đăng nhập của bạn vì quyền truy cập vào API docker là root trên máy chủ và root có thể xem tệp của bất kỳ người dùng nào. Nếu bạn không tin tưởng người dùng có quyền root trên máy chủ ,

Đối với a docker run, điều này trông giống như:

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

Hoặc đối với tệp soạn, bạn có:

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

Lựa chọn D:Với các công cụ điều phối như Swarm Mode và Kubernetes, chúng tôi hiện có những bí mật hỗ trợ tốt hơn so với âm lượng. Với Swarm Mode, tệp được mã hóa trên hệ thống tệp của trình quản lý (mặc dù khóa giải mã cũng thường ở đó, cho phép khởi động lại trình quản lý mà không cần quản trị viên nhập khóa giải mã). Quan trọng hơn, bí mật chỉ được gửi cho các công nhân cần bí mật (chạy một vùng chứa với bí mật đó), nó chỉ được lưu trữ trong bộ nhớ trên công nhân, không bao giờ trên đĩa và nó được đưa vào dưới dạng tệp vào vùng chứa bằng tmpfs gắn kết. Người dùng trên máy chủ lưu trữ bên ngoài swarm không thể gắn kết bí mật đó trực tiếp vào vùng chứa của họ, tuy nhiên, với quyền truy cập mở vào API docker, họ có thể trích xuất bí mật từ vùng chứa đang chạy trên nút, vì vậy, một lần nữa, hãy giới hạn người có quyền truy cập này vào API. Từ soạn thảo, nội dung tiêm bí mật này trông giống như:

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

Bạn bật chế độ bầy đàn với docker swarm initmột nút, sau đó làm theo hướng dẫn để thêm các nút bổ sung. Bạn có thể tạo bí mật bên ngoài với docker secret create aws_creds $HOME/.aws/credentials. Và bạn triển khai tệp soạn thảo với docker stack deploy -c docker-compose.yml stack_name.

Tôi thường phiên bản các bí mật của mình bằng cách sử dụng tập lệnh từ: https://github.com/sudo-bmitch/docker-config-update

Tùy chọn E: Có các công cụ khác để quản lý bí mật và tôi thích nhất là Vault vì nó cho khả năng tạo các bí mật có giới hạn thời gian tự động hết hạn. Sau đó, mọi ứng dụng đều nhận được bộ mã thông báo riêng để yêu cầu bí mật và những mã thông báo đó cung cấp cho họ khả năng yêu cầu những bí mật có giới hạn thời gian đó miễn là họ có thể tiếp cận máy chủ vault. Điều đó làm giảm rủi ro nếu một bí mật được đưa ra khỏi mạng của bạn vì nó sẽ không hoạt động hoặc nhanh chóng hết hạn. Chức năng dành riêng cho AWS dành cho Vault được ghi lại tại https://www.vaultproject.io/docs/secrets/aws/index.html


20

Một cách tiếp cận khác là chuyển các khóa từ máy chủ đến bộ chứa docker. Bạn có thể thêm các dòng sau vào docker-composetệp.

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}

2
Biến môi trường khu vực chính xác là AWS_REGION. Xem stackoverflow.com/questions/44151982/…
John Camerin vào

3
Vui lòng kiểm tra tài liệu chính thức đề cập đến AWS_DEFAULT_REGION docs.aws.amazon.com/cli/latest/userguide/…
prafi Ngày

6
Khi tôi sử dụng AWS_DEFAULT_REGION, tôi có một ngoại lệ là không thể tìm thấy vùng mặc định. Tìm kiếm của tôi dẫn đến docs.aws.amazon.com/sdk-for-java/v1/developer-guide/…. Điều này chỉ định biến môi trường AWS_REGION và điều đó đã hoạt động với tôi.
John Camerin

Nếu bạn đang sử dụng thông tin đăng nhập tạm thời thì bạn cũng có thể cầnAWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}
Davos

12

Tuy nhiên, một cách tiếp cận khác là tạo ổ đĩa tạm thời chỉ đọc trong docker-compos.yaml. AWS CLI và SDK (như boto3 hoặc AWS SDK cho Java, v.v.) đang tìm kiếm defaulthồ sơ trong ~/.aws/credentialstệp.

Nếu bạn muốn sử dụng các cấu hình khác, bạn cũng chỉ cần xuất biến AWS_PROFILE trước khi chạy docker-composelệnh

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

Trong ví dụ này, tôi đã sử dụng người dùng root trên docker. Nếu bạn đang sử dụng người dùng khác, chỉ cần thay đổi /root/.awsthành thư mục chính của người dùng

:ro - là viết tắt của âm lượng docker chỉ đọc

Nó rất hữu ích khi bạn có nhiều cấu hình trong hồ sơ ~/.aws/credentialsvà bạn cũng đang sử dụng MFA. Cũng hữu ích khi bạn muốn kiểm tra cục bộ docker-container trước khi triển khai nó trên ECS mà bạn có Vai trò IAM, nhưng cục bộ thì không.


Trên cửa sổ .aws` danh mục nằm "%UserProfile%\.aws". Vì vậy, tôi cho rằng bạn phải thay đổi: - ~/.aws/:/root/.aws:rođể- %UserProfile%\.aws:/root/.aws:ro
Artur Siepietowski

1
Điều này sẽ chỉ hoạt động với các quy trình xây dựng đơn lẻ chứ không phải đa tầng.
wlarcheveque

@wlarcheveque Chăm sóc để xây dựng?
ErikE

RẤT cẩn thận khi sử dụng - host:containercú pháp, nếu tệp / thư mục không tồn tại trên máy chủ mà nó được tạo (dưới dạng root) và awscli sẽ không cảm ơn bạn vì đã cung cấp cho nó tệp không byte. Bạn nên sử dụng "biểu mẫu dài" chỉ định loại là ràng buộc, đường dẫn máy chủ và đường dẫn vùng chứa trên các dòng riêng biệt, điều này không thành công nếu tệp không tồn tại, đó là những gì bạn muốn trong docker-compose.dev của mình. yml nhưng không có trong docker-compo.yml của bạn (triển khai sản phẩm / AWS).
dragon788

0

Bạn có thể tạo ~/aws_env_credschứa

touch ~/aws_env_creds
chmod 777 ~/aws_env_creds
vi ~/aws_env_creds

thêm giá trị dưới đây (Thay thế khóa của bạn)

AWS_ACCESS_KEY_ID=AK_FAKE_KEY_88RD3PNY
AWS_SECRET_ACCESS_KEY=BividQsWW_FAKE_KEY_MuB5VAAsQNJtSxQQyDY2C

"esc" để lưu tệp.

Chạy và kiểm tra vùng chứa

 my_service:
      build: .
      image: my_image
      env_file:
        - ~/aws_env_creds
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.