Я запускаю докер-контейнер на Amazon EC2. Наразі я додав облікові дані AWS до Dockerfile. Не могли б ви повідомити мені найкращий спосіб зробити це?
Я запускаю докер-контейнер на Amazon EC2. Наразі я додав облікові дані AWS до Dockerfile. Не могли б ви повідомити мені найкращий спосіб зробити це?
Відповіді:
Найкращий спосіб - використовувати IAM Role і взагалі не мати справу з обліковими даними. (див. http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html )
Облікові дані можна отримати з http://169.254.169.254.....
Оскільки це приватна ip-адреса, вона може бути доступна лише з екземплярів EC2.
Усі сучасні бібліотеки клієнтів AWS "знають", як отримати, оновити та використовувати облікові дані звідти. Тож у більшості випадків про це навіть не потрібно знати. Просто запустіть ec2 з правильною роллю IAM, і ви готові піти.
Як варіант, ви можете передавати їх під час виконання як змінні середовища (тобто docker run -e AWS_ACCESS_KEY_ID=xyz -e AWS_SECRET_ACCESS_KEY=aaa myimage
)
Ви можете отримати доступ до цих змінних середовища, запустивши printenv на терміналі.
AWS_SECRET_ACCESS_KEY
, ні AWS_SECRET_KEY
, у будь-якому разі ваша відповідь була дуже корисною. Спасибі.
З моменту того, як було задано це питання, у Docker багато що змінилося, тож ось спробу оновленої відповіді.
По-перше, зокрема, з обліковими даними AWS для контейнерів, які вже запущені всередині хмари, використання ролей IAM, як вважає Вор, є дійсно хорошим варіантом. Якщо ви можете це зробити, додайте ще один плюс один до його відповіді і пропустіть решту цього.
Як тільки ви починаєте запускати речі поза хмарою або використовуєте інший тип секрету, є два ключових місця, які я рекомендую не зберігати:
Змінні середовища: коли вони визначені в контейнері, кожен процес всередині контейнера має до них доступ, вони видно через / proc, програми можуть скидати своє середовище в stdout, де воно зберігається в журналах, і найголовніше, що вони відображаються в чіткий текст при огляді контейнера.
В самому зображенні: зображення часто надсилаються до реєстрів, де багато користувачів мають доступ для витягування, іноді без будь-яких облікових даних, необхідних для витягування зображення. Навіть якщо ви видалите секрет з одного шару, зображення можна розібрати за допомогою звичайних утиліт Linux, наприклад, tar
і секрет можна знайти з кроку, де він був вперше доданий до зображення.
То які ще є варіанти секретів у контейнерах Docker?
Варіант A: Якщо вам потрібен цей секрет лише під час збірки вашого зображення, ви не можете використовувати секрет до початку збірки і ще не маєте доступу до BuildKit, то багатоступенева збірка - найкращий з поганих варіантів. Ви повинні додати секрет до початкових етапів збірки, використовувати його там, а потім скопіювати висновок цього етапу без секрету до етапу випуску і лише просунути цей етап випуску на сервери реєстру. Цей секрет все ще знаходиться в кеші зображень на сервері збірки, тому я, як правило, використовую це лише в крайньому випадку.
Варіант B: Також під час побудови, якщо ви можете використовувати BuildKit, який був випущений в 18.09, на даний момент існують експериментальні функції, які дозволяють вводити секрети як об'ємне кріплення для однієї лінії RUN. Це монтування не записується на шари зображення, тому ви можете отримати доступ до секрету під час побудови, не турбуючись, що він буде перенесений на загальнодоступний сервер реєстру. Отриманий файл Docker виглядає так:
# 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:Під час виконання на одному вузлі, без режиму зграї чи іншої оркестрації, ви можете змонтувати облікові дані як том, призначений лише для читання. Доступ до цих облікових даних вимагає того самого доступу, який ви мали б за межами докера до того самого файлу облікових даних, тому він не кращий і не гірший за сценарій без докера. Найголовніше, що вміст цього файлу не повинен бути видимим під час перевірки контейнера, перегляду журналів або надсилання зображення на сервер реєстру, оскільки обсяг не відповідає такому в кожному сценарії. Для цього потрібно скопіювати свої облікові дані на хост докера, окремо від розгортання контейнера. (Зверніть увагу, будь-хто, хто має можливість запускати контейнери на цьому хості, може переглядати ваші облікові дані, оскільки доступ до API докера є root на хості, а root може переглядати файли будь-якого користувача. Якщо ви не довіряєте користувачам root на хості ,
Для 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, ми тепер маємо підтримку секретів, яка краща за обсяг. У режимі зграї файл шифрується у файловій системі менеджера (хоча там часто є і ключ розшифровки, що дозволяє перезапустити менеджер без введення адміністратором ключа розшифровки). Що ще важливіше, секрет надсилається лише працівникам, яким потрібен секрет (запуск контейнера з цим секретом), він зберігається лише в пам’яті на робочому місці, ніколи не на диску, і вводиться як файл у контейнер за допомогою tmpfs кріплення. Користувачі на хості поза роєм не можуть монтувати цей секрет безпосередньо у свій власний контейнер, однак, маючи відкритий доступ до 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
Ви вмикаєте ройовий режим docker swarm init
для одного вузла, а потім дотримуєтесь інструкцій щодо додавання додаткових вузлів. Ви можете створити секрет зовні за допомогою docker secret create aws_creds $HOME/.aws/credentials
. І ви розгортаєте файл написання за допомогою docker stack deploy -c docker-compose.yml stack_name
.
Я часто викладаю свої секрети, використовуючи скрипт за адресою : https://github.com/sudo-bmitch/docker-config-update
Варіант E: Існують інші інструменти для управління секретами, і мій улюблений - Сейф, оскільки він дає можливість створювати обмежені в часі секрети, які автоматично закінчуються. Потім кожна програма отримує власний набір токенів для запиту секретів, і ці маркери дають їм можливість запитувати ці обмежені в часі секрети до тих пір, поки вони можуть дістатися до сервера сховища. Це зменшує ризик, якщо секрет коли-небудь буде вилучено з вашої мережі, оскільки він або не буде працювати, або швидко закінчиться. Функціональність, специфічна для AWS для Сейфу, задокументована за адресою https://www.vaultproject.io/docs/secrets/aws/index.html
Іншим підходом є передача ключів від хост-машини до контейнера докера. Ви можете додати наступні рядки до docker-compose
файлу.
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}
Ще один підхід полягає у створенні тимчасового тому, доступного лише для читання, у docker-compose.yaml. AWS CLI та SDK (наприклад, boto3 або AWS SDK для Java тощо) шукають default
профіль у ~/.aws/credentials
файлі.
Якщо ви хочете використовувати інші профілі, вам потрібно також експортувати змінну AWS_PROFILE перед запуском docker-compose
команди
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
У цьому прикладі я використовував root користувача на docker. Якщо ви використовуєте іншого користувача, просто перейдіть /root/.aws
до домашнього каталогу користувача
:ro
- означає обсяг докера, доступний лише для читання
Дуже корисно, коли у вас є кілька профілів, ~/.aws/credentials
і ви також використовуєте MFA. Також корисно, коли ви хочете локально протестувати докер-контейнер перед розгортанням його на ECS, на якому у вас є ролі IAM, але локально - ні.
"%UserProfile%\.aws"
. Тож я припускаю, що вам доведеться змінити: - ~/.aws/:/root/.aws:ro
на- %UserProfile%\.aws:/root/.aws:ro
- host:container
синтаксис, якщо файл / папка не існує на хості, який він створює (як корінь), і awscli не подякує вам за подання йому нульового байтового файлу. Ви повинні використовувати "довгу форму", яка визначає тип bind, шлях хосту та шлях контейнера в окремих рядках, це не вдається, якщо файл не існує, саме цього ви хочете у своєму docker-compose.dev. yml, але не у вашому docker-compose.yml (розгортання prod / AWS).
Ви можете створити ~/aws_env_creds
вміст
touch ~/aws_env_creds
chmod 777 ~/aws_env_creds
vi ~/aws_env_creds
додати значення нижче (Замінити ключ свого)
AWS_ACCESS_KEY_ID=AK_FAKE_KEY_88RD3PNY
AWS_SECRET_ACCESS_KEY=BividQsWW_FAKE_KEY_MuB5VAAsQNJtSxQQyDY2C
"esc", щоб зберегти файл.
Запустіть і протестуйте контейнер
my_service:
build: .
image: my_image
env_file:
- ~/aws_env_creds