تم إعداد ترجمة للمقال قبل بدء دورة Python Web Developer .
عند إنشاء صورة Docker ، قد تحتاج إلى أسرار ، مثل كلمة مرور لمستودع الحزمة الخاصة. لا تريد أن ينتهي هذا السر في الصورة ، لأنه بعد ذلك سيتمكن أي شخص يمكنه الوصول إلى الصورة من الوصول إلى مستودعك الخاص.ملاحظة : إذا كنت تعتقد "لماذا لا تستخدم متغيرات البيئة فقط؟" والتي يتم استخدامها للأسرار في وقت التشغيل عند إنشاء صورة. تركز هذه المقالة على أسرار البناء التي يتم استخدامها عند إنشاء صورة باستخدام ملف Docker.
تحتفظ الإصدارات الأحدث من Docker بالأسرار باستخدام خدمة BuildKit التجريبية ، وفي Docker Compose 1.25 والإصدارات الأحدث ، يمكنك بالفعل إنشاء صور باستخدام BuildKit. لسوء الحظ ، اعتبارًا من مارس 2020 ، لا تزال القدرة على العمل بأمان مع أسرار Compose قيد التطوير .اذا ما العمل الآن؟ ماذا نفعل الآن؟في مقالة اليوم ، سأوضح كيف يمكنك استخدام نفس ملف Dockerfile لإنشاء صور أسرار بشكل آمن دون فقدان مزايا التطور السريع باستخدام Docker Compose.خياران لاستخدام ملف إرساء الخاص بك
من السهل جدًا استخدام نفس ملف Dockerfile للإنتاج وللتطوير المحلي باستخدام Docker Compose. عادةً ما تستخدم ملف Dockerfile مع وظيفة الإنشاء من Compose:version: "3.7"
services:
yourapp:
build:
context: "."
ثم يمكنك القيام بما يلي:$ docker-compose up
باستخدام هذا الأمر ، يمكنك (إعادة) تجميع الصورة ثم تشغيلها.للاستخدام في الإنتاج ، تقوم بجمع الصورة وإرسالها بالدفع :$ docker build -t myimage .
$ docker push myimage
وبينما كل شيء يسير على ما يرام. ولكن ماذا لو كنت بحاجة إلى بناء سري؟المحاولة الأولى (غير آمنة)
لنفترض أن لديك نصًا برمجيًا يحتاج إلى بنية سرية ، على سبيل المثال ، لتنزيل حزمة Python من مستودع DevPI خاص . من أجل البساطة ، سنستمد السر بكل بساطة بمساعدة use-secret.sh
لإثبات أننا نمتلكه.
set -euo pipefail
echo "Secret is: $THEPASSWORD"
يمكنك ببساطة تمرير السر باستخدام وسيطات بناء Docker ، حيث يتم دعمها في كل مكان ، بما في ذلك Docker Compose.ملاحظة : بعد تجاوز نطاق مناقشتنا ، أود أن أقول إن استخدام ملفات Docker في هذه المقالة ليس أفضل ممارسة ، ومع ذلك ، يمكن أن يتداخل التعقيد المفرط مع نقل المعنى الرئيسي للمقالة.
لذلك ، إذا كنت تريد تشغيل تطبيق Python الخاص بك عند الإنتاج باستخدام Docker ، فإليك طريقتان جيدتان للقيام بذلك:FROM python:3.8-slim-buster
ARG THEPASSWORD
COPY use_secret.sh .
RUN ./use_secret.sh
يمكننا أن نكتب docker-compose.yml
، والتي ستنتقل سرا:version: "3.7"
services:
yourapp:
build:
context: "."
args:
THEPASSWORD: "s3kr!t"
للعمل المحلي ، يمكنك تشغيل أو إنشاء صورة باستخدام Compose:$ docker-compose build | grep Secret
Secret is: s3kr!t
وكل شيء جيد.ويمكننا أيضًا تجميع الصورة باستخدام Docker ، استعدادًا لنقلها إلى سجل الصور:$ docker build -t myimage --build-arg THEPASSWORD=s3krit . | grep Secret
Secret is: s3krit
القيام بذلك غير آمن: لا تفعل ذلك أبدًا . إذا قررنا إلقاء نظرة على طبقات الصورة ، فسنرى السر يكمن فيها!$ docker history myimage
IMAGE CREATED CREATED BY SIZE
c224231ec30b 47 seconds ago |1 THEPASSWORD=s3krit /bin/sh -c ./use_secre… 0B
6aef62acf0db 48 seconds ago /bin/sh -c
f88b19ca8e65 About a minute ago /bin/sh -c
...
أي شخص يمكنه الوصول إلى هذه الصورة سيتعرف على كلمة مرورك. ما الذي يمكن فعله عندئذ؟أسرار BuildKit (حل جزئي)
BuildKit هو حل جديد (ولا يزال تجريبيًا) لإنشاء صور Docker ، والتي تضيف ، من بين أمور أخرى ، دعمًا للاستخدام الآمن للأسرار أثناء التجميع . تتمتع Docker Compose بدعم BuildKit منذ الإصدار v1.25.ولكن هناك مشكلة واحدة: لا يزال Docker Compose لا يدعم وظيفة أسرار BuildKit. يجري العمل الآن على هذا ، ولكن اعتبارًا من مارس 2020 ، لا توجد حلول جاهزة ، ناهيك عن إصدار مستقر.لذلك ، سنقوم بدمج هذين النهجين:- ستواصل Docker Compose استخدام وسيطات الإنشاء لتمرير الأسرار ؛
- للحصول على صورة إنتاج تم إنشاؤها باستخدام بناء عامل الميناء ، نستخدم BuildKit لتمرير الأسرار.
بهذه الطريقة يمكننا استخدام نفس ملف Dockerfile للعمل محليًا وعلى الإنتاج.يعمل BuildKit مع الأسرار كما يلي: تم تحميل الملف مع الأسرار في دليل مؤقت أثناء تنفيذ الأمر RUN ، على سبيل المثال ، في /var/secrets/thepassword
. نظرًا لأنه تم تحميله أثناء تنفيذ الأمر RUN ، فلن تتم إضافته إلى الصورة النهائية.سنقوم بتعديل الملف use_secret.sh
للتحقق من وجود مثل هذا الملف المؤقت. إذا كان موجودًا ، فإنه يستخدم إعدادات متغير البيئة الخاصة به $THEPASSWORD
. إذا لم يكن الملف موجودًا ، فسنعود إلى متغير البيئة. أي أنه $THEPASSWORD
يمكن تثبيته باستخدام BuildKit أو بناء الوسائط:
set -euo pipefail
if [ -f /run/secrets/thepassword ]; then
export THEPASSWORD=$(cat /run/secrets/thepassword)
fi
echo "Secret is: $THEPASSWORD"
ثم سنقوم بتعديل ملف Dockerfile لإضافة BuildKit وتركيب السر:
FROM python:3.8-slim-buster
ARG THEPASSWORD
COPY use_secret.sh .
RUN --mount=type=secret,id=thepassword ./use_secret.sh
docker-compose.yml
نحن لا نغير الملف :version: "3.7"
services:
yourapp:
build:
context: "."
args:
THEPASSWORD: "s3kr!t"
الآن تحتاج إلى تحديد متغيرين للبيئة ، أحدهما سيخبر Docker أنك بحاجة إلى استخدام BuildKit ، والثاني الذي يحتاج Compose إلى استخدام إصدار CLI من Docker ، وبالتالي BuildKit. سنكتب أيضًا سر الملف:$ export DOCKER_BUILDKIT=1
$ export COMPOSE_DOCKER_CLI_BUILD=1
$ echo 's3krit' > /tmp/mypassword
باستخدام Compose ، نستخدم وسائط البناء:$ docker-compose build --progress=plain \
--no-cache 2>&1 | grep Secret
يرجى ملاحظة أنه من --no-cache
الضروري أن نفهم أن الصورة ستعاد بناءها حقًا إذا قمت بنفسك بتشغيل كل ما سبق. في الواقع ، يمكن حذف هذه المعلمة. 2>&1
إعادة التوجيه stderr
إلى stdout
العملية الصحيحة grep
.عندما نكون مستعدين للبناء على الإنتاج ، نستخدم بناء عامل الميناء مع وظائف الأسرار من BuildKit:$ docker build --no-cache -t myimage \
--secret id=thepassword,src=/tmp/mypassword \
--progress=plain . 2>&1 | grep Secret
هل هو آمن؟
دعونا نتأكد من أن السر غير مرئي:$ docker history myimage
IMAGE CREATED CREATED BY SIZE
a77f3c32b723 25 seconds ago RUN |1 THEPASSWORD= /bin/sh -c ./use_secret.… 0B
<missing> 25 seconds ago COPY use_secret.sh .
...
مرحى! قمنا بتمرير السر إلى ملف Dockerfile نفسه باستخدام Compose docker build
، وفي الحالة الأخيرة لم نكشف عن السر من التجميع.
تعلم المزيد عن الدورة.