Moby: جعل uid & gid قابلين للتهيئة لوحدات التخزين المشتركة

تم إنشاؤها على ٢٣ يوليو ٢٠١٤  ·  141تعليقات  ·  مصدر: moby/moby

يرجى توفير خيار لجعل ملكية وحدات التخزين المشتركة قابلة للتكوين.

على سبيل المثال ، حالة الاستخدام الحالية الخاصة بي هي تشغيل معيد إعادة توجيه logstash داخل حاوية ، والتي تحتوي على / var / lib / docker مشتركة للقراءة فقط كوحدة تخزين من المضيف.

نظرًا لأنه تم تعيين / var / lib / docker على 0700 root: الجذر على المضيف ، لا يمكنني الوصول إلى وحدة التخزين كمستخدم غير جذر.

ما أود الحصول عليه هو شيء مثل NFS حيث يمكن للمرء تعيين uid & gid من المضيف إلى المستخدمين والمجموعات على العميل.

أي docker run -v / var / lib / docker: / var / lib / docker: ro : $ user: $ group سيجعل الحجم متاحًا في الحاوية للقراءة فقط ، ينتمي إلى $ user: $ group.

kinfeature

التعليق الأكثر فائدة

نحتاج حقًا إلى حل go-to (وليس gosu) عبر الأنظمة الأساسية لتعيين uid / gid. تسبب هذه المشكلة وحدها أضرارًا جسيمة لكيفية إدراك المبتدئين لعمال الرصيف.

ال 141 كومينتر

لا أعرف _كيف_ قاموا بتنفيذ ذلك ، وإذا كانت هناك ميزة قابلة للمقارنة على Linux ، ولكن في OS X ، توجد ميزة "لتجاهل الملكية" على وحدة تخزين. سيؤدي هذا بشكل فعال إلى جعل أي مستخدم يرى الملفات / الدلائل كما لو كان المالك.

على الرغم من أن هذا لن يخدم جميع الحالات ، إلا أنه قد يكون إضافة جيدة

يتعامل gh # 5910 مع هذا من جانب SELinux.

الرابط: # 5910 ؛)

يعمل تغيير SELinux في الواقع على تغيير التسميات الموجودة على المحتوى. من المحتمل أن تفعل التغيير على المضيف. لا أعرف أي طريقة أخرى للقيام بذلك لـ UID / GID. لكن عمل chown -R $ UID: $ GID على نقطة التركيب.

أو يمكنك إضافة هذا النوع من الوصول باستخدام قوائم التحكم في الوصول. لكنني أعتقد أنك ستحتاج إلى تغيير كل INODE في نقطة التثبيت.

أنا أيضا بحاجة إلى هذه الميزة.

على سبيل المثال ، أريد إنشاء حاوية ويب وإرفاق مجلدات بمواقع الويب والتكوينات بها ، بحيث تكون هذه الحاوية شاملة تمامًا لأي عدد من مواقع الويب.

ومع ذلك ، أحتاج إلى وصول git لدفع الكود إلى مستودع موقع الويب. نظرًا لأنني أرغب في عزل تطبيقاتي - أريد أن يكون كل دليل موقع ويب مملوكًا لمستخدم / مجموعة منفصلة ، وسيكون من الرائع أن تكون الملفات المكتوبة بواسطة حاوية Docker في وحدة تخزين مملوكة لهذا المستخدم / المجموعة المنفصلة.

+1 لهذه الميزة.
لا أفهم كيف يمكن أن تعمل مجلدات القراءة / الكتابة بدونها. يُعد توقع أن يكون المعرف الفريد العمومي / uid هو نفسه على الصورة والمضيف مطلبًا قويًا لا يتوافق مع مبادئ عزل Docker.

أنا شخصياً أعمل على حل هذا الأمر باستخدام أوامر useradd / groupadd القبيحة والبطيئة لأدوات التطوير Dockerized الخاصة بي: https://github.com/ndless-nspire/Ndless/blob/master/ndless-sdk/bin-docker/nspire-docker

قد أفتقد النقطة تماما. لكنني كنت أعاني من مشكلة مماثلة حيث أريد التأكد من أن مستخدم http لديه أذونات الكتابة على / var / log ، وهو وحدة تخزين ومن المحتمل أن يكون من المضيف مع الجذر: الجذر كمالك.

لقد قمت بحلها عن طريق تعيين نقطة إدخال تضمن إنشاء أدلة السجل والحصول على الأذونات الصحيحة. أعتقد أن هذا يعمل لأن البرنامج النصي لنقطة الدخول يعمل كجذر.

(تعليق تمت إزالته - علامة تبويب خاطئة ، آسف)

لقد اخترقت هذا في Ubuntu خارج Docker. قم بتثبيت حزمة bindfs وربط الدليل بمحتويات وحدة التخزين بمسار آخر أثناء تعيين UID و GID لتلك المستخدمة داخل الحاوية:

sudo bindfs -u UID -g GID oldpath newpath

ثم استخدم newpath كوحدة تخزين عامل إرساء. لا يزال Oldpath يظهر الملكية الصحيحة للمضيف ، newpath للضيف.

jjv المشكلة هي أن bindfs بطيئة حقًا.

@ cpuguy83 نعم إنه بعيد عن المستوى الأمثل ولكنه ربما يساعد شخصًا في موقف مشابه. كان هذا هو جعل الأشياء تعمل داخل آلة افتراضية للتطوير (لا يسمح vmhgfs بإعداد UID / GID) أثناء الإنتاج لا يزال يتعين على UID و GID التطابق بين المضيف والضيف ...

سيكون من الرائع حقًا استخدام نوع من وظائف bindfs عندما يقوم عامل التحميل بتنفيذ هذا ، على افتراض أنه لا يسبب الكثير من الأداء. بهذه الطريقة ، لن تضطر إلى التأكد من تشغيل الحاوية بصفتك المستخدم الصحيح. يجب أن يكون من الممكن أيضًا استخدام الأسماء المنطقية بدلاً من uid / gid الحرفي.

jsternberg إنه أداء رائع. يشبه إلى حد كبير استخدام مجلدات vbox المشتركة.

+1

بالنسبة لحالات استخدام التطوير المحلي ، أعتقد أن Docker بحاجة بالتأكيد إلى هذه الميزة. وفي هذه الحالة ، أريد أن تدعم هذه الميزة كلاً من Windows و OSX.

يبدو أن Vagrant يدعم هذا من خلال تعيين UID / PID للمستخدم المضيف مع المستخدم المتشرد. ولكن لغرض التطوير ، أريد حقًا استخدام Docker بدلاً من Vagrant ، نظرًا لأنه خفيف الوزن جدًا من Vagrant لتشغيل تطبيقات متعددة المضيف.

