Moby: Jadikan uid & gid dapat dikonfigurasi untuk volume bersama

Dibuat pada 23 Jul 2014  ·  141Komentar  ·  Sumber: moby/moby

Harap berikan opsi untuk membuat kepemilikan volume bersama dapat dikonfigurasi.

Misalnya kasus penggunaan saya saat ini adalah menjalankan logstash-forwarder di dalam sebuah wadah, yang memiliki /var/lib/docker berbagi hanya-baca sebagai volume dari Host.

Karena /var/lib/docker disetel ke 0700 root:root di Host, saya tidak dapat mengakses volume sebagai pengguna non-root.

Apa yang ingin saya miliki adalah sesuatu seperti dengan NFS di mana seseorang dapat memetakan uid & gid dari Host ke pengguna & grup di klien.

Yaitu docker run -v /var/lib/docker:/var/lib/ docker:ro :$user:$group akan membuat volume tersedia dalam wadah sebagai hanya baca, milik $user:$group.

kinfeature

Komentar yang paling membantu

Kami benar-benar membutuhkan solusi masuk ke (bukan gosu) lintas platform untuk memetakan uid/gid. Masalah ini saja menyebabkan kerusakan besar pada bagaimana buruh pelabuhan dirasakan oleh para pemula.

Semua 141 komentar

Saya tidak tahu _bagaimana_ mereka menerapkan ini, dan jika fitur yang sebanding ada di Linux, tetapi di OS X, ada fitur untuk 'mengabaikan kepemilikan' pada volume. Secara efektif ini akan membuat pengguna _any_ melihat file/direktori seolah-olah mereka adalah pemiliknya.

Meskipun ini tidak akan melayani semua kasus, ini mungkin tambahan yang bagus

gh#5910 menangani ini dari sisi SELinux.

tautan: #5910 ;)

Perubahan SELinux sebenarnya mengubah label pada konten. Berpotensi Anda dapat melakukan perubahan pada Host. Saya tahu tidak ada cara lain untuk melakukan ini untuk UID/GID. Tetapi melakukan chown -R $UID:$GID pada titik pemasangan.

Atau Anda dapat menambahkan jenis akses ini menggunakan ACL. Tapi saya pikir Anda perlu mengubah setiap INODE pada titik pemasangan.

Saya juga membutuhkan fitur ini.

Misalnya, saya ingin membuat wadah web, dan melampirkan volume dengan situs web dan konfigurasi ke dalamnya, sehingga wadah itu akan sepenuhnya universal untuk sejumlah situs web.

Namun, saya memerlukan akses git untuk mendorong kode ke repositori situs web. Karena saya ingin aplikasi saya diisolasi - saya ingin setiap direktori situs web dimiliki oleh pengguna/grup yang terpisah, dan akan lebih bagus jika file yang ditulis oleh wadah Docker ke dalam volume akan dimiliki oleh pengguna/grup yang terpisah itu.

+1 untuk fitur ini.
Saya tidak mengerti bagaimana volume baca/tulis dapat bekerja tanpanya. Mengharapkan panduan/uid sama pada gambar dan Host adalah persyaratan kuat yang tidak sesuai dengan prinsip isolasi Docker.

Saya pribadi mengatasi ini dengan perintah useradd/groupadd yang jelek dan lambat untuk alat pengembangan Dockerized saya: https://github.com/ndless-nspire/Ndless/blob/master/ndless-sdk/bin-docker/nspire-docker

Saya mungkin benar-benar kehilangan intinya. Tetapi saya berjuang dengan masalah serupa di mana saya ingin memastikan bahwa pengguna http memiliki izin menulis di /var/log, yang merupakan volume dan kemungkinan dari Host dengan root:root sebagai pemilik.

Saya menyelesaikannya dengan menetapkan titik masuk yang memastikan bahwa direktori log dibuat dan memiliki izin yang tepat. Saya kira ini berfungsi karena skrip entrypoint berjalan sebagai root.

(komentar dihapus -- salah tab, maaf)

Saya meretas ini di Ubuntu di luar Docker. Instal paket bindfs dan ikat direktori dengan konten volume ke jalur lain sambil memetakan UID dan GID ke yang digunakan di dalam wadah:

sudo bindfs -u UID -g GID jalur lama jalur baru

Kemudian gunakan newpath sebagai volume buruh pelabuhan. Oldpath masih menunjukkan kepemilikan yang benar untuk Host, newpath untuk tamu.

@jjv masalahnya adalah bindfs BENAR-BENAR BENAR-BENAR lambat.

@ cpuguy83 ya itu jauh dari optimal tetapi mungkin membantu seseorang dalam situasi yang sama. Ini untuk membuat semuanya bekerja di dalam mesin virtual pengembangan (vmhgfs tidak mengizinkan pengaturan UID/GID) sementara dalam produksi, UID dan GID masih harus cocok antara Host dan tamu ...

Sebenarnya akan lebih baik jika jenis fungsionalitas bindfs digunakan ketika buruh pelabuhan mengimplementasikan ini, dengan asumsi itu tidak menyebabkan terlalu banyak hit kinerja. Dengan begitu, Anda tidak perlu memastikan container dijalankan sebagai pengguna yang benar. Seharusnya juga dimungkinkan untuk menggunakan nama logis alih-alih uid/gid literal.

@jsternberg Ini adalah hit kinerja yang luar biasa. Hampir mirip dengan menggunakan folder bersama vbox.

+1

untuk kasus penggunaan pengembangan lokal, saya pikir Docker pasti membutuhkan fitur ini. Dan dalam kasus seperti itu, saya ingin fitur ini mendukung Windows dan OSX.

Vagrant tampaknya mendukung ini dengan memetakan UID/PID pengguna Host ke pengguna gelandangan. Tetapi untuk tujuan pengembangan, saya sangat ingin menggunakan Docker daripada Vagrant, karena jauh lebih ringan daripada Vagrant untuk menjalankan aplikasi multi-host.

Tolong beri tahu saya apa yang saya lewatkan di sini (saya tidak punya pengalaman dengan Go), tetapi tidakkah fungsi Go Mount() menerima flag? Tidak bisakah kami mengizinkan perintah seperti
-v host/folder:container/folder -mount-as user:group
Tidak bisakah Anda mendapatkan uid/gid dengan pencarian (https://golang.org/src/os/user/lookup_unix.go)
dan kemudian meneruskannya (uid=1,gid=1) sebagai flag ke Mount()? (https://golang.org/src/syscall/syscall_linux.go?s=19154:19249#L754)

@krisgraham bind mount tidak mendukung pengaturan uid/gid seperti itu.

Juga memisahkan opsi -v dari opsi --mount-as menyebabkan kebingungan ketika ada beberapa opsi -v

Apa solusi yang baik untuk ini? Saya ingin menggunakan Docker untuk pengembangan aktif, dan tidak memiliki semacam volume terpasang sebenarnya bukan pilihan karena saya harus membangun kembali setiap kali saya membuat perubahan dalam kode saya.

Alasan saya ingin menggunakan Docker untuk pengembangan aktif adalah agar konsisten dengan lingkungan produksi saya.

@berfarah Saya menggunakan buruh pelabuhan untuk pengembangan aktif setiap hari.
Jarang ada kasus ketika saya harus dipusingkan dengan perm.
Jika Anda menggunakan boot2docker di OSX, maka pastikan direktori kerja Anda berada di dalam /Users dan Anda akan baik-baik saja.

@ cpuguy83 Terima kasih atas balasan cepatnya. Saya mengalami masalah izin dengan lingkungan Rails di mana log tidak dapat ditulis, dan terkadang ada titik kegagalan karena izin. Ini karena layanan saya memiliki UID yang berbeda dengan salah satu file.

@berfarah Solusi saya adalah menulis file docker saya sedemikian rupa sehingga wadah-pengguna/grup yang memiliki kode memiliki UID/GUID yang sama dengan pengguna Host saya. Misalnya, karena UID pengguna Host saya adalah 1000:

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

@berfarah Punya log untuk pergi stdout/stderr untuk RAILS_ENV=pengembangan?

@ cpuguy83 Masalah ini tidak mempengaruhi OSX; thaJeztah berkomentar pada 24 Jul 2014:

pada OS X, ada fitur untuk 'mengabaikan kepemilikan' pada volume. Secara efektif ini akan membuat setiap pengguna melihat file/direktori seolah-olah mereka adalah pemiliknya.

@ncjones sebenarnya, hal yang sama berlaku untuk OS X. "Volume" yang saya bicarakan di sana, adalah harddisk/partisi (volume) yang digunakan pada OS X itu sendiri. Saya ragu itu membuat perbedaan untuk bekerja dengan Boot2Docker, tapi saya tidak yakin.

Komentar saya dimaksudkan untuk memberi tahu jika sesuatu _similar_ dimungkinkan di Linux (jadi di dalam VM Boot2Docker)

Maaf atas kebingungan di sana.

@ryneeverett Terima kasih, itu membantu. Apakah Anda kemudian hanya mengubah izin menjadi 775 dari 755 dan 664 dari 644 masing-masing di mana Anda perlu? sunting: Keterampilan membaca!

@cpuguy83 Terima kasih! Itu sepertinya perbaikan yang lebih membatasi daripada solusi @ryneeverett , karena ini bukan sesuatu yang bisa saya bawa ke semua proyek.

@berfarah Senang Anda menemukan itu membantu. Ya, saya hanya memastikan bahwa file Host saya memiliki izin yang benar dan Docker menyimpannya dalam volume.

+1

Ini adalah sesuatu yang akan sangat berguna untuk volume bersama melalui buruh pelabuhan, dan mengatasi masalah keamanan yang saya miliki:

  • Volume bersama di mana container uid dan gid secara tidak sengaja dipetakan ke pengguna non-root yang memiliki hak istimewa di host. (mis. file yang dibuat oleh wadah di Host dipetakan ke pengguna yang dapat sudo tanpa passwd, mengakses konten yang dibatasi, dll.)

Memperbaiki ini akan sangat nyaman bagi orang-orang perusahaan yang menjalankan banyak kontainer dengan Apache atau middleware dan membagikan volume logging dan/atau berbagai direktori konten/upload. Saya pribadi juga mengalami sakit kepala dengan izin ini saat menyimpan aplikasi pengguna akhir di Linux (seperti syncomm/spotify). Banyak solusi saat ini sendiri bermasalah. Pada akhirnya, ini harus diperbaiki di dalam buruh pelabuhan. Saya terutama tidak merasa nyaman menjalankan skrip shell root sebagai titik masuk, terutama ketika masalah ini menyoroti bagaimana 00:0 uid/gid dalam wadah akan dipetakan untuk melakukan root pada Host saya. Saya suka proposal awal "docker run -v /var/lib/docker:/var/lib/ docker:ro :$user:$group".

@syncomm saya akan mengambil pendekatan yang berlawanan.
Docker tidak dapat membuat asumsi tentang kepemilikan data Anda.

Pendekatan yang Anda soroti di bagian bawah komentar Anda akan dapat dilakukan jika kami secara otomatis memetakan file nyata ini ke fs berbasis fuse di mana kami dapat mengubah uids/gids... dan ini akan menimbulkan dampak kinerja yang signifikan.

Dan segera uid 0 dalam wadah tidak akan menjadi uid 0 di host... yang juga membuat kepemilikan file semakin rumit.

Apakah ini duplikat #2259?

@ cpuguy83 Terima kasih atas umpan baliknya, meskipun saya tidak yakin apa yang Anda maksud dengan pendekatan yang berlawanan. Awan Anda menjelaskan? Saya setuju bahwa kepemilikan data tidak harus diasumsikan oleh buruh pelabuhan, tetapi saya percaya memberikan pemetaan yang konsisten dari wadah ke Host tentu membuat pekerjaan mengawasi data ini jauh lebih mudah bagi konsumen buruh pelabuhan.

Saya setuju, bahwa seperti solusi bindfs, menjadikannya pembungkus sekering akan menimbulkan overhead yang besar. Namun, harus ada jalan keluar dari teka-teki ini tanpa hukuman besar. Pada dasarnya wadah berperilaku dengan benar (seolah-olah itu adalah mesin unik yang terpisah dari Host), dan ketika kami memasang direktori Host sebagai volume, ia (dengan benar) melihat sistem file POSIX di sana, izin, dan semuanya. Sayangnya, itu membuatnya sangat sulit untuk berbagi data antara dua "host" secara konsisten. Hal-hal seperti nfs, cifs, dll. digunakan untuk ini dan mendukung pemetaan uid dan gid -- saya pikir mungkin ada paralel di sini dalam memecahkan masalah. Sejujurnya, saya perlu menggali lebih dalam repo untuk mencari tahu di mana ini terjadi dalam kode dan memahaminya dengan lebih baik.

Kapan perubahan yang Anda sebutkan pada kepemilikan file akan turun? uid 0 TIDAK sama untuk wadah dan Host sebenarnya akan membuat saya merasa jauh lebih nyaman membuat titik masuk dari skrip shell root. Maka itu hanya masalah melakukan solusi yang disarankan untuk meneruskan uid/gid yang benar sebagai env dan melakukan adduser pada peluncuran kontainer.

@syncomm Sayangnya, tidak terlalu sepengetahuan saya, bukan tanpa membungkusnya dalam beberapa jenis sistem file lain yang dapat dipasang dengan pengaturan uid/gid.

Pada akhirnya ini terlihat seperti sesuatu yang memerlukan dukungan kernel untuk pemetaan ulang dua arah penuh dari UID dan GID, dan bahkan tidak terlihat mudah untuk dikelola.

Untuk skenario yang tidak sensitif terhadap kinerja, mungkin sesuatu dapat dilakukan menggunakan FUSE.

Masih memberi +1 untuk kasus penggunaan pengembangan, karena saya berakhir dengan file milik root di rumah saya.

Untuk kasus penggunaan saya, itu akan cukup jika buruh pelabuhan hanya dapat menerapkan label uid/gid dan selinux khusus ke volume Host ketika membuatnya meninggalkan izin dan label sendiri jika direktori sudah ada. Saat ini saya mengatasinya dengan memiliki titik masuk terpisah untuk gambar yang berjalan sebagai root hanya untuk memperbaiki izin volume.

@ibukanov tidak dapat menerapkan uid/gid, tetapi label selinux akan datang.

@ cpuguy83 apa alasan teknis ketidakmampuan untuk menerapkan uid/gid khusus saat membuat direktori volume Host?

@ibukanov Lihat komentar di atas.

@ cpuguy83 Saya hanya tidak melihat dari komentar apa masalahnya. Untuk kasus pengguna saya, saya tidak perlu memetakan ulang uid/gid. Saat ini di dalam wadah saat menjalankan sebagai root saya bisa chown uid:gid /host_volume && chmod 770 /host_volume . Alangkah baiknya jika buruh pelabuhan dapat melakukannya sendiri ketika membuat direktori pada Host di belakang /Host_volume. Dengan cara ini saya tidak memerlukan peretasan untuk menyediakan titik masuk tambahan dalam wadah hanya untuk melakukan operasi di atas sebagai root wadah dan selalu dapat menjalankan kode menggunakan akun non-root.

@ibukanov Ah, itu hal yang berbeda.
Docker tidak, dengan sengaja, membuat perubahan pada direktori host.
Jika kita melakukan #9092, maka jika buruh pelabuhan membuat dir, itu akan memperlakukannya seperti volume normal (yaitu, menyalin semua yang ada di jalur volume di wadah ke Host dan chmod/chown seperti di wadah).

@ cpuguy83 - yah, buruh pelabuhan memang mengubah sesuatu di Host ketika membuat volume Host yang hilang. Tapi #9092 terdengar seolah-olah itu akan menyelesaikan kasus penggunaan saya.

@cpuguy83 menulis:

Dan segera uid 0 dalam wadah tidak akan menjadi uid 0 di host... yang juga membuat kepemilikan file semakin rumit.

Apakah ada masalah yang ada untuk melacak ini? Saya tidak dapat menemukannya.

Terima kasih!

Apakah ada masalah yang ada untuk melacak ini? Saya tidak dapat menemukannya.

@dato Cari "User Namespace"; implementasi awal dapat ditemukan di sini: https://github.com/docker/docker/pull/12648 dan di sini https://github.com/docker/docker/pull/11253

Tetapi ada berbagai diskusi / masalah sebelum itu :)

+1

supaya saya tahu saya berada di kapal yang sama dengan semua orang:

Saya menggunakan gambar nginx dan memasang volume ke /usr/shared/nginx/html untuk pengembangan lokal. Nginx berjalan sebagai www-data , tetapi volume dipasang sebagai 1000:staff dan jadi saya mendapatkan 403 forbidden .

@MrMMorris Saya tidak berpikir itu perahu yang sama - masalah ini adalah ketika file yang dibuat di dalam wadah (pada volume yang dipasang) tidak dapat dibaca di luar wadah tanpa akses Sudo. Pengguna www-data Anda hanya memerlukan akses baca ke file yang di-mount sehingga Anda hanya dapat chmod a+r pada file Anda.

@ncjones chmod/chown tampaknya tidak berpengaruh pada izin di wadah

Saya sangat bingung karena saya bersumpah ini bekerja di banyak titik selama saya menggunakan ...

Baiklah ini memalukan...

Tampaknya setelah memutakhirkan ke compose 1.3.0rc-1 (mungkin tidak) ATAU menghapus semua wadah/gambar saya dan menjalankan docker-compose up lagi telah memperbaiki semuanya.... Tidak ada lagi 403 forbidden

Saya tahu itu berhasil sebelumnya, jadi saya mengambil pendekatan rm -rf * ..

Saya juga perlu masalah ini diselesaikan entah bagaimana. Saya memiliki gambar buruh pelabuhan yang saya gunakan untuk menjalankan beberapa pekerjaan kompilasi berat yang harus diisolasi. Jadi container harus naik, menerima beberapa input eksternal, proses kemudian akan menghasilkan binari (output). Tanpa manajemen izin yang tepat, ini adalah mimpi buruk yang mencoba membuat ini berfungsi. Gambar saya harus portabel jadi saya tidak bisa berasumsi banyak tentang host.

@alercunha Dalam kasus Anda, kedengarannya baik-baik saja menggunakan satu pengguna di dalam wadah buruh pelabuhan, yaitu kompilasi sebagai root

@alercunha
Kami telah mengatasi masalah ini dalam pengaturan build dengan meminta container Docker chown output build. Dockerfile kami akan berisi sesuatu seperti:

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

Uid/gid aktual dari pengguna Host Docker kemudian dapat diberikan ke wadah saat dijalankan. Misalnya, perintah build Jenkins akan menggunakan sesuatu seperti:

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

@motin Membangun sebagai root adalah sesuatu yang saya coba hindari karena saya menggunakan buruh pelabuhan/buildroot untuk membangun beberapa proyek pihak ketiga. Idenya adalah untuk memiliki perlindungan terhadap kode sumber yang mengacaukan lingkungan build saya. Jadi membangun sebagai root sepertinya bukan ide yang bagus.

@ncjones Terima kasih! Itu sebenarnya ide yang bagus, mungkin berfungsi dengan baik sebagai solusi dalam kasus khusus saya.

@alercunha Dalam hal ini mungkin perlu dipertimbangkan untuk menggunakan gambar/wadah terpisah untuk setiap proyek pihak ketiga. Itu juga bisa menguntungkan komunitas open source dengan lebih baik, misalnya jika Anda mengirimkan gambar buruh pelabuhan resmi untuk membangun setiap proyek pihak ketiga tersebut.

Untuk memberikan semua hak istimewa ke www-data, Anda dapat menggunakan:

RUN usermod -u 1000 www-data

Mengalami masalah saat menjalankan pekerjaan di buruh pelabuhan pada volume terpasang. File yang dihasilkan dimiliki oleh root dan tidak dapat dikelola oleh pengguna yang menjalankan perintah buruh pelabuhan. Solusi saat ini adalah menjalankan mengikuti setelah pekerjaan untuk memperbaiki izin.

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

apakah mungkin agar buruh pelabuhan mengubah izin volume terpasang berbasis Host untuk dimiliki oleh pengguna yang ditentukan dalam perintah USER dari DockerFile? Jelas izin harus dapat dikonfigurasi tetapi kita dapat memiliki ini memiliki perilaku default.

@mig-foxbat
Untuk tujuan saya, itu akan cukup jika buruh pelabuhan hanya menetapkan kepemilikan dan izin pada direktori Host dari titik pemasangan pada gambar ketika direktori Host dibuat untuk pertama kalinya. Jika direktori host sudah ada, buruh pelabuhan bisa membiarkannya sendiri.

@mig- foxbat & tidak diubah (seperti pada beberapa pemetaan wadah virtual yang mirip dengan apa yang dapat dilakukan dengan _NFS_).

Apa yang Anda coba lakukan dapat dengan mudah dilakukan hari ini dengan menjalankan _chown_ di beberapa skrip startup di dalam wadah Anda.

Saya suka arsitektur plug-in volume yang akan datang, tetapi saya lebih suka tim Docker menambahkan fitur ini. Docker berfungsi dengan baik hingga Anda menggunakan volume dengan pengguna non-root di wadah Anda. Kemudian ketika hal-hal (misalnya, logging) tidak berfungsi, Anda membuang laptop Anda melalui jendela Starbucks atau Anda menemukan item stackoverflow yang dirujuk di atas.

+1 Saya ingin wadah menjalankan aplikasi sebagai pengguna non-root, yang menjadi rumit karena masalah ini.

Mengapa tidak menerapkan fitur ini menggunakan kemampuan id_map LXC?

Saya baru menyadari bahwa jawaban untuk "id_map" (alias dukungan User Namespace) sudah disebutkan di atas oleh @thaJeztah

Meskipun dibutuhkan sedikit kerja ekstra untuk mengatur izin, kami menjalankan lusinan wadah sebagai non-root dan menghindari masalah izin. Sebagian besar wadah data kami dimulai dengan sesuatu seperti:
Konsul ENV CONTAINER_USER
ENV CONTAINER_UID 312312
RUN adduser -D $CONTAINER_USER -u $CONTAINER_UID
JALANKAN mkdir -p /var/consul/
CMD chown $CONTAINER_USER.$CONTAINER_USER /var/consul/

Dengan wadah run yang sebenarnya serupa dalam hal pengaturan UID/useradd info. Ini adalah beberapa pekerjaan duplikat (harus mengatur UID pada wadah data dan wadah yang dijalankan) namun cukup kecil. Memiliki izin perubahan buruh pelabuhan atau izin peta dengan cepat akan menambah beberapa kompleksitas yang layak dan pengguna harus lebih berhati-hati dari perspektif keamanan. Saya juga untuk apa pun yang membantu mengurangi kompleksitas baris perintah, jadi jika semuanya mandiri dalam dockerfile, itu sedikit lebih mudah tentang apa yang terjadi.

Sekarang ada catatan di atas untuk mencoba mengakses file Host dalam wadah dengan semacam pemetaan. Saya pikir ini tentu saja merupakan proposisi yang berisiko. Sering mencoba berbagi file tanpa pemetaan Host langsung mungkin merupakan solusi terbaik, karena jika tidak, Anda agak membalikkan keamanan buruh pelabuhan. Daripada wadah yang memiliki izin lebih sedikit daripada yang seharusnya, Anda berbicara tentang wadah yang berjalan sebagai non-root yang memiliki akses tingkat root (dianggap sering menggunakan kasus) untuk meng-host file. Izin grup atau solusi lain yang saya rasa harus menang dalam sebagian besar situasi.

Saya mengatasi ini dengan skrip shell entrypoint yang membaca direktori yang di-mount dan mengeksekusi subcommand melalui su.

Contoh dalam wadah solr tempat direktori /data dipasang sebagai volume dari Host:

#!/bin/bash

chown -R $SOLR_USER:$SOLR_USER /data

su -c "$@" -m $SOLR_USER

_POLONGAN PENGGUNA_

_Cara terbaik untuk mendapatkan notifikasi jika ada perubahan dalam diskusi ini adalah dengan mengklik tombol Subscribe di kanan atas._

Orang-orang yang tercantum di bawah ini menghargai diskusi bermakna Anda dengan +1 acak:

@jcercurati
@iangelov
@scue
@razvanphp
@hantu
@andrerocker
@anandnalya
@ddopson
@hason
@hadim
@iyn
@cgrantcharovtp
@sandytrinh
@gomex
@DrBenton
@tehmaspc
@segphault
@avaz
@edavisme
@ayeo
@stanislavb
@smebberson
@tony-kerz
@msierks
@pdonorio
@samsong8610
@qm78
@joshughes
@roelvanduijnhoven
@vladimirbright
@ava-dylang

Mengatakan apa pun di utas ini membuat pengguna berlangganan secara otomatis, jadi ya semua orang itu berlangganan kecuali mereka juga, dengan sengaja berhenti berlangganan. (juga tidak yakin _who_ yang Anda maksud sebagai your )

Ini pasti suatu keharusan. Docker harus memetakan ulang UID dengan benar. Kalau tidak, semua yang dibuat dari wadah ke volume OS Host dimiliki oleh root. Solusinya mengerikan - mengubah pengguna di dalam wadah yang mengarah ke segala macam komplikasi, harus makan di mana-mana, Dockerfile tumbuh dengan keburukan. Dan yang terburuk dari semua UID hardcoding membuat wadah tidak portabel!

+1 Fitur ini akan sangat dihargai, karena saya ingin menghindari peralihan antara wadah buruh pelabuhan dan sistem Host saya, hanya untuk menghindari menimpa id pengguna pada file.

Mendapatkan kustomisasi UID dimungkinkan saat ini, tetapi dalam batasan berikut:

  • Kustomisasi Uid dimungkinkan dengan membuat wadah menerima uid yang dibutuhkannya melalui variabel lingkungan. Ini memberi host kontrol penuh atas uid yang digunakan wadah, dan memiliki manfaat tambahan: beberapa variabel dapat disetel ke nilai uid yang sama. Pemetaan ulang Uid tidak dapat mendukung beberapa pemetaan uid penampung ke satu uid host, karena pemetaan harus 1:1. Misalnya, jika pemetaan yang diinginkan ternyata aplikasi harus dijalankan sebagai uid=0, Anda dapat melakukannya dengan menyuntikkan variabel, tetapi tidak melalui pemetaan ulang uid. Lihat @ncjones dan @mitchcapper solusi di atas.
  • Namun, root uid=0 tidak dapat diubah ke nilai yang berbeda, kecuali dengan memetakan ulang: #12648.

Hampir semua kerangka kerja pengembangan web modern memiliki folder log dan folder cache yang ada di dalam proyek, yang ditentukan dalam konfigurasi proyek dan dibagikan melalui volume yang dipasang. Saya menggunakan vboxfs terlebih dahulu tetapi terlalu lambat. Saya menemukan docker-machine-nfs untuk membuat mount NFS dan itu cepat, tetapi sekarang file web saya dalam wadah dimiliki oleh 502:dialout dan tidak dapat chmod atau chown sehingga aplikasi web saya tidak akan berjalan. Saya mencoba kotak gelandangan buruh pelabuhan tetapi membutuhkan gelandangan dengan semua env vars dan konfigurasi yang berbeda, dan belum berfungsi dengan mesin buruh pelabuhan. Bahkan jika ini adalah proses manual untuk jangka pendek, apakah ada solusi untuk menambahkan pengguna 502 ke www-data atau sesuatu? Itu saja yang saya butuhkan untuk berbisnis!

+1

Bagi yang mengikuti ini; saat ini ada PR untuk fitur eksperimental yang secara rekursif akan mengubah kepemilikan file yang dipasang di bind. Ini harus digunakan dengan hati-hati, karena fitur itu akan mengubah file di host (yang mungkin tidak seperti yang Anda inginkan dalam semua kasus); lihat https://github.com/docker/docker/pull/14632 (dan https://github.com/docker/docker/pull/16767)

+1

Omong-omong, saya memecahkan masalah ini dengan menggunakan ACL

@kvaps , mau menjelaskan?

@posita , taruhan saya adalah @kvaps berbicara tentang POSIX ACLs . Jika saya benar, itu tidak sama dengan permintaan OP.

@posita , @denydias , maaf untuk jawaban yang panjang. Ya, saya berbicara tentang ini.
Saya memiliki banyak wadah seperti owncloud, samba dan minidlna. Setiap orang bekerja dengan uid dan gid yang berbeda.
Mereka semua beroperasi dengan file yang sama. Apa yang semua orang dapat membaca dan menulis file, saya memasang sistem file dengan opsi acl ke mesin Host, dan memberi semua orang hak uid dan gid untuk file ini dengan sederhana, seperti perintah chown :

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

@kvaps , perintah setfacl tidak berfungsi di Dockerfile . Contoh:

FROM nginx

ADD data/conf /etc/nginx

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

VOLUME /etc/nginx

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

Hasil:

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

ACL hanya berfungsi setelah dipasang pada mesin Host dan menjalankan setfacl . Versi buruh pelabuhan:

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

Ini sangat mudah dilakukan dengan benar, dan juga sangat mudah untuk dikacaukan. Jadi jangan mengacaukannya!
Cara yang tepat untuk melakukannya adalah: Pertama kali container dijalankan, host menginjeksi uid mana yang harus digunakan container (seperti yang sudah dijelaskan di atas).
Cara yang lebih buruk untuk melakukan ini adalah: mengharapkan wadah untuk memaksakan persyaratan uidnya pada Host. Ini salah, salah, salah. Misalnya, pertimbangkan dua wadah yang berbagi mount yang sama: satu wadah menulis file untuk dilayani, dan wadah lain menjalankan httpd untuk melayani file. Sekarang, jika kedua wadah ini memiliki definisi yang bersaing untuk uid, sistem ini paling buruk akan rusak, atau paling tidak kekurangan. ACL yang disetel tidak akan masuk akal bagi host, dan kemungkinan besar akan lebih lebar dari yang diperlukan, yang berarti sekarang menjadi masalah keamanan. Tolong jangan lakukan ini!! Lakukan dengan cara yang benar.

Sepakat. Meninggalkan pemetaan antara UID ke wadah adalah solusi yang cukup baik. Hanya ingin buruh pelabuhan itu memimpin dengan memberi contoh, dan mendukung pemetaan UID/GID seperti itu di gambar buruh pelabuhan resmi.

Dipecahkan saat run time, tanpa harus chown .

Saya telah menggunakan sesuatu yang dekat dengan solusi @ncjones ', tetapi saya tidak ingin file chown karena saya tidak ingin mereka dimodifikasi di Host. Jadi saya memilih untuk mengubah UID saat startup kontainer.

Saya membuat pengguna khusus di Dockerfile :

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

Saya mendefinisikan skrip startup di Dockerfile :

CMD ["/run.sh"]

Saya memiliki baris ini di skrip /run.sh :

usermod -u $USER_ID username

Sekarang saya dapat memilih USER_ID saat container dimulai:

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

Berhasil menyelesaikan ini menggunakan args dockerfile baru. Tidak perlu melakukan sesuatu yang istimewa setelah wadah dibuat, jadi saya pikir saya akan membagikannya. (Memerlukan Docker 1.9)

Di Dockerfile:

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

Kemudian untuk membangun:

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

Selebihnya normal :)

Sunting:
saya menulis posting ini pada masalah yang salah (itu yang lain terkait dengan boot2docker).
Maaf.

@pa-de-solminihac usermod -u $USER_ID username akan mengubah id pengguna username dan akan memicu perubahan kepemilikan file di HOME username , tetapi setiap file sebelumnya dimiliki oleh username luar RUMAHnya mungkin akan menjadi tidak dapat dibaca/tidak dapat ditulis karena sekarang milik pengguna yang berbeda

@riquito Saya menggunakannya dengan pengguna khusus, dibuat di Dockerfile :

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

Oleh karena itu tidak ada file yang sebelumnya dimiliki oleh username . Jadi saya rasa tidak ada masalah ;)

FYI, setfacl _not_ bekerja pada volume yang menelusuri kembali ke OS X:

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

(Dalam hal ini, /opt/test -host dari OS X melalui mesin Docker dan Boot2Docker. Lihat juga boot2docker/boot2docker#581.)

@posita Apakah Anda menggunakan virtualbox untuk meng-host gambar boottodocker Anda? Jika demikian, itu mungkin sebenarnya merupakan batasan dengan cara virtualbox melakukan folder bersama. Saya mengalami banyak masalah dalam melakukan segala jenis permeabilitas reguler melalui folder bersama kotak virtual.

@ava-dylang, itu poin yang bagus. Di atas adalah melalui Mesin Docker dengan driver Parallels , yang menggunakan implementasi folder bersama asli Parallels, yang tampaknya juga terbatas. (Lihat juga ini https://github.com/docker/machine/issues/13#issuecomment-164320881 mengenai proposal untuk jenis lingkungan tersebut.)

FWIW, saya mengalami masalah dengan kepemilikan file di utilitas saya, Scuba .

Saya mengatasi masalah ini dengan menambahkan skrip "init" yang membuat pengguna di wadah dengan UID/GID yang sama dengan pengguna yang memanggil di Host. Lihat JonathonReinhart/scuba#11 dan JonathonReinhart/scuba#13.

Sekarang file yang dibuat dalam wadah terlihat persis seperti yang dibuat di host.

_Update:_ Itu menyebabkan masalah (JonathonReinhart/scuba#22). Saya malah memperbaikinya dengan membuat /etc/passwd dan teman-teman saya sendiri, berdasarkan uid/gid dari pengguna Host, dan menyuntikkannya ke dalam wadah (lihat JonathonReinhart/scuba#24).

+1

Untuk membuatnya lebih mudah dipelihara dan aman saat host berjalan dalam mode multi-tenant.

Saya memiliki masalah izin dengan pemasangan Wordpress seperti itu, ketika Anda membagikan seluruh Wordpress dari Host ke wadah dengan volume.

Di tumpukan saya, saya memiliki gambar dasar, yang merupakan debian dengan modifikasi dasar saya dan setiap gambar lainnya akan dibuat dari gambar ini.

Pada gambar dasar, saya memiliki bagian ini:

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

www-data tidak dibuat oleh instalasi php atau nginx. Ini adalah pengguna/grup yang ditentukan secara default di Debian dan mungkin distro lain. Beberapa PHP, instalasi Nginx menyarankan untuk menggunakan pengguna ini di file konfigurasi mereka.

Jika UID/GID pengguna host Anda adalah 500 (UID/GID pengguna non-root pertama linux pertama adalah 500 atau 1000), maka skrip ini mengubah UID/GID pengguna www-data menjadi 500 dari 33. Dengan cara ini jika Anda membagikan apa pun dari Host, Docker menganggap file dan folder itu milik pengguna www-data !

Dalam file pengaturan PHP-FPM Anda, atur pengguna dan grup ke www-data juga.

Di nginx Dockerfile Anda, Anda juga harus mengatur ini:

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

Dengan cara ini pengguna nginx dapat mengakses file yang dimiliki oleh www-data (Anda dapat menentukan nama pengguna nginx di file konfigurasi nginx).

Setelah peretasan ini, instalasi Wordpress saya tidak memiliki masalah izin APAPUN! Semua file berada di host + memperbarui Wordpress berfungsi dengan sempurna!

@DJviolin Saya tidak yakin bahwa masalah seperti ini adalah tempat yang tepat untuk tutorial Wordpress, dan saya ragu untuk menjelaskannya di sini. Namun, untuk pemula yang malang yang entah bagaimana mungkin tersandung pada ini:

  1. Apa yang Anda posting membuat banyak asumsi tentang instalasi - yaitu nilai UID/GID, nama pengguna dan grup, dll. Ini tidak terlalu portabel di seluruh distribusi.
  2. Lebih penting lagi, memberikan akses world-writable ( 0777) ke seluruh instalasi Wordpress Anda sangat berbahaya, dan secara eksplisit direkomendasikan untuk tidak dilakukan dalam dokumentasi WP resmi. Selain itu, dengan semua ini dipasang dari host, Anda baru saja mengizinkan unggahan sewenang-wenang dari Internet untuk menulis ke sistem file _host_.

@jantman Maaf, saya buruk. Sepertinya peretasan pertama memecahkan masalah izin juga. Tidak perlu mengubah izin default apa pun.

Jelas setiap orang perlu mengetahui pengguna host mereka UID:GID dan mengubah konfigurasi sesuai dengan ini. Plus terhubung dengan pengguna yang sudah ada atau baru dalam pencarian. Milik saya adalah contoh kerja untuk tumpukan hidup.

Sampai buruh pelabuhan tidak memberikan solusi untuk masalah ini, asumsi akan tetap ada.

Solusi saya sama dengan @JonathonReinhart atau @pa-de-solminihac.

Anda dapat melakukan ini dengan membuat volume lokal, itu baru saja mendarat di master https://github.com/docker/docker/pull/20262 .

Menutup ini sebagai tetap.

Hai, saya juga harus membuat solusi di dockerfile saya:

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

dan kemudian di start.sh

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

Karena $USER_ID dapat disuntikkan sebagai parameter lingkungan, dimungkinkan untuk menggunakan gambar buruh pelabuhan itu tanpa modifikasi.

Bagaimanapun saya pikir harus ada lebih banyak fungsionalitas bawaan untuk hal-hal semacam itu dan saya bertanya-tanya bagaimana cara menggunakan volume lokal yang disarankan oleh

@keywan-ghadami Saya juga bingung dengan volume lokal. Masalahnya adalah Anda harus membuat sistem file terlebih dahulu (atau menggunakan tmpfs). Jadi tidak menggunakan /var/lib/docker. Sebenarnya Anda tidak dapat menggunakan sub-direktori dari _any_ FS yang ada karena bind mount tidak mendukung opsi uid . Saya tidak tahu untuk apa volume lokal; anda dapat membuat dan memasang FS sendiri dan kemudian menggunakan volume Host normal ( -v my-created-fs:container-mount-point ).

Saya cukup terlambat ke utas ini tetapi apakah masalah ini telah diselesaikan? Ini tidak 100% jelas dari semua masalah berbeda yang dirujuk di sini. @brthor tampaknya memiliki solusi terbaik dari apa yang saya lihat tetapi melibatkan opsi baris perintah yang dapat dengan lebih mudah ditambahkan ke Dockerfile dan dilakukan di belakang layar.

Bagi saya, hard-coding UID dan GID adalah ide yang buruk untuk portabilitas antar lingkungan dan saya tidak melihat kebutuhan untuk menambahkan argumen baris perintah setiap kali saya mem-boot sebuah wadah atau membuat gambar ketika itu bisa menjadi opsi sederhana di file docker. Mungkinkah tidak ada opsi sederhana di Dockerfile atau mungkin melalui docker-compose.yml di mana Anda dapat menentukan semacam opsi "peta uid dari Host"?

Mungkin sudah ada solusi yang bagus di luar sana, tetapi saya tidak dapat mengetahuinya dari dokumentasi atau utas ini.

Terima kasih @alvinchevolleaux Saya dapat mengonfirmasi bahwa kami telah menggunakan solusi yang saya posting di atas di CI untuk https://github.com/dotnet/cli berhasil selama berbulan-bulan sekarang.

Rekomendasikan!

@brthor Ya, itulah yang saya export USER_ID=$(id -u) ke .bash_profile saya sehingga semuanya otomatis untuk berbagai lingkungan saya. Terimakasih banyak.

Seperti yang dibahas di atas, saat berbagi konten dari folder beranda ke dalam wadah, tambahkan akun pengguna dengan UID yang sama dengan milik Anda. Berikut adalah trik untuk mengatasi jika UID Anda tidak 1000. Saya berasumsi bahwa setiap pengguna membuat gambar buruh pelabuhannya sendiri dari Dockerfile.

Dockerfile harus berisi:

RUN useradd --uid 1000 -m vagrant
USER vagrant

Konstanta 1000 diganti dengan UID Anda yang sebenarnya menggunakan _git filter_. Jalankan yang berikut ini di host Anda:

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

Terakhir, tambahkan file .gitattributes untuk menerapkan filter git:

Dockerfile filter=uidfix

Ini berfungsi dengan mengganti 1000 dengan UID Anda yang sebenarnya saat Anda checkout Dockerfile dengan _smudging_ file. Git akan _clean_ file (menempatkan kembali 1000 ) ketika Anda melakukan. Perintah apa pun yang dijalankan dalam wadah dijalankan sebagai pengguna vagrant dengan UID yang benar.

Jahitan tiket ini harus dibuka kembali karena semua solusi yang diberikan di sini hanya solusi
Saya menemukan solusi terdokumentasi yang baik dan lebih lengkap di https://github.com/rocker-org/rocker/blob/master/rstudio/userconf.sh
Ini menggunakan argumen runtime yang memungkinkan untuk menggunakan gambar prebuild yang tidak mungkin dilakukan dengan filter git

@calavera Saya tidak mengerti solusi Anda.

misalnya

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

Ketika saya melihat di direktori /tmp/test tidak ada file. Sepertinya folder /tmp/test tidak sedang dipasang di wadah... Melainkan membuat volume wadah. Yang tidak benar-benar ingin saya inginkan.

Saya tidak dapat menemukan dokumentasi yang memberi tahu saya opsi --opt yang valid. Jadi saya benar-benar menebak bagaimana ini seharusnya bekerja.

Silakan buka kembali masalah ini. Driver lokal baru tampaknya sama sekali tidak mengatasi masalah pemasangan direktori Host lokal dengan id pengguna yang dipilih.

@calavera
Bisakah Anda memberi komentar tentang bagaimana kami dapat menyelesaikan masalah file yang dijatuhkan sebagai root dengan volume host lokal? Saya telah melihat masalah ini sering muncul, terutama ketika menggunakan buruh pelabuhan untuk skenario CI.

Melihat PR yang ditautkan, saya tidak melihat sesuatu yang jelas, tetapi saya yakin saya melewatkan sesuatu

Saya telah menggunakan variasi solusi ini di wadah saya, seperti docbill/docker-force . Namun, menurut saya solusi yang lebih bersih adalah wadah yang hanya bertanggung jawab untuk melakukan squashroot ...

Menggunakan sesuatu seperti bindfs untuk lokal akan membantu. Anda dapat menjalankannya dengan -o map=$(id -u)/root:@$(id -g)/ @root (dengan asumsi tidak ada ruang nama pengguna) dan Anda akan melihat file sebagai milik Anda di luar wadah saat dimiliki oleh akar di dalamnya.

@ktosiek Terima kasih, sepertinya itu memiliki potensi. Bisakah Anda memposting contoh lengkap sesi perintah atau konsol docker run ?

Bisakah seseorang memposting pembaruan status tentang masalah ini: apakah itu ditutup sebagai "tidak akan diperbaiki" atau apakah ini benar-benar telah diterapkan? Utasnya cukup panjang, jadi mohon maafkan saya karena tidak dapat melihat sekilas apa resolusinya.

@quinncomendant lihat https://github.com/docker/docker/issues/7198#issuecomment -191990887
Laporkan jika tidak berhasil.

Terima kasih @LK4D4.

Untuk meringkas, masalah ditutup dengan perbaikan yang memungkinkan mount opts untuk driver volume local .

Sejauh yang saya tahu, tidak ada opsi untuk mengatur user:group dari _host-directory yang dipasang sebagai volume_ (tolong perbaiki saya jika opsi itu ada — itulah yang saya pelajari di sini).

@quinncomendant benar; ketika mengikat-mount direktori Host Anda ingin wadah menggunakan file yang ada apa adanya, yang mencakup izin. Jika Anda ingin mengubah izin tersebut, Anda harus melakukannya di host, sebelum mengikatnya

@quinncomendant Atau dalam istilah yang lebih sederhana ini TIDAK AKAN MEMPERBAIKI.... Karena
solusi yang diberikan tidak benar-benar melakukan apa pun untuk mengatasi masalah tersebut
dilaporkan, juga tidak ada rencana untuk memecahkan masalah itu.

Pada 6 Juli 2016 pukul 17:20, Sebastiaan van Stijn [email protected]
menulis:

@quinncomendant https://github.com/quinncomendant benar; Kapan
mengikat-mount direktori Host Anda ingin wadah menggunakan file yang
apakah ada apa adanya, yang mencakup izin. Jika Anda ingin mengubahnya
izin, Anda harus melakukannya di Host, sebelum mengikatnya


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/docker/docker/issues/7198#issuecomment -230909967, atau bisu
benang
https://github.com/notifications/unsubscribe/ADBcWLihVjI1FoSMLKu7DyhwFOpGX0KKks5qTBwMgaJpZM4CQMjR
.

Ini tampaknya menjadi masalah yang TIDAK AKAN PERBAIKI. Sepertinya aspek _pengembangan_ penampung terus diabaikan dan masih mengharuskan kita menulis peretasan.

Saya secara khusus menemukan masalah ini karena pengembang yang saya dukung menjalankan file proyek yang menghasilkan perintah dari dalam wadah dan keluar ke volume yang dipasang Host (menginstal alat ini di Host sepenuhnya mengalahkan tujuan menggunakan wadah, bukan?).

Mereka ingin dengan cepat beralih pada file-file ini, namun seperti yang ditunjukkan oleh orang lain di utas ini, mereka ditulis sebagai uid/gid wadah berjalan, yang mengharuskan mereka untuk dikunyah dengan benar pada Host untuk dimanipulasi lebih lanjut (oleh IDE misalnya).

Benar-benar perlu ada cara _docker spesifik_ untuk shim dalam uid/gid sementara dalam kasus semacam ini.

@boj Ini adalah skenario persis yang saya Scuba . Solusi saya saat ini membuat, selama startup, pengguna dalam wadah dengan uid/gid yang sama dengan pengguna Host. Ini bukan solusi yang paling sederhana, tetapi itu bekerja dengan baik.

@JonathonReinhart Terima kasih, Anda memberi saya sedikit inspirasi.

Saya akhirnya menulis pembungkus skrip yang dipanggil dari Host seperti ini (mereka menggunakan Django dalam kasus ini):

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

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

@boj Masalah potensial dengan solusi itu ( -u $(id -u):$(id -g) ) adalah tidak ada entri di /etc/passwd atau /etc/group untuk uid/gid itu dalam wadah: https://github .com/JonathonReinhart/scuba/issues/11

@JonathonReinhart Tercatat. Dalam kasus khusus ini saya hanya peduli dengan file yang ditulis ke host pengembang dan mereka memiliki izin yang sama dengan pengguna host.

Tidak perlu khawatir tentang apa yang sebenarnya terjadi saat runtime, hanya ini yang benar-benar saya butuhkan.

@JonathonReinhart

Jika perangkat lunak dalam wadah memerlukan entri di /etc/passwd atau /etc/group, buatlah entri tersebut dapat ditulis oleh dunia dalam gambar dan kemudian tambahkan entri yang diperlukan di sana saat startup.

Jadi solusi yang disebutkan oleh @JonathonReinhart (pemetaan uid/gid) menyelesaikan ini.

Sepertinya ini sudah didukung di runc (https://github.com/opencontainers/runc/blob/8c9db3a7a5145f6b26c8051af319eee6f72c9ca8/libcontainer/configs/config.go#L19-24). Di Docker ada konfigurasi userns-remap untuk deamon, di sini kita pada dasarnya perlu membuatnya lebih halus (tingkat wadah alih-alih tingkat deamon), apakah ada minat/rencana untuk mendukung ini?

docker-compose.yml ini tidak berfungsi:

version: '2'

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

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

Seseorang dapat memberitahu saya mengapa? Saya mengikuti pedoman resmi: https://docs.docker.com/engine/reference/commandline/volume_create/#/driver -specific-options

Apakah mungkin untuk melampirkan volume bernama dari Host? Dengan driver_opts Anda dapat mendefinisikan uid (dan mungkin gid ?).

+1

+1

@lazyuser @xiaods Tolong hentikan dengan +1. Itu tidak menghasilkan apa-apa selain mengirim spam ke semua ---> peserta itu.

@bamarni Ya, saya pikir fitur ruang nama pengguna baru dapat menyelesaikan ini, tetapi seperti yang Anda katakan, itu perlu diterapkan per wadah. Hasil akhirnya adalah: Sebuah wadah berjalan seperti yang dianggapnya sebagai "root", tetapi sebenarnya UID/GID yang diteruskan pada baris perintah docker run . File akan "keluar" dari wadah yang dimiliki oleh pengguna yang sesuai saat itu.

@lazyuser @xiaods @JonathonReinhart Anda sebaiknya mengklik tombol +1 di bawah deskripsi masalah

Atau klik subscribe di sebelah kanan jika hanya ingin notifikasi...

@JonathonReinhart : pasti, saya telah memeriksa dokumen lagi tetapi sayangnya memiliki pemetaan daemon-lebar alih-alih per-wadah adalah keputusan sadar karena batasan:

Catatan: Pembatasan pemetaan per-daemon tunggal berlaku untuk saat ini karena Docker membagikan lapisan gambar dari cache lokalnya di semua wadah yang berjalan pada instance mesin. Karena kepemilikan file harus sama untuk semua wadah yang berbagi konten lapisan yang sama, keputusan dibuat untuk memetakan kepemilikan file pada tarikan buruh pelabuhan ke pengguna daemon dan pemetaan grup sehingga tidak ada penundaan untuk menjalankan wadah setelah konten diunduh. Desain ini mempertahankan kinerja yang sama untuk tarikan buruh pelabuhan, dorongan buruh pelabuhan, dan startup kontainer seperti yang diharapkan pengguna dengan ruang nama pengguna dinonaktifkan.

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

Dear @JonathonReinhart , @pa-de-solminihac dan @nalipaz ,
Terima kasih atas upaya Anda untuk mendidik saya dan orang lain untuk tidak meninggalkan komentar yang tidak terkait dengan masalah ini dengan melakukan hal itu! FYI, Github tidak mengizinkan pencarian masalah yang menjadi langganan seseorang tanpa setidaknya mengomentarinya. Untuk informasi lebih lanjut, lihat https://github.com/isaacs/github/issues/283. Ironisnya, masalah Github hampir seusia dengan masalah Docker, dan keduanya tampaknya diprioritaskan dengan cara yang sama.

Untuk semua, maaf untuk spamming. Pertama kali itu adalah solusi untuk bug github yang disebutkan di atas, dan kali ini saya tidak bisa menahan diri untuk memberikan ironi dari situasi tersebut.

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 menyadarinya, itu 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.

@codekitchen-ws Peringatan lain: File dapat dipindahkan setelah dibuat dan sebelum pemiliknya berubah. Bergantung pada Shell, Anda juga ingin mengutip "$f" (untuk mencegah pemisahan kata di jalur).

+1

@briansrepo Itu pendekatan yang menarik. Jika ini ada dalam pernyataan Dockerfile RUN , yang dijalankan pada waktu pembuatan. Bagaimana itu bisa mengetahui pengguna docker run pada waktu eksekusi?

@btiernay Terima kasih! Itu tidak menggunakan UID pengguna yang mengaktifkan gambar. Ini secara khusus menyalin pengguna Host dan grup Host dari direktori Host apa pun yang dipasang di /mount. Itu tidak melihat file atau subdirektori lain. Terserah pengguna untuk memastikan izin diatur ke sesuatu yang dapat mereka tulis di sistem host.

Contoh: Asumsikan direktori host /var/www/html dimiliki oleh brian:www-data. Anda meluncurkan gambar yang memasang direktori sistem host /var/www/html di direktori gambar /mount. Kemudian Anda membuat /mount/index.html dari dalam gambar. Jika Anda memeriksa kepemilikan /var/www/html/index.html pada sistem host, itu akan dimiliki oleh brian:www-data.

Berdasarkan contoh itu, katakanlah Anda memiliki direktori host /var/www/html/upload yang dimiliki oleh www- data:www-data. Perlu diingat direktori Host yang di-mount /var/www/html masih dimiliki oleh brian:www-data. Sekarang masuk ke gambar dan buat /mount/upload/file.pdf. Jika Anda memeriksa file Host /var/www/html/upload/file.pdf itu akan dimiliki oleh brian:www-data , bukan www- data:www-data , karena direktori Host yang di-mount /var/www/html adalah dimiliki oleh brian:www-data. Masuk akal?

TL;DR: Anda meneruskan pengguna:grup yang ingin Anda gunakan dengan membuka direktori Host yang dipasang ke pengguna:grup.

@briansrepo terima kasih atas penjelasannya. Itu semua masuk akal tetapi masih tidak mengerti bagaimana ini bisa bekerja di dalam RUN . Saya pikir ini perlu dijalankan di latar belakang ketika wadah dijalankan (yaitu docker run ).

@btiernay Saya suka ide ini juga.
@briansrepo setidaknya mencakup apa yang terjadi dari wadah.
Proses pembuatan masih dapat diatasi dengan sesuatu seperti

RUN usermod -u 1000 www-data

Ini masih merupakan solusi.

Di tumpukan LEMP saya, saya memiliki prakonfigurasi Nginx ini di Dockerfile dasar saya:

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

Ini adalah peretasan di mana setiap file yang baru dibuat dari sesi host ssh mendapatkan uid, gid 500 dan nginx tidak akan memiliki akses ke file-file itu pada akhirnya (karena pengguna atau grup dengan id 500 tidak ada dalam wadah). Anda dapat memeriksa uid, nomor gid mana yang harus Anda buat untuk pengguna www-data Anda ketika Anda menyalin file baru ke volume bersama di Host dari sesi ssh dan kemudian Anda docker exec ke dalam wadah ini dan melihat file uid, gid.

Masalah yang saya temukan, jika saya menyalin file baru ke folder bersama di mesin Host (yang Anda akses dengan sesi ssh, seperti dalam instance CoreOS di DigitalOcean), Nginx tidak memiliki akses ke file yang baru dibuat itu. Jadi jika Anda ingin kompatibilitas mutlak dengan hak istimewa, Anda harus membagikan file server web Anda ke dalam wadah Docker saat membuat wadah (setidaknya ini terjadi 1 tahun yang lalu, ketika saya mengalami masalah uid, gid ini dengan volume bersama) .

ATAU Anda juga dapat menginstal layanan ssh ke dalam wadah buruh pelabuhan yang membagikan file ke wadah nginx, dengan cara ini jika Anda menyalin/memodifikasi file, mereka mendapatkan uid yang benar, gid. Tetapi ini bertentangan dengan praktik terbaik Docker bahwa Anda harus menggunakan docker inspect alih-alih sesi ssh, karena "Docker bukan VM" (itu akan menjadi solusi yang terlalu mudah, bukan?).

Dalam pemikiran saya, wadah Docker harus bertindak seperti sebagai layanan atau yang dapat dieksekusi dan tidak boleh menyandera file server web saya jika saya tidak mau. Basis data adalah hal yang berbeda (kadang-kadang), tetapi saya tidak mengerti mengapa tidak mungkin untuk mencapai infrastruktur wadah cawan suci yang sama, di mana semua file statis, server web, basis data Anda tinggal di luar wadah (tetapi wadah bisa memodifikasinya (seperti menghapus, membuat, memodifikasi) dan Anda juga dapat memodifikasinya tanpa masalah hak istimewa dari host.

Dengan docker volume create --opt Anda dapat mendefinisikan uid, gid, tetapi itu tidak benar untuk docker-compose : https://github.com/docker/compose/issues/3715

Kami benar-benar membutuhkan solusi masuk ke (bukan gosu) lintas platform untuk memetakan uid/gid. Masalah ini saja menyebabkan kerusakan besar pada bagaimana buruh pelabuhan dirasakan oleh para pemula.

Kami telah membuat solusi untuk masalah ini yang mengubah izin pengguna/grup dan file wadah Docker yang ditetapkan pada waktu pembuatan ke UID/GID tempat wadah dimulai saat runtime.

Proyek dan instruksi pemasangan ada di: https://github.com/boxboat/fixuid

Contoh: Wadah Docker dibangun menggunakan pengguna/grup dockeruser:dockergroup sebagai UID/GID 1000:1000 . Host berjalan sebagai UID/GID 1001:1002 . Gambar dijalankan dengan docker run -u 1001:1002 . fixuid akan:

  • ubah dockeruser UID menjadi 1001
  • ubah dockergroup GID menjadi 1002
  • ubah semua izin file untuk dockeruser:dockergroup menjadi 1001:1002
  • perbarui $HOME di dalam wadah menjadi dockeruser $HOME
  • sekarang wadah dan host UID/GID cocok dan file yang dibuat dalam wadah di host mount akan cocok

Itu dapat berjalan sebagai ENTRYPOINT atau sebagai bagian dari skrip startup. Itu diinstal dalam wadah sebagai biner yang dimiliki oleh root dengan bit setuid , dan meningkatkan hak istimewa untuk membuat perubahan yang sesuai. Seharusnya hanya digunakan dalam wadah pengembangan.

Jika ini terbukti berguna, Mesin Docker mungkin dapat menggabungkan beberapa atau semua logika melalui flag di docker run

Dipecahkan dengan menggunakan docker volume .

@hashar bagaimana? bisa kasih contohnya pliss

jadi apakah masih belum ada solusi untuk ini selain menggunakan gosu dan skrip entrypoint?!

Untuk saat ini, sepertinya ada 2 opsi sebagai solusi untuk ini, hingga tim Docker membuat pembaruan resmi tentang ini.

Sayang sekali bahwa ini masih menjadi masalah. Secara teori ada userns-remap tetapi tidak ramah pengguna.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat