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?
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?
Câu trả lời:
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.
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.
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:
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.
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ư tar
và 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 init
mộ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
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-compose
tệ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}
AWS_DEFAULT_REGION
docs.aws.amazon.com/cli/latest/userguide/…
AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}
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 default
hồ sơ trong ~/.aws/credentials
tệ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-compose
lệ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/.aws
thà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/credentials
và 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.
"%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
- host:container
cú 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).
Bạn có thể tạo ~/aws_env_creds
chứ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