من فضلك قل لي ما الذي أفتقده هنا (ليس لدي أي خبرة مع Go) ، لكن ألا تقبل وظيفة Go Mount () العلامات؟ لا يمكن أن نسمح لأمر مثل
-v host/folder:container/folder -mount-as user:group
ألا يمكنك الحصول على uid / gid مع البحث (https://golang.org/src/os/user/lookup_unix.go)
ثم قم بتمريرها (uid = 1، gid = 1) كأعلام إلى Mount ()؟ (https://golang.org/src/syscall/syscall_linux.go؟s=19154:19249#L754)

لا تدعم أدوات ربط

يؤدي أيضًا فصل الخيار -v عن الخيار -mount-as إلى حدوث ارتباك عند وجود خيار متعدد -v

ما الحل الجيد لهذا؟ أرغب في استخدام Docker للتطوير النشط ، ولا يعد عدم وجود وحدة تخزين مركبة من نوع ما خيارًا حقًا حيث يتعين علي إعادة البناء في كل مرة أقوم فيها بإجراء تغيير في الكود الخاص بي.

السبب في أنني أرغب في استخدام Docker للتطوير النشط هو أنه يتوافق مع بيئة الإنتاج الخاصة بي.

berfarah أستخدم عامل ميناء للتطوير النشط كل يوم.
نادرًا ما يكون هناك حالة عندما أحتاج إلى العبث مع التجاعيد.
إذا كنت تستخدم boot2docker على OSX ، فتأكد من أن dir الخاص بك يعمل داخل / المستخدمين ويجب أن تكون على ما يرام.

@ cpuguy83 شكرا على الرد السريع. أواجه مشكلات تتعلق بالأذونات في بيئة ريلز حيث لا يمكن كتابة السجلات ، وهناك أحيانًا نقاط فشل بسبب الأذونات. هذا بسبب أن خدماتي لها معرّف فريد مختلف عن أحد الملفات.

berfarah الحل البديل الخاص بي هو كتابة ملفات dockerfiles الخاصة بي بحيث يكون لمستخدمي / مجموعات الحاوية التي تمتلك الرمز نفس UID / GUID المستخدم الخاص بي. على سبيل المثال ، نظرًا لأن المستخدم المضيف الخاص بي UID هو 1000:

RUN \
    groupadd code_executor_group && \
    useradd code_executor_user -g code_executor_group -u 1000

berfarah هل لديك سجلات للانتقال إلى stdout / stderr لـ RAILS_ENV = التطوير؟

@ cpuguy83 لا تؤثر هذه المشكلة على OSX ؛ thaJeztah علق في 24 Jul 2014:

في OS X ، توجد ميزة "لتجاهل الملكية" على وحدة تخزين. سيؤدي هذا بشكل فعال إلى جعل أي مستخدم يرى الملفات / الدلائل كما لو كان المالك.

ncjones في الواقع ، الأمر نفسه ينطبق على OS X. "المجلدات" التي كنت أتحدث عنها هناك ، هي الأقراص الصلبة / الأقسام (المجلدات) المستخدمة في OS X نفسه. أشك في أن هذا يحدث فرقًا في العمل مع Boot2Docker ، لكنني لست متأكدًا.

كان الهدف من تعليقي هو معرفة ما إذا كان هناك شيء ما _similar_ ممكن في Linux (وبالتالي داخل Boot2Docker VM)

آسف للارتباك هناك.

ryneeverett شكرا ، هذا مفيد. هل انتهيت بعد ذلك من تعديل الأذونات إلى 775 من 755 و 664 من 644 على التوالي حيث تحتاج إلى ذلك؟ تحرير: مهارات القراءة!

@ cpuguy83 شكرا! يبدو أن هذا إصلاح أكثر تقييدًا من حل ryneeverett ، لأنه ليس شيئًا يمكنني المضي قدمًا في جميع المشاريع.

berfarah سعيد لأنك وجدت هذا مفيدًا. نعم ، أنا فقط أتأكد من أن ملفات مضيفي لديها الأذونات الصحيحة وأن Docker يحتفظ بها في المجلدات.

+1

هذا شيء سيكون مفيدًا للغاية للأحجام المشتركة من خلال عامل الإرساء ، ويعالج مشكلة أمنية لدي:

  • وحدات التخزين المشتركة حيث يتم تعيين uid و gid للحاوية عن طريق الخطأ إلى مستخدم غير جذر ذي امتياز على المضيف. (على سبيل المثال ، يتم تعيين الملفات التي تم إنشاؤها بواسطة الحاوية على المضيف لمستخدم يمكنه sudo w / o passwd ، والوصول إلى المحتوى المقيد بخلاف ذلك ، وما إلى ذلك)

سيكون إصلاح هذا مناسبًا جدًا لأصحاب المؤسسات الذين يشغلون عددًا كبيرًا من الحاويات مع Apache أو بعض البرامج الوسيطة ومشاركة وحدات تخزين التسجيل و / أو أدلة المحتوى / التحميل المختلفة. لقد عانيت شخصيًا من بعض المشاكل مع هذه الأذونات أثناء تخزين تطبيقات المستخدم النهائي في حاويات في Linux (مثل syncomm / spotify). العديد من الحلول اليوم هي نفسها إشكالية. في النهاية ، يجب إصلاح هذا داخل عامل الإرساء. لا أشعر بالراحة بشكل خاص عند تشغيل البرامج النصية لقشرة الجذر كنقطة إدخال ، خاصةً عندما تسلط هذه المشكلة الضوء على كيفية تعيين uid / gid 0: 0 في الحاوية إلى الجذر على مضيفي. يعجبني الاقتراح الأولي "docker run -v / var / lib / docker: / var / lib / docker: ro : $ user: $ group".

syncomm سأتبع النهج المعاكس تمامًا.
لا يستطيع Docker وضع افتراضات حول ملكية بياناتك.

سيكون النهج الذي تبرزه في الجزء السفلي من تعليقك ممكنًا إذا أردنا تعيين هذه الملفات الحقيقية تلقائيًا إلى fs القائم على الصمامات حيث يمكننا تغيير uids / gids ... وهذا من شأنه أن يؤدي إلى تأثير كبير على الأداء.

وسرعان ما لن يكون uid 0 في الحاوية uid 0 على المضيف ... مما يجعل ملكية الملفات أكثر صعوبة.

هل هذه نسخة مكررة من # 2259؟

@ cpuguy83 شكرًا على التعليقات ، على الرغم من أنني لست متأكدًا مما

أوافق على أنه مثل حل bindfs ، فإن جعله غلافًا مصهرًا سيتحمل بعض النفقات العامة العميقة. ومع ذلك ، يجب أن يكون هناك مخرج من هذا اللغز دون عقوبات ضخمة. بشكل أساسي ، تتصرف الحاوية بشكل صحيح (كما لو كانت جهازًا فريدًا منفصلاً عن المضيف) ، وعندما نقوم بتركيب دليل مضيف كوحدة تخزين ، فإنه (بشكل صحيح) نرى نظام ملفات POSIX هناك والأذونات وكل شيء. لسوء الحظ ، هذا يجعل من الصعب حقًا مشاركة البيانات بين "المضيفين" بطريقة متسقة. يتم استخدام أشياء مثل nfs و cifs وما إلى ذلك لهذا الأمر وتدعم تعيين uid و gid - أعتقد أنه يمكن أن يكون هناك تشابه هنا في حل المشكلة. بصراحة ، أحتاج إلى البحث في الريبو أكثر لمعرفة مكان حدوث ذلك في الكود وفهمه بشكل أفضل.

متى ستسقط التغييرات التي ذكرتها لملكية الملفات؟ إن عدم كون uid 0 هو نفسه بالنسبة للحاوية والمضيف سيجعلني في الواقع أشعر براحة أكبر عند إنشاء نقطة دخول لبرنامج نصي لقذيفة الجذر. بعد ذلك ، فإن الأمر يتعلق فقط بتنفيذ الحل البديل المقترح لتمرير uid / gid الصحيح كبيئة عمل والقيام بوظيفة adduser عند تشغيل الحاوية.

syncomm لسوء الحظ ، لم

في نهاية المطاف ، يبدو هذا وكأنه شيء يتطلب دعم kernel لإعادة رسم خرائط ثنائية الاتجاه كاملة لمعرفات UIDs و GIDs ، ولا يبدو من السهل إدارتها.

بالنسبة للسيناريوهات غير الحساسة للأداء ، ربما يمكن عمل شيء باستخدام FUSE.

لا يزال +1 لحالات استخدام التطوير ، لأنني انتهيت من وجود ملفات مملوكة للجذر في منزلي.

بالنسبة لحالة الاستخدام الخاصة بي ، سيكون كافيًا إذا كان بإمكان عامل الإرساء تطبيق uid / gid وعلامة selinux المخصصة على وحدة تخزين المضيف عند إنشائه مع ترك الإذن والتسميات بمفردها إذا كان الدليل موجودًا بالفعل. حاليًا أقوم بالتغلب على ذلك من خلال وجود نقطة دخول منفصلة للصورة يتم تشغيلها كجذر فقط لإصلاح إذن وحدة التخزين.

ibukanov لا يمكنه تطبيق uid / gid ، لكن تسمية selinux قادمة.

@ cpuguy83 ما هو السبب التقني لعدم القدرة على تطبيق uid / gid مخصص عند إنشاء دليل وحدة تخزين مضيف؟

ibukanov انظر التعليقات أعلاه.

@ cpuguy83 أنا لا أرى من التعليقات ما هي المشكلة. بالنسبة لحالة المستخدم الخاصة بي ، لا أحتاج إلى إعادة تعيين uid / gid. حاليًا داخل الحاوية عند التشغيل كجذر يمكنني chown uid:gid /host_volume && chmod 770 /host_volume . ماذا سيكون لطيفًا إذا كان عامل التحميل يستطيع القيام بذلك من تلقاء نفسه عندما يقوم بإنشاء الدليل على المضيف خلف / host_volume. بهذه الطريقة لن أحتاج إلى اختراق لتوفير نقطة دخول إضافية في الحاوية فقط لأداء العملية المذكورة أعلاه كجذر حاوية ويمكن دائمًا تشغيل الكود باستخدام حساب غير الجذر.

ibukanov آه ، هذا شيء مختلف.
لا يقوم Docker ، عن قصد ، بإجراء تغييرات على dirs المضيف.
إذا فعلنا # 9092 ، إذا قام عامل التحميل بإنشاء dir ، فسوف يتعامل معها على أنها وحدة تخزين عادية (على سبيل المثال ، انسخ كل شيء في مسار وحدة التخزين في الحاوية إلى المضيف و chmod / chown كما كان في الحاوية).

@ cpuguy83 - حسنًا ، يقوم عامل

كتب @ cpuguy83 :

وسرعان ما لن يكون uid 0 في الحاوية uid 0 على المضيف ... مما يجعل ملكية الملفات أكثر صعوبة.

هل هناك مشكلة قائمة لتتبع هذا؟ لم أتمكن من العثور على واحد.

شكرا!

هل هناك مشكلة قائمة لتتبع هذا؟ لم أتمكن من العثور على واحد.

dato ابحث عن "مساحة اسم المستخدم" ؛ يمكن العثور على تطبيق أولي هنا: https://github.com/docker/docker/pull/12648 وهنا https://github.com/docker/docker/pull/11253

ولكن هناك العديد من المناقشات / القضايا التي سبقت ذلك :)

+1

فقط لأعلم أنني في نفس القارب مثل الجميع:

أنا أستخدم صورة nginx وأقوم بتركيب مجلد على / usr / shared / nginx / html من أجل التنمية المحلية. يعمل Nginx كـ www-data ، ولكن يتم تحميل الحجم كـ 1000:staff وهكذا أحصل على 403 forbidden .

MrMMorris لا أعتقد أن هذا هو نفس القارب - هذه المشكلة هي عندما تكون الملفات التي تم إنشاؤها داخل حاوية (على وحدة تخزين محمولة) غير قابلة للقراءة خارج الحاوية دون الوصول إلى sudo. يحتاج مستخدم www-data الخاص بك فقط إلى الوصول للقراءة إلى الملفات التي تم تحميلها ، لذا يجب أن تكون قادرًا فقط على chmod a+r على ملفاتك.

يبدو أن ncjones chmod / chown ليس له أي تأثير على الأذونات في الحاوية

أنا في حيرة من أمري لأنني أقسم أن هذا نجح في نقاط متعددة أثناء استخدامي ...

حسنًا ، هذا محرج ...

يبدو إما بعد الترقية لإنشاء 1.3.0rc-1 (ربما لا) أو حذف جميع الحاويات / الصور وتشغيل docker-compose up مرة أخرى قد أصلح كل شيء .... لا مزيد من 403 forbidden

كنت أعلم أنه كان يعمل من قبل بطريقة أو بأخرى ، لذا اتبعت نهج ol ' rm -rf * ..

أحتاج أيضًا إلى حل هذه المشكلة بطريقة ما. لدي صورة عامل إرساء أستخدمها لتنفيذ بعض أعمال التجميع الثقيلة التي يجب عزلها. لذلك يجب أن ترتفع الحاوية ، وتتلقى بعض المدخلات الخارجية ، ثم تقوم بمعالجة ثم ستنتج الثنائيات (الإخراج). بدون إدارة إذن مناسبة ، كانت محاولة الحصول على هذا العمل كابوسًا. يجب أن تكون صوري محمولة لذا لا يمكنني تحمل الكثير عن المضيف.

alercunha في حالتك ، يبدو جيدًا أن تستخدم مستخدمًا واحدًا داخل حاوية عامل الإرساء ، أي التجميع كجذر

تضمين التغريدة
لقد عملنا على حل هذه المشكلة في إعداد بناء من خلال جعل حاوية Docker تخفف من إخراج الإنشاء. سيحتوي ملف Dockerfile الخاص بنا على شيء مثل:

env USER_ID 1000
env GROUP_ID 1000
cmd bash -lc '\
  build.sh && \
  chown -R $USER_ID:$GROUP_ID build \
'

يمكن بعد ذلك توفير uid / gid الفعلي لمستخدم مضيف Docker إلى الحاوية عند التشغيل. على سبيل المثال ، سيستخدم أمر Jenkins build شيئًا مثل:

docker run \
  -e USER_ID=`id -u` \
  -e GROUP_ID=`id -g` \
  -v $basedir:/workspace

motin Building as root هو شيء أحاول تجنبه لأنني أستخدم docker / buildroot لبناء العديد من مشاريع الطرف الثالث. الفكرة هي الحصول على بعض الحماية ضد هذا الكود المصدري العبث ببيئة البناء الخاصة بي. لذا فإن البناء كجذر لا يبدو فكرة جيدة.

@ ncjones شكرا! هذه في الواقع فكرة جيدة ، قد تعمل بشكل جيد كحل في حالتي الخاصة.

alercunha في هذه الحالة ، قد يكون من المفيد التفكير في استخدام صور / حاويات منفصلة لكل مشروع تابع لجهة خارجية. يمكن أن يفيد ذلك أيضًا مجتمع المصدر المفتوح بشكل أفضل ، على سبيل المثال إذا قمت بإرسال صور عامل ميناء رسمية لبناء كل مشروع من مشاريع الطرف الثالث.

لمنح جميع الامتيازات لـ www-data ، يمكنك استخدام:

RUN usermod -u 1000 www-data

تمت مواجهة مشكلة عند تشغيل مهمة في عامل إرساء على وحدة تخزين مُثبتة. كانت الملفات الناتجة مملوكة للجذر ولا يمكن إدارتها بواسطة المستخدم الذي يقوم بتشغيل أمر عامل الإرساء. الحل الحالي هو تشغيل المتابعة بعد المهمة لإصلاح الأذونات.

docker run -t --rm \
    -v $PWD:/usr/src/app \
    -w /usr/src/app \
    debian:wheezy chown -R $(id -u):$(id -g) ./

هل من الممكن أن يقوم عامل الإرساء بتغيير الإذن الخاص بوحدات التخزين المثبتة على المضيف بحيث تكون مملوكة للمستخدم المحدد في أمر المستخدم الخاص بملف DockerFile؟ من الواضح أن الأذونات يجب أن تكون قابلة للتكوين ولكن يمكننا الحصول على هذا السلوك الافتراضي.

@ ميج فوكسبات
بالنسبة لأغراضي ، سيكون كافيًا إذا قام عامل الإرساء بتعيين الملكية والإذن على دليل المضيف من نقطة التحميل في الصورة عند إنشاء دليل المضيف لأول مرة. إذا كان دليل المضيف موجودًا بالفعل ، فقد يتركه عامل الإرساء بمفرده.

@ mig-foxbat & ibukanov ، كان الشرط الأساسي الإلزامي بالنسبة لي ، عند فتح هذه المشكلة ، هو أن الأذونات على نظام ملفات المضيفين لا تتغير (كما هو الحال في بعض الخرائط الافتراضية في الحاوية المشابهة لما يمكن للمرء فعله مع _NFS_).

ما تحاول القيام به يمكن القيام به بسهولة اليوم عن طريق تشغيل _chown_ في بعض البرامج النصية لبدء التشغيل داخل الحاوية الخاصة بك.

أحب بنية المكونات الإضافية ذات الحجم القادم ، لكنني أفضل كثيرًا أن يضيف فريق Docker هذه الميزة. يعمل Docker جيدًا حتى تستخدم وحدات التخزين مع مستخدم غير جذر في الحاوية الخاصة بك. ثم عندما لا تعمل الأشياء (على سبيل المثال ، التسجيل) ، إما أن ترمي الكمبيوتر المحمول من خلال نافذة Starbucks أو تجد عنصر stackoverflow المشار إليه أعلاه.

+1 أريد أن يكون لدي حاويات تقوم بتشغيل التطبيقات كمستخدم غير جذر ، الأمر الذي يصبح معقدًا بسبب هذه المشكلة.

لماذا لا يتم تنفيذ هذه الميزة باستخدام قدرة id_map في LXC؟

لقد لاحظت للتو أن الإجابة على "id_map" (المعروفة أيضًا باسم دعم مساحة اسم المستخدم) مذكورة أعلاه بالفعل بواسطةthaJeztah

في حين أن الأمر يتطلب القليل من العمل الإضافي لتعيين الأذونات ، فإننا نشغل عشرات الحاويات على أنها غير جذر ونتجنب مشاكل الأذونات. تبدأ معظم حاويات البيانات لدينا بشيء مثل:
قنصل ENV CONTAINER_USER
ENV CONTAINER_UID 312312
RUN adduser -D $ CONTAINER_USER -u $ CONTAINER_UID
RUN mkdir -p / var / consul /
CMD chown $ CONTAINER_USER. $ CONTAINER_USER / var / consul /

مع تشابه حاوية التشغيل الفعلية من حيث إعداد معلومات UID / المستخدم. هذا بعض الأعمال المكررة (الحاجة إلى تعيين UID على كل من حاوية البيانات وحاوية التشغيل) على الرغم من أنها صغيرة إلى حد ما. إن الحصول على أذونات تغيير عامل الإرساء أو أذونات الخريطة أثناء التنقل من شأنه أن يضيف بعض التعقيد اللائق وسيتعين على المستخدمين توخي الحذر أكثر من منظور الأمان. أنا أيضًا أؤيد أي شيء يساعد في تقليل تعقيد سطر الأوامر ، لذلك إذا كان كل شيء موجودًا ذاتيًا في ملف الرصيف ، فسيكون ما يحدث أكثر وضوحًا.

توجد الآن الملاحظة أعلاه لمحاولة الوصول إلى ملفات المضيف في حاوية بنوع من التعيين. أعتقد أن هذا بالتأكيد اقتراح محفوف بالمخاطر. غالبًا ما تكون محاولة مشاركة الملفات دون تعيين مباشر للمضيف هو الحل الأفضل ، وإلا فإنك تقوم بعكس أمان عامل الميناء إلى حد ما. بدلاً من الحاوية التي تحتوي على أذونات أقل مما لو كان الأمر بخلاف ذلك ، فأنت تتحدث عن حاوية تعمل على أنها ليست جذر لها وصول إلى مستوى الجذر (يُفترض غالبًا استخدام الحالة) لاستضافة الملفات. أذونات المجموعة أو الحلول الأخرى التي أشعر أنه يجب الفوز بها في معظم المواقف.

لقد عملت على حل هذا الأمر باستخدام برنامج نصي لشل نقطة الدخول يقوم بتشكيل الدليل المُثبت وينفذ الأمر الفرعي عبر su.

مثال في حاوية solr حيث تم تثبيت الدليل / data في شكل وحدة تخزين من المضيف:

#!/bin/bash

chown -R $SOLR_USER:$SOLR_USER /data

su -c "$@" -m $SOLR_USER

_USER POLL_

_ أفضل طريقة للحصول على إشعار عند حدوث تغييرات في هذه المناقشة هي النقر فوق الزر "اشتراك" في أعلى اليسار.

قدّر الأشخاص المدرجون أدناه مناقشتك الكاملة مع إجراء +1 عشوائي:

تضمين التغريدة
تضمين التغريدة
scue
تضمين التغريدة
@شبح
تضمين التغريدة
تضمين التغريدة
تضمين التغريدة
@يحتوي على
hadim
iyn
تضمين التغريدة
تضمين التغريدة
تضمين التغريدة
تضمين التغريدة
تضمين التغريدة
تضمين التغريدة
تضمين التغريدة
edavism
ayeo
تضمين التغريدة
تضمين التغريدة
@ توني كرز
تضمين التغريدة
تضمين التغريدة
هههههههههههههه
@ qm78
تضمين التغريدة
تضمين التغريدة
تضمين التغريدة
@ أفا ديلانغ

يؤدي قول أي شيء في سلاسل الرسائل هذه إلى اشتراك المستخدم تلقائيًا ، لذلك نعم ، يتم اشتراك كل هؤلاء الأشخاص ما لم يتم إلغاء اشتراكهم عن قصد بالإضافة إلى ذلك. (لست متأكدًا أيضًا من _ من_ الذي تشير إليه على أنه your )

هذا بالتأكيد أمر لا بد منه. يجب أن يعيد عامل Docker تعيين معرفات المستخدم بشكل صحيح. وإلا فإن كل شيء يتم إنشاؤه من الحاوية إلى وحدة تخزين نظام التشغيل المضيف مملوك للجذر. الحل رهيب - تغيير المستخدمين داخل الحاوية مما يؤدي إلى كل أنواع المضاعفات ، الاضطرار إلى التشويش في كل مكان ، ينمو Dockerfile مع القبح. والأسوأ من ذلك كله أن UIDs ذات التشفير الثابت تجعل الحاويات غير قابلة للنقل!

+1 ستكون هذه الميزة محل تقدير كبير ، لأنني أريد تجنب التبديل بين حاوية عامل الإرساء ونظام المضيف الخاص بي ، فقط لتجنب الكتابة فوق معرف المستخدمين على الملفات.

الحصول على تخصيص UID ممكن الآن ، ولكن ضمن القيود التالية:

  • يمكن تخصيص Uid بجعل الحاوية تقبل المعرف (المعرفات) الذي تحتاجه عبر متغير البيئة. يمنح هذا المضيف سيطرة كاملة على uid (s) الذي تستخدمه الحاوية ، وله فائدة إضافية: يمكن تعيين متغيرات متعددة على نفس قيمة uid. إعادة تعيين Uid غير قادر على دعم تعيين Uid متعدد الحاوية إلى معرف مضيف واحد ، حيث يجب أن يكون التعيين 1: 1. على سبيل المثال ، إذا كان التعيين المطلوب هو في الواقع أن التطبيق يجب أن يعمل كـ uid = 0 ، فيمكنك القيام بذلك عن طريق الحقن بالمتغيرات ، ولكن ليس عن طريق إعادة تعيين المعرف. انظرncjones وmitchcapper حل أعلاه.
  • مع ذلك ، لا يمكن تغيير uid الجذر = 0 إلى قيمة مختلفة ، إلا من خلال إعادة التعيين: # 12648.

تحتوي جميع أطر تطوير الويب الحديثة تقريبًا على مجلد سجلات ومجلد ذاكرة تخزين مؤقت داخل المشروع ، محدد في تكوين المشروع ومشاركته عبر وحدة التخزين المركبة. لقد استخدمت vboxfs أولاً ولكن كان بطيئًا جدًا. لقد وجدت docker-machine-nfs لإنشاء حوامل NFS وهو سريع ، ولكن الآن ملفات الويب الخاصة بي في الحاويات مملوكة لـ 502: Dialout ولا يمكن أن يكون chmod أو chmod حتى لا يتم تشغيل تطبيق الويب الخاص بي. لقد جربت صندوق الرصيف المتشرد لكنه يتطلب متشردًا مع جميع المتغيرات والتكوينات البيئية المختلفة ، ولا يعمل بعد مع آلة الرصيف. حتى لو كانت عملية يدوية على المدى القصير ، فهل هناك حل بديل لإضافة المستخدم 502 إلى بيانات www أو شيء من هذا القبيل؟ هذا كل ما أحتاجه لأكون في العمل!

+1

لأولئك الذين يتابعون هذا ؛ يوجد حاليًا علاقات عامة لميزة تجريبية ستغير ملكية الملفات المثبتة بشكل متكرر. يجب استخدامه بحذر ، لأن هذه الميزة ستغير الملفات الموجودة على المضيف (والتي قد لا تكون ما تريده في جميع الحالات) ؛ راجع https://github.com/docker/docker/pull/14632 (و https://github.com/docker/docker/pull/16767)

+1

بالمناسبة ، لقد قمت بحل هذه المشكلة باستخدام ACL

kvaps ، العناية بالتفصيل؟

posita ، رهاني هو أن kvaps يتحدث عن POSIX ACLs . إذا كنت على حق ، فهذا ليس هو نفسه طلب OP.

posita ، denydias ، آسف للإجابة الطويلة. نعم ، أنا أتحدث عن هذا.
لدي العديد من الحاويات مثل owncloud و samba و minidlna. كل شخص يعمل مع مختلف uid و gid.
تعمل جميعها بنفس الملفات. ما الذي يمكن للجميع قراءة الملفات وكتابتها ، لقد قمت بتثبيت نظام ملفات بخيار acl في الجهاز المضيف ، ومنحت الجميع حقوق uid و gid لهذه الملفات ، مثل الأمر chown :

# give access for owncloud (apache uid 33):
setfacl -R -m "u:33:rwx" /data
# give access for samba (uid 1000):
setfacl -R -m "u:1000:rwx" /data
# give access for minidlna (uid 997):
setfacl -R -m "u:997:r-x" /data
# preserve this permissions for new files and folders:
setfacl -R -d -m "u:33:rwx" /data
setfacl -R -d -m "u:1000:rwx" /data
setfacl -R -d -m "u:997:r-x" /data

kvaps ، الأمر setfacl لا يعمل في Dockerfile . مثال:

FROM nginx

ADD data/conf /etc/nginx

RUN mkdir -p /etc/nginx/sites-enabled

VOLUME /etc/nginx

RUN setfacl -dR -m u:1000:rwx /etc/nginx && setfacl -R -m u:1000:rwx /etc/nginx

نتيجة:

root<strong i="12">@3975ac4fba98</strong>:/etc/nginx# getfacl sites-enabled/
# file: sites-enabled/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x

تعمل قوائم ACL فقط بعد التحميل على الجهاز المضيف وتشغيل setfacl . إصدار عامل ميناء:

Client version: 1.7.1
Client API version: 1.19
Go version (client): go1.4.2
Git commit (client): 786b29d
OS/Arch (client): linux/amd64
Server version: 1.7.1
Server API version: 1.19
Go version (server): go1.4.2
Git commit (server): 786b29d
OS/Arch (server): linux/amd64

من السهل جدًا القيام بذلك بشكل صحيح ، كما أنه من السهل جدًا القيام به. لذلك لا تفسدها!
الطريقة الصحيحة للقيام بذلك هي: في المرة الأولى التي يتم فيها تشغيل الحاوية ، يقوم المضيف بحقن المواد التي يجب أن تستخدمها الحاوية (كما هو موضح أعلاه).
أسوأ طريقة للقيام بذلك هي: توقع أن تفرض الحاوية متطلبات السوائل الخاصة بها على المضيف. هذا خطأ، خطأ، خطأ. على سبيل المثال ، ضع في اعتبارك حاويتين تشتركان في تحميل مشترك: حاوية واحدة تكتب الملفات للخدمة ، وحاوية أخرى تشغل httpd لخدمة الملفات. الآن ، إذا كان لكل من هاتين الحاويات تعريفات متنافسة لـ uid ، فسيتم كسر هذا النظام في أسوأ الأحوال ، أو يكون معيبًا في أحسن الأحوال. لن تكون قوائم ACL التي يتم تعيينها منطقية بالنسبة للمضيف ، ومن المحتمل أن تكون أوسع من اللازم ، مما يعني أنها الآن مشكلة أمنية. ارجوك لا تفعل هذا!! أفعلها بالطريقة الصحيحة.

متفق. يعد ترك التعيين بين UID في الحاوية حلاً جيدًا بما فيه الكفاية. أردت فقط أن يقود عامل الإرساء الطريق بالقدوة ، ويدعم تعيينات UID / GID في صور عامل الإرساء الرسمية.

تم حلها في وقت التشغيل ، دون الحاجة إلى chown .

لقد استخدمت شيئًا قريبًا من حل ncjones ، لكنني لا أريد ملفات chown لأنني لا أريد تعديلها على المضيف. لذلك اخترت تغيير UID عند بدء تشغيل الحاوية.

أنشأت مستخدمًا مخصصًا في Dockerfile :

RUN adduser --no-create-home --disabled-login --gecos "" username --uid 1000

أحدد برنامج نصي لبدء التشغيل في Dockerfile :

CMD ["/run.sh"]

لدي هذا السطر في نصي النصي /run.sh :

usermod -u $USER_ID username

الآن يمكنني اختيار USER_ID عند بدء الحاوية:

docker run -e USER_ID=$(id -u)

تمكنت من حل هذا باستخدام dockerfile args الجديد. لا يتطلب الأمر القيام بأي شيء خاص بعد بناء الحاوية ، لذلك اعتقدت أنني سأشاركها. (يتطلب Docker 1.9)

في Dockerfile:

# Setup User to match Host User, and give superuser permissions
ARG USER_ID=0
RUN useradd code_executor -u ${USER_ID} -g sudo
RUN echo 'code_executor ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER ${USER_ID} 

ثم للبناء:

docker build --build-arg USER_ID=$(id -u)

كل شيء آخر كالمعتاد :)

