ฉันใช้งาน Docker-container บน Amazon EC2 ขณะนี้ฉันได้เพิ่ม AWS Credentials ไปยัง Dockerfile แล้ว โปรดแจ้งให้เราทราบวิธีที่ดีที่สุดในการดำเนินการนี้ได้ไหม
ฉันใช้งาน Docker-container บน Amazon EC2 ขณะนี้ฉันได้เพิ่ม AWS Credentials ไปยัง 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 ตามที่Vor แนะนำเป็นตัวเลือกที่ดีมาก ถ้าทำได้ก็ให้บวกอีกหนึ่งคำตอบแล้วข้ามส่วนที่เหลือไป
เมื่อคุณเริ่มใช้งานสิ่งต่างๆนอกระบบคลาวด์หรือมีความลับประเภทอื่นมีสองสถานที่สำคัญที่ฉันแนะนำให้ไม่เก็บความลับ:
ตัวแปรสภาพแวดล้อม: เมื่อกำหนดสิ่งเหล่านี้บนคอนเทนเนอร์ทุกกระบวนการภายในคอนเทนเนอร์สามารถเข้าถึงได้พวกเขาสามารถมองเห็นได้ผ่าน / proc แอปอาจถ่ายโอนสภาพแวดล้อมไปยัง stdout ที่เก็บไว้ในบันทึกและที่สำคัญที่สุดคือปรากฏใน ล้างข้อความเมื่อคุณตรวจสอบคอนเทนเนอร์
ในตัวรูปภาพเอง: รูปภาพมักจะถูกผลักไปที่รีจิสเตอร์ที่มีผู้ใช้จำนวนมากสามารถดึงการเข้าถึงได้บางครั้งก็ไม่มีข้อมูลรับรองที่จำเป็นในการดึงรูปภาพ แม้ว่าคุณจะลบความลับออกจากเลเยอร์เดียวภาพก็สามารถถอดประกอบได้ด้วยยูทิลิตี้ Linux ทั่วไปเช่นtar
และสามารถดูความลับได้จากขั้นตอนที่เพิ่มลงในภาพครั้งแรก
แล้วตัวเลือกอื่น ๆ สำหรับความลับในคอนเทนเนอร์ Docker มีอะไรบ้าง?
ตัวเลือก A:หากคุณต้องการความลับนี้ในระหว่างการสร้างอิมเมจของคุณเท่านั้นไม่สามารถใช้ความลับนี้ได้ก่อนที่การสร้างจะเริ่มต้นและยังไม่มีสิทธิ์เข้าถึง BuildKit การสร้างแบบหลายขั้นตอนเป็นตัวเลือกที่ไม่ดีที่สุด คุณจะต้องเพิ่มความลับในขั้นตอนเริ่มต้นของการสร้างใช้ที่นั่นจากนั้นคัดลอกผลลัพธ์ของขั้นตอนนั้นโดยไม่มีความลับไปยังขั้นตอนการเผยแพร่ของคุณและผลักขั้นตอนการเผยแพร่นั้นไปยังเซิร์ฟเวอร์รีจิสทรีเท่านั้น ความลับนี้ยังคงอยู่ในแคชรูปภาพบนบิลด์เซิร์ฟเวอร์ดังนั้นฉันมักจะใช้สิ่งนี้เป็นทางเลือกสุดท้ายเท่านั้น
ตัวเลือก B:นอกจากนี้ในช่วงเวลาสร้างหากคุณสามารถใช้ BuildKit ซึ่งเปิดตัวใน 18.09 ขณะนี้มีคุณลักษณะทดลองที่อนุญาตให้ใส่ข้อมูลลับเป็นตัวกำหนดโวลุ่มสำหรับบรรทัด 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 Mode หรือการควบคุมอื่น ๆ คุณสามารถเมานต์หนังสือรับรองเป็นโวลุ่มอ่านอย่างเดียว การเข้าถึงข้อมูลประจำตัวนี้ต้องการการเข้าถึงแบบเดียวกับที่คุณมีภายนอกนักเทียบท่าในไฟล์ข้อมูลรับรองเดียวกันดังนั้นจึงไม่ดีหรือแย่ไปกว่าสถานการณ์ที่ไม่มีนักเทียบท่า สิ่งสำคัญที่สุดคือไม่ควรมองเห็นเนื้อหาของไฟล์นี้เมื่อคุณตรวจสอบคอนเทนเนอร์ดูบันทึกหรือพุชอิมเมจไปยังเซิร์ฟเวอร์รีจิสทรีเนื่องจากโวลุ่มอยู่นอกนั้นในทุกสถานการณ์ สิ่งนี้ต้องการให้คุณคัดลอกข้อมูลประจำตัวของคุณบนโฮสต์นักเทียบท่าแยกต่างหากจากการปรับใช้คอนเทนเนอร์ (หมายเหตุทุกคนที่มีความสามารถในการเรียกใช้คอนเทนเนอร์บนโฮสต์นั้นสามารถดูข้อมูลประจำตัวของคุณได้เนื่องจากการเข้าถึง 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 ตอนนี้เรามีการสนับสนุนลับที่ดีกว่า Volume ด้วยโหมด Swarm ไฟล์จะถูกเข้ารหัสบนระบบไฟล์ตัวจัดการ (แม้ว่าคีย์ถอดรหัสมักจะอยู่ที่นั่นด้วยทำให้ตัวจัดการสามารถเริ่มต้นใหม่ได้โดยที่ผู้ดูแลระบบไม่ต้องป้อนคีย์ถอดรหัส) ที่สำคัญกว่านั้นความลับจะถูกส่งไปยังคนงานที่ต้องการความลับเท่านั้น (ใช้งานคอนเทนเนอร์ที่มีความลับนั้น) มันจะถูกเก็บไว้ในหน่วยความจำบนคนงานเท่านั้นไม่เคยใส่ดิสก์และจะถูกฉีดเป็นไฟล์ลงในคอนเทนเนอร์ด้วย tmpfs เมานต์ ผู้ใช้บนโฮสต์นอกฝูงไม่สามารถเชื่อมต่อความลับนั้นลงในคอนเทนเนอร์ของตนเองได้โดยตรงอย่างไรก็ตามด้วยการเข้าถึง 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
คุณเปิดโหมดจับกลุ่ม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/.aws
เป็นโฮมไดเร็กทอรีของผู้ใช้
:ro
- ย่อมาจากวอลุ่มนักเทียบท่าอ่านอย่างเดียว
จะมีประโยชน์มากเมื่อคุณมีหลายโปรไฟล์ใน~/.aws/credentials
ไฟล์และคุณกำลังใช้ MFA ด้วย นอกจากนี้ยังมีประโยชน์เมื่อคุณต้องการทดสอบ Docker-container ในพื้นที่ก่อนที่จะปรับใช้กับ ECS ที่คุณมีบทบาท IAM แต่ในเครื่องคุณไม่ทำ
"%UserProfile%\.aws"
ตั้งอยู่ ผมคิดว่าคุณต้องเปลี่ยน - ~/.aws/:/root/.aws:ro
เป็น- %UserProfile%\.aws:/root/.aws:ro
- host:container
ไวยากรณ์หากไฟล์ / โฟลเดอร์ไม่มีอยู่ในโฮสต์ที่สร้างขึ้น (เป็นรูท) และ awscli จะไม่ขอบคุณที่ป้อนไฟล์เป็นศูนย์ไบต์ คุณควรใช้ "แบบยาว" ที่ระบุประเภทคือการผูกพา ธ โฮสต์และพา ธ คอนเทนเนอร์ในบรรทัดแยกกันซึ่งจะล้มเหลวหากไม่มีไฟล์ซึ่งเป็นสิ่งที่คุณต้องการใน 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