Moby: Tambahkan kemampuan untuk memasang volume sebagai pengguna selain root

Dibuat pada 17 Okt 2013  ·  157Komentar  ·  Sumber: moby/moby

Kasus penggunaan: pasang volume dari Host ke wadah untuk digunakan oleh Apache sebagai pengguna www.
Masalahnya saat ini semua tunggangan dipasang sebagai root di dalam wadah.
Misalnya, perintah ini
docker run -v /tmp:/var/www ubuntu stat -c "%U %G" /var/www
akan mencetak "root root"

Saya perlu memasangnya sebagai pengguna www di dalam wadah.

areapi arekernel arevolumes exexpert kinenhancement

Komentar yang paling membantu

Bisakah saya mengatakan tidak - memaksa pengguna untuk menambahkan skrip pembantu yang melakukannya

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

(terima kasih @bfirsh untuk contoh Anda)

cukup mengerikan.

Artinya container harus dimulai sebagai root, bukan dijalankan sebagai pengguna redis yang dimaksud. (seperti yang disinggung oleh @aldanor )

dan itu berarti pengguna tidak dapat melakukan sesuatu seperti:

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

Semua 157 komentar

Jika Anda chown volume (di sisi Host) sebelum mengikatnya, itu akan berfungsi.
Dalam hal ini, Anda dapat melakukan:

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

(Dengan asumsi bahwa 101:101 adalah UID:GID dari pengguna www-data di penampung Anda.)

Kemungkinan lain adalah melakukan bind-mount, lalu chown di dalam wadah.

@mingfang Akankah chown tidak bekerja untuk Anda?

Akan berguna untuk memiliki jalan pintas untuk ini. Saya sering mendapati diri saya menulis skrip run yang baru saja mengatur izin pada volume:

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

Bagaimana jika Anda tidak memiliki hak untuk chown itu?

Akankah skrip pembantu yang chown volume menyelesaikan masalah ini? Skrip ini bisa menjadi ENTRYPOINT dari Dockerfile Anda.

Bisakah saya mengatakan tidak - memaksa pengguna untuk menambahkan skrip pembantu yang melakukannya

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

(terima kasih @bfirsh untuk contoh Anda)

cukup mengerikan.

Artinya container harus dimulai sebagai root, bukan dijalankan sebagai pengguna redis yang dimaksud. (seperti yang disinggung oleh @aldanor )

dan itu berarti pengguna tidak dapat melakukan sesuatu seperti:

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

Ada _one_ cara untuk membuatnya bekerja, tetapi Anda harus mempersiapkan terlebih dahulu di dalam Dockrfile Anda.

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

(Saya tidak menguji contoh ini, saya sedang mengerjakan wadah chromium yang kemudian ditampilkan pada wadah _separate_ X11 yang ....)

Dan tentu saja metode itu hanya berfungsi untuk volume baru langsung, tidak mengikat
dipasang atau volume-dari volume. ;)

Selain itu, beberapa wadah yang menggunakan volumes-from akan memiliki uid/gid yang berbeda untuk pengguna yang sama, yang juga memperumit masalah.

@SvenDowideit @tianon metode itu juga tidak berfungsi. Contoh lengkap:

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

Dua run, dengan dan tanpa volume -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$ 

Kami sedang menghadapi masalah yang akan diselesaikan dengan ini (saya pikir). Kami memiliki bagian NFS untuk direktori home pengembang kami. Pengembang ingin memasang /home/dev/git/project ke Docker tetapi tidak bisa karena kami mengaktifkan Root Squash.

Ini melarang root mengakses /home/dev/git/project jadi ketika saya mencoba dan menjalankan docker mount /home/dev/git/project saya mendapatkan kesalahan lstat permission denied .

@frankamp Ini karena preferensi buruh pelabuhan saat ini adalah untuk tidak mengubah hal-hal Host yang tidak berada dalam kendali Docker sendiri.

Definisi "VOLUME" Anda sedang ditimpa oleh -v pwd`:/var/lib/reds` Anda.
Tetapi dalam menjalankan ke-2 Anda, ia menggunakan volume yang dikendalikan buruh pelabuhan, yang dibuat di /var/lib/docker. Ketika wadah dimulai, buruh pelabuhan menyalin data dari gambar ke dalam volume, lalu mengunyah volume dengan uid:gid dari direktori yang volumenya ditentukan.

Saya tidak yakin ada banyak yang bisa dilakukan di sini, dan sayangnya bind mount tidak mendukung (sejauh yang saya tahu) pemasangan sebagai uid/gid yang berbeda.

Solusi saya untuk ini adalah melakukan apa yang dilakukan SvenDowideit di atas (buat pengguna baru dan chown di depan di dockerfile), tetapi kemudian alih-alih memasang volume Host, gunakan wadah khusus data, dan salin volume Host yang ingin saya pasang ke wadah dengan tar cf - . | docker run -i --volumes-from app_data app tar xvf - -C /data . Ini akan menjadi sedikit lebih mudah setelah https://github.com/docker/docker/pull/13171 digabungkan (dan docker cp berfungsi dua arah), tetapi mungkin ini bisa menjadi alternatif untuk -v host_dir:container_dir , mis. mungkin -vc host_dir:container_dir , (vc untuk volume-copy), di mana konten Host_dir akan disalin ke dalam wadah data. Meskipun saya tidak bisa mengatakan saya mengerti mengapa/bagaimana file yang disalin mewarisi izin pengguna wadah, dari apa yang saya tahu mereka lakukan, dan ini adalah satu-satunya solusi masuk akal yang berhasil saya buat yang tidak merusak portabilitas.

Bagaimana dengan ac?

Apakah ada perbaikan atau solusi? Saya mengalami masalah yang sama dengan OpenShift, folder yang dipasang dimiliki oleh root: root dan gambar yang dibuat sebelumnya tidak akan berfungsi.

Saya juga sedang mencari solusi. Jika semua volume yang dipasang dimiliki oleh root , tidak mungkin menjalankan container Docker Anda dengan pengguna selain root .

Nah Anda dapat mencoba s6-overlay . Ini mencakup fitur yang secara khusus ditargetkan untuk membantu mengatasi masalah semacam ini.

@dreamcat4 : Terima kasih atas penunjuknya. Memperbaiki kepemilikan & izin sepertinya merupakan solusi yang menarik, tetapi bukankah saya harus menjalankan wadah Docker saya sebagai root agar itu berfungsi?

@brikis98 Ya itu benar. Namun s6-overlay juga memiliki fitur lain, yang memungkinkan Anda untuk mengembalikan izin saat meluncurkan server / daemon Anda.

@dreamcat4 Ah, mengerti, terima kasih.

Saya memiliki uid/gid yang sama di dalam dan di luar wadah dan inilah yang saya dapatkan:

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 bisakah Anda membuka masalah terpisah?

tidak masalah, tetapi apakah ini tidak relevan di sini?

@darkermatter ini adalah permintaan fitur, bukan laporan bug, mencampur kasus Anda dengan kasus lain membuat sulit untuk mengikuti diskusi, juga masalah Anda mungkin tidak terkait langsung

@thaJeztah yah, seperti yang dilakukan @frankamp dan yang lainnya, saya hanya mendemonstrasikan apa yang terjadi setelah menjalankan chmod, dll. di dalam Dockerfile. Saya akan mengajukannya sebagai laporan bug, tetapi relevan dengan diskusi ini.

mirip dengan apa yang diusulkan @ebuchman , tanpa menyalin volume Host, Anda dapat membuat wadah khusus data terlebih dahulu, yang melakukan
chown 1000:1000 /volume-mount sebagai root saat dimulai.
Misalnya di docker compose sintaks 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"

Dengan cara ini wadah Anda dapat berjalan sebagai pengguna non-root. Wadah khusus data hanya berjalan satu kali.
Dengan asumsi Anda mengetahui uid dan gid yang digunakan my-beautiful-service sebelumnya. Biasanya 1000.1000.

Karena Anda dapat (dalam 1.11) menentukan opsi pemasangan untuk volume yang akan digunakan di docker volume create Anda, saya akan mengatakan ini tampaknya cukup dekat dengan siap untuk ditutup.

Anda tidak bisa hanya menentukan uid/gid secara langsung karena ini tidak didukung dengan pengikatan mount, tetapi banyak sistem file yang dapat Anda gunakan dengan mount opts baru dapat bekerja dengan uid/gid opts.

Saya pikir masalahnya masih berlanjut jika Anda ingin memasang drive CIFS di dalam wadah Anda, tetapi mungkin itu harus menjadi tiket lain?

@ michaeljs1990 Anda dapat melakukan ini, hanya saja tidak per wadah (kecuali jika Anda membuat volume terpisah untuk setiap kombo uid/gid yang Anda inginkan).

@cpuguy83 , dapatkah Anda menjelaskan bagaimana seseorang harus menggunakan docker volume create untuk menghindari masalah ini?

Saya baru saja mengalami masalah ini hari ini dengan buruh pelabuhan 1.11 dan harus melakukan rejiggering yang menyakitkan untuk meyakinkan gambar buruh pelabuhan agar mengizinkan saya menulis ke file pada drive yang terpasang. Akan sangat menyenangkan jika saya tidak perlu melakukan itu lagi apalagi mencoba menjelaskannya kepada orang lain.

Tidak yakin apakah ini yang Anda tanyakan, tetapi ...

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

Bangun gambar di atas bernama "test"

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

Baik /hello dan /hello/world dalam contoh di atas akan dimiliki oleh 1000:1000

Jadi begitu. Jadi, saya melakukan sesuatu yang serupa tetapi sedikit berbeda, yang mungkin membuatnya layak untuk dibagikan. Pada dasarnya, saya menambahkan pengguna ke Dockerfile yang membagikan UID, GID, nama pengguna, dan grup saya untuk pengguna di luar wadah. Semua <...> adalah hal-hal yang diganti dengan nilai yang relevan.

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

Setelah ini, seseorang dapat beralih menggunakan USER atau menggunakan su di lain waktu (misalnya skrip entrypoint atau saat menggunakan shell). Ini memungkinkan saya menulis ke volume yang dipasang karena saya adalah pengguna yang sama yang membuat. Seseorang juga dapat menggunakan chown di dalam wadah untuk memastikan seseorang memiliki izin pada hal-hal yang relevan. Juga, menginstal sudo umumnya merupakan langkah cerdas saat melakukan ini juga.