يحرر:
لقد كتبت هذا المنشور حول المشكلة الخاطئة (كان موضوعًا آخر متعلقًا بـ boot2docker).
آسف.

@ pa-de-solminihac usermod -u $USER_ID username سيغير معرّف المستخدم username وسيؤدي إلى تغيير ملكية الملفات في منزل username ، لكن كل ملف مملوك سابقًا بواسطة من المحتمل أن يصبح username خارج منزله غير قابل للقراءة / غير قابل للكتابة نظرًا لأنه ينتمي الآن إلى مستخدم مختلف

riquito أستخدمه مع مستخدم مخصص ، تم إنشاؤه في Dockerfile :

adduser --no-create-home --disabled-login --gecos "" username --uid 1000

لذلك لا توجد ملفات مملوكة سابقًا لـ username . لذلك أعتقد أنه لا توجد مشكلة ؛)

لمعلوماتك ، لا يعمل setfacl _لا_ على وحدات التخزين التي تعود إلى OS X:

root<strong i="7">@0da3c867240d</strong>:~# setfacl --default --recursive --modify u:500:rwx --modify g:500:rwx /opt/test
setfacl: /opt/test: Operation not supported

(في هذه الحالة ، تتم استضافة /opt/test من OS X عبر جهاز Docker و Boot2Docker. راجع أيضًا boot2docker / boot2docker # 581.)

posita هل تستخدم Virtualbox لاستضافة صورة boottodocker الخاصة بك؟ إذا كان الأمر كذلك ، فقد يكون ذلك في الواقع قيدًا على الطريقة التي يعمل بها virtualbox على المجلدات المشتركة. لقد واجهت الكثير من المتاعب في القيام بأي نوع من النفاذية العادية من خلال المجلد المشترك للمربع الظاهري.

@ ava-dylang ، هذه نقطة جيدة. ما ورد أعلاه عبر Docker Machine مع برنامج تشغيل Parallels ، والذي يستخدم تنفيذ المجلدات المشتركة الأصلية لـ Parallels ، والتي تبدو محدودة بالمثل. (راجع أيضًا https://github.com/docker/machine/issues/13#issuecomment-164320881 بخصوص اقتراح لهذه الأنواع من البيئات.)

FWIW ، كنت أواجه مشكلة في ملكية الملفات في المنفعة الخاصة بي ، سكوبا .

لقد عملت على حل المشكلة عن طريق إضافة نص برمجي "init" يقوم بإنشاء مستخدم في الحاوية بنفس UID / GID مثل المستخدم المستدعى في المضيف. انظر JonathonReinhart / scuba # 11 و JonathonReinhart / scuba # 13.

تبدو الملفات التي تم إنشاؤها في الحاوية الآن تمامًا كما لو تم إنشاؤها على المضيف.

_Update: _ الذي تسبب في حدوث مشكلات (JonathonReinhart / scuba # 22). بدلاً من ذلك ، قمت بإصلاحه عن طريق إنشاء /etc/passwd وأصدقائي ، بناءً على uid / gid للمستخدم المضيف ، وحقنته في الحاوية (انظر JonathonReinhart / scuba # 24).

+1

لجعلها أكثر قابلية للصيانة والأمان عند تشغيل المضيف في وضع المستأجرين المتعددين.

واجهت مشكلات في الإذن مع تثبيتات Wordpress ، عندما تشارك Wordpress بالكامل من المضيف إلى الحاوية مع وحدة تخزين.

في مجموعتي ، لدي صورة أساسية ، وهي دبيان مع تعديلاتي الأساسية وسيتم إنشاء كل صورة أخرى من هذه الصورة.

في الصورة الأساسية ، لدي هذا الجزء:

### Start of Nginx WEBSERVER setup
RUN mkdir -p /var/www
# Modify www-data user and set UID, GID to 500
# https://muffinresearch.co.uk/linux-changing-uids-and-gids-for-user/
RUN groupmod -g 500 www-data \
    && usermod -u 500 www-data \
    #&& `find / -user 33 -exec chown -h 500 {} \;` \
    #&& `find / -group 33 -exec chgrp -h 500 {} \;` \
    && usermod -g 500 www-data \
    && chown -R www-data:www-data /var/www \
    && chmod g+s /var/www
### End of Nginx WEBSERVER setup

لم يتم إنشاء www-data بواسطة تثبيتات php أو nginx. إنه مستخدم / مجموعة محددة بشكل افتراضي في دبيان وربما توزيعات أخرى. تقترح بعض تثبيتات PHP و Nginx استخدام هذا المستخدم في ملفات التكوين الخاصة بهما.

إذا كان UID / GID للمستخدم المضيف هو 500 (معظم UID / GID لمستخدم Linux الأول غير الجذر الافتراضي هو 500 أو 1000) ، فغير هذا البرنامج النصي www-data UID / GID للمستخدم إلى 500 من 33. بهذه الطريقة إذا أنت تشارك أي شيء من المضيف ، يعتقد Docker أن تلك الملفات والمجلدات يملكها مستخدم www-data !

في ملفات إعداد PHP-FPM ، اضبط المستخدم والمجموعة على www-data أيضًا.

في ملف nginx Dockerfile الخاص بك ، عليك أيضًا ضبط هذا:

# Allow Nginx to access /var/run/php-fpm/php-fpm.sock
RUN usermod -aG www-data nginx

بهذه الطريقة ، يمكن للمستخدم nginx الوصول إلى الملفات التي يمتلكها www-data (يمكنك تحديد اسم مستخدم nginx في ملفات التكوين nginx).

بعد هذا الاختراق ، لا يواجه تثبيت Wordpress الخاص بي أي مشكلات تتعلق بالإذن! جميع الملفات موجودة على المضيف + تحديث وورد يعمل بشكل لا تشوبه شائبة!

DJviolin لست متأكدًا من أن مشكلة مثل هذه هي المكان المناسب لبرنامج Wordpress التعليمي ، وأتردد في شرحها هنا. ومع ذلك ، بالنسبة للمبتدئين التعساء الذين قد يتعثرون بطريقة ما في هذا:

  1. ما نشرته يقدم الكثير من الافتراضات حول التثبيت - مثل قيم UID / GID ، أسماء المستخدمين والمجموعات ، إلخ. إنها ليست محمولة بشكل رهيب عبر التوزيعات.
  2. والأهم من ذلك ، أن منح إمكانية الوصول للكتابة العالمية (0777) إلى تثبيت Wordpress بالكامل أمر خطير للغاية ، ويوصى به صراحةً ضده في وثائق WP الرسمية. علاوة على ذلك ، مع كل هذا مثبت من المضيف ، فقد سمحت للتو بالتحميلات التعسفية من الإنترنت للكتابة إلى نظام الملفات _host_.

jantman آسف يا سيئة. يبدو أن الاختراق الأول يحل مشكلات الإذن أيضًا. ليست هناك حاجة لتغيير أي إذن افتراضي.

من الواضح أن الجميع بحاجة إلى معرفة UID للمستخدم المضيف

حتى لا يقدم عامل الميناء حلاً لهذه المشكلة ، ستبقى الافتراضات.

الحل الذي أقدمه هو نفسه

يمكنك القيام بذلك عن طريق إنشاء مجلدات محلية ، لقد هبطت للتو في الصفحة الرئيسية https://github.com/docker/docker/pull/20262.

إغلاق هذا على أنه ثابت.

مرحبًا ، كان علي أيضًا إجراء حل بديل في ملف عامل الإرساء الخاص بي:

...
COPY start.sh /root/start.sh
CMD /root/start.sh

ثم في start.sh

usermod -u $USER_ID www-data
exec php-fpm

نظرًا لأنه يمكن إدخال USER_ID $ كمعامل بيئة ، فمن الممكن استخدام صورة عامل الإرساء هذه بدون تعديل.

على أي حال ، أعتقد أنه يجب أن يكون هناك المزيد من الوظائف المضمنة لهذا النوع من الأشياء ، وأتساءل عن كيفية استخدام المجلدات المحلية التي اقترحها calavera ، هل يمكن لأحد أن يقدم مثالاً؟

@ keywan-ghadami كنت محتارًا على المجلدات المحلية أيضًا. المشكلة هي أنه عليك إنشاء نظام الملفات أولاً (أو استخدام tmpfs). لذلك لا يستخدم / var / lib / docker. في الواقع ، لا يمكنك استخدام دليل فرعي لـ _ أي_ FS ​​موجود لأن روابط الربط لا تدعم الخيار uid . لا أعرف ما هي المجلدات المحلية ؛ يمكنك أيضًا إنشاء FS وتركيبه بنفسك ثم استخدام وحدة تخزين مضيف عادية ( -v my-created-fs:container-mount-point ).

لقد تأخرت كثيرًا في هذا الموضوع ولكن هل تم حل هذه المشكلة؟ ليس واضحًا بنسبة 100٪ من جميع المشكلات المختلفة المشار إليها هنا. يبدو أن brthor لديه أفضل حل مما يمكنني رؤيته ولكنه يتضمن خيارات سطر الأوامر التي يمكن إضافتها بسهولة إلى Dockerfile وتنفيذها خلف الكواليس.

بالنسبة لي ، يعد التشفير الثابت UID و GID فكرة سيئة لقابلية النقل بين البيئات ولا أرى الحاجة إلى إضافة وسيطات سطر أوامر في كل مرة أقوم فيها بتشغيل حاوية أو إنشاء صورة عندما يكون ذلك خيارًا بسيطًا في ملف Dockerfile. هل يمكن ألا يكون هناك خيار بسيط في ملف Dockerfile أو ربما من خلال docker-compose.yml حيث يمكنك تحديد نوع من خيار "map uid من المضيف"؟

قد يكون هناك حل جيد بالفعل ولكن لا يمكنني معرفة ذلك من الوثائق أو هذا الموضوع.

شكرًا alvinchevolleaux ، يمكنني أن أؤكد أننا استخدمنا الحل الذي نشرته أعلاه في CI لـ https://github.com/dotnet/cli بنجاح لعدة أشهر حتى الآن.

هل أوصي به!

brthor نعم ، هذا ما export USER_ID=$(id -u) إلى ملفي الشخصي .bash_profile لذلك كل شيء تلقائي لبيئاتي المختلفة. تشكرات.

كما تمت مناقشته أعلاه ، عند مشاركة محتوى من مجلدك الرئيسي في حاوية ، أضف حساب مستخدم بنفس المعرف الفريد الخاص بك. إليك حيلة للتعامل معها إذا لم يكن معرفك

يجب أن يحتوي Dockerfile على:

RUN useradd --uid 1000 -m vagrant
USER vagrant

يتم استبدال الثابت 1000 بمعرفك الفعلى باستخدام مرشح _git_. قم بتشغيل ما يلي على مضيفك:

git config filter.uidfix.smudge "sed s/1000/$UID/g"
git config filter.uidfix.clean "sed s/$UID/1000/g"

أخيرًا ، أضف ملف .gitattributes لتطبيق مرشح git:

Dockerfile filter=uidfix

يعمل هذا عن طريق استبدال 1000 بـ UID الفعلي الخاص بك عند سحب ملف Dockerfile عن طريق _smudging_ الملف. سيقوم Git بتنظيف الملف (إعادة 1000 ) عند الالتزام. يتم تشغيل أي أوامر يتم تشغيلها في الحاوية كمستخدم vagrant باستخدام المعرف الفريد العمومي (UID) الصحيح.

يجب إعادة فتح هذه التذكرة لأن جميع الحلول المقدمة هنا ليست سوى حلول بديلة
لقد وجدت حلاً جيدًا موثقًا وأكثر اكتمالاً في https://github.com/rocker-org/rocker/blob/master/rstudio/userconf.sh
يستخدم وسيطات وقت التشغيل التي تجعل من الممكن استخدام صور الإنشاء المسبق وهو أمر غير ممكن مع مرشح git

@ كالافيرا أنا لا أفهم الحل الخاص بك.

على سبيل المثال

$ mkdir /tmp/test
$ sudo docker volume create --name=test -d local --opt type=nfs --opt device=/tmp/test:/data --opt o=notime,nosuid,uid=11459,git=11459
$ sudo docker run -t -i -v test:/tmp fedora bash -i
[.. $] touch /tmp/foo.txt
[.. $] exit
$ ls -la /tmp/test

عندما أنظر في الدليل / tmp / test ، لا توجد ملفات. لا يبدو الأمر كما لو كان المجلد / tmp / test قيد التثبيت في الحاوية ... بل إنه ينشئ وحدة تخزين حاوية. وهو ما لا أريده حقًا.

لا يمكنني العثور على أي وثائق تخبرني ما هي الخيارات الصالحة. لذا فأنا أخمن حقًا كيف يُفترض أن يعمل هذا.

يرجى إعادة فتح هذه المشكلة. لا يبدو أن برنامج التشغيل المحلي الجديد يعالج على الإطلاق مشكلة تحميل أدلة المضيف المحلي بمعرف المستخدم المحدد.

تضمين التغريدة
هل يمكنك التعليق على كيفية حل مشكلة إسقاط الملفات كجذر مع وحدات تخزين المضيف المحلية؟ لقد رأيت هذه المشكلة تظهر بشكل متكرر ، خاصة عند استخدام سيناريوهات عامل الإرساء لسيناريوهات CI.

بالنظر إلى العلاقات العامة المرتبطة ، لا أرى أي شيء واضحًا على الفور ، لكنني متأكد من أنني أفقد شيئًا ما

لقد كنت أستخدم أشكالًا مختلفة من هذا الحل البديل في حاوياتي ، مثل docbill / docker-force. ومع ذلك ، يبدو لي أن الحل الأنظف عبارة عن حاوية مسؤولة فقط عن عمل الاسكواشروت ...

يجب أن يساعد استخدام شيء مثل bindfs للغة المحلية. يمكنك تشغيله باستخدام -o map = $ (id -u) / root: @ $ (id -g) / root (بافتراض عدم وجود مساحة اسم مستخدم) ويجب أن ترى الملفات على أنها ملفاتك خارج الحاوية أثناء ملكيتها جذر بداخله.

ktosiek شكرًا ، يبدو أن ذلك ينطوي على إمكانات. هل يمكنك نشر مثال كامل على الأمر docker run أو جلسة وحدة التحكم؟

هل يمكن لشخص ما أن ينشر تحديثًا لحالة هذه المشكلة: هل تم إغلاقه بسبب "لن يتم إصلاحه" أم أنه تم تنفيذ ذلك بالفعل؟ الخيط طويل جدًا ، لذا يرجى أن تسامحني لأنك لا أستطيع أن أرى من لمحة ما هو القرار.

quinncomendant انظر https://github.com/docker/docker/issues/7198#issuecomment -191990887
أبلغ إذا لم تنجح.

شكرا @ LK4D4.

للتلخيص ، تم إغلاق المشكلة بإصلاح يتيح خيارات التحميل لمحرك التخزين local .

بقدر ما أستطيع أن أقول ، لا توجد خيارات لتعيين المستخدم: مجموعة من _المضيف-دليل مُركب كوحدة تخزين _ (الرجاء تصحيحني إذا كان هذا الخيار موجودًا - هذا ما جئت إلى هنا لأتعلمه).

quinncomendant صحيح ؛ عند ربط دليل مضيف ، فأنت تريد أن تستخدم الحاوية الملفات الموجودة هناك كما هي ، والتي تتضمن الأذونات. إذا كنت تريد تغيير هذه الأذونات ، فأنت بحاجة إلى القيام بذلك على المضيف ، قبل ربطها

quinncomendant أو بعبارات أبسط هذا لن يتم إصلاح .... منذ
الحل المقدم لا يفعل أي شيء في الواقع لمعالجة المشكلة
ذكرت ، وليس هناك خطة لحل هذه المشكلة.

في 6 يوليو 2016 الساعة 17:20 ، سيباستيان فان ستيجن إخطارات @github.com
كتب:

quinncomendant https://github.com/quinncomendant صحيح ؛ متي
ربط تحميل دليل مضيف تريد أن تستخدم الحاوية الملفات التي
هل هناك كما هو ، والذي يتضمن الأذونات. إذا كنت تريد تغيير هؤلاء
الأذونات ، عليك القيام بذلك على المضيف ، قبل ربطها

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/docker/docker/issues/7198#issuecomment -230909967 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe/ADBcWLihVjI1FoSMLKu7DyhwFOpGX0KKks5qTBwMgaJpZM4CQMjR
.

يبدو أن هذه مشكلة لن يتم إصلاحها. يبدو دائمًا أنه لا يزال يتم التغاضي عن جوانب تطوير الحاويات وما زالت تتطلب منا كتابة الاختراقات.

لقد صادفت هذه المشكلة على وجه التحديد لأن المطورين الذين أدعمهم يقومون بتشغيل ملف مشروع لإنشاء أوامر من داخل الحاوية وخارجها إلى وحدة التخزين المُثبتة على المضيف (تثبيت هذه الأدوات على المضيف يتعارض تمامًا مع الغرض من استخدام الحاوية ، أليس كذلك؟).

إنهم يريدون تكرار هذه الملفات بسرعة ، ولكن كما أشار آخرون في هذا الموضوع إلى أنها مكتوبة على أنها uid / gid تعمل الحاوية ، مما يتطلب خنقها بشكل صحيح على المضيف ليتم معالجتها بشكل أكبر (بواسطة IDE على سبيل المثال).

هناك حاجة حقًا إلى وجود طريقة محددة لرسالة الرصيف للتلوين في uid / gid مؤقت في هذه الأنواع من الحالات.

boj هذا هو السيناريو الدقيق الذي سكوبا . ينشئ الحل الحالي ، أثناء بدء التشغيل ، مستخدمًا في الحاوية بنفس uid / gid مثل المستخدم المضيف. إنه ليس الحل الأبسط ، لكنه يعمل بشكل جيد.

JonathonReinhart شكرًا ، لقد أعطيتني القليل من الإلهام.

انتهى بي الأمر بكتابة غلاف نصي يسمى من المضيف مثل هذا (يستخدمون django في هذه الحالة):

# bin/manage.py
#!/bin/sh

docker run -v $(pwd):/usr/local/prj -it --entrypoint="/usr/bin/python3.4" -w /usr/local/prj -u $(id -u):$(id -g) prj src/prj/manage.py $@

boj المشكلة المحتملة في هذا الحل ( -u $(id -u):$(id -g) ) هي أنه لا يوجد إدخال في /etc/passwd أو /etc/group لهذا uid / gid في الحاوية: https: // github .com / JonathonReinhart / سكوبا / قضايا / 11

تضمين التغريدة في هذه الحالة بالذات ، أهتم فقط بالملفات المكتوبة إلى مضيف المطور وأن لديهم نفس الأذونات مثل المستخدم المضيف.

لا داعي للقلق بشأن ما يحدث بالفعل في وقت التشغيل ، كان هذا كل ما احتاجه حقًا.

تضمين التغريدة

إذا كان البرنامج الموجود في الحاوية يحتاج إلى إدخال في / etc / passwd أو / etc / group ، فاجعل تلك العناصر قابلة للكتابة في العالم في الصورة ثم أضف الإدخالات الضرورية هناك عند بدء التشغيل.

لذا فإن الحل المذكور بواسطة JonathonReinhart (رسم الخرائط uid / gid) يحل هذا.

يبدو أن هذا مدعوم بالفعل في runc (https://github.com/opencontainers/runc/blob/8c9db3a7a5145f6b26c8051af319eee6f72c9ca8/libcontainer/configs/config.go#L19-24). في Docker يوجد userns-remap config لـ deamon ، هنا نحتاج بشكل أساسي إلى أن يكون أكثر دقة (مستوى الحاوية بدلاً من مستوى deamon) ، هل هناك أي اهتمام / خطة لدعم هذا؟

هذا docker-compose.yml لا يعمل:

version: '2'

services:
  app:
    build: ./app
    container_name: myapp
    volumes:
      #- "../app:/root/www/myapp:rw"
      - myapp:/root/www/myapp:rw

volumes:
  myapp:
    driver: local
    driver_opts:
      o: uid=500
      device: ../app

يمكن لأي شخص أن يخبرني لماذا؟ أنا أتبع الإرشادات الرسمية: https://docs.docker.com/engine/reference/commandline/volume_create/#/driver -specific-options

هل من الممكن إرفاق مجلدات مسماة من المضيف؟ باستخدام driver_opts يمكنك تحديد uid (وربما gid ؟).

+1

+1

xiaodslazyuser من فضلك توقف مع + 1 في ل. إنه لا يحقق شيئًا سوى إرسال رسائل غير مرغوب فيها إلى كل هؤلاء ---> المشاركين.

bamarni نعم ، أعتقد أن ميزة مساحة اسم المستخدم الجديدة يمكن أن تحل هذه المشكلة ، ولكن كما قلت ، يجب أن يتم تنفيذها لكل حاوية. ستكون النتيجة النهائية: تشغيل الحاوية كما تعتقد أنه "جذر" ، ولكنها في الواقع هي UID / GID الذي تم تمريره في سطر الأوامر docker run . ثم "تخرج" الملفات من الحاوية التي يملكها المستخدم المناسب.

xiaodslazyuserJonathonReinhart يجب عليك بدلا انقر على زر +1 تحت وصف القضية

أو فقط انقر فوق "اشتراك" على اليمين إذا كنت تريد إخطارات فقط ...

JonathonReinhart : بالتأكيد ، لقد

ملاحظة: قيد التعيين الفردي لكل برنامج خفي في مكانه في الوقت الحالي لأن Docker يشارك طبقات الصورة من ذاكرة التخزين المؤقت المحلية الخاصة به عبر جميع الحاويات التي تعمل على مثيل المحرك. نظرًا لأن ملكية الملف يجب أن تكون هي نفسها لجميع الحاويات التي تشارك محتوى الطبقة نفسه ، فقد تم اتخاذ القرار لتعيين ملكية الملف على docker سحب إلى المستخدم الخفي وتعيينات المجموعة بحيث لا يكون هناك تأخير لتشغيل الحاويات بمجرد تنزيل المحتوى. يحافظ هذا التصميم على نفس الأداء لسحب عامل الإرساء ودفع عامل الإرساء وبدء تشغيل الحاوية كما يتوقع المستخدمون مع تعطيل مساحات أسماء المستخدمين.

_ (https://docs.docker.com/engine/reference/commandline/dockerd/#/daemon-user-namespace-options) _

عزيزي JonathonReinhart و @ pa-de-solminihac و nalipaz ،
شكرًا لك على جهودك في تثقيفي والآخرين بعدم ترك تعليقات لا علاقة لها بالمسألة من خلال القيام بذلك بالضبط! لمعلوماتك ، لا يسمح Github بالبحث عن المشكلات التي يشترك فيها الفرد دون التعليق عليها على الأقل. لمزيد من المعلومات ، راجع https://github.com/isaacs/github/issues/283. ومن المفارقات أن مشكلة Github هي تقريبًا نفس عمر مشكلة Docker ، ويبدو أن كلاهما يحظى بالأولوية على نحو مماثل.

للجميع ، آسف لإرسال البريد العشوائي. في المرة الأولى كان حلًا بديلًا لخلل github المذكور أعلاه ، وهذه المرة لم أستطع مقاومة إعطاء سخرية الموقف.

لقد حللت هذا باستخدام inotifywait . ستحتاج إلى تثبيت أدوات inotify لتشغيلها داخل صورة عامل الإرساء. من الممكن تشغيله على نظامك المضيف بدلاً من ذلك ، لكنني أردت حلاً محمولاً.

RUN export DEBIAN_FRONTEND=noninteractive \
  && apt -y update \
  && apt -y install inotify-tools \
  && inotifywait -m -r /mount -e create --format '%w%f' \
    | while read f; do chown $(stat -c '%u' /mount):$(stat -c '%g' /mount) $f; done

يعمل هذا عن طريق توجيه inotifywait لمشاهدة أي ملفات أو أدلة جديدة تم إنشاؤها في الدليل / mount. عندما يلاحظ واحدًا ، فإنه يغير الملكية إلى نفس المستخدم والمجموعة كمجلد / mount. لقد استخدمت التمثيل الصحيح لكليهما ، في حالة عدم وجود المستخدم / المجموعة المضيفة في الحاوية. داخل الحاوية لا يهم من يملكها ، لأن كل شيء يعمل كجذر. خارج الحاوية ، يُظهر نظام ملفات المضيف نفس الملكية لأي دليل تم تركيبه في / mount.

لقد صممته عمدًا لتعيين ملكية الملفات والأدلة التي تم إنشاؤها حديثًا فقط ، من أجل الحفاظ على ملكية الملفات والأدلة الموجودة مسبقًا. إنه أكثر أمانًا من التخلص من كل ذلك بعبارة chown -R في كل مرة يتم فيها تثبيت نظام الملفات. إذا كانت الأذونات الموحدة تعمل في مشروعك وتريد حلاً أبسط يعمل بكفاءة أكبر ، فابحث عن inotify-hookable .

تحذير: نظرًا لأنه سيتم إنشاء ساعة inotify واحدة لكل دليل فرعي ، فمن الممكن أن يتم الوصول إلى الحد الأقصى لمقدار ساعات inotify لكل مستخدم. الحد الأقصى الافتراضي هو 8192 ؛ يمكن زيادتها عن طريق الكتابة إلى / proc / sys / fs / inotify / max_user_watches.

@ codekitchen-ws تحذير آخر: يمكن نقل ملف بعد الإنشاء وقبل تغيير المالك. اعتمادًا على الغلاف ، سترغب أيضًا في اقتباس "$f" (لمنع تقسيم الكلمات في المسار).

+1

briansrepo هذا نهج مثير للاهتمام. إذا كان هذا في بيان Dockerfile RUN ، فسيتم تنفيذه في وقت الإنشاء. كيف يمكن معرفة المستخدم docker run وقت التنفيذ؟

btiernay شكرا! لا يستخدم المعرف الفريد للمستخدم الذي أطلق الصورة. يقوم بشكل خاص بنسخ المستخدم المضيف والمجموعة المضيفة لأي دليل مضيف يتم تحميله في / mount. لا ينظر إلى أي ملفات أو أدلة فرعية أخرى. يعود الأمر إلى المستخدم للتأكد من تعيين الأذونات لشيء يمكنه الكتابة إليه على النظام المضيف.

مثال: افترض أن الدليل المضيف / var / www / html مملوك لـ brian: www-data. تقوم بتشغيل صورة تقوم بتحميل دليل نظام المضيف / var / www / html في دليل / تحميل الصور. ثم تقوم بإنشاء /mount/index.html من داخل الصورة. إذا ذهبت تحقق من ملكية /var/www/html/index.html على النظام المضيف ، فسيكون ملكًا لـ brian: www-data.

بناءً على هذا المثال ، لنفترض أن لديك دليل مضيف / var / www / html / upload مملوك لـ www- data: www-data. ضع في اعتبارك أن دليل المضيف الموصول / var / www / html لا يزال مملوكًا لـ brian: www-data. انتقل الآن إلى الصورة وأنشئ /mount/upload/file.pdf. إذا قمت بالتحقق من ملف المضيف /var/www/html/upload/file.pdf ، فسيكون ملكًا لـ brian: www-data ، وليس www- data: www-data ، لأن دليل المضيف المثبت / var / www / html هو يملكها بريان: www-data. منطقي؟

TL ؛ DR: تقوم بتمرير user: group الذي تريد استخدامه عن طريق تغيير دليل المضيف المُحمل إلى user: group.

شكرا briansrepo على التوضيح. كل هذا منطقي ولكن ما زلت لا أفهم كيف يمكن أن يعمل هذا داخل RUN . أعتقد أن هذا سيحتاج إلى التنفيذ في الخلفية عند تنفيذ الحاوية (على سبيل المثال ، docker run ).

btiernay أحب هذه الفكرة أيضًا.
briansrepo على الأقل يغطي ما يحدث من الحاويات.
لا يزال من الممكن معالجة عملية الإنشاء بشيء مثل

RUN usermod -u 1000 www-data

هذه لا تزال حلول بالرغم من ذلك.

في مكدس LEMP لديّ هذا التكوين المسبق لـ Nginx في ملف Dockerfile الأساسي الخاص بي:

### Start of Nginx WEBSERVER setup
RUN mkdir -p /var/www
# Modify www-data user and set UID, GID to 500
# https://muffinresearch.co.uk/linux-changing-uids-and-gids-for-user/
RUN groupmod -g 500 www-data \
    && usermod -u 500 www-data \
    && usermod -g 500 www-data \
    && chown -R www-data:www-data /var/www \
    && chmod g+s /var/www
### End of Nginx WEBSERVER setup

هذا اختراق حيث أن كل الملفات التي تم إنشاؤها حديثًا من جلسة ssh مضيفة تحصل على uid و gid 500 و nginx لن تتمكن من الوصول إلى هذه الملفات في النهاية (لأن المستخدم أو المجموعة ذات المعرف 500 لم تكن موجودة في الحاوية). يمكنك التحقق من رقم uid ورقم gid الذي يتعين عليك إنشاؤه لمستخدمك www-data عندما تنسخ ملفات جديدة إلى وحدة التخزين المشتركة على المضيف من جلسة ssh وبعد ذلك يمكنك docker exec في هذه الحاوية و النظر في الملفات ، uid ، gid.

المشكلة التي وجدتها ، إذا قمت بنسخ ملفات جديدة إلى المجلد المشترك على الجهاز المضيف (الذي قمت بالوصول إليه من خلال جلسة ssh ، كما هو الحال في مثيل CoreOS على DigitalOcean) ، فلن يتمكن Nginx من الوصول إلى تلك الملفات التي تم إنشاؤها حديثًا. لذلك إذا كنت تريد التوافق المطلق مع الامتيازات ، فيجب عليك مشاركة ملفات خادم الويب في حاوية Docker عند إنشاء الحاويات (على الأقل كان هذا هو الحال منذ عام واحد ، عندما واجهت مشكلات uid ، مع وحدات التخزين المشتركة) .

أو يمكنك أيضًا تثبيت خدمة ssh في حاوية عامل الإرساء التي تشارك الملفات في حاوية nginx ، وبهذه الطريقة إذا قمت بنسخ / تعديل الملفات ، فستحصل على uid ، gid الصحيح. ولكن هذا ضد أفضل ممارسات Docker التي يجب أن تستخدم docker inspect بدلاً من جلسات ssh ، لأن "Docker ليس VM" (سيكون حلاً سهلاً للغاية ، أليس كذلك؟).

في تفكيري ، يجب أن تعمل حاوية Docker كخدمة أو ملف تنفيذي ويجب ألا تأخذ ملفات خادم الويب الخاصة بي كرهائن إذا لم أرغب في ذلك. تعد قاعدة البيانات نوعًا مختلفًا من الأشياء (في بعض الأحيان) ، لكنني لا أفهم لماذا لا يكون من الممكن تحقيق نفس البنية التحتية لحاوية الكأس المقدسة ، حيث تعيش جميع ملفات قاعدة البيانات الثابتة وخادم الويب خارج الحاويات (ولكن يمكن للحاويات قم بتعديلها (مثل الحذف ، الإنشاء ، التعديل) ويمكنك أيضًا تعديلها دون أي مشكلات خاصة من المضيف.

باستخدام docker volume create --opt يمكنك تحديد uid ، gid ، لكن هذا ليس صحيحًا مع docker-compose : https://github.com/docker/compose/issues/3715

نحتاج حقًا إلى حل go-to (وليس gosu) عبر الأنظمة الأساسية لتعيين uid / gid. تسبب هذه المشكلة وحدها أضرارًا جسيمة لكيفية إدراك المبتدئين لعمال الرصيف.

لقد أنشأنا حلاً لهذه المشكلة يغير أذونات المستخدم / المجموعة والملف الخاصة بحاوية Docker التي تم تعيينها في وقت الإنشاء إلى UID / GID الذي بدأت به الحاوية في وقت التشغيل.

المشروع وتعليمات التثبيت موجودة على: https://github.com/boxboat/fixuid

مثال: تم إنشاء حاوية Docker باستخدام مستخدم / مجموعة dockeruser:dockergroup كـ UID / GID 1000:1000 . يتم تشغيل المضيف كـ UID / GID 1001:1002 . يتم تشغيل الصورة بـ docker run -u 1001:1002 . fixuid سوف:

  • قم بتغيير UID dockeruser إلى 1001
  • قم بتغيير dockergroup GID إلى 1002
  • قم بتغيير كافة أذونات الملفات من dockeruser:dockergroup القديم إلى 1001: 1002
  • تحديث $ HOME داخل الحاوية إلى dockeruser $ HOME
  • الآن تتطابق الحاوية والمضيف مع UID / GID والملفات التي تم إنشاؤها في الحاوية على حوامل المضيف

يمكن تشغيله باعتباره ENTRYPOINT أو كجزء من برنامج نصي لبدء التشغيل. يتم تثبيته في الحاوية كثنائي مملوك لـ root مع بت setuid ، ويقوم بتصعيد الامتيازات لإجراء التغييرات المناسبة. يجب استخدامه فقط في حاويات التطوير.

إذا ثبت أن هذا مفيد ، فقد يكون محرك Docker قادرًا على دمج بعض أو كل المنطق عبر العلامات في docker run

تم حلها باستخدام docker volume .

hashar كيف؟ يمكنك إعطاء مثال الثابتة والمتنقلة

فهل لا يوجد حل لهذا بخلاف استخدام gosu ونص دخول ؟!

في الوقت الحالي ، يبدو أن هناك خيارين كحل بديل لهذا ، حتى يقوم فريق Docker بإجراء تحديث رسمي حول هذا الأمر.

من العار أن هذه لا تزال مشكلة. من الناحية النظرية ، هناك إعادة رسم خريطة مستخدمين ولكنها ليست سهلة الاستخدام.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات