Moby: أضف القدرة على تحميل وحدة التخزين كمستخدم بخلاف الجذر

تم إنشاؤها على ١٧ أكتوبر ٢٠١٣  ·  157تعليقات  ·  مصدر: moby/moby

حالة الاستخدام: قم بتحميل وحدة تخزين من مضيف إلى حاوية لاستخدامها بواسطة apache كمستخدم www.
تكمن المشكلة حاليًا في أن جميع الحوامل مثبتة كجذر داخل الحاوية.
على سبيل المثال ، هذا الأمر
docker run -v / tmp: / var / www ubuntu stat -c "٪ U٪ G" / var / www
سيطبع "الجذر"

أحتاج إلى تثبيته كمستخدم www داخل الحاوية.

areapi arekernel arevolumes exexpert kinenhancement

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

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

#!/bin/sh
chown -R redis:redis /var/lib/redis
exec sudo -u redis /usr/bin/redis-server

(شكرا bfirsh على الخاص بك على سبيل المثال)

أمر فظيع جدا.

هذا يعني أن الحاوية يجب أن تبدأ كجذر ، بدلاً من تشغيلها كمستخدم redis المقصود. (كما ألمح aldanor إلى)

وهذا يعني أن المستخدم لا يمكنه فعل شيء مثل:

docker run -v /home/user/.app_cfg/ -u user application_container application :(

ال 157 كومينتر

إذا كان الحجم chown (على جانب المضيف) قبل ربطه ، فسوف يعمل.
في هذه الحالة ، يمكنك القيام بما يلي:

mkdir /tmp/www
chown 101:101 /tmp/www
docker run -v /tmp/www:/var/www ubuntu stat -c "%U %G" /var/www

(بافتراض أن 101:101 هو UID: GID للمستخدم www-data في الحاوية الخاصة بك.)

الاحتمال الآخر هو القيام بعملية الربط ، ثم chown داخل الحاوية.

mingfang هل chown لا يعمل من أجلك؟

سيكون من المفيد أن يكون لديك اختصار لهذا. غالبًا ما أجد نفسي أكتب نصوصًا برمجية run تقوم فقط بتعيين الأذونات على وحدة تخزين:

https://github.com/orchardup/docker-redis/blob/07b65befbd69d9118e6c089e8616d48fe76232fd/run

ماذا لو لم يكن لديك حقوق chown ذلك؟

هل سيحل البرنامج النصي المساعد الذي يشير إلى الحجم chown هذه المشكلة؟ يمكن أن يكون هذا scirpt ENTRYPOINT لملف Dockerfile الخاص بك.

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

#!/bin/sh
chown -R redis:redis /var/lib/redis
exec sudo -u redis /usr/bin/redis-server

(شكرا bfirsh على الخاص بك على سبيل المثال)

أمر فظيع جدا.

هذا يعني أن الحاوية يجب أن تبدأ كجذر ، بدلاً من تشغيلها كمستخدم redis المقصود. (كما ألمح aldanor إلى)

وهذا يعني أن المستخدم لا يمكنه فعل شيء مثل:

docker run -v /home/user/.app_cfg/ -u user application_container application :(

هناك طريقة _ واحدة_ لإنجاحها ، ولكن عليك الاستعداد مسبقًا داخل Dockrfile الخاص بك.

RUN mkdir -p /var/lib/redis ; chown -R redis:redis /var/lib/redis
VOLUME ["/var/lib/redis"]
ENTRYPOINT ["usr/bin/redis-server"]
USER redis

(لم أختبر هذا المثال ، فأنا أعمل على حاوية من الكروم يتم عرضها بعد ذلك على حاوية _ منفصلة_ X11 ...)

وبالطبع هذه الطريقة تعمل فقط مع الأحجام الجديدة المباشرة ، وليس الربط
مركبة أو مجلدات من مجلدات. ؛)

بالإضافة إلى ذلك ، سيكون للحاويات المتعددة التي تستخدم volumes-from معرف مستخدم / معرف مختلف لنفس المستخدم ، مما يعقد الأمور أيضًا.

SvenDowideit تيانون هذه الطريقة لا تعمل أيضًا. مثال كامل:

FROM ubuntu
RUN groupadd -r redis    -g 433 && \
useradd -u 431 -r -g redis -d /app -s /sbin/nologin -c "Docker image user" redis 
RUN mkdir -p /var/lib/redis
RUN echo "thing" > /var/lib/redis/thing.txt
RUN chown -R redis:redis /var/lib/redis
VOLUME ["/var/lib/redis"]
USER redis
CMD /bin/ls -lah /var/lib/redis

تشغيلان ، مع وبدون حجم a -v:

bash-3.2$ docker run -v `pwd`:/var/lib/redis voltest 
total 8.0K
drwxr-xr-x  1 root root  102 Aug  7 21:30 .
drwxr-xr-x 28 root root 4.0K Aug  7 21:26 ..
-rw-r--r--  1 root root  312 Aug  7 21:30 Dockerfile
bash-3.2$ docker run  voltest 
total 12K
drwxr-xr-x  2 redis redis 4.0K Aug  7 21:30 .
drwxr-xr-x 28 root  root  4.0K Aug  7 21:26 ..
-rw-r--r--  1 redis redis    6 Aug  7 21:26 thing.txt
bash-3.2$ 

نحن نواجه مشكلة سيتم حلها من خلال هذا (على ما أعتقد). لدينا حصة NFS لأدلة الصفحة الرئيسية لمطورنا. يريد المطورون تحميل /home/dev/git/project في Docker لكن لا يمكنهم ذلك لأن لدينا Root Squash ممكّن.

هذا يمنع الجذر من الوصول إلى /home/dev/git/project لذلك عندما أحاول تشغيل docker mounting /home/dev/git/project أحصل على خطأ lstat permission denied .

frankamp هذا لأن التفضيل الحالي للموظف هو عدم تعديل أشياء المضيف التي لا تخضع لسيطرة Docker الخاصة.

يتم استبدال تعريف "VOLUME" الخاص بك بواسطة -v pwd`: / var / lib / reds`.
ولكن في الجولة الثانية ، تستخدم وحدة تخزين يتم التحكم فيها بواسطة عامل الإرساء ، والذي تم إنشاؤه في / var / lib / docker. عندما تبدأ الحاوية ، يقوم عامل الإرساء بنسخ البيانات من الصورة إلى المجلد ، ثم يقوم بتغيير الحجم باستخدام uid: gid الخاص بالدير الذي تم تحديد المجلد له.

لست متأكدًا من وجود الكثير الذي يمكن القيام به هنا ، وللأسف لا تدعم حوامل الربط (بقدر ما أستطيع أن أقول) التركيب كمعرف uid / gid مختلف.

كان الحل الخاص بي لهذا هو القيام بما فعله SvenDowideit أعلاه (إنشاء مستخدم جديد وتكوينه مقدمًا في ملف dockerfile) ، ولكن بدلاً من تحميل وحدة تخزين المضيف ، استخدم حاوية البيانات فقط ، وانسخ وحدة تخزين المضيف التي أردت تحميلها في حاوية بها tar cf - . | docker run -i --volumes-from app_data app tar xvf - -C /data . سيصبح هذا أسهل قليلاً بمجرد دمج https://github.com/docker/docker/pull/13171docker cp يعمل في كلا الاتجاهين) ، ولكن ربما يمكن أن يصبح بديلاً لـ -v host_dir:container_dir ، أي. ربما -vc host_dir:container_dir ، (vc for volume-copy) ، حيث سيتم نسخ محتويات host_dir في حاوية البيانات. على الرغم من أنني لا أستطيع أن أقول إنني أفهم لماذا / كيف ترث الملفات المنسوخة أذونات مستخدم الحاوية ، مما يمكنني قوله أنهم يفعلون ، وهذا هو الحل الوحيد المعقول الذي تمكنت من التوصل إليه ولا يؤدي إلى تدمير قابلية النقل.

ماذا عن دوري أبطال آسيا؟

هل هناك أي إصلاح أو حل بديل؟ واجهت نفس المشكلة مع OpenShift ، المجلد المُثبت مملوك من قِبل الجذر: لن تعمل الصور الجذر والمعالجة مسبقًا.

أنا أبحث عن حل بديل أيضًا. إذا كانت جميع وحدات التخزين المثبتة مملوكة لـ root ، فإنه يجعل من المستحيل تشغيل حاويات Docker الخاصة بك مع أي مستخدم آخر غير root .

حسنًا ، يمكنك تجربة s6-overlay . يتضمن ميزات مستهدفة بشكل خاص للمساعدة في حل هذه الأنواع من المشاكل.

@ dreamcat4 : شكرا على المؤشر. يبدو أن إصلاح الملكية والأذونات كحل بديل مثير للاهتمام ، ولكن ألن يتعين علي تشغيل حاوية Docker الخاصة بي كجذر حتى يعمل ذلك؟

@ brikis98 نعم هذا صحيح. ومع ذلك ، يحتوي s6-overlay أيضًا على ميزة أخرى ، والتي تسمح لك بإسقاط الأذونات مرة أخرى عند تشغيل الخوادم / الشياطين.

@ dreamcat4 آه ، مسكتك ، شكرًا.

لدي نفس المعرف / gid داخل وخارج الحاوية وهذا ما أحصل عليه:

nonroot$ ls -l .dotfiles/
ls: cannot access .dotfiles/byobu: Permission denied
ls: cannot access .dotfiles/config: Permission denied
ls: cannot access .dotfiles/docker: Permission denied
ls: cannot access .dotfiles/vim: Permission denied
ls: cannot access .dotfiles/bashrc: Permission denied
ls: cannot access .dotfiles/muse.yml: Permission denied
ls: cannot access .dotfiles/my.cnf: Permission denied
ls: cannot access .dotfiles/profile: Permission denied
total 0
-????????? ? ? ? ?            ? bashrc
d????????? ? ? ? ?            ? byobu
d????????? ? ? ? ?            ? config
d????????? ? ? ? ?            ? docker
-????????? ? ? ? ?            ? muse.yml
-????????? ? ? ? ?            ? my.cnf
-????????? ? ? ? ?            ? profile
d????????? ? ? ? ?            ? vim
nonroot$ ls -l .ssh
ls: cannot access .ssh/authorized_keys: Permission denied
total 0
-????????? ? ? ? ?            ? authorized_keys
nonroot$

darkermatter هل يمكنك من فضلك فتح قضية منفصلة؟

ليست مشكلة ، لكن أليس هذا مناسبًا هنا؟

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

haJeztah حسنًا ، كما فعل @ frankamp وآخرون ، كنت أشرح ببساطة ما يحدث بعد تشغيل chmod وما إلى ذلك داخل Dockerfile. سأقدمها كتقرير خطأ ، لكنها ذات صلة بهذه المناقشة.

على غرار ما اقترحه ebuchman ، بدون نسخ وحدة تخزين مضيفة ، يمكنك إنشاء حاوية بيانات فقط أولاً ، وهذا يؤدي إلى
chown 1000:1000 /volume-mount كجذر عندما بدأ.
على سبيل المثال ، في عامل الإرساء ، يؤلف بناء جملة v2

version: '2'
services:
  my-beautiful-service:
    ...
    depends_on:
      - data-container
    volumes_from:
      - data-container

  data-container:
    image: same_base_OS_as_my-beautiful-service
    volumes:
      - /volume-mount
    command: "chown 1000:1000 /volume-mount"

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

بما أنك تستطيع (في 1.11) تحديد خيارات التحميل لوحدة تخزين لاستخدامها في docker volume create ، فإنني أقول إن هذا يبدو قريبًا جدًا من الاستعداد للإغلاق.

لا يمكنك فقط تحديد uid / gid مباشرة لأن هذا غير مدعوم مع حوامل الربط ، ولكن العديد من أنظمة الملفات التي يمكنك استخدامها مع خيارات التحميل الجديدة يمكن أن تعمل مع uid / gid opts.

أعتقد أن المشكلة لا تزال تتأرجح في الحالات التي تريد فيها تركيب محرك CIFS داخل الحاوية الخاصة بك ، ولكن ربما يجب أن تكون تذكرة أخرى؟

@ michaeljs1990 يمكنك القيام بذلك ، وليس لكل حاوية (إلا إذا قمت بإنشاء وحدات تخزين منفصلة لكل مجموعة uid / gid تريدها).

@ cpuguy83 ، هل يمكنك توضيح كيف يجب على المرء استخدام docker volume create لتجنب هذه المشكلة؟

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

لست متأكدًا مما إذا كان هذا هو ما تطلبه ولكن ...

FROM busybox
RUN mkdir /hello && echo hello > /hello/world && chown -R 1000:1000 /hello

بناء الصورة أعلاه باسم "اختبار"

$ docker volume create --name hello
$ docker run -v hello:/hello test ls -lh /hello

سيكون كل من /hello و /hello/world في المثال أعلاه مملوكًا لـ 1000: 1000

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

FROM <some_image>
RUN groupadd -g <my_gid> <my_group> && \
    useradd -u <my_uid> -g <my_gid> <my_user>

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

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

هناك خيار لتعيين مستخدمين مضيفين uids / gids مع مستخدمين حاويات uids / gids بـ --userns-remap . أنا شخصياً لم أجربها. شاهد مناقشة جيدة حول هذا الموضوع http://stackoverflow.com/questions/35291520/docker-and-userns-remap-how-to-manage-volume-permissions-to-share-data-betwee .

@ cpuguy83 :

لا يمكنك فقط تحديد uid / gid مباشرة لأن هذا غير مدعوم مع حوامل الربط ، ولكن العديد من أنظمة الملفات التي يمكنك استخدامها مع خيارات التحميل الجديدة يمكن أن تعمل مع uid / gid opts.

ما هي أنظمة الملفات التي تفكر فيها والتي يمكنها قبول وسيطات uid / gid؟ أعلم أن FAT يمكنها ذلك ، لكن هذا يبدو متطرفًا مثل أي شيء آخر يتم اقتراحه في هذا الموضوع.

IMO ، Docker لديه خياران:

  1. الدعم الرسمي لوحدات التخزين كمستخدم / مجموعة محددة (باستخدام اسم المستخدم / المجموعة المحدد داخل الحاوية ، ولا يتطلب من المضيف أن يكون لديه هذه المعرفة بالأجزاء الداخلية للحاوية).
  2. أو ... تخلص من التوجيه USER (وعلامات وقت التشغيل المرتبطة).

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

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

نوع من الحل لهذا سيكون رائعًا. ما لم تتوقع الحاوية ذلك على وجه التحديد ، فإنها تجعل من الصعب جدًا إضافة وحدات تخزين إلى الحاويات القياسية مثل elasticsearch و redis و couchDB والعديد من الحاويات الأخرى دون كتابة ملف Dockerfile مخصص يحدد الأذونات. يؤدي هذا غالبًا إلى جعل الأمر docker run -v أو الأمر volume: في عامل الإرساء عديم الفائدة.

chrisfosterelli لماذا عديمة الفائدة؟ لا أعتقد أنه من غير المألوف تحديد ملكية الملفات / dirs التي تتوقع استخدامها.

@ cpuguy83 لأنه لا يبدو أنه من الممكن تعيين الملكية دون استخدام ملف Dockerfile مخصص يعيّن الأذونات والأحجام ، وهذا هو سبب الاعتقاد بأنها غير مفيدة لتحديد وحدات التخزين. أنا لا أقوم بربط الحاويات بنظام الملفات المضيف ، إذا كان ذلك مناسبًا.

chrisfosterelli لكن كل ملفات Dockerfiles القياسية هذه يجب أن تحتوي على الأذونات التي تم تعيينها بالفعل.

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

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

@ cpuguy83 لقد قمت بمزيد من الحفر وعزلته إلى هذا: لنفترض أن لدي حاوية بحث مطاطي ستنشئ دليلًا /data عند بدء التشغيل (في حالة عدم وجود بيانات) ، ثم استخدم docker run -v /data elasticsearch . يصبح الدليل /data مملوكًا لـ root:root وسيخفق الآن البرنامج الخفي الذي يتم تشغيله كـ elasticsearch داخل الحاوية لأنه لا يمكنه الكتابة إلى /data .

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

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

justincormack أعتقد ذلك ، لكنني أعتقد أن هذا لا يعمل عندما أتوقع أن تقوم الحاوية بإنشاء البيانات في المجلد (بدلاً من المضيف). أتفهم أن هذه مشكلة غريبة نوعًا ما ، لذلك أنا أعالجها حاليًا من خلال إصلاحها في Dockerfile المنبع نفسه إلى mkdir -p && chmod الدليل.

chrisfosterelli لهذا السبب قلت تعيين umask ، إذا كان umask الخاص بك هو 000 (في الحاوية) ، فسيتم إنشاء جميع الملفات الجديدة بأذونات 666 أو 777 ، وإذا كان نقطة التثبيت هي 777 للبدء بذلك يجب أن تكون على ما يرام؟ إذا كانت الأذونات للقراءة والكتابة دائمًا في جميع أنحاء العالم ، فلا يجب أن يكون uid و gid مهمين؟

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

chrisfosterelli همم ، هذا سؤال جيد. يبدو لي أن الأذونات على وحدة تخزين جديدة هي ما يمنحه umask الافتراضي ، لذلك يمكنك محاولة تشغيل برنامج Docker daemon باستخدام 000 umask ومعرفة ما إذا كان الحجم قابلًا للكتابة عالميًا. ربما يجب أن يكون لدينا بعض خيارات الأذونات على docker volume create .

(يمكنك إصلاحه باستخدام حاوية جذر كانت تنتج chmod وخرجت أيضًا ولكن هذا أمر قبيح)

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

@ cpuguy83 أعتقد أنه سيكون من المنطقي إنشائه حيث قام المستخدم بالمرور بـ -u حيث من المحتمل أن يكون المستخدم يحاول كتابة الحجم على أي حال من داخل الحاوية ، أليس كذلك؟

تمكنت من التحميل باعتباري المستخدم الذي اخترته باستخدام الخطوات التالية:

  • أنشئ المستخدم داخل Docker بنفس UID / GID مثل المستخدم الذي يمتلك الملفات على المضيف.
  • قم بإنشاء نقاط التحميل مقدمًا وقم بتقطيعها إلى المستخدم المستهدف في الحاوية

اقتبس chrisfosterelli :

لقد قمت بحفر أكثر قليلاً وعزلته إلى هذا: لنفترض أن لدي حاوية بحث مطاطي ستنشئ دليلًا / بيانات عند بدء التشغيل (في حالة عدم وجود بيانات) ، ثم استخدم docker run -v / data elasticsearch. يصبح الدليل / البيانات مملوكًا لـ root: root ، وسيخفق البرنامج الخفي الذي يعمل كـ elasticsearch داخل الحاوية الآن في البدء لأنه لا يمكنه الكتابة إلى / data.

هذا هو مثال عظيم! لدي مثال مشابه مع صورة Solr. يحتاج Solr إلى "مركز" واحد أو أكثر ، كل منها عبارة عن مجموعة من ملفات التكوين وأجزاء الفهرس ذات الصلة. يتم وضع كل نواة داخل دليل باسم محدد من قبل المستخدم. على سبيل المثال ، إذا كنت أرغب في إنشاء نواة باسم products ، فسيكون المسار /opt/solr/server/solr/products . يتم اختيار اسم النواة من قبلي ، لذلك لا يمكن لمشرف الصورة Solr إنشاء هذا الدليل مسبقًا في الصورة.

أرغب في حفظ بيانات الفهرس الخاصة بي حتى أتمكن من ترقية صورتي إلى Solr أحدث دون الحاجة إلى إعادة فهرسة جميع المستندات الخاصة بي ، ولكن إذا قمت بتركيب وحدة تخزين على /opt/solr/server/solr/products ، فهذا يعني أنها مملوكة لـ root ولا يمكن لـ Solr (التي تعمل كـ solr ) كتابة أي شيء إليها. يحتوي الدليل الأصلي /opt/solr/server/solr على ملفات أخرى ، لذا لا يمكنني تحميل وحدة تخزين هناك أيضًا. (في لغة Docker الأخيرة ، أعتقد أن وحدات التخزين الخاصة بي تسمى "مجلدات مسماة" ، أي وحدات التخزين التي لم يتم تركيبها على مسار محدد على المضيف ولكن تتم إدارتها بالكامل بواسطة Docker بالنسبة لي.)

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

ctindel ربما ... إذا لم يكن الدليل موجودًا بالفعل.

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

@ cpuguy83 يعمل فقط مع الحجم المحدد.

@ kamechen ما الذي يعمل فقط؟

@ cpuguy83 عند استخدام وحدة تخزين محددة يتم تحميل الملفات تحت المستخدم الذي تحتاجه

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

هل كان هناك حل للمشكلة التي أثارهاandrewmichaelsmith؟

نحن نواجه مشكلة سيتم حلها من خلال هذا (على ما أعتقد). لدينا حصة NFS لأدلة الصفحة الرئيسية لمطورنا. يرغب المطورون في تحميل / home / dev / git / project في Docker ولكن لا يمكنهم ذلك لأن لدينا Root Squash ممكّنًا.

هذا يمنع الجذر من الوصول إلى / home / dev / git / project ، لذا عندما أحاول تشغيل docker mounting / home / dev / git / project ، أحصل على إذن lstat مرفوض خطأ.

أعتقد أنه من الممكن التغلب على هذا باستخدام bindfs .
استخدام docker -v ... لتحميل وحدة التخزين في مكان مؤقت ثم bindfs لتركيبها حيث neded كمستخدم آخر.

piccaso ، الطريقة التي فهمت بهاandrewmichaelsmith هي أن المشكلة تكمن في فشل التثبيت على جانب المضيف بسبب rootquash. ولكن لا يزال من الممكن استخدام bindfs كحل بديل في الواقع ، ولكن هذه المرة على الجانب المضيف. أولاً ، على المضيف ، تقوم بربط مشاركة nfs في موقع مؤقت كمستخدم غير جذر باستخدام FUSE ، ثم تقوم بتركيب هذا المجلد المؤقت في عامل الإرساء بـ -v ... .

ضع في اعتبارك أن bindfs (على الأقل مع FUSE) بها قدر كبير من حمل وحدة المعالجة المركزية.

نعم ، bindfs غير مرغوب فيه إلى حد كبير. إنه أبطأ حتى من أنظمة ملفات CoW.
هناك بعض الأعمال التي يتم إجراؤها في النواة للسماح بإزاحة uid / gid على الحامل والتي قد تساعد.

هناك بعض الأعمال التي يتم إجراؤها في النواة للسماح بإزاحة uid / gid على الحامل والتي قد تساعد.

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

NikolausDemmel أشك في أن يتغير. يتطلب syscall mount CAP_SYS_ADMIN ، وهو ليس شيئًا يُمنح لمستخدم غير جذر ، أو حتى شيئًا نعطيه للمستخدم الجذر للحاوية.

@ cpuguy83 شكرا للتوضيح. وهذا يعني أن تركيب وحدات التخزين الكبيرة على المجلدات المضيفة التي يتم تركيبها على NFS مع root-squash لن تعمل في المستقبل المنظور (بسبب قيود نظام mount syscall كما تقول) ، باستثناء استخدام الحلول مثل FUSE مع bindfs .

عذرًا ، كان هذا وقتًا إضافيًا قليلاً ، لأن OP كان يسأل عن تغيير UID / GID داخل الحاوية. لكنه نوع من الوجه الآخر للعملة وقد تم طرحه في المناقشة أعلاه. أردت فقط توضيح هذا التمييز.

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

آسف إذا لم يكن هذا هو أفضل مكان لوضعه ، فقد كنت أعاني منذ أيام ولم أستطع التفكير في مكان أفضل.

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

  1. إذا أردنا استخدام صورة Docker لشخص آخر ، فعلينا إعادة البناء باستخدام ملف Dockerfile مخصص
  2. نحتاج إما إلى إنشاء صورة عامل إرساء مخصصة لكل مستخدم محلي ، أو نستخدم حساب "خدمة" واحد ولن نتمكن من التمييز بين أنشطة المستخدم في FS.

هل يمكن لـ Bindfs أو userNS السماح لنا بالتغلب على هذا؟

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

هل أفعل شيئًا خاطئًا بشكل خاص هنا؟

rlabrecque شاهد منشوري سابقًا حول مطابقة معرف مستخدم عامل الإرساء مع معرف المضيف. لقد استخدمت هذا النهج وهو يعمل بشكل جيد حقًا بالنسبة لنا. بشكل أساسي ، قم بتشغيل HOST_UID=$(id -u) و HOST_GID=$(id -g) وأنشئ Dockerfile الذي يوسع $ HOST_GID و $ HOST_UID في الأمرين التاليين:

RUN groupadd -g $HOST_GID mygroup
RUN useradd -l -u $HOST_UID -g mygroup myuser

استخدم Dockerfile الذي تم إنشاؤه مع ملء المعرف لإنشاء صورتك.

haridsv لقد فعلت شيئًا مشابهًا وهو يعمل بشكل رائع على Linux. لكن يبدو أن هذا لا يعمل بالنسبة لي على نظام التشغيل Windows: لا تزال الملفات الموجودة داخل الحامل مملوكة لجذر.

لقد حللت هذا باستخدام 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.

لقد استخدمنا برنامج نصي من جانب المضيف لـ chown حجم beng الذي تم تركيبه مما يتجنب الحاجة إلى إعادة بناء الصورة:

#!/bin/bash
set -e

DOCKER_IMAGE=<docker_image>
COMMAND=<internal_command>

DOCKER_USER=docker-user
DOCKER_GROUP=docker-group

HOME_DIR=/work
WORK_DIR="$HOME_DIR/$(basename $PWD)"

PARAMS="$PARAMS -it --rm"
PARAMS="$PARAMS -v $PWD:$WORK_DIR"
PARAMS="$PARAMS -w $WORK_DIR"

USER_ID=$(id -u)
GROUP_ID=$(id -g)

run_docker()
{
  echo \
    groupadd -f -g $GROUP_ID $DOCKER_GROUP '&&' \
    useradd -u $USER_ID -g $DOCKER_GROUP $DOCKER_USER '&&' \
    chown $DOCKER_USER:$DOCKER_GROUP $WORK_DIR '&&' \
    sudo -u $DOCKER_USER HOME=$HOME_DIR $COMMAND
}

if [ -z "$DOCKER_HOST" ]; then
    docker run $PARAMS $DOCKER_IMAGE "$(run_docker) $*"
else
    docker run $PARAMS $DOCKER_IMAGE $COMMAND "$*"
fi

ماذا عن استخدام نظام الملفات ACL على الدليل المضيف؟ بهذه الطريقة يمكنك إخبار نظام الملفات بتطبيق أذونات معينة على الملفات المنشأة حديثًا داخل الدليل. إذا قمت بتعيين ACL على مستوى المضيف ، فسيحدث ذلك أيضًا إذا قمت بتعديل البيانات من الحاوية.

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

يبدو أن kamechen على حق في أن المجلدات المسماة "تعمل فقط". في حالة وحدات التخزين المسماة ، تؤدي الأذونات الحالية إلى "نتائج عكسية" وتغيير أذونات وحدة التخزين ، وأنا شخصياً أعتبر هذا خطأ (# 28041).

thegecko ، لماذا لا تأخذ هذا النهج أكثر ولا تنشئ مستخدمين ضمن نقطة دخول؟

هذا هو المثال الخاص بي ، فهو يكتشف مالك الدليل الموصول ، ويقوم بإنشاء مستخدم بنفس المعرف الفريد ويقوم بتشغيل الأمر كما هو الحال مع هذا المستخدم:

ملف Dockerfile

FROM ubuntu

RUN mkdir /project
VOLUME /project

ENV GOSU_VERSION 1.9
RUN set -x \
    && apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \
    && dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \
    && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch" \
    && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc" \
    && export GNUPGHOME="$(mktemp -d)" \
    && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
    && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
    && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \
    && chmod +x /usr/local/bin/gosu \
    && gosu nobody true \
    && apt-get purge -y --auto-remove ca-certificates wget

ADD entrypoint.sh /

ENTRYPOINT ["/entrypoint.sh"]

CMD /project/run.sh

نقطة الدخول

#!/bin/sh

USER=dockeruser
VOLUME=/project
UID="$(stat -c '%u' $VOLUME)" && \
useradd --uid "$UID" "$USER" && \
ls -l "$VOLUME" && \
exec gosu "$USER" "$@"

run.sh

#!/bin/sh

echo "Running as \"$(id -nu)\""

عندما أقوم بتشغيل sudo docker build -t test . && sudo docker run --rm -v /tmp/docker-test/:/project test:latest فإنه ينتج:

total 12
-rw-r--r-- 1 dockeruser dockeruser 990 Dec 12 10:55 Dockerfile
-rwxr-xr-x 1 dockeruser dockeruser 156 Dec 12 11:03 entrypoint.sh
-rwxr-xr-x 1 dockeruser dockeruser  31 Dec 12 11:01 run.sh
Running as "dockeruser"

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

AndreasBackx يعمل استخدام وحدات التخزين فقط على افتراض أن الصورة تحتوي على بيانات في المسار الذي تقوم بالتصعيد إليه.
استخدام الروابط يستخدم UID / GID لمسار المضيف.

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

لكن دعنا نعود خطوة للوراء للحظة.
لا يجعل Docker الأمور أكثر صعوبة هنا.
UID / GID في الحاوية هو نفسه UID / GID على المضيف .. حتى إذا كانت أسماء المستخدمين / المجموعة غير متطابقة ، فإن UID / GID هو المهم هنا.
تمامًا كما هو الحال بدون عامل الإرساء ، فأنت بحاجة إلى الخروج بمعرف uid / gid الذي تريد استخدامه لخدمتك (خدماتك) واستخدامه خارج نطاق الاصطلاح.
تذكر ، لا يلزم وجود uid / gid في /etc/passwd أو /etc/group لتعيين ملكية الملف عليه.

@ cpuguy83 أشكركم على التوضيح.

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

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

اكتشفت للتو أن الخيار -o في usermod للسماح لمعرفات IDS المكررة ، يبدو خيارًا شرعيًا.

RUN usermod -o -u 1000 <user>

لست متأكدًا من سبب عدم إصلاح ذلك بأي طريقة معقولة.

docker run -it -u 1000:4211 -v /home/web/production/nginx_socks:/app/socks -e SOCKS_PATH=/app/socks --name time_master  time_master

سجل الدخول لترى:

drwxr-xr-x    8 geodocr_ geodocr       4096 Jun  4 18:51 .
drwxr-xr-x   57 root     root          4096 Jun  6 21:17 ..
-rwxrwx---    1 geodocr_ geodocr        140 Jun  4 18:49 .env
-rwxrwx--x    1 geodocr_ geodocr         78 Jun  4 18:49 entrypoint.sh
drwxrwxr-x    2 geodocr_ geodocr       4096 Jun  4 18:51 handlers
-rwxrwx---    1 geodocr_ geodocr        242 Jun  4 18:49 requirements.txt
-rwxrwx---    1 geodocr_ geodocr       1270 Jun  4 18:49 server.py
drwxr-xr-x    2 root     root          4096 Jun  6 21:00 socks
drwxr-xr-x   10 geodocr_ geodocr       4096 Jun  4 18:51 utils

ملف dockefile على وجه التحديد يفعل

RUN adduser  -D -u 1000 $USER 
#
RUN addgroup $GROUP -g 4211 
#
RUN addgroup $USER $GROUP 
RUN mkdir /app/socks
USER $USER  
#

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

لا يوجد أي منها جذر ، لذلك يبدو أنه يتصاعد كجذر خطأ.

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

disarticulate إذا كنت تريد أن يكون مسار المضيف شيئًا آخر غير الجذر ، فعليك تغيير مسار المضيف.

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

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

jalaziz ماذا يفعل عندما لا يكون مستخدم الحاوية على المضيف؟ تتمثل إحدى الفوائد الرئيسية للحاويات في أنك لست مضطرًا إلى كشف تبعياتها (بما في ذلك المستخدمين) للمضيف.

taybin أتوقع أن يقوم Docker فقط بإنشاء المجلد مع uid: gid لمستخدم الحاوية أو إذا كان المجلد موجودًا داخل الحاوية ، فسيؤدي ذلك إلى إنشاء مجلد مضيف بنفس uid: gid and mask.

ملاحظة: لا أتوقع تغيير أذونات Docker إذا كان المجلد موجودًا بالفعل على المضيف.

taybin بالضبط كما وصف frol . يجب أن تستخدم فقط uid: gid من الحاوية.

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

في حالتي ، لم يكن لدي بالضرورة سيطرة صريحة على صورة عامل الإرساء التي تم استخدامها (لم أستطع تعديل ملف Docker حسب رغبتي).

لذلك ، جربت هذا:

docker run -it -u $(id -u $USER):$(id -g $USER) -v $(pwd):/src -w /src node:latest npm run build

مما يؤدي إلى إنشاء مجلد يسمى ./built-app . ومع ذلك ، كان المالك لا يزال root بأذونات صارمة.

كان الحل الخاص بي هو:

docker run -it -v $(pwd):/src -w /src node:latest /bin/bash -c "npm run build; chmod -R 777 ./built-app"

الذي لا يزال لديه مالك root ، لكن أذونات مخففة. ثم تمكن نظام التشغيل المضيف (Ubuntu) من الوصول إلى ./built-app بدون امتيازات sudo.

@ rms1000watt هل جربت الأمر التالي؟

docker run -it -v $(pwd):/src -w /src node:latest /bin/bash -c "npm run build; chown -R ${UID}:${GID} ./built-app"

يجب أن يعمل ذلك لأنه سيستخدم UID و GID لمضيفك مباشرة على الملفات نفسها. يعد استخدام chmod -R 777 ممارسة سيئة بشكل عام.

saada يصيح! دعوة جيدة. أنا سوف إعطائها بالرصاص.

يمكنني إكمال أسلوبي في قراءة هذا وفهم كيفية عمل _UID و GID في حاويات Docker_
https://medium.com/@mccode/understanding -how-uid-and-gid-work-in-docker-container-c37a01d01cf

يوجد أساسًا نواة واحدة ومجموعة واحدة مشتركة من الموائع والمعرفات العامة مما يعني أن جذر جهازك المحلي هو نفسه جذر الحاوية الخاصة بك ، وكلاهما يشتركان في نفس UID


لدي خادم apache وأريد مشاركة ملفات webapp الخاصة بي مع حاوية apache لتعديلها على المضيف (التطوير وتغييرها باستخدام محرر نصوص) ومشاهدة النتائج من خلال عملية تعمل في الحاوية. في بعض الأحيان ، اكتب ملفات جديدة ، وإذا لم أغير السلوك الافتراضي بالامتيازات التي يتم إنشاؤها بواسطة المستخدم الجذر ولا يمكن لمستخدمي المحلي تعديلها بعد الآن.

ما فعلته هو إنشاء صورة مخصصة تضيف هذا في ملف عامل الإرساء الخاص بي:

RUN adduser -D -u 1002 dianjuar -G www-data
USER dianjuar

ربما لجعل docker-compose.yml محمولاً ليتمكن أي شخص من استخدامه ، يتم وضع بعض المعلمات في عملية الإنشاء.

إليك نمط حاوية لتعيين معرف المستخدم / معرف المجموعة في وقت التشغيل بطريقة يسهل نقلها. https://github.com/Graham42/mapped-uid-docker

الطريقة التي اتبعتها:

1- قم بإنشاء الدليل على الخادم المضيف
2- قم بتغيير صلاحياتها للمستخدم الذي له معرف المستخدم والمجموعة = 1000
3- قم بتشغيل docker-compose up
فحص الحاوية وكل شيء على ما يرام.

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

مشكلة نموذجية:

  • سرب عامل الميناء ، لذا فإن CAPP_ADD غير متاح ، ولا يعد ربط الربط حلاً
  • تشترك حاويتان من صورتين مختلفتين في نفس الحجم ، لذلك توجد قواعد بيانات مختلفة للمستخدم / المجموعة على كليهما
  • على سبيل المثال ، يجب أن يتمتع المرء بحقوق الوصول إلى www-data (على سبيل المثال ، دعنا نشفر أداة تنزيل الشهادة)
  • يستخدم الآخر أيضًا بيانات www (أي nginx)
  • لكن الثالث يتطلب الوصول من المستخدم openldap (أي خادم openldap)
  • chmod بسيط جدا أيضا ليس حلا

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

هناك مجموعات أخرى تواجه نفس المشكلة تمامًا.

اي فكرة كيف تحل هذا؟

كيف تحل هذا بدون Docker؟ هذا ليس عامل ميناء محدد
مشكلة.

يوم الجمعة ، 12 كانون الثاني (يناير) 2018 ، الساعة 10:24 صباحًا ، أرسل Marc Wäckerlin [email protected]
كتب:

مشكلة نموذجية:

  • سرب عامل ميناء ، لذلك CAPP_ADD غير متاح ، ربط جبل ليس
    المحلول
  • تشترك حاويتان من صورتين مختلفتين في نفس الحجم ، لذلك
    قواعد بيانات مختلفة للمستخدم / المجموعة على كليهما
  • على سبيل المثال ، يجب أن يكون لدى المرء حقوق الوصول www-data (على سبيل المثال ، دعونا نقوم بتشفير
    تنزيل الشهادة)
  • يستخدم الآخر أيضًا بيانات www (أي nginx)
  • لكن الثالث يتطلب الوصول من المستخدم openldap (أي openldap
    الخادم)
  • chmod بسيط جدا أيضا ليس حلا

هذا يعني أن لدي خادم ويب يحصل على شهادات SSL لنطاقاته
من دعنا نشفر وخادم OpenLDAP لنفس المجال ، حيث أريد
لإعادة استخدام الشهادات.

هناك مجموعات أخرى تواجه نفس المشكلة تمامًا.

اي فكرة كيف تحل هذا؟

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

-

  • بريان جوف

حتى بدون سرب ، يمكنني حلها في عامل ميناء: ربط جبل.

إنها مشكلة خاصة بعمال الرصيف ، لأنه لا يوجد CAP_ADD.

لا يمكن تعيين حوامل ربط mwaeckerlin لمعرف مستخدم مختلف.
ولكن حتى مع السرب يمكنك ربط جبل .... لماذا هناك حاجة CAP_ADD؟

بدون CAP_ADD ، يفشل التحميل داخل عامل الإرساء.

لكن من خلال كتابة تعليقي ، حصلت للتو على حل ممكن ، لكن لسوء الحظ ، يتطلب ذلك تغيير Dockerfile في كلتا الصورتين ، لذلك لن يعمل مع مكتبة أو صور أخرى تابعة لجهات خارجية:

  • أنشئ مجموعة بمعرف مجموعة مشترك صريح في جميع ملفات Dockerfiles
  • إعطاء حقوق للمجموعة

mwaeckerlin لماذا تحتاج إلى التركيب داخل الحاوية؟

لأنني لا أستطيع تحديد مستخدم / مجموعة مع خيار عامل الإرساء -v .

الفكرة المحددة أعلاه هي: ربط الحاوية داخل الحاوية ، ثم تشريد الهدف يجب ألا يغير المصدر.

mwaeckerlin إذا قمت بتغييره ، فسيتم تغييره في كل مكان. هذا هو لب المشكلة في هذه القضية.
Chowning / Chmoding ملف / dir يغير كلا المكانين.

أيضًا ليست هناك حاجة لتكون قادرًا على التركيب داخل الحاوية ، يمكنك --mount type=bind,source=/foo,target=/bar

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

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

هنا شيء من هذا القبيل من شأنه أن يساعد على الأقل في بعض الحالات: --mount type=bind,source=/foo,target=/bar,user=me,group=mine

أي توصيات أو أفضل الممارسات بخصوص هذا الموضوع: مستخدم وحدة التخزين المشتركة من قبل مستخدمين مختلفين في صور مختلفة في سرب عامل الميناء؟

  1. لا تشارك مجلدات
  2. مزامنة مع uid / gids الخاص بك
  3. تأكد من أن الأذونات متساهلة بما يكفي لجميع المشاركين
  4. استخدم حوامل المصهر على المضيف للربط بمعرف uid / gid مختلف لكل حاوية

هل يمكنك توضيح النقطة 4؟
ربما مثال عملي على كيفية القيام بذلك؟

في الجمعة ، 12 يناير 2018 ، الساعة 17:27 ، كتب بريان جوف ، [email protected] :

>

  1. لا تشارك مجلدات
  2. مزامنة مع uid / gids الخاص بك
  3. تأكد من أن الأذونات متساهلة بما يكفي لجميع المشاركين
  4. استخدم حوامل المصهر على المضيف للربط بمعرف uid / gid مختلف لكل منها
    وعاء

-
أنت تتلقى هذا لأنك مشترك في هذا الموضوع.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/moby/moby/issues/2259#issuecomment-357282169 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe-auth/AHSjvgjb0BFbJhZ1VWM-pLGfa7tRBvDNks5tJ4VPgaJpZM4BGxv9
.

باستخدام شيء مثل https://bindfs.org/ - حتى أن هناك مكونًا إضافيًا لوحدة تخزين Docker واحدًا على الأقل يقوم بتنفيذه بالفعل (https://github.com/lebokus/docker-volume-bindfs هي أول نتيجة وجدتها عبر Google) .

لا يمكنني تغيير الإذن بعد تركيب وحدة التخزين ، فهل يحصل أي شخص على هذا؟

الحل:
إضافة هذا إلى Dockerfile
RUN echo "if [ -e container_volume_path ]; then sudo chown user_name container_volume_path; fi" >> /home/user_name/.bashrc
تم تغيير ملكية container_volume_path بعد أن يتم تركيب وحدة التخزين.

تبدو القدرة على تعيين uid و gid كعنصر غامض مفقود لمعالجة وحدة التخزين. قد يكون المسار الأقل مفاجأة هو إدراجه والإصلاحات المقترحة ثقيلة ويصعب اكتشافها ، مع عدم تقديم أفضل الممارسات:

إعادة:
1) لا تشارك مجلدات

  • جيد ، لكنه غير جوهري للمناقشة حول تعيين uid / gid
    2) قم بمزامنة معرفاتك / معرفاتك
  • هذا ما تهدف الوظيفة إلى القيام به ، ولكن دون إجبار chown في Dockerfile
    3) تأكد من أن الأذونات متساهلة بما يكفي لجميع المشاركين
  • يعتمد هذا مرة أخرى على السلوك المحدد في Dockerfile ، حيث يمكن أن يكون تعيينًا بسيطًا
    4) استخدم حوامل المصهر على المضيف لربط uid / gid مختلفة لكل حاوية
  • نصيحة جيدة ، يبدو هذا أيضًا مثل حلق الياك.

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

عندما يمكن أن يكون تعيينًا بسيطًا

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

أحتاج وحدات تخزين مشتركة ، على سبيل المثال في الحالة التالية:

الشهادات المشتركة

  • الحاوية 1 هي وكيل عكسي يتعامل مع دعونا نشفر جميع المجالات المستضافة
  • الحاوية 2 هو خادم ldap يحتاج أيضًا إلى توفير شهادة مجاله

الحل: ترث حاوية الصورة 2 من نفس الصورة من الحاوية 1 ، تنشئ الصورة الأساسية المشتركة مجموعة مشتركة ، ثم يكون لكلتا الحاوية نفس وصول المجموعة

القاعدة المشتركة Dockerfile

RUN groupadd -g 500 ssl-cert

لنقم بتشفير الصورة letsencrypt-config.sh :

chgrp -R ssl-cert /etc/letsencrypt

Dockerfile من mwaeckerlin / عكس الوكيل :

RUN usermod -a -G ssl-cert www-data

Dockerfile من mwaeckerlin / openldap :

RUN usermod -a -G ssl-cert openldap

هذا هو.

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

ولكن ربما أفتقد نقطة كبيرة بعد البحث في الويب خلال الأيام الثلاثة الماضية.
لن تعمل أي من التوصيات أعلاه أو المرتبطة و (الحلول البديلة) بأي شكل من الأشكال.