Sementara itu memecahkan masalah, saya tidak tahu bahwa saya menyukainya karena ini perlu dilakukan untuk setiap pengguna. Juga, saya mengkodekan hal-hal yang sulit (yuck!), Tapi mungkin template dapat digunakan untuk membuat ini sedikit lebih lancar. Saya ingin tahu apakah shim ini dapat diserap ke dalam docker run entah bagaimana. Jika sudah ada cara yang lebih baik untuk melakukan ini, saya akan sangat tertarik untuk mengetahui apa itu.

Ada opsi untuk memetakan uids/gids pengguna host dengan pengguna kontainer uids/gids dengan --userns-remap . Secara pribadi saya belum mencobanya. Lihat diskusi yang bagus tentang topik ini http://stackoverflow.com/questions/35291520/docker-and-userns-remap-how-to-manage-volume-permissions-to-share-data-betwee .

@cpuguy83 :

Anda tidak bisa hanya menentukan uid/gid secara langsung karena ini tidak didukung dengan pengikatan mount, tetapi banyak sistem file yang dapat Anda gunakan dengan mount opts baru dapat bekerja dengan uid/gid opts.

Sistem file apa yang Anda pikirkan yang dapat menerima argumen uid/gid? Saya tahu FAT bisa, tapi itu terasa sama kacaunya dengan hal lain yang diusulkan di utas ini.

IMO, Docker memiliki dua opsi:

  1. Dukungan resmi untuk memasang volume sebagai pengguna/grup tertentu (menggunakan nama pengguna/grup yang ditentukan di dalam wadah, tidak mengharuskan tuan rumah memiliki pengetahuan ini tentang internal wadah).
  2. Atau... singkirkan direktif USER (dan flag runtime terkait).

Mampu berjalan sebagai pengguna non-root sementara hanya dapat me-mount volume yang dimiliki oleh root adalah sebuah kesalahan. Berbagi uid/gid antara Host dan container adalah kesalahan lainnya.

@mehaase volumes mengambil kepemilikan apa pun yang sudah ada di jalur dalam wadah. Jika lokasi dalam wadah dimiliki oleh root, maka volume akan mendapatkan root. Jika lokasi di wadah dimiliki oleh sesuatu yang lain, volumenya akan mendapatkan itu.

Semacam solusi untuk ini akan sangat bagus. Kecuali jika wadah secara khusus mengharapkannya, itu membuat _sangat_ sulit untuk menambahkan volume ke wadah standar seperti elasticsearch, redis, couchDB, dan banyak lainnya tanpa menulis Dockerfile khusus yang menetapkan izin. Ini sebagian besar membuat perintah docker run -v atau volume: direktif di docker-compose tidak berguna.

@chrisfosterelli mengapa tidak berguna? Saya tidak berpikir itu luar biasa untuk mengatur kepemilikan file/dir yang Anda harapkan untuk digunakan.

@ cpuguy83 Karena tampaknya tidak mungkin untuk mengatur kepemilikan tanpa menggunakan Dockerfile khusus yang mengatur izin dan volume, itulah sebabnya mereka tidak berguna untuk mendefinisikan volume. Saya tidak mengikat wadah ke sistem file Host saya, jika itu relevan.

@chrisfosterelli Tapi semua Dockerfiles standar ini harus memiliki izin yang sudah ditetapkan.

Saya pikir apa yang @chrisfosterelli coba katakan, @cpuguy83 , (dan tolong koreksi saya jika saya salah @chrisfosterelli) adalah bahwa variabel-variabel ini (UID, GID, dll.) menjadi dinamis dan perlu disetel di run-time (wrt khusus ke file yang dimiliki secara internal dan dari volume yang dipasang), tetapi kami tidak memiliki cara untuk melakukannya saat ini. Responsnya sejauh ini tampaknya tidak harus ditentukan run-time, tetapi itu mengabaikan masalah kegunaan mendasar yang disajikan oleh saran semacam itu. Sekali lagi jika saya salah memahami semua ini, jangan ragu untuk mengoreksi saya.

@jakirkham Saya pasti tidak mengerti apa masalah kegunaannya.
File ada dalam gambar, mereka harus memiliki kepemilikan dan izin yang diperlukan untuk menjalankan aplikasi. Ini tidak ada hubungannya dengan volume itu sendiri. Volume hanya mengambil apa yang diatur dalam gambar.

@cpuguy83 Saya melakukan sedikit lebih menggali dan mengisolasi ini: Katakanlah saya memiliki wadah elasticsearch yang akan membuat direktori /data saat memulai (jika tidak ada data), lalu gunakan docker run -v /data elasticsearch . Direktori /data menjadi milik root:root dan daemon yang berjalan sebagai elasticsearch di dalam wadah sekarang akan gagal untuk memulai karena tidak dapat menulis ke /data .

Akan ideal jika saya dapat mengatur volume ini untuk dimiliki oleh elasticsearch tanpa memerlukan Dockerfile khusus ... meskipun saya kira Anda dapat berargumen bahwa masalah semacam ini harus diselesaikan di gambar hulu.

@chrisfosterelli ada beberapa pembicaraan di milis kernel memiliki overlay seperti driver yang dapat mengubah kepemilikan tetapi tidak banyak yang dapat kita lakukan tanpa sesuatu seperti itu. Saya ingin tahu, bisakah Anda membuat semua file di dunia volume Anda membaca dan menulis dan mengatur umask dengan tepat sehingga file baru juga? (Saya belum mencoba).

@justincormack Saya percaya begitu, tapi saya pikir itu tidak berfungsi ketika saya mengharapkan wadah untuk membuat data dalam volume (bukan Host). Saya mengerti ini adalah masalah yang aneh, jadi saya saat ini mengatasinya dengan memperbaikinya di Dockerfile hulu itu sendiri ke direktori mkdir -p && chmod .

@chrisfosterelli itulah mengapa saya mengatakan setel umask, jika umask Anda adalah 000 (dalam wadah) semua file baru akan dibuat dengan izin 666 atau 777 , dan jika mount point adalah 777 untuk memulai itu seharusnya baik-baik saja? Jika izin selalu dunia baca dan tulis, uid dan gid seharusnya tidak masalah?

@justincormack Ya kedengarannya benar ... bagaimana saya bisa melakukannya saat membuat wadah buruh pelabuhan dengan volume yang tidak dipasang di Host?

@chrisfosterelli hmm, itu pertanyaan yang bagus. Bagi saya sepertinya izin pada volume baru adalah apa yang akan diberikan umask default, jadi Anda dapat mencoba menjalankan daemon buruh pelabuhan dengan 000 umask dan melihat apakah volumenya dapat ditulisi dunia. Mungkin kita harus memiliki beberapa opsi izin pada docker volume create .

(Anda bisa memperbaikinya dengan wadah root yang melakukan chmod dan keluar juga tapi itu jelek)

Pada membuat tidak baik. Masalahnya adalah jika wadah tidak memiliki jalur, jalur akan dibuat dengan root. Ini bisa dibilang bisa dilakukan sebagai apa pun yang diteruskan pengguna.

@ cpuguy83 Saya pikir akan lebih masuk akal untuk membuatnya saat pengguna meneruskan dengan -u karena itu mungkin pengguna yang mencoba menulis volume dari dalam wadah kan?

Saya dapat memasang sebagai pengguna pilihan saya menggunakan langkah-langkah di bawah ini:

  • Buat pengguna di dalam Docker dengan UID/GID yang sama dengan pengguna yang memiliki file di Host.
  • Buat titik pemasangan terlebih dahulu dan berikan kepada pengguna target di wadah

Quote @chrisfosterelli :

Saya melakukan sedikit lebih menggali dan mengisolasi ini: Katakanlah saya memiliki wadah elasticsearch yang akan membuat direktori /data saat memulai (jika tidak ada data), lalu gunakan docker run -v /data elasticsearch. Direktori /data menjadi milik root:root dan daemon yang berjalan sebagai elasticsearch di dalam wadah sekarang akan gagal untuk memulai karena tidak dapat menulis ke /data.

Ini adalah contoh yang bagus! Saya memiliki contoh serupa dengan gambar Solr. Solr membutuhkan satu atau lebih "inti", yang masing-masing merupakan kumpulan file konfigurasi terkait dan fragmen indeks. Setiap inti ditempatkan di dalam direktori dengan nama yang ditentukan pengguna. Misalnya jika saya ingin membuat inti bernama products , jalurnya adalah /opt/solr/server/solr/products . Nama inti dipilih oleh saya, sehingga pengelola gambar Solr tidak dapat membuat direktori ini sebelumnya di dalam gambar.

Saya ingin data indeks saya disimpan sehingga saya dapat memutakhirkan gambar saya ke Solr yang lebih baru tanpa perlu mengindeks ulang semua dokumen saya, tetapi jika saya memasang volume ke /opt/solr/server/solr/products , maka itu dimiliki oleh root dan Solr (berjalan sebagai solr ) sebenarnya tidak dapat menulis apa pun padanya. Direktori induk /opt/solr/server/solr berisi file lain, jadi saya juga tidak dapat memasang volume di sana. (Dalam bahasa Docker terbaru, saya yakin volume saya disebut "volume bernama", yaitu volume yang tidak dipasang ke jalur yang ditentukan pada Host tetapi sepenuhnya dikelola oleh Docker untuk saya.)

Saya telah membicarakan hal ini dengan pengelola gambar Solr dan ada beberapa solusi (dan dia telah membuat beberapa perubahan pada gambar untuk membantu) tetapi semuanya cukup rumit dan memerlukan perubahan kasus per kasus pada gambar hulu. Memiliki fitur yang dibahas di utas ini akan membuat _semua gambar_ lebih dapat diperluas tanpa perlu membuat Dockerfile baru.

@ctindel mungkin... jika direktori belum ada.

@ cpuguy83 Itu benar, saya setuju. Itu pasti kasus penggunaan saya. Tampaknya tidak masuk akal untuk membuat direktori sebagai root jika tidak ada ketika id pengguna telah ditentukan secara eksplisit untuk menjalankan wadah.

@ cpuguy83 itu hanya berfungsi untuk volume bernama.

@kamechen Apa yang berhasil?

@ cpuguy83 Saat Anda menggunakan volume bernama, file dipasang di bawah pengguna yang Anda butuhkan

@eciuca Yah.... itu tergantung. Jika volume bernama kosong, atau data dalam volume bernama dibuat oleh pengguna yang sama yang Anda butuhkan.

Apakah pernah ada solusi untuk masalah yang diangkat oleh @andrewmichaelsmith?

Kami sedang menghadapi masalah yang akan diselesaikan dengan ini (saya pikir). Kami memiliki bagian NFS untuk direktori home pengembang kami. Pengembang ingin memasang /home/dev/git/project ke Docker tetapi tidak bisa karena kami mengaktifkan Root Squash.

Ini melarang root mengakses /home/dev/git/project jadi ketika saya mencoba dan menjalankan pemasangan buruh pelabuhan /home/dev/git/project saya mendapatkan izin lstat ditolak kesalahan.

Saya pikir mungkin untuk mengatasi ini menggunakan bindfs .
Menggunakan -v ... docker untuk memasang volume di lokasi sementara dan kemudian bindfs untuk memasangnya di tempat yang diperlukan sebagai pengguna lain.

@piccaso , cara saya memahami @andrewmichaelsmith adalah bahwa masalahnya adalah pengikatan-mount di sisi Host gagal karena rootquash. Tapi bindfs sebenarnya masih bisa digunakan sebagai solusi, tapi kali ini di sisi host. Pertama, di Host, Anda mengikat-mount nfs yang dibagikan ke lokasi sementara sebagai pengguna non-root menggunakan FUSE, dan kemudian Anda memasang folder sementara itu di buruh pelabuhan dengan -v ... .

Perhatikan bahwa bindfs (setidaknya dengan FUSE) memiliki sedikit overhead CPU.

Ya, bindfs sangat tidak diinginkan. Ini lebih lambat daripada sistem file CoW.
Ada beberapa pekerjaan yang sedang dilakukan di kernel untuk memungkinkan perpindahan uid/gid pada mount yang dapat membantu.

Ada beberapa pekerjaan yang sedang dilakukan di kernel untuk memungkinkan perpindahan uid/gid pada mount yang dapat membantu.

Ini mungkin juga hanya akan membantu mengatasi kasus penggunaan di mana saya ingin memetakan ulang uid/gid di dalam wadah. Mount itu sendiri seperti yang dieksekusi oleh daemon buruh pelabuhan masih akan dieksekusi sebagai root pada Host. Pemahaman saya adalah bahwa dengan Kernel bind mount hanya dapat dibuat sebagai root. Tidak yakin apakah ada pekerjaan untuk mengubahnya agar mount dapat dilakukan oleh pengguna non-root (saya hanya tahu sedikit tentang cara Linux menangani mount untuk menilai apakah itu masuk akal).

@NikolausDemmel Saya ragu itu akan berubah. Syscall mount membutuhkan CAP_SYS_ADMIN, yang bukan sesuatu yang diberikan kepada pengguna non-root, atau bahkan sesuatu yang kami berikan kepada pengguna root dari sebuah wadah.

@ cpuguy83 Terima kasih atas klarifikasinya. Itu berarti memasang volumen buruh pelabuhan ke folder Host yang merupakan NFS mount dengan root-squash tidak akan berfungsi di masa mendatang (karena keterbatasan mount syscall seperti yang Anda katakan), simpan untuk menggunakan solusi seperti FUSE dengan bindfs .

Maaf, ini sedikit OT, karena OP bertanya tentang mengubah UID/GID di dalam wadah. Tapi itu adalah sisi lain dari koin dan telah muncul dalam diskusi di atas. Hanya ingin memperjelas perbedaan itu.

Saya menjalankan Docker untuk Mac, dan telah memasang volume tetapi sepertinya saya tidak dapat mengatur izin untuk layanan web untuk mengakses file. Bagaimana cara memperbaikinya? Saya mencoba mengubah perm dan mengatur grup menjadi staf, tetapi tampaknya Alpine tidak memiliki grup staf.

Maaf jika ini bukan tempat terbaik untuk meletakkannya, saya telah berjuang selama berhari-hari dan tidak bisa memikirkan tempat yang lebih baik.

@NikolausDemmel : Kami mencoba menggunakan Docker untuk beberapa pekerjaan bioinformatika. Kami memiliki beberapa sistem file besar yang dipasang root-squashed melalui NFS. Kami membaca dalam urutan data yang sangat besar (fastq), dan menulis file BAM yang agak lebih kecil dengan pembacaan genom yang selaras dengan datastore. Saat ini, kami dapat menggunakan buruh pelabuhan dengan melakukan gambar khusus untuk membuat pengguna di dalam wadah dan menggunakan USER di akhir untuk membuatnya berfungsi, tetapi ini bermasalah karena beberapa alasan:

  1. Jika kita ingin menggunakan image Docker orang lain, kita harus membangun kembali dengan Dockerfile kustom
  2. Kami juga perlu membuat gambar buruh pelabuhan khusus untuk setiap pengguna lokal, atau kami menggunakan satu akun "layanan" dan kami tidak akan dapat membedakan antara aktivitas pengguna di FS.

Bisakah Bindfs atau userNS membiarkan kami menyiasatinya?

Saya pikir saya mengalami masalah yang sama, kasus penggunaan saya adalah:
Gambar Docker menyimpan alat build portabel kami untuk proyek tertentu, kami menggunakan pemasangan volume dengan jalur relatif baik dengan sesuatu seperti docker run -v ./:/src/ image atau yang setara dalam file komposisi buruh pelabuhan. Sebuah build secara otomatis dimulai, dan file baru dibuat dalam subfolder di volume yang ditautkan.
Terkadang kami suka menggunakan file yang dibuat dari host, tetapi fakta bahwa file tersebut masih dimiliki oleh pengguna di docker, daripada pengguna host yang menjalankan docker cenderung membuat segalanya menjadi rumit.

Apakah saya melakukan sesuatu yang salah di sini?

@rlabrecque lihat posting saya sebelumnya tentang mencocokkan id pengguna buruh pelabuhan dengan host. Saya menggunakan pendekatan ini dan itu bekerja dengan sangat baik untuk kami. Pada dasarnya, jalankan HOST_UID=$(id -u) dan HOST_GID=$(id -g) dan hasilkan Dockerfile yang memperluas $HOST_GID dan $HOST_UID dalam dua perintah di bawah ini:

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

Gunakan Dockerfile yang dihasilkan dengan ID yang diisi, untuk membangun gambar Anda.

@haridsv Saya telah melakukan sesuatu yang serupa dan berfungsi dengan baik di Linux. Tapi itu sepertinya tidak berhasil untuk saya di Windows: file di dalam mount masih dimiliki oleh root.

Saya memecahkan ini dengan menggunakan inotifywait . Anda perlu menginstal inotify-tools untuk menjalankannya di dalam gambar buruh pelabuhan Anda. Dimungkinkan untuk menjalankannya di sistem Host Anda, tetapi saya menginginkan solusi portabel.

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

Ini bekerja dengan menginstruksikan inotifywait untuk melihat file atau direktori baru yang dibuat di direktori /mount. Ketika ia menyadarinya, ia mengubah kepemilikan menjadi pengguna dan grup yang sama dengan folder /mount. Saya menggunakan representasi integer keduanya, jika pengguna/grup Host tidak ada di wadah. Di dalam wadah tidak masalah siapa pemiliknya, karena semuanya berjalan sebagai root. Di luar wadah, sistem file host menunjukkan kepemilikan yang sama dengan direktori apa pun yang dipasang di /mount.

Saya sengaja mendesainnya untuk hanya mengatur kepemilikan file dan direktori yang baru dibuat, untuk mempertahankan kepemilikan file dan direktori yang sudah ada sebelumnya. Ini lebih aman daripada membuang semua itu dengan pernyataan chown -R setiap kali sistem file dipasang. Jika izin seragam berfungsi untuk proyek Anda dan Anda menginginkan solusi sederhana yang berjalan lebih efisien, lihat inotify-hookable .

Peringatan: Karena satu jam tangan inotify akan dibuat per subdirektori, mungkin jumlah maksimum jam tangan inotify per pengguna akan tercapai. Maksimum default adalah 8192; itu dapat ditingkatkan dengan menulis ke /proc/sys/fs/inotify/max_user_watches.

Kami telah menggunakan skrip sisi host untuk chown volume yang dipasang yang menghindari kebutuhan untuk membangun kembali gambar:

#!/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

bagaimana dengan menggunakan sistem file ACL di direktori Host? Dengan begitu Anda dapat memberi tahu sistem file untuk menerapkan izin khusus ke file yang baru dibuat di dalam direktori. Jika Anda mengatur ACL di tingkat host, jika Anda mengubah data dari wadah, itu juga akan terjadi.

@thaJeztah @justincormack @cpuguy83

@kamechen tampaknya benar bahwa volume bernama "hanya berfungsi". Dalam kasus volume bernama, izin yang ada "menjadi bumerang" dan mengubah izin volume, dan saya, secara pribadi, menganggap ini sebagai bug (#28041).

@thegecko , mengapa tidak mengambil pendekatan ini lebih jauh dan tidak membuat pengguna di dalam titik masuk?

Ini adalah contoh saya, ia mendeteksi pemilik direktori yang dipasang, membuat pengguna dengan UID yang sama dan menjalankan perintah seperti di bawah pengguna ini:

file docker

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

titik masuk.sh

#!/bin/sh

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

lari.sh

#!/bin/sh

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

Ketika saya menjalankan sudo docker build -t test . && sudo docker run --rm -v /tmp/docker-test/:/project test:latest hasilnya:

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"

Apakah ada yang mempertimbangkan masalah ini? Memastikan volume Anda memiliki gid dan uid yang sama dengan container Anda akan mempersulit pengelolaan container Anda agar tidak menggunakan root. Praktik terbaik Docker merekomendasikan untuk tidak menjalankan layanan dengan root jika memungkinkan, tetapi tidak harus menyiapkan gid dan uid di Host serta wadah yang mengalahkan kemudahan penggunaan yang membuat Docker populer?

@AndreasBackx Menggunakan volume hanya berfungsi dengan asumsi gambar memiliki data di jalur pemasangan Anda.
Menggunakan bind menggunakan UID/GID jalur host.

Saat ini tidak ada cara (seperti tidak ada dukungan kernel) untuk memetakan atau mengubah UID/GID dari file/dir ke sesuatu yang lain tanpa mengubah yang asli kecuali menggunakan sesuatu seperti FUSE, yang sangat lambat.

Tapi mari kita mundur sejenak.
Docker tidak benar-benar membuat segalanya lebih sulit di sini.
UID/GID dalam wadah sama dengan UID/GID di host.. bahkan jika nama pengguna/grup tidak cocok, UID/GID yang penting di sini.
Sama seperti tanpa buruh pelabuhan, Anda harus membuat uid/gid yang ingin Anda gunakan untuk layanan Anda dan menggunakannya di luar konvensi.
Ingat, uid/gid tidak perlu ada di /etc/passwd atau /etc/group agar kepemilikan file disetel.

@cpuguy83 terima kasih atas penjelasannya.

Saya mengalami masalah ini hari ini saat membuat pipa node , UID pengguna Host saya adalah 1000 dan gambar node membuat pengguna khusus dengan UID spesifik itu , bahkan ada masalah tentang itu

Saya akan menggunakan pengguna simpul dan melanjutkan tetapi rasanya sedikit kotor. saya benar-benar membagikan apa yang Anda tulis @ cpuguy83 tentang "mari kita mundur sejenak", tetapi kadang-kadang itu bisa menjadi masalah yang sulit untuk diselesaikan.

Baru saja mengetahui opsi -o pada usermod untuk mengizinkan duplikat IDS, tampaknya merupakan opsi yang sah.

RUN usermod -o -u 1000 <user>

Tidak yakin mengapa ini belum diperbaiki dengan cara apa pun yang masuk akal.

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

masuk untuk melihat:

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

Dokefile secara khusus melakukannya

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

Tidak masuk akal bahwa volume ini dipasang sebagai root, ketika pengguna dalam wadah tidak dipilih, atau pengguna yang menjalankan perintah tidak dipilih. Saya bisa mengerti jika perintah RUN dipasang sebagai pengguna yang menjalankan perintah, atau pengguna yang memiliki direktori, atau bahkan pengguna yang ditentukan dalam Dockerfile.

Tak satu pun dari ini adalah root, jadi pemasangan sebagai root tampaknya merupakan bug.

Juga baru saja dicentang, membuat volume, lalu memasangnya berfungsi. Jadi masih bug.

@disarticulate Jika Anda ingin jalur Host menjadi sesuatu selain root, maka Anda harus mengubah jalur Host.

Saya tidak berpikir ini telah disebutkan sebelumnya, tetapi bug ini sangat mengganggu ketika Anda mengandalkan Docker untuk membuat volume host untuk Anda. Docker tampaknya selalu membuat volume Host dengan root, bahkan ketika direktori yang Anda pasang memiliki pemilik yang berbeda.

Tampaknya hal yang benar untuk dilakukan di sini adalah membuat volume dengan izin kepemilikan milik USER gambar.

@jalaziz apa yang harus dilakukan ketika pengguna wadah tidak ada di Host? Salah satu manfaat utama container adalah Anda tidak perlu mengekspos dependensinya (termasuk pengguna) ke host.

@taybin Saya berharap Docker hanya membuat folder dengan uid:gid dari pengguna wadah ATAU jika folder ada di dalam wadah, itu akan membuat folder Host dengan uid:gid dan mask yang sama.

CATATAN: Saya tidak berharap Docker mengubah izin jika folder sudah ada di Host.

@taybin Persis seperti yang dijelaskan @frol . Seharusnya hanya menggunakan uid:gid dari wadah.

Namun, ini mengungkapkan masalah umum saya dengan pendekatan saat ini. Saya harus tahu uid yang digunakan wadah untuk mengizinkan penulisan dan mengatur izin pada direktori Host berdasarkan uid:gid itu. Jika penulis upstream pernah mengubah uid, izin akan rusak. Semuanya terlihat sangat rapuh.

Dalam kasus saya, saya tidak perlu memiliki kontrol eksplisit atas gambar buruh pelabuhan mana yang sedang digunakan (saya tidak bisa hanya mengedit file Docker sesuai keinginan saya).

Jadi, saya mencoba ini:

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

Yang membuat folder bernama ./built-app . Namun, pemiliknya masih root dengan izin yang ketat.

Solusi saya adalah ini:

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

Yang masih memiliki pemilik root , tetapi izinnya longgar. Kemudian OS Host saya (Ubuntu) dapat mengakses ./built-app tanpa hak sudo.

@rms1000watt sudahkah Anda mencoba perintah berikut?

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

Itu akan berhasil karena akan menggunakan UID dan GID Host Anda langsung ke file itu sendiri. Menggunakan chmod -R 777 umumnya merupakan praktik yang buruk.

@saada Ups! Panggilan yang bagus. Aku akan mencobanya.

Saya dapat menyelesaikan pendekatan saya dengan membaca ini dan memahami bagaimana _UID dan GID bekerja di wadah Docker_
https://medium.com/@mccode/understanding -how-uid-and-gid-work-in-docker-containers-c37a01d01cf

Pada dasarnya ada satu kernel dan satu kumpulan uid dan gid bersama yang berarti bahwa root mesin lokal Anda sama dengan root wadah Anda, keduanya berbagi UID yang sama


Saya memiliki server Apache dan saya ingin membagikan file webapp saya dengan wadah Apache untuk memodifikasinya di Host (pengembangan, mengubahnya menggunakan editor teks) dan melihat hasilnya dengan proses yang berjalan di wadah. Terkadang proses itu, menulis file baru dan jika saya tidak mengubah perilaku default dengan hak istimewa, file tersebut dihasilkan oleh pengguna root dan pengguna lokal saya tidak dapat mengubahnya lagi.

Apa yang saya lakukan adalah, buat gambar khusus dengan menambahkan ini di dockerfile saya:

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

Mungkin untuk membuat docker-compose.yml saya portabel bagi siapa saja yang dapat menggunakannya adalah meletakkan beberapa parameter pada proses pembuatan.

Berikut adalah pola wadah untuk menetapkan userid/groupid saat runtime dengan cara yang mudah dibawa-bawa. https://github.com/Graham42/mapped-uid-docker

Cara yang saya ikuti:

1- buat direktori di server host
2- ubah izinnya ke pengguna yang memiliki userid dan groupid = 1000
3- jalankan docker-compose up
memeriksa wadah dan semuanya baik-baik saja.

Catatan: Saya menggunakan pengguna root di server Host dan saya berasumsi bahwa jika saya menggunakan pengguna non-root yang memiliki uid = 1000 saya akan dapat memasang volume tanpa mengkhawatirkan izin tetapi saya belum mengujinya. Apakah ada yang mengikuti cara serupa?

Masalah Umum:

  • kawanan buruh pelabuhan, jadi CAPP_ADD tidak tersedia, bind-mount bukan solusi
  • dua wadah dari dua gambar berbeda berbagi volume yang sama, jadi basis data pengguna/grup yang berbeda di keduanya
  • misalnya seseorang harus memiliki hak akses www-data (yaitu, mari mengenkripsi pengunduh sertifikat)
  • yang lain juga menggunakan www-data (yaitu nginx)
  • tetapi yang ketiga memerlukan akses dari openldap pengguna (yaitu server openldap)
  • begitu sederhana chmod juga bukan solusi

Itu berarti, saya memiliki server web, yang mendapatkan sertifikat SSL untuk domainnya dari let's encrpt dan server OpenLDAP untuk domain yang sama, tempat saya ingin menggunakan kembali sertifikat tersebut.

Ada kombinasi lain yang mengalami masalah yang persis sama.

Ada ide untuk mengatasi ini?

Bagaimana Anda menyelesaikan ini tanpa Docker? Ini bukan spesifik Docker
masalah.

Pada Jumat, 12 Januari 2018 pukul 10:24, Marc [email protected]
menulis:

Masalah Umum:

  • kawanan buruh pelabuhan, jadi CAPP_ADD tidak tersedia, bind-mount tidak a
    larutan
  • dua wadah dari dua gambar berbeda berbagi volume yang sama, jadi
    database pengguna/grup yang berbeda di keduanya
  • misalnya seseorang harus memiliki hak akses www-data (yaitu mari mengenkripsi
    pengunduh sertifikat)
  • yang lain juga menggunakan www-data (yaitu nginx)
  • tetapi yang ketiga memerlukan akses dari openldap pengguna (yaitu openldap
    pelayan)
  • begitu sederhana chmod juga bukan solusi

Itu berarti, saya memiliki server web, yang mendapatkan sertifikat SSL untuk domainnya
dari mari encrpt dan server OpenLDAP untuk domain yang sama, di tempat yang saya inginkan
untuk menggunakan kembali sertifikat.

Ada kombinasi lain yang mengalami masalah yang persis sama.

Ada ide untuk mengatasi ini?


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/moby/moby/issues/2259#issuecomment-357267193 , atau bisukan
benang
https://github.com/notifications/unsubscribe-auth/AAwxZgyvdCwGGVkUqCxK9nDFw1zxSKjUks5tJ3kXgaJpZM4BGxv9
.

--

  • Brian Goff

Bahkan tanpa swarm, saya bisa menyelesaikannya di docker: bind-mount.

Ini adalah masalah khusus buruh pelabuhan, karena tidak ada CAP_ADD.

@mwaeckerlin bind mount tidak dapat dipetakan ke ID pengguna yang berbeda.
Tetapi bahkan dengan swarm Anda dapat mengikat mount.... mengapa CAP_ADD diperlukan?

Tanpa CAP_ADD, pemasangan di dalam buruh pelabuhan gagal.

Tetapi dengan menulis komentar saya, saya baru saja mendapatkan solusi yang memungkinkan, tetapi sayangnya itu perlu mengubah Dockerfile di kedua gambar, sehingga tidak akan berfungsi untuk perpustakaan atau gambar pihak ketiga lainnya:

  • buat grup dengan id grup umum yang diberikan secara eksplisit di semua Dockerfiles
  • memberikan hak kepada grup

@mwaeckerlin Mengapa Anda perlu memasang di dalam wadah?

Karena saya tidak dapat menentukan pengguna/grup dengan opsi buruh pelabuhan -v .

Ide yang ditentukan di atas adalah: Bind-mount di dalam wadah, lalu chown pada target tidak boleh mengubah sumbernya.

@mwaeckerlin Jika Anda mengubahnya, itu berubah di mana-mana. Ini adalah inti dari masalah dalam masalah ini.
Mengunyah/Chmoding file/dir yang dipasang di bind mengubah kedua tempat.

Juga tidak perlu dapat memasang di dalam wadah, Anda dapat --mount type=bind,source=/foo,target=/bar

Ya, saya baru saja mengujinya di luar buruh pelabuhan, jadi ide di atas salah.

Masalah utama, yang sering saya lihat di buruh pelabuhan, adalah bahwa pengguna, grup tidak identik dalam gambar yang berbeda, bahkan ketika nama pengguna atau nama grup yang sama ada di keduanya, mereka sering memiliki id yang berbeda.

Di sini sesuatu seperti ini setidaknya akan membantu dalam beberapa kasus: --mount type=bind,source=/foo,target=/bar,user=me,group=mine

Adakah rekomendasi atau praktik terbaik mengenai topik ini: pengguna volume bersama oleh pengguna yang berbeda dalam gambar berbeda di kawanan buruh pelabuhan?

  1. Jangan bagikan volume
  2. Sinkronkan uid/gid Anda
  3. Pastikan izin cukup permisif untuk semua yang berbagi
  4. Gunakan dudukan sekering pada Host untuk mengikat ke uid/gid yang berbeda untuk setiap wadah

Bisakah Anda menguraikan poin 4?
Contoh praktis mungkin tentang bagaimana melakukannya?

Pada Jumat, 12 Jan 2018, 17:27 Brian Goff, [email protected] menulis:

>

  1. Jangan bagikan volume
  2. Sinkronkan uid/gid Anda
  3. Pastikan izin cukup permisif untuk semua yang berbagi
  4. Gunakan dudukan sekering pada Host untuk mengikat ke uid/gid yang berbeda untuk masing-masing
    wadah


Anda menerima ini karena Anda berlangganan utas ini.
Balas email ini secara langsung, lihat di GitHub
https://github.com/moby/moby/issues/2259#issuecomment-357282169 , atau bisukan
benang
https://github.com/notifications/unsubscribe-auth/AHSjvgjb0BFbJhZ1VWM-pLGfa7tRBvDNks5tJ4VPgaJpZM4BGxv9
.

Menggunakan sesuatu seperti https://bindfs.org/ -- bahkan setidaknya ada satu plugin volume Docker yang sudah mengimplementasikannya (https://github.com/lebokus/docker-volume-bindfs adalah hasil pertama yang saya temukan melalui Google) .

saya tidak dapat mengubah izin setelah memasang volume, apakah ada yang mendapatkan ini?

solusi:
Menambahkan ini ke Dockerfile
RUN echo "if [ -e container_volume_path ]; then sudo chown user_name container_volume_path; fi" >> /home/user_name/.bashrc
Kepemilikan container_volume_path diubah setelah volume dipasang.

Mampu memetakan uid dan gid sepertinya merupakan elemen misterius yang hilang untuk penanganan volume buruh pelabuhan. Jalan yang paling tidak mengejutkan adalah memasukkannya dan perbaikan yang disarankan sulit ditemukan, sambil tidak memberikan manfaat praktik terbaik:

Ulang:
1) Jangan bagikan volume

  • Bagus, tapi tidak penting untuk diskusi tentang pemetaan uid/gid
    2) Sinkronkan uid/gid Anda
  • Itulah fungsi yang dimaksudkan untuk dilakukan, tetapi tanpa memaksa chown di Dockerfile
    3) Pastikan izin cukup permisif untuk semua yang berbagi
  • Ini sekali lagi bergantung pada perilaku yang didefinisikan dalam Dockerfile, ketika itu bisa berupa pemetaan sederhana
    4) Gunakan dudukan sekering pada Host untuk mengikat uid/gid yang berbeda untuk setiap wadah
  • Saran yang bagus, itu juga sepertinya mencukur yak.

@colbygk

ketika itu bisa menjadi pemetaan sederhana

Itu masalahnya, tidak mungkin melakukan "pemetaan sederhana" karena tidak didukung di lapisan vfs.
Beberapa sistem file menyediakan kemampuan untuk memetakan kepemilikan (misalnya bindfs atau nfs), tetapi mengimplementasikannya dalam kasus umum saat ini tidak memungkinkan.

Saya membutuhkan volume bersama misalnya dalam situasi berikut:

Sertifikat Bersama

  • container 1 adalah reverse-proxy yang menangani mari kita mengenkripsi untuk semua domain yang dihosting
  • container 2 adalah server ldap yang juga perlu memberikan sertifikat domainnya

solusi: wadah gambar 2 mewarisi dari gambar yang sama dari wadah 1, gambar dasar yang sama membuat grup yang sama, kemudian kedua wadah memiliki akses grup yang sama

Dockerfile dari basis umum :

RUN groupadd -g 500 ssl-cert

letsencrypt-config.sh di mari kita mengenkripsi gambar :

chgrp -R ssl-cert /etc/letsencrypt

Dockerfile dari mwaeckerlin/reverse-proxy :

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

Dockerfile dari mwaeckerlin/openldap :

RUN usermod -a -G ssl-cert openldap

Itu dia.

Semua ini mengilustrasikan tentang cara mengubah userperms selama entrypoint atau selama proses build agar seluruh buruh pelabuhan berjalan di pengguna yang berbeda.

Tapi mungkin saya melewatkan poin penting setelah mencari di web selama 3 hari terakhir.
Tidak satu pun dari rekomendasi dan (solusi) di atas atau yang ditautkan lainnya akan berfungsi dengan cara apa pun.

Semua volume yang dipasang ke wadah selalu dimiliki oleh root:root di dalam wadah. Terlepas dari apakah saya mengubah pemilik di muka di Host dengan UID/GID yang cocok atau tidak.

Saya tidak bisa menghilangkan perasaan bodoh karena mencoba melakukan sesuatu yang sangat mendasar - dari sudut pandang saya.

  • Windows 10 Pro 1803 (17134.112)
  • Docker untuk Windows 18.03.1-ce-win65 (17513)
  • Windows WSL dengan Hyper-V dan Ubuntu

Mencoba memulai wadah Apache2 biasa tempat root dokumen dipasang ke Host sehingga saya dapat mengembangkan kode sumber php sambil segera mengujinya di wadah buruh pelabuhan.

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

Di dalam wadah buruh pelabuhan, directoy _/var/www/html_ selalu dimiliki oleh _ root:root_ , jadi aplikasi php saya tidak akan pernah bisa membuka, atau menulis dengan data apa pun di dalam folder itu..
Belum ada yang berhasil... :(

Bagi mereka yang mencari solusi yang cukup elegan, lihat apa yang disarankan @elquimista di sini . Saya sudah menguji ini dan berfungsi dengan baik

Kami telah menggunakan https://github.com/boxboat/fixuid#specify -paths-and-behavior-across-devices dengan keberuntungan. Selain itu, ini mengatur pengguna di dalam wadah untuk mencocokkan pengguna di Host.

Berikut contoh konfigurasi dari gambar:

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

dan untuk menjalankan:

$ 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

Perhatikan bahwa ini juga merupakan gangguan saat menggunakan sistem penyimpanan yang tidak mendukung izin dan kepemilikan unix. Dalam hal ini, pemasangan penyimpanan harus dilakukan sehingga mendapatkan uid yang benar untuk digunakan di dalam wadah karena setiap upaya untuk mengunyah file akan gagal. Jika ada cara untuk memberi tahu buruh pelabuhan untuk menyajikan file sebagai milik uid tertentu, terlepas dari kepemilikan di luar wadah itu akan menyederhanakan banyak hal.

@tlhonmey

Jika ada cara untuk memberi tahu buruh pelabuhan untuk menyajikan file seperti yang dimiliki oleh uid tertentu

Tidak ada, bukan tanpa sistem file khusus (misalnya seperti bindfs).

@tlhonmey Ya, saya dapat mengatasi masalah "sistem penyimpanan yang tidak mendukung izin unix" dengan beberapa symlink.

Pada dasarnya, memasang dari drive NTFS, saya akan meletakkan sesuatu di -v ./HostNtfsStuff:/data/ntfsMount dan kemudian membuat symlink dan chown itu ln -s -T /data/ntfsMount /var/lib/myApp && chown -Rh myApp:myApp /var/lib/myApp/

Anda juga dapat menguji: su myApp -c 'echo foo > /var/lib/myApp/bar' && cat /data/ntfsMount/bar

Penggunaan saya adalah untuk windows devs untuk dapat menjalankan wadah MySQL dan bertahan pada volume yang dipasang, tetapi ini berlaku untuk banyak aplikasi.

Jadi solusinya adalah mengelola sekelompok pasangan uid:gid secara manual dan berharap mereka tidak berbenturan dengan Host, atau skrip pembantu, atau:

Ada _one_ cara untuk membuatnya bekerja, tetapi Anda harus mempersiapkan terlebih dahulu di dalam Dockrfile Anda.

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

(Saya tidak menguji contoh ini, saya sedang mengerjakan wadah chromium yang kemudian ditampilkan pada wadah _separate_ X11 yang ....)

Saya menggunakan teknik terakhir sampai hari ini ketika saya mencoba mengikat mount volume container dan itu rusak. Rupanya Anda tidak bisa melakukan itu. Volume dibuat sebagai root dan kemudian aplikasi di dalamnya tidak dapat menulisnya sebagai pengguna. Populasi otomatis yang dijelaskan dalam dokumentasi VOLUME tampaknya juga tidak berfungsi dengan pemasangan ikatan.

Saya melihat ini membaca Praktik Terbaik Dockerfile dan skrip pembantu adalah yang mereka rekomendasikan:

#!/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 "$@"

Jadi chown rekursif untuk memastikan Anda memiliki kepemilikan di setiap awal, lalu jalankan aplikasi Anda sebagai pengguna. exec juga memaksa PID 1 sehingga sinyal berfungsi. Dan jika saya ingin mengisi volume dengan sesuatu seperti skrip pembantu untuk digunakan di luar wadah pada data yang dihasilkan, itu mungkin harus masuk ke skrip pembantu juga. Ingin tahu, apakah ada hit kinerja untuk container start jika aplikasi Anda menyimpan banyak file pada volume, terutama jika penyimpanannya tidak lokal.

Sepertinya ada solusi yang lebih baik. Mungkin sesuatu seperti memetakan uid dan gid wadah dengan nama pengguna dan grup tertentu di Host. Bisakah buruh pelabuhan mengintip /etc wadah dan mencari tahu ini mungkin?

Anda tidak dapat memetakan uids/gids di tingkat sistem file, setidaknya tanpa fuse.

Anda tidak dapat memetakan uids/gids di tingkat sistem file, setidaknya tanpa fuse.

Agak apa yang saya takutkan. Adakah yang tahu apa hukuman kinerjanya jika buruh pelabuhan menggunakan sekering seperti ini?

@mdegans

Jadi chown rekursif untuk memastikan Anda memiliki kepemilikan di setiap awal,

Anda tidak perlu melakukan chown di setiap awal. Sebagai gantinya, periksa pemilik direktori data dan hanya lakukan chown rekursif jika tidak benar. Seperti ini:

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

Jadi idealnya ini akan terjadi pada start pertama saja.

Dan berhati-hatilah saat menjalankan wadah dengan skrip titik masuk seperti itu; jika Anda memasang (mis.) direktori-rumah Anda ke dalam wadah, semua file Anda akan di-chown ke postgres

Dalam desain gambar buruh pelabuhan yang baik, pengguna waktu proses bukan root dan oleh karena itu tidak dapat file chown ...!

Dalam desain gambar buruh pelabuhan yang baik, pengguna waktu proses tidak melakukan root dan oleh karena itu tidak dapat melakukan chown file …!

Benar, tetapi seharusnya tidak ada yang menghentikan sakelar ke dan dari root yang sering diperlukan... sama seperti Anda biasanya tidak menjalankan apa pun sebagai root hingga Anda membutuhkannya, tetapi ketika Anda melakukannya, maka Anda dapat melakukan satu atau beberapa hal berikut:

  • sudo
  • su
  • USER root

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

Menurut pendapat saya, terserah kepada pengguna gambar Docker untuk memastikan dia menetapkan izin pada volume yang dipasang dengan benar.

Ini sangat mirip dengan apa yang kami lakukan secara tradisional sebelum container menjadi sesuatu, misalnya ketika saya ingin menjalankan nginx dan saya perlu memastikan direktori HTML statis dimiliki oleh pengguna yang tepat. Untuk mengetahui bahwa saya perlu membuka file nginx.conf saya, periksa pengguna pekerja dan atur izin yang sesuai. Sebenarnya, ini semua dijelaskan dalam dokumentasi nginx.

Ini hanya masalah izin Unix, tidak ada yang baru dengan Docker di sini. Jadi mungkin solusi untuk masalah ini adalah dokumentasi yang lebih baik untuk setiap gambar Docker tentang apa yang seharusnya menjadi kepemilikan volume yang dipasang. Saya tidak ingat daemon start-up nginx memastikan direktori memiliki kepemilikan yang benar, itu hanya akan gagal jika tidak diatur dengan benar.

Namun ini benar karena kami sekarang memiliki pengguna yang berpotensi ditetapkan di dalam wadah dan bukan di luar, itu membuat segalanya tampak berbeda (dan sebenarnya tidak). Tetapi UID di dalam dan di luar setara, jadi foobar pengguna dengan UID 2000 mungkin ada di dalam wadah dan tidak di luar, tetapi UID 2000 masih dapat diatur pada file dan direktori di luar. Kita harus mengubah pemikiran kita dalam hal UID/GID daripada nama-nama ramah manusia yang biasa kita tangani.
Itu juga membuat hal-hal berpotensi lebih sulit jika Anda perlu berbagi volume antara 2 wadah yang ditulis oleh 2 penulis berbeda. Ada kemungkinan bahwa pengaturan izin menggunakan sistem Unix tradisional (pengguna, grup, dan lainnya) tidak cukup untuk menyelesaikan masalah (tidak ada UID atau GID umum). Saya akui bahwa sejak saya menggunakan Docker, saya menggunakan lebih banyak POSIX ACL. Karena itu saya dapat menetapkan 3 izin pengguna yang berbeda ke file yang sama. misalnya penulis wadah dengan izin rw, pembaca wadah dengan izin r dan pengguna host dengan izin r.

Satu opsi lagi: GID umum dapat diterapkan menggunakan flag setgid untuk direktori bersama. Masker file dapat diterapkan menggunakan ACL.

Sebelum Anda melakukan apa pun di wadah Docker, jalankan:

```
umask 0000
````

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

Mampir terlambat ke utas ini untuk menegaskan kembali betapa bermanfaatnya fitur ini.

Sejujurnya, saya telah menyebarkan kontainer selama sekitar satu tahun sekarang, dan saya melihat ini menjadi masalah nyata di semua tempat. Memberikan solusi pada tingkat ini, di sini, sepertinya satu-satunya pilihan yang masuk akal.

Seperti yang ada sekarang, sejumlah besar gambar Docker memilih untuk tetap menjalankan titik masuk mereka sebagai root sehingga mereka dapat mem-bootstrap direktori dan izin file hanya untuk menjatuhkan hak istimewa sebelum menjalankan proses aplikasi.

Masalah sebenarnya muncul ketika Anda menyadari bahwa tidak semua orang dapat menggunakan praktik ini. Untuk beberapa platform populer, seperti Kubernetes atau OpenShift, beberapa lingkungan ini mungkin dikonfigurasi untuk tidak mengizinkan container yang diistimewakan... karena... keamanan. Di luar kepala saya, saya tidak mungkin melihat bagaimana sebuah lembaga keuangan besar bahkan akan mempertimbangkan untuk mengadopsi platform wadah yang memproses informasi sensitif tanpa jenis pembatasan ini.

Masalah keamanan yang ditimbulkan oleh praktik _entrypoint-as-root_ telah mendorong sejumlah besar diagram kemudi Kubernetes untuk menyediakan initContainers yang dapat chown dan chmod volume sebelum container aplikasi dimulai . Ini mungkin tampak seperti cara yang bagus, tetapi percayalah ketika saya mengatakan ini: ini bukan .

Bagan helm, khususnya, dikotori dengan uids dan gids hardcode karena mereka perlu di-rip secara diam-diam dari runtime aplikasi. Informasi tersebut disembunyikan di dalam wadah dan tidak segera tersedia selama penerapan.

Meskipun ada beberapa cara untuk mengatasi masalah ini, hal itu terus mengganggu konfigurasi penyebaran di seluruh sebagai _hack untuk membuat semuanya bekerja_. Jumlah penerapan yang terpengaruh oleh hal ini meningkat pesat dan teknik yang digunakan orang bertentangan dengan semua manfaat lain yang dibawa oleh kontainer ke meja.

Saya harap ada cara untuk mengimplementasikan ini sebagai bagian dari spesifikasi OCI sehingga solusi lain yang bergantung pada Docker dapat menggunakannya untuk menyediakan penerapan yang sepenuhnya otomatis secara elegan.

JADI, pertanyaannya menjadi: di mana lagi di internet mereka mengembangkan spesifikasi OCI umum, di mana diskusi ini harus dibawa? Dengan asumsi itu bukan cara terbaik untuk memasukkan fitur ini ke buruh pelabuhan (akhirnya, melalui persyaratan untuk kepatuhan di masa depan, adopsi standar yang disepakati bersama).

Karena masalahnya pasti tidak akan pernah hilang dengan sendirinya, dan solusinya membutuhkan beberapa jenis perubahan yang sangat mendasar.

initContainers yang dapat chown dan chmod volume sebelum container aplikasi dimulai. Ini mungkin tampak seperti cara yang bagus, tetapi percayalah ketika saya mengatakan ini: tidak.

FWIW; fitur ini hanya diperlukan untuk situasi di mana file dibagikan di antara beberapa ruang nama (baik file (sebelumnya) yang ada di "host", atau lokasi file umum yang dibagikan di antara beberapa wadah yang berjalan sebagai pengguna yang berbeda). Dalam situasi di mana file telah dibuat sebelumnya di host, ini dapat dikurangi dengan memastikan file tersebut memiliki kepemilikan dan izin yang benar sebelum membagikannya dengan penampung. Secara efektif itu tidak berbeda dari (misalnya) menjalankan nginx di host, dan memastikan bahwa file di webroot memiliki izin yang benar.

Saat berbagi antar container yang berjalan sebagai pengguna yang berbeda, jalankan kedua container dengan uid yang sama (atau gid , dan atur izin grup yang benar, mirip dengan cara kerjanya saat menjalankan dua proses non-kontainer yang perlu memiliki akses ke sumber daya yang sama).

beberapa lingkungan ini mungkin dikonfigurasi untuk tidak mengizinkan wadah yang diistimewakan... karena... keamanan. Di luar kepala saya, saya tidak mungkin melihat bagaimana sebuah lembaga keuangan besar bahkan akan mempertimbangkan untuk mengadopsi platform wadah yang memproses informasi sensitif tanpa jenis pembatasan ini.

Hanya untuk mencegah kebingungan; wadah yang dijalankan sebagai root tidak sama dengan wadah "hak istimewa" ( --privileged atau opsi, seperti set --cap-add ). Wadah yang diistimewakan ( --privileged ) sangat tidak aman, sedangkan wadah yang dijalankan sebagai root terisi penuh dan tidak akan dapat pecah ; melewatinya file/direktori yang dipasang-terikat adalah membuat lubang di dalamnya, jadi _will_ memberinya akses ke file/direktori yang Anda lewati sebagai pengikat-mount.

Bagan helm, khususnya, dikotori dengan uid dan gid yang di-hardcode karena itu perlu di-rip secara diam-diam dari runtime aplikasi. Informasi tersebut disembunyikan di dalam wadah dan tidak segera tersedia selama penerapan.

Ingin tahu: apakah uid/gid itu tidak diketahui; seperti apa tampilan UXnya? (karena saya harus menyediakan uid/gid pemetaan untuk digunakan untuk memetakan Host uid/gid ke container-uid/gid (tidak diketahui)?

JADI, pertanyaannya menjadi: di mana lagi di internet mereka mengembangkan spesifikasi OCI umum, di mana diskusi ini harus dibawa?

Saya tidak berpikir (sekilas) bahwa perubahan spesifikasi OCI diperlukan; ini dapat diselesaikan di luar spesifikasi OCI; masalah utama adalah bahwa mekanisme untuk memetakan uids/gids saat ini tidak ada di kernel (atau ada (seperti shiftfs ), tetapi tidak tersedia secara umum)

Ini adalah jalinan klasik dari pengalihan tanggung jawab / orang lain dapat atau harus menyelesaikan masalah ini. Entah itu:

  • Pengguna
  • Implementasi spesifik dari platform Docker / containerization
  • spesifikasi OCI
  • Inti
  • Berkas sistem

Masalahnya sudah dinyatakan secara efektif: bahwa meminta pengguna melakukan ini kikuk dan kurang aman. Namun efek langsung dari membuat pengguna melakukan peretasan per gambar juga penting:

Artinya Anda tidak dapat dengan mudah mengoperasikan dan berbagi / mencampur gambar untuk bekerja sama dari pengguna yang berbeda. Jadi:

  • Mematahkan berbagi komunitas (cukup banyak). Karena pengguna yang berbeda menentukan dari kumpulan namespace global yang sama, uid dan gid mereka untuk gambar yang dikembangkan secara individual
  • Memaksa pengguna untuk mengembangkan standar ad-hoc mereka sendiri dan berharap orang lain akan mengikuti konvensi yang mereka pilih sendiri
  • Memaksa pengguna menggunakan root untuk semuanya. Yang pasti kurang aman. Karena Anda menghilangkan lapisan ekstra perlindungan eskalasi istimewa yang seharusnya Anda miliki. Dan membuat kerentanan penembusan kontainer menjadi lebih mudah untuk dieksploitasi, karena pengguna sudah root di dalam penampung untuk memulai. Belum lagi dapat menjalankan layanan lain dalam wadah yang sama, yang juga merupakan cara lain untuk menyamping, sebelum naik.

Jadi ini adalah perdagangan. Mereka di atas adalah trade off saat ini. Sedangkan Anda akan memiliki set trade off yang berbeda untuk mengalihkan tanggung jawab di tempat lain, ke satu atau lebih entitas lain yang tercantum di atas.

BTW sehubungan dengan melihat lebih dekat pada solusi berbasis sistem file, telah menemukan komentar 'berpotensi dapat berguna' ini dari tautan laba-laba:

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

Yang memiliki beberapa referensi berbeda untuk fitur umum yang sama ini (ke proyek/tempat lain), termasuk ke sistem file terdistribusi (dikenal sebagai 'Lustre'), dan masalah lain terkait ZFS. Nah, kebetulan saya menggunakan ZFS di sini sendiri.

Kemudian juga ditemukan salinan lain dari bug yang sama di ubuntu/launchpad. Merujuk pada masalah ZOL #4177 yang sama,

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

Yang mengatakan bug yang dimaksud telah diperbaiki di zfs versi 0.6.5.7+ SO. Apakah ini berarti bahwa kita berpotensi dapat menggunakan zfs dan ACL, sebagai semacam penyimpanan cadangan untuk memetakan ulang uid dan gid? Yah, ini bukan sesuatu yang pernah saya dengar sebelumnya.

Oh mungkin solusi ini hanya berfungsi untuk wadah LXC. Karena dia juga mengatakan dalam komentarnya di sana (pemimpin proyek LXC), "kami menggunakan pembantu setuid (newuidmap dan newgidmap)" yang kemudian dapat "mengatur peta uid dan gid". Jadi mungkin ada juga beberapa mekanisme yang diperlukan di LXC itu sendiri, jika tidak, bagian zfs acls tidak dapat digunakan? Atau mungkin saya keliru. Saya tidak sepenuhnya yakin saya mengikuti ini sepanjang jalan.

Tautan menarik lainnya, kali ini tentang shiftfs , dan diskusi tentang kemungkinan menyerap fitur-fiturnya ke dalam overlay. Yang tentu saja merupakan sistem file dasar yang sudah digunakan buruh pelabuhan.

Namun apa yang terjadi jika fitur pemetaan ulang diimplementasikan ke overlayfs , namun saya ingin menggunakan driver penyimpanan zfs sebagai gantinya untuk sistem file dasar saya? Apakah saya kemudian harus kehilangan kemampuan untuk memetakan ulang uid/gid, jika itu diimplementasikan berdasarkan sistem file? Atau bisakah kita menerapkan keduanya secara terpisah? Maaf, saya agak tidak jelas apakah daemon Docker perlu mengetahui pemetaan ulang semacam itu, dan menyediakan api dan flag umum (untuk diturunkan ke lapisan driver fs). Atau jika kita sebaliknya akan melakukan pemetaan ulang secara manual di sisi Host (di sistem file, di luar buruh pelabuhan). Aspek itu juga masih sedikit tidak jelas bagi saya.

[EDIT] oops, lupa sertakan tautannya! Ini dia

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

Masalah ini tentang volume/bind-mount, jadi pisahkan dari sistem file penampung

Kami akan menggunakan overlay dengan uid/gid shift untuk bindmount jika overlay memasukkan fitur shiftfs, tetapi harus mundur ke sesuatu yang lain (atau tidak sama sekali) pada sistem yang tidak didukung.

Podman adalah pengganti drop-in Docker tanpa akar https://www.youtube.com/watch?v=N0hSn5EwW8w https://podman.io/ . Dengan podman, root tidak digunakan sehingga izin pengguna ditangani dengan benar. Tim kami beralih ke Podman karena masalah ini dan bekerja dengan sangat baik.

Ini tidak masuk akal.
Masalah yang sama berlaku.
Perhatikan bahwa buruh pelabuhan juga memiliki mode tanpa akar.

Anda dapat menguji Podman dengan perintah berikut. Podman tidak memiliki daemon terpisah seperti Docker, dan semuanya berjalan di bawah pengguna yang mengeksekusi perintah podman . Jadi file yang dibuat di dalam podman dimiliki oleh pengguna yang menjalankan perintah 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

Ini bukan tempat yang tepat untuk mengiklankan podman -- jika ada detail teknis khusus tentang cara kerjanya yang dapat membantu menyelesaikan masalah ini, itu akan relevan untuk didiskusikan, terutama sebagai solusi potensial untuk masalah yang Anda' saat ini kembali mengomentari. Sejauh ini, bukan itu yang terjadi, jadi silakan diskusikan ini di tempat lain.

Fakta bahwa podman memiliki arsitektur yang sangat berbeda dengan Docker yang membuat masalah ini tidak terlalu parah/menyakitkan tidak secara ajaib memungkinkan Docker untuk sepenuhnya mengubah cara kerjanya hanya untuk menyelesaikan masalah yang satu ini. Saya dapat meyakinkan Anda bahwa ada banyak alasan mengapa Docker terstruktur seperti itu, dan sejujurnya adalah iman yang buruk untuk mengabaikan semua sejarah itu.

@tianon Ya tentu saja, ada pro dan kontra untuk kedua pendekatan tersebut. Saya menyebutkan podman hanya karena menjalankan wadah dengan podman dengan pengguna target secara khusus memecahkan masalah teknis ini, yaitu, "memasang volume sebagai pengguna selain root".

Silakan lihat izin "test_file" yang dibuat di komentar saya di atas. Ini pertama-tama me-mount direktori "~/podman_test", dan menulis file "test_file" di dalam wadah podman. Kemudian setelah pengguna keluar dari wadah, Anda dapat melihat bahwa file tersebut dimiliki oleh "kkimdev", bukan root.

Masalahnya adalah saran Anda untuk memperbaiki masalah dengan Docker adalah bahwa itu sama dengan "jangan gunakan Docker" yang tidak terlalu konstruktif pada pelacak masalah untuk Docker.

Ya, podman dirancang berbeda yang membuat masalah ini diperdebatkan untuk alat itu -- itu bagus dan bagus, tetapi sama sekali di luar topik di sini. Rootless memiliki pengorbanan yang berbeda, beberapa di antaranya baik-baik saja untuk sebagian orang, beberapa di antaranya tidak. Ini semakin baik seiring waktu (dan sebagian besar peningkatan kernel), tetapi bukan solusi umum untuk semua orang di sini.

Ini memerlukan modifikasi kernel atau shim untuk solusi generik seperti yang dibahas secara rinci di atas (dan karena @cpuguy83 dan yang lainnya telah berupaya membantu menyelesaikan masalah ini dengan cara yang umum).

Docker membuka masalah khusus ini sejak 2013 dan hampir enam tahun kemudian tidak ada perbaikan mudah yang terlihat. Podman dirancang untuk mendapatkan kompatibilitas dengan Docker tetapi juga mengatasi kelemahan desain Docker (termasuk berjalan sebagai pengguna yang tidak memiliki hak yang tidak memerlukan daemon Docker pengguna super).

Jika pengguna dapat memberi saran kepada orang lain tentang masalah GitHub, itu tidak masalah. Ini adalah komunitas. Jangan ragu untuk merekomendasikan apa pun yang bisa membantu.

Saya dapat meyakinkan Anda bahwa ada banyak alasan mengapa Docker terstruktur seperti itu

Begitu juga grep . Tetapi jika seseorang perlu mencari lebih cepat, saya tetap akan merekomendasikan ripgrep . Bahkan pada pelacak masalah grep . Seharusnya tidak masalah pelacak masalah siapa itu, selama itu menyelesaikan masalah pengguna dan membuat mereka bahagia.

Jika Podman tidak bekerja untuk Anda: baiklah! Tetapi jika membantu orang lain karena mereka hanya perlu mengganti docker dengan podman di infrastruktur mereka: biarkan saja.

Argumen utama Podman adalah ia tidak menjalankan daemon dan itulah argumen utama saya yang menentangnya. Bagaimana cara mendapatkan kembali wadah saya setelah reboot? Saya tidak akan melakukannya dengan tangan dan yang lainnya hanyalah desain yang buruk. Saya juga tidak ingin wadah buruh pelabuhan saya dimiliki oleh pengguna tetapi dimiliki oleh sistem dan ini berarti root.
Podman masuk akal jika Anda adalah satu-satunya orang yang menggunakannya.

Dan untuk memperbaiki masalah Anda: Buat wadah dengan COPY --chown ...:... !

Juga Docker tidak memiliki masalah seperti itu dan Anda dapat mengontrol server buruh pelabuhan dari jarak jauh yang juga penting bagi saya.

Ada alat untuk menghasilkan pod dari menjalankan container, yang juga tidak akan saya rekomendasikan karena Anda harus membuatnya dari awal dengan cara yang bersih.

Saya kira kita harus kembali ke topik sekarang: IMHO saran pertama baik-baik saja tetapi yang lainnya hanya meledakkan masalah ini dan tidak akan menyelesaikan apa pun.


@SuperSandro2000 , Anda dapat mengklik di sini untuk tanggapan atas pernyataan Anda.

Bagaimana cara mendapatkan kembali wadah saya setelah reboot? Saya tidak akan melakukannya dengan tangan dan yang lainnya hanyalah desain yang buruk.

Nah, Podman memiliki integrasi asli dengan systemd (seperti _hampir_ setiap hal lain di hampir semua distribusi GNU Linux modern). Jadi Anda tidak perlu mempertahankan 'dua' sistem boot (seperti pertama-tama memiliki systemd untuk memulai daemon Docker yang kemudian harus membuat putaran lain untuk memulai wadah dalam konfigurasi yang berbeda). Jadi dengan Podman Anda dapat mengontrol semuanya dengan systemd (artinya: sistem yang kemungkinan besar sudah Anda instal dan jalankan).

Saya juga tidak ingin wadah buruh pelabuhan saya dimiliki oleh pengguna tetapi dimiliki oleh sistem dan ini berarti root.

Tidak apa-apa jika Anda tidak menginginkannya. Anda masih dapat menjalankan Podman sebagai pengguna super tetapi Anda tidak _harus_ lagi. Secara umum itu dianggap sebagai ide yang buruk dan meningkatkan permukaan serangan karena jika seseorang dapat mengeksploitasi daemon Docker Anda, ia memiliki kendali tentang _semuanya_ pada sistem.

Podman masuk akal jika Anda adalah satu-satunya orang yang menggunakannya.

Pernyataan ini tidak masuk akal. Podman memungkinkan Anda untuk menyebar pada satu sistem yang merupakan fitur yang sangat masuk akal jika Anda memiliki banyak orang yang bekerja pada sistem yang sama.

Dan untuk memperbaiki masalah Anda: Buat wadah dengan COPY --chown ...:... !

IMHO masalahnya di sini adalah _mounting_ volume untuk wadah di _runtime_. Yang hanya sedikit hubungannya dengan membangun citra.

Juga Docker tidak memiliki masalah seperti itu dan Anda dapat mengontrol server buruh pelabuhan dari jarak jauh yang juga penting bagi saya.

Lucu bahwa Anda menyebutkan dengan tepat blog yang memiliki posting ini di dalamnya. Namun saya tidak terlalu berpengalaman dengan detail jaringan dari kedua implementasi tetapi seperti yang saya pahami, podman dimulai dengan aturan jaringan yang paling sedikit dan pengguna yang tidak memiliki hak tidak dapat mengatur pasangan veth

Untuk lebih jelasnya, Anda harus bisa mendapatkan pengaruh yang sama dengan buruh pelabuhan tanpa root seperti yang Anda dapatkan dengan podman.
Ini karena dockerd berjalan saat pengguna Anda dan root di wadah dipetakan ke UID Anda.

Ini memang memiliki kekurangan dan tentu saja tidak berfungsi saat berbagi daemon dengan banyak pengguna.
https://get.docker.com/rootless

Pada 27 Juni 2019, pukul 07.52, Alexander Adam [email protected] menulis:

Saya kira kita harus kembali ke topik sekarang: IMHO saran pertama baik-baik saja tetapi yang lainnya hanya meledakkan masalah ini dan tidak akan menyelesaikan apa pun.

@SuperSandro2000 https://github.com/SuperSandro2000 , Anda dapat mengklik di sini untuk tanggapan atas pernyataan Anda.
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/

Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, melihatnya di GitHub https://github.com/moby/moby/issues/2259?email_source=notifications&email_token=AAGDCZXX2UQCG7LUVH57V6LP4TH2DA5CNFSM4AI3DP62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYXL2XI#issuecomment-506379613 , atau mematikan benang https://github.com/notifications/ unsubscribe-auth/AAGDCZX437HJP4M6XG3SEY3P4TH2DANCNFSM4AI3DP6Q .

@alexanderadam

IMHO masalahnya di sini adalah memasang volume untuk wadah saat runtime. Yang hanya sedikit hubungannya dengan membangun citra.

Solusi saya adalah tidak memasang direktori tetapi memanggangnya dalam wadah jika memungkinkan.

Maksud saya podman terdengar bagus tetapi saya tidak akan beralih karena untuk saat ini saya tidak melihat keuntungan apa pun bagi saya. Terima kasih atas penjelasannya.

podman mengalami masalah yang sama jika Apache di dalam container dijalankan di bawah pengguna www . https://github.com/containers/libpod/issues/3990

Solusinya bisa dengan memetakan pengguna www dari wadah ke UID di Host jika tidak ada pengguna root di dalam wadah. Saya tidak tahu apakah itu mungkin.

Jika Anda ingin menjalankan --read-only (untuk melakukan hal yang sama seperti kebijakan readOnlyRootFilesystem Kubernetes), Anda dapat melakukan hal di bawah ini. Itu dibangun di atas solusi yang disarankan @jpetazzo :

  • Gambar buruh pelabuhan saya membuat dan menggunakan pengguna dengan uid=1001 dan gid=1001
  • Secara terpisah, buat volume buruh pelabuhan
  • Hitung uid:gid hingga 1001
  • Pasang gambar itu saat menjalankan aplikasi.

File Docker:

FROM ubuntu

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

USER appuser

Kemudian:

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

Sekarang, ketika menjalankan gambar buruh pelabuhan dan memasang volume, /some_dir milik pengguna yang saya inginkan.

$ 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

Saya akan menunjukkan lagi, karena mudah hilang di utas, bahwa symlink yang dikunyah mungkin akan berfungsi untuk sebagian besar skenario. Kelemahannya adalah Anda perlu mengaturnya, yang sering berarti mengganti titik masuk dengan skrip yang kemudian menjalankan perintah asli.

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

+1

Saya pikir sejauh ini ini adalah masalah paling menjengkelkan yang saya miliki dengan buruh pelabuhan dan melihat berapa lama ini sudah terbuka menunjukkan ini tidak terjadi pada banyak orang lain?

Ini bukan masalah jika Anda tahu solusinya. Kasus saya:

  • Hostnya adalah Linux

    • uid dalam wadah == uid yang diinginkan di Host - tidak diperlukan solusi
    • uid in container != uid yang diinginkan pada Host - jalankan beberapa perintah setfacl dan berikan akses rw baik untuk pengguna Host dan pengguna container
  • Host adalah MacOS - semuanya bekerja di luar kotak untuk aplikasi Docker resmi.

jalankan saja beberapa perintah setfacl dan berikan akses rw baik untuk pengguna host dan pengguna kontainer

Ini masalah. Saya tidak ingin menjalankan beberapa perintah setfacl untuk setiap gambar buruh pelabuhan dan mendeteksi OS.

Ini sebenarnya adalah masalah keamanan yang besar juga.

Contoh skenario:

  • host1 telah menginstal buruh pelabuhan
  • host1 memiliki beberapa layanan yang berjalan di wadah buruh pelabuhan - semuanya adalah jalur lokal mount di bawah /docker/my-service-01|02|03|etc
  • setiap kontainer dibuat oleh vendor yang berbeda dan masing-masing mengikuti kebijakan uid dan guid mereka sendiri, sehingga mengharuskan Anda untuk chown -R uid.gid /docker/my-service-01... yang sesuai.

Hasil:

  • Pada titik tertentu, pengguna normal atau layanan yang dibuat pada host akan memiliki akses penuh ke /docker/my-service-01|02|03|etc yang tidak dimaksudkan atau diinginkan.
  • Jika Anda ingin memasang volume sebagai "hanya-baca" pada dua wadah dari vendor yang berbeda - itu akan gagal karena uid.gid tidak akan cocok dengan yang diperlukan dan Anda tidak akan dapat chown karena setiap wadah memiliki kebijakan uid.gid sendiri dan berbeda :)

Ya, kami telah membahas masalah ini secara panjang lebar sebelumnya dan fakta kunci yang dikomunikasikan kembali (pada waktu itu) adalah bahwa kernel linux tidak memiliki mekanisme pendukung yang mendasari untuk menyediakan uid dan gid yang dapat dipetakan ulang. Jadi seseorang perlu menambahkan ke kernel agar proyek ini (moby / buruh pelabuhan) dapat mengimplementasikan fungsionalitas yang sangat diinginkan ini. Kalau tidak, kami sudah mendapatkan fitur ini beberapa waktu lalu. Kembali ketika pertama kali dilihat.

Jadi cara paling produktif untuk melanjutkan diskusi ini (hari ini) adalah dengan: Lihat apakah ada situasi yang berubah. Cari komentar teknis dari pengembang jalur utama kernel linux di vger.org. Cari set tambalan/permintaan gabungan sebelumnya pada kernel untuk fitur dasar yang hilang ini. dll.

Dengan harapan untuk pemahaman yang lebih baik tentang apa yang telah terjadi di tingkat yang lebih rendah itu. Apa yang menjadi batu sandungan? Apakah itu masalah kinerja? Apakah keberatan dari segi model/pelemahan keamanan? Apakah masih ada di meja atau di peta jalan masa depan, tetapi hanya masuk akal setelah fitur lain B dan C dapat diimplementasikan? Semua pengembangan kernel ini berlangsung di tempat lain. Di saluran lain.

@DXist Fakta ini bekerja secara ajaib di OSX dan bukan di Linux mengejutkan dan menjadi masalah tersendiri.

Sesuai komentar terakhir @ dreamcat4 , adakah yang melakukan upaya baru untuk melihat apa statusnya? Apakah kami memiliki dukungan di Kernel untuk uid dan gid yang dapat dipetakan ulang sekarang? Apa status keseluruhan di sini?

Saya telah menggunakan Ruang Nama Pengguna Linux untuk menyelesaikan masalah ini dengan sempurna. Bekerja persis sama (AFAICT) dengan platform lain (wadah melihat volume yang dipasang mengikat sebagai root, Host melihatnya sebagai pengguna yang menjalankan buruh pelabuhan).

Panduan ada di sini: https://www.jujens.eu/posts/en/2017/Jul/02/docker-userns-remap/

@patrobinson +1

Apakah halaman ini membantu?
0 / 5 - 0 peringkat