جميع وحدات التخزين المثبتة على الحاوية مملوكة دائمًا للجذر: الجذر داخل الحاوية. بغض النظر عما إذا قمت بتغيير المالك مقدمًا على المضيف مع مطابقة UID / GID أم لا.

لا أستطيع أن أفقد الشعور بأنني غبي أحاول القيام بشيء أساسي للغاية - من وجهة نظري.

  • Windows 10 Pro 1803 (17134.112)
  • Docker for Windows 18.03.1-ce-win65 (17513)
  • Windows WSL مع Hyper-V و Ubuntu

محاولة بدء حاوية apache2 عادية حيث يتم تثبيت جذر المستند على المضيف حتى أتمكن من تطوير كود مصدر php أثناء اختباره على الفور على حاوية عامل التحميل.

root<strong i="16">@win10</strong>:# docker run --rm -v /c/Users/<MyUser>/Development/www-data:/var/www/html -it httpd:2.4 /bin/bash

داخل حاوية عامل الإرساء ، يكون الدليل _ / var / www / html_ مملوكًا دائمًا لـ _ root: root_ ، لذلك لن يتمكن تطبيق php أبدًا من فتح أو الكتابة باستخدام أي بيانات داخل هذا المجلد على الإطلاق ..
لا شيء يعمل بعد ... :(

لأولئك الذين يبحثون عن حل أنيق بشكل معقول ، تحقق مما اقترحه elquimista هنا . لقد اختبرت هذا وأعمل بشكل جيد

لقد استخدمنا https://github.com/boxboat/fixuid#specify -paths-and-Conduct-عبر الأجهزة مع الحظ. بالإضافة إلى ذلك ، يقوم بإعداد مستخدم داخل الحاوية لمطابقة مستخدم على المضيف.

فيما يلي مثال على التكوين من الصورة:

$ cat /etc/fixuid/config.yml
user: lion
group: lion
paths:
  - /home/lion
  - /home/lion/.composer/cache
  - /tmp

وللتشغيل:

$ docker run --rm -it --init \
    -u 1000:1000 \
    -v `pwd`:/app \
    -v "$HOME/.composer/cache:/home/lion/.composer/cache" \
    --entrypoint='fixuid' \
    php:7.2-cli \
        /bin/bash

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

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

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

لا يوجد ، ليس بدون نظام ملفات مخصص (مثل bindfs).

tlhonmey نعم ، لقد تمكنت من التغلب على مشكلة "أنظمة التخزين التي لا تدعم أذونات يونكس" باستخدام بعض الروابط الرمزية.

بشكل أساسي ، أثناء التركيب من محركات أقراص NTFS ، كنت أضع الأشياء في -v ./HostNtfsStuff:/data/ntfsMount ثم أقوم بعمل ارتباط رمزي وقم بتبديل هذا ln -s -T /data/ntfsMount /var/lib/myApp && chown -Rh myApp:myApp /var/lib/myApp/

يمكنك أيضًا اختبار: su myApp -c 'echo foo > /var/lib/myApp/bar' && cat /data/ntfsMount/bar

كان استخدامي لمطوري Windows أن يكونوا قادرين على تشغيل حاويات MySQL والاستمرار في وحدات التخزين المثبتة ، ولكنه ينطبق على الكثير من التطبيقات.

لذا فإن الحل هو إدارة مجموعة من uid: أزواج gid يدويًا ونأمل ألا تتعارض مع المضيف ، أو نص مساعد ، أو:

هناك طريقة _ واحدة_ لإنجاحها ، ولكن عليك الاستعداد مسبقًا داخل Dockrfile الخاص بك.

RUN mkdir -p /var/lib/redis ; chown -R redis:redis /var/lib/redis
VOLUME ["/var/lib/redis"]
ENTRYPOINT ["usr/bin/redis-server"]
USER redis

(لم أختبر هذا المثال ، فأنا أعمل على حاوية من الكروم يتم عرضها بعد ذلك على حاوية _ منفصلة_ X11 ...)

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

لقد رأيت هذا أفضل ممارسات القراءة Dockerfile والنص المساعد هو ما يوصون به:

#!/usr/bin/env bash
set -e

if [ "$1" = 'postgres' ]; then
    chown -R postgres "$PGDATA"

    if [ -z "$(ls -A "$PGDATA")" ]; then
        gosu postgres initdb
    fi

    exec gosu postgres "$@"
fi

exec "$@"

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

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

لا يمكنك تعيين uids / gids على مستوى نظام الملفات ، على الأقل ليس بدون مصهر.

لا يمكنك تعيين uids / gids على مستوى نظام الملفات ، على الأقل ليس بدون مصهر.

كندة ما كنت أخافه. هل لديك أي فكرة عن عقوبة الأداء إذا استخدم عامل الميناء فتيل مثل هذا؟

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

لذا ، فإن الأمر يتكرر للتأكد من امتلاكك للملكية في كل بداية ،

لا تحتاج إلى القيام بـ chown في كل بداية. بدلاً من ذلك ، تحقق من مالك دليل البيانات وقم بإجراء العودية chown فقط إذا لم يكن صحيحًا. مثله:

 [ $(stat -c %U "$PG_DATA") == "postgres" ] || chown -R postgres "$PG_DATA"

لذلك من الناحية المثالية سيحدث هذا في البداية الأولى فقط.

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

في تصميم صورة عامل إرساء جيد ، لا يكون مستخدم وقت التشغيل جذرًا وبالتالي لا يمكنه ملفات chown …!

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

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

  • sudo
  • su
  • USER root

حسب: https://f1.holisticinfosecforwebdevelopers.com/chap03.html#vps -countermeasures-docker-the-default-user-is-root

في رأيي المتواضع ، الأمر متروك لمستخدم صورة Docker للتأكد من أنه / هي يعيّن الإذن على وحدة التخزين المثبتة بشكل صحيح.

إنه مشابه جدًا لما كنا نفعله تقليديًا قبل أن تصبح الحاويات شيئًا ، على سبيل المثال عندما أردت تشغيل nginx وكنت بحاجة للتأكد من أن دليل HTML الثابت ملك للمستخدم الصحيح. لكي أعرف أنني سأحتاج إلى فتح ملف nginx.conf الخاص بي ، تحقق من مستخدم العمال وعيّن الأذونات وفقًا لذلك. في الواقع ، تم وصف هذا كله في وثائق nginx.

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

ومع ذلك ، هذا صحيح أنه نظرًا لأن لدينا الآن مستخدمين من المحتمل أن يكونوا محددين داخل الحاوية وليس خارجها ، فهذا يجعل الأشياء تبدو مختلفة (وهم ليسوا كذلك). لكن المعرف الفريد العمومي (UID) من الداخل والخارج متكافئان ، لذلك قد يوجد foobar مع UID 2000 داخل حاوية وليس خارجها ، ولكن لا يزال من الممكن تعيين UID 2000 على الملفات والدلائل الموجودة بالخارج. علينا تغيير طريقة تفكيرنا فيما يتعلق بـ UID / GID بدلاً من الأسماء البشرية الصديقة التي اعتدنا التعامل معها.
كما أنه يجعل الأمور أكثر صعوبة إذا كنت بحاجة إلى مشاركة مجلد بين حاويتين كتبهما مؤلفان مختلفان. من المحتمل ألا يكون تعيين الأذونات باستخدام نظام Unix التقليدي (للمستخدم والمجموعة وغيرهم) كافياً لحل المشكلة (لا يوجد UID أو GID مشترك). أعترف أنه منذ استخدامي Docker ، أقوم باستخدامات أكثر بكثير لـ POSIX ACL. لذلك يمكنني تعيين 3 أذونات مختلفة للمستخدمين لنفس الملف. على سبيل المثال ، كاتب حاوية بإذن من rw ، وقارئ حاوية بإذن r ومستخدم مضيف بإذن r.

خيار آخر: يمكن فرض GID المشترك باستخدام علامة setgid للأدلة المشتركة. يمكن فرض قناع الملف باستخدام ACL.

قبل أن تفعل أي شيء في حاوية Docker ، قم بتشغيل:

""
Umask 0000
""

https://en.wikipedia.org/wiki/Umask

الإسقاط متأخرًا إلى هذا الموضوع لإعادة تأكيد مدى فائدة هذه الميزة.

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

كما هو الحال اليوم ، اختار عدد كبير من صور Docker الاستمرار في تشغيل نقاط الدخول الخاصة بهم كـ root حتى يتمكنوا من تشغيل أذونات الدليل والملف فقط لإسقاط الامتيازات قبل تشغيل عملية التطبيق.

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

دفعت المخاوف الأمنية التي أثارتها ممارسة _entrypoint-as-root_ عددًا كبيرًا من مخططات Kubernetes إلى توفير initContainers الذي يمكنه chown و chmod قبل بدء حاوية التطبيق . قد يبدو هذا وكأنه طريقة لطيفة ، لكن ثق بي عندما أقول هذا: إنه ليس كذلك .

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

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

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

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

نظرًا لأن المشكلة بالتأكيد لا تختفي من تلقاء نفسها ، ويتطلب الحل بعض أنواع التغييرات الأساسية للغاية.

initContainers يمكنها قطع وحدات التخزين وتغييرها قبل بدء حاوية التطبيق. قد يبدو هذا وكأنه طريقة لطيفة ، لكن ثق بي عندما أقول هذا: إنه ليس كذلك.

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

عند المشاركة بين الحاويات التي تعمل كمستخدم مختلف ، يمكنك إما تشغيل كلتا الحاويات بنفس uid (أو gid ، وتعيين أذونات المجموعة الصحيحة ، على غرار كيفية عمل ذلك عند تشغيل اثنين العمليات غير المعبأة في حاويات والتي تحتاج إلى الوصول إلى نفس الموارد).

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

فقط لمنع الارتباك. الحاوية التي تعمل كـ root ليست هي نفسها الحاوية "المميزة" ( --privileged أو الخيارات ، مثل --cap-add set). الحاويات المميزة ( --privileged ) غير آمنة بدرجة كبيرة ، في حين أن الحاوية التي تعمل كـ root محتواة بالكامل ولن تكون قادرة على كسرها ؛ يؤدي تمريرها إلى الملفات / الدلائل المثبتة على الروابط إلى إحداث ثقوب في ذلك ، لذا _سوف تمنحها إمكانية الوصول إلى الملفات / الدلائل التي تمررها كجهاز ربط.

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

يتساءل: إذا كانت هذه uids / gids غير معروفة ؛ كيف ستبدو UX؟ (حيث يتعين علي تقديم معرّف تعريف / معرف للخرائط لاستخدامه في تعيين معرف مضيف / معرف مضيف إلى معرف حاوية / معرف (غير معروف)؟

إذن ، يصبح السؤال: في أي مكان آخر على الإنترنت يطورون مواصفات OCI المشتركة ، وأين يجب إجراء هذه المناقشة؟

لا أعتقد (في لمحة) أن هناك حاجة إلى تغيير مواصفات OCI ؛ يمكن حل هذا خارج مواصفات OCI ؛ المشكلة الرئيسية هي أن آليات تعيين معرفات / معرفات مفقودة حاليًا في النواة (أو موجودة (مثل shiftfs ) ، ولكنها غير متوفرة بشكل شائع)

هذا شكل خماسي كلاسيكي لتمرير المسؤوليات / يمكن لشخص آخر أو يجب أن يحل هذه المشكلة. إما أن يكون:

  • مستخدم
  • التنفيذ المحدد لمنصة Docker / containerization
  • مواصفات OCI
  • نواة
  • نظام الملفات

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

وهذا يعني أنه لا يمكنك بسهولة التعامل مع الصور ومشاركتها / مزجها للعمل معًا من مستخدمين مختلفين. لذلك إما:

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

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

راجع للشغل فيما يتعلق بإلقاء نظرة فاحصة على حل قائم على نظام الملفات ، فقد وجدت أن هذا التعليق "قد يكون مفيدًا" لروابط العنكبوت:

https://github.com/docker/compose/issues/3270#issuecomment -365644540

الذي يحتوي على عدة مراجع مختلفة لهذه الميزة العامة نفسها (إلى مشروع / أماكن أخرى) ، بما في ذلك نظام الملفات الموزع (المعروف باسم "Luster") ، ومشكلة أخرى تتعلق بـ ZFS. حسنًا ، لقد صادفت استخدام ZFS هنا بنفسي.

ثم عثرت أيضًا على نسخة أخرى من نفس الخطأ على ubuntu / launchpad. الإشارة إلى نفس مشكلة ZOL # 4177 ،

https://bugs.launchpad.net/ubuntu/+source/zfs-linux/+bug/1567558

والذي يشير إلى أن الخطأ المعني قد تم إصلاحه في إصدار zfs 0.6.5.7+ SO. هل هذا يعني أنه من المحتمل أن نتمكن من استخدام zfs و ACLs ، كنوع من مخزن الدعم لإعادة تعيين Uids و gids بطريقة ما؟ حسنًا ، هذا ليس شيئًا سمعت عنه من قبل.

ربما هذا الحل يعمل فقط مع حاويات LXC. لأنه كان يقول أيضًا في تعليقاته هناك (قائد مشروع LXC) ، "نستخدم مساعدين setuid (newuidmap و newgidmap)" يمكنهم بعد ذلك "إعداد خريطة uid و gid". من المفترض أن هناك أيضًا بعض الآليات الضرورية في LXC نفسها ، وإلا فلا يمكن استخدام جزء zfs acls؟ أو ربما أكون مخطئا. لست متأكدًا تمامًا من أنني أتبع هذا طوال الطريق.

رابط آخر مثير للاهتمام ، هذه المرة حول shiftfs ، ومناقشة حول إمكانية استيعاب ميزاته في التراكبات. وهو بالطبع نظام ملفات أساسي يستخدمه عامل الإرساء بالفعل.

ولكن ماذا يحدث إذا تم تنفيذ ميزة إعادة التعيين في overlayfs ، ومع ذلك أريد استخدام محرك تخزين zfs بدلاً من ذلك لنظام الملفات الأساسي؟ هل يجب أن أترك بعد ذلك خارج القدرة على إعادة رسم خريطة uids / gids ، إذا كان يتم تنفيذه على أساس كل نظام ملفات؟ أو هل يمكننا تنفيذ كل منهما بشكل منفصل؟ عذرًا ، أنا غير واضح بعض الشيء فيما إذا كان Docker daemon يحتاج إلى أن يكون على دراية بمثل هذه التغييرات ، وأن يوفر واجهة برمجة تطبيقات مشتركة وأعلامًا (لتمريرها إلى طبقة السائقين fs). أو إذا كنا سنقوم بدلاً من ذلك بإعادة التعيين يدويًا بأنفسنا على جانب المضيف (في نظام الملفات ، خارج عامل الإرساء). هذا الجانب لا يزال غير واضح بعض الشيء بالنسبة لي.

عفوًا ، نسيت تضمين الرابط! ها هو

https://lists.linuxfoundation.org/pipermail/containers/2018-June/039172.html

تتعلق هذه المشكلة بوحدات التخزين / الروابط المتصاعدة ، لذا فهي منفصلة عن نظام ملفات الحاوية

سنستخدم بشكل مفرط مع تحويل uid / gid لـ bindmount إذا تم دمج ميزات shiftfs المتراكبة ، ولكن سيتعين علينا الرجوع إلى شيء آخر (أو لا شيء) على الأنظمة غير المدعومة.

Podman هو بديل Docker بدون جذر https://www.youtube.com/watch؟v=N0hSn5EwW8w https://podman.io/ . مع podman ، لا يتم استخدام الجذر لذلك يتم التعامل مع إذن المستخدم بشكل صحيح. تحول فريقنا إلى Podman بسبب هذه المشكلة وعمل جيدًا.

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

يمكنك اختبار Podman بالأوامر التالية. لا يحتوي Podman على برنامج خفي منفصل بخلاف Docker ، وكل شيء يعمل تحت المستخدم الذي ينفذ أوامر podman . لذا فإن الملفات التي تم إنشاؤها داخل podman مملوكة للمستخدم الذي قام بتشغيل الأمر podman run ... .

kkimdev<strong i="8">@ubuntu</strong>:~$ mkdir podman_test
kkimdev<strong i="9">@ubuntu</strong>:~$ ls -agh podman_test
total 8.0K
drwxrwxr-x 2 kkimdev 4.0K Jun 27 04:23 .
drwxr-xr-x 8 kkimdev 4.0K Jun 27 04:23 ..

kkimdev<strong i="10">@ubuntu</strong>:~$ podman run --rm -it -v ~/podman_test:/podman_test alpine
/ # cd /podman_test/
/podman_test # touch test_file
/podman_test # ls -agh
total 8K
drwxrwxr-x    2 root        4.0K Jun 27 02:24 .
drwxr-xr-x   20 root        4.0K Jun 27 02:24 ..
-rw-r--r--    1 root           0 Jun 27 02:24 test_file

/podman_test #

kkimdev<strong i="11">@ubuntu</strong>:~$ ls -agh podman_test/
total 8.0K
drwxrwxr-x 2 kkimdev 4.0K Jun 27 04:24 .
drwxr-xr-x 8 kkimdev 4.0K Jun 27 04:23 ..
-rw-r--r-- 1 kkimdev    0 Jun 27 04:24 test_file

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

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

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

يرجى إلقاء نظرة على إذن "test_file" الذي تم إنشاؤه في تعليقي أعلاه. يقوم أولاً بتحميل الدليل "~ / podman_test" ، ويكتب ملف "test_file" داخل حاوية podman. ثم بمجرد خروج المستخدم من الحاوية ، يمكنك أن ترى أن الملف مملوك لـ "kkimdev" وليس الجذر.

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

نعم ، تم تصميم podman بشكل مختلف مما يجعل هذه المشكلة محل نقاش لهذه الأداة - هذا جيد وجيد ، ولكن خارج الموضوع تمامًا هنا. Rootless لها مقايضات مختلفة ، بعضها جيد لبعض الناس ، وبعضها ليس كذلك. إنه يتحسن بمرور الوقت (ومعظمه من تحسينات النواة) ، لكنه ليس حلاً عامًا للجميع هنا.

يتطلب هذا إما تعديلات kernel أو رقاقة لحل عام كما تمت مناقشته بالتفصيل أعلاه (وكما أن @ cpuguy83 وآخرون كانوا يعملون على محاولة المساعدة في حل هذه المشكلة بطريقة عامة).

كان Docker قد فتح هذه المشكلة بالذات منذ عام 2013 وبعد ما يقرب من ست سنوات لا يوجد تحسن سهل في الأفق. تم تصميم Podman للحصول على التوافق مع Docker ولكنه يحل عيوب تصميم Docker أيضًا (بما في ذلك التشغيل كمستخدم غير متميز لا يتطلب خفي Docker للمستخدم المتميز).

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

يمكنني أن أؤكد لكم أن هناك الكثير من الأسباب وراء هيكلة Docker على النحو الذي هو عليه

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

إذا كان Podman لا يعمل من أجلك: حسنًا! ولكن إذا ساعد الآخرين لأن عليهم فقط استبدال docker بـ podman في بنيتهم ​​التحتية: فقط دعهم يفعلون ذلك.

الحجة الرئيسية لـ Podmans هي أنها لا تدير برنامجًا خفيًا وهذه هي حجتي الرئيسية ضدها. كيف يمكنني استعادة الحاوية الخاصة بي بعد إعادة التشغيل؟ لن أفعل ذلك يدويًا وكل شيء آخر هو مجرد تصميم سيء. كما أنني لا أرغب في امتلاك حاوية عامل الإرساء الخاصة بي من قبل مستخدم ولكن مملوكة للنظام وهذا يعني الجذر.
بودمان منطقي إذا كنت الشخص الوحيد الذي يستخدمه.

ولإصلاح مشكلتك: أنشئ حاوية بـ COPY --chown ...:... !

كما أن Docker ليس لديه مثل هذه المشاكل ويمكنك التحكم عن بعد في خوادم Docker وهو أمر مهم بالنسبة لي أيضًا.

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

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


@ SuperSandro2000 ، يمكنك النقر هنا للرد على بياناتك.

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

حسنًا ، لدى Podman تكامل أصلي مع systemd (مثل _ تقريبًا_ كل شيء آخر في جميع توزيعات GNU Linux الحديثة تقريبًا). لذلك لا يتعين عليك الاحتفاظ بنظامين للتمهيد (مثل امتلاك systemd أولاً لبدء برنامج Docker الخفي الذي يتعين عليه بعد ذلك إجراء جولة أخرى من بدء تشغيل الحاويات بتكوين مختلف). لذلك مع Podman ، يمكنك التحكم في كل شيء باستخدام systemd (بمعنى: النظام الذي من المحتمل أن تكون قد قمت بتثبيته وتشغيله على أي حال).

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

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

بودمان منطقي إذا كنت الشخص الوحيد الذي يستخدمه.

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

ولإصلاح مشكلتك: أنشئ حاوية بـ COPY --chown ...:... !

IMHO المشكلة هنا هي _mounting_ وحدة تخزين للحاوية في _runtime_. الأمر الذي لا علاقة له ببناء الصورة.

كما أن Docker ليس لديه مثل هذه المشاكل ويمكنك التحكم عن بعد في خوادم Docker وهو أمر مهم بالنسبة لي أيضًا.

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

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

هذا له عيوب وبالطبع لا يعمل عند مشاركة البرنامج الخفي مع عدة مستخدمين.
https://get.docker.com/rootless

في 27 حزيران (يونيو) 2019 ، الساعة 7:52 صباحًا ، كتب ألكسندر آدم [email protected] :

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

@ SuperSandro2000 https://github.com/SuperSandro2000 ، يمكنك النقر هنا للرد على بياناتك ، رغم ذلك.
https://podman.io/blogs/2018/09/13/systemd.html https://osric.com/chris/accidental-developer/2018/12/docker-versus-podman-and-iptables/ https: / /osric.com/chris/accidental-developer/2018/12/using-docker-to-get-root-access/
-
أنت تتلقى هذا لأنه تم ذكرك.
الرد على هذا البريد الإلكتروني مباشرة، مشاهدته على جيثب https://github.com/moby/moby/issues/2259؟email_source=notifications&email_token=AAGDCZXX2UQCG7LUVH57V6LP4TH2DA5CNFSM4AI3DP62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYXL2XI#issuecomment-506379613 ، أو كتم موضوع https://github.com/notifications/ إلغاء الاشتراك - المصادقة / AAGDCZX437HJP4M6XG3SEY3P4TH2DANCNFSM4AI3DP6Q .

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

IMHO المشكلة هنا هي تحميل وحدة تخزين للحاوية في وقت التشغيل. الأمر الذي لا علاقة له ببناء الصورة.

كان الحل هو عدم تحميل الدليل ولكن أخبزه في الحاوية إذا كان ذلك ممكنًا.

أعني أن podman يبدو جيدًا ولكنني لن أقوم بالتبديل لأنني لا أرى أي ميزة بالنسبة لي في الوقت الحالي. شكرا للتوضيح على أي حال.

يعاني podman من نفس المشكلة إذا تم تشغيل Apache داخل الحاوية تحت مستخدم www . https://github.com/containers/libpod/issues/3990

قد يكون الحل هو تعيين مستخدم www من الحاوية إلى UID على المضيف إذا لم يكن هناك مستخدم root داخل الحاوية. لا أعرف ما إذا كان ذلك ممكنًا.

إذا كنت تريد الركض باستخدام --read-only (للقيام بنفس سياسة readOnlyRootFilesystem Kubernetes) ، فمن الممكن القيام بما يلي. إنه يعتمد على الحل البديل الذي اقترحهjpetazzo :

  • تنشئ صورة عامل الإرساء الخاصة بي وتستخدم مستخدمًا برمز المستخدم = 1001 و gid = 1001
  • بشكل منفصل ، قم بإنشاء وحدة تخزين عامل إرساء
  • chown the uid: gid to 1001
  • قم بتركيب تلك الصورة عند تشغيل التطبيق.

ملف Docker:

FROM ubuntu

RUN groupadd -g 1001 appgroup && \
    useradd -u 1001 -g appgroup appuser

USER appuser

ثم:

$ docker build . -t test
$ docker volume create somedir
$ docker run -v somedir:/some_dir alpine chown -R 1001:1001 /some_dir

الآن ، عند تشغيل صورة عامل الإرساء وتثبيت وحدة التخزين ، ينتمي / some_dir إلى المستخدم الذي أريده.

$ docker run -it --read-only -v somedir:/some_dir test ls -lrt

...
dr-xr-xr-x  13 root    root        0 Nov  4 15:22 sys
drwxr-xr-x   2 appuser appgroup 4096 Nov  5 09:45 some_dir
drwxr-xr-x   1 root    root     4096 Nov  5 09:45 etc
...

$ docker run -it --read-only -v somedir:/some_dir test touch /some_dir/hello
$ docker run -it --read-only -v somedir:/some_dir test ls -lrt /some_dir

-rw-r--r-- 1 appuser appgroup 0 Nov  5 09:52 hello

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

https://github.com/moby/moby/issues/2259#issuecomment -466094263

+1

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

إنها ليست مشكلة إذا كنت تعرف الحل. حالاتي:

  • المضيف هو لينكس

    • uid في الحاوية == uid المطلوب على المضيف - لا حاجة إلى حل بديل
    • uid في الحاوية! = uid المطلوب على المضيف - فقط قم بتشغيل بضعة أوامر setfacl وامنح rw حق الوصول لكل من المستخدم المضيف ومستخدم الحاوية
  • المضيف هو MacOS - كل شيء يعمل خارج الصندوق لتطبيق Docker الرسمي.

فقط قم بتشغيل أمرين من setfacl وامنح rw حق الوصول لكل من المستخدم المضيف ومستخدم الحاوية

هذه مشكله. لا أريد تشغيل أمرين من setfacl لكل صورة عامل إرساء واكتشاف نظام التشغيل.

هذه في الواقع مشكلة أمنية كبيرة أيضًا.

سيناريو مثال:

  • تم تثبيت عامل الإرساء على host1
  • يحتوي host1 على خدمة متعددة تعمل في حاويات Docker - وكلها عبارة عن مسارات محلية مثبتة تحت /docker/my-service-01|02|03|etc
  • تم إنشاء كل حاوية بواسطة بائع مختلف وكل واحدة تتبع سياسة uid و guid الخاصة بها ، مما يتطلب منك chown -R uid.gid /docker/my-service-01... وفقًا لذلك.

نتيجة:

  • في مرحلة ما ، سيكون لدى المستخدمين العاديين أو المستخدمين الذين تم إنشاؤهم على host وصول كامل إلى /docker/my-service-01|02|03|etc وهو أمر غير مقصود ولا مرغوب فيه.
  • إذا كنت ترغب في تحميل وحدة تخزين كـ "للقراءة فقط" على حاويتين من بائعين مختلفين - فستفشل نظرًا لأن uid.gid لن يتطابق مع العناصر المطلوبة ولن تكون قادرًا على chown لأن كل حاوية لها سياسة uid.gid وهي مختلفة :)

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

لذا فإن الطريقة الأكثر إنتاجية لمواصلة هذا النقاش (اليوم) هي: معرفة ما إذا كان أي من هذه المواقف قد تغير منذ ذلك الحين. ابحث عن تعليق تقني من مطوري linux kernel mainline على vger.org. ابحث عن مجموعات التصحيح / طلبات الدمج السابقة على kernel لهذه الميزة الأساسية المفقودة. إلخ.

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

DXist حقيقة أن هذا يعمل بطريقة سحرية على OSX وليس على Linux أمر مفاجئ ومشكلة في حد ذاته.

وفقًا لتعليق @ dreamcat4 ، هل قام أي شخص بمحاولة جديدة لمعرفة ما هي حالة هذا؟ هل لدينا دعم في Kernel للأجهزة Uids و gids القابلة لإعادة التخطيط الآن؟ ما هو الوضع العام هنا؟

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

الدليل موجود هنا: https://www.jujens.eu/posts/en/2017/Jul/02/docker-userns-remap/

@ باتروبينسون +1

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