Saya memiliki aplikasi yang menjalankan berbagai hal menyenangkan dengan Git (seperti menjalankan git clone & git push) dan saya mencoba untuk merevisinya.
Saya mengalami masalah meskipun di mana saya harus dapat menambahkan kunci SSH ke wadah untuk 'pengguna' wadah untuk digunakan.
Saya mencoba menyalinnya ke dalam /root/.ssh/
, mengubah $HOME
, membuat bungkus git ssh, dan masih belum berhasil.
Berikut adalah Dockerfile untuk referensi:
#DOCKER-VERSION 0.3.4
from ubuntu:12.04
RUN apt-get update
RUN apt-get install python-software-properties python g++ make git-core openssh-server -y
RUN add-apt-repository ppa:chris-lea/node.js
RUN echo "deb http://archive.ubuntu.com/ubuntu precise universe" >> /etc/apt/sources.list
RUN apt-get update
RUN apt-get install nodejs -y
ADD . /src
ADD ../../home/ubuntu/.ssh/id_rsa /root/.ssh/id_rsa
RUN cd /src; npm install
EXPOSE 808:808
CMD [ "node", "/src/app.js"]
app.js
menjalankan perintah git like git pull
Jawaban:
Ini masalah yang lebih sulit jika Anda perlu menggunakan SSH saat membangun. Misalnya jika Anda menggunakan
git clone
, atau dalam kasus sayapip
dannpm
untuk mengunduh dari repositori pribadi.Solusi yang saya temukan adalah menambahkan kunci Anda menggunakan
--build-arg
bendera. Kemudian Anda dapat menggunakan--squash
perintah eksperimental baru (ditambahkan 1,13) untuk menggabungkan lapisan sehingga tombol tidak lagi tersedia setelah penghapusan. Inilah solusi saya:Bangun perintah
Dockerfile
Pembaruan: Jika Anda menggunakan Docker 1.13 dan memiliki fitur eksperimental pada Anda dapat menambahkan
--squash
ke perintah build yang akan menggabungkan lapisan, menghapus kunci SSH dan menyembunyikannyadocker history
.sumber
id_rsa.pub
file karena tidak diperlukan.$(openssl rsa -in ~/.ssh/id_rsa)
bukanTernyata saat menggunakan Ubuntu, ssh_config tidak benar. Anda perlu menambahkan
ke Dockerfile Anda agar bisa mengenali kunci ssh Anda.
sumber
RUN echo " Host example.com" >> /root/.ssh/config RUN echo " User <someusername>" >> /root/.ssh/config
Kunci ssh tetap tersimpan di dalam gambar, bahkan jika Anda menghapus kunci dalam perintah lapisan setelah menambahkannya (lihat komentar di posting ini ).
Dalam kasus saya ini tidak apa-apa, jadi ini yang saya gunakan:
sumber
Jika Anda menggunakan buruh pelabuhan menulis pilihan mudah adalah untuk meneruskan agen SSH seperti itu:
sumber
SSH_AUTH_SOCK
adalah variabel, yang berisi path ke ssh-agentSSH_AUTH_SOCK
blog.joncairns.com/2013/12/understanding-ssh-agent-and-ssh-add$SSH_AUTH_SOCK
, Anda harus me-mount path ini -/run/host-services/ssh-auth.sock
.Memperluas jawaban Peter Grainger saya dapat menggunakan multi-stage build yang tersedia sejak Docker 17.05. Status halaman resmi:
Ingatlah ini di sini adalah contoh saya
Dockerfile
termasuk tiga tahap membangun. Ini dimaksudkan untuk membuat gambar produksi aplikasi web klien..dockerignore
mengulangi isi.gitignore
file (mencegahnode_modules
dan mengakibatkandist
direktori proyek tidak disalin):Contoh perintah untuk membuat gambar:
Jika kunci SSH pribadi Anda tidak memiliki frasa sandi, cukup tentukan
SSH_KEY_PASSPHRASE
argumen kosong .Begini Cara kerjanya:
1). Pada tahap pertama saja
package.json
,yarn.lock
file dan kunci SSH pribadi disalin ke gambar perantara pertama bernamasources
. Untuk menghindari frasa sandi kunci SSH yang diminta, secara otomatis ditambahkanssh-agent
. Akhirnyayarn
perintah menginstal semua dependensi yang diperlukan dari NPM dan klon repositori private git dari Bitbucket melalui SSH.2). Tahap kedua membangun dan memperkecil kode sumber aplikasi web dan menempatkannya di
dist
direktori gambar perantara berikutnya bernamaproduction
. Perhatikan bahwa kode sumber yang diinstalnode_modules
disalin dari gambar bernamasources
diproduksi pada tahap pertama oleh baris ini:Mungkin itu juga bisa menjadi baris berikut:
Kami hanya memiliki
node_modules
direktori dari gambar perantara pertama di sini, tidak adaSSH_KEY
danSSH_KEY_PASSPHRASE
argumen lagi. Semua yang dibutuhkan untuk membangun disalin dari direktori proyek kami.3). Pada tahap ketiga kami mengurangi ukuran gambar akhir yang akan ditandai sebagai
ezze/geoport:0.6.0
dengan hanya memasukkandist
direktori dari gambar perantara kedua bernamaproduction
dan menginstal Node Express untuk memulai server web.Listing gambar memberikan output seperti ini:
di mana gambar yang tidak di-tag terhubung ke tahap pembuatan lanjutan pertama dan kedua.
Jika Anda berlari
Anda tidak akan melihat menyebutkan dari
SSH_KEY
danSSH_KEY_PASSPHRASE
pada gambar akhir.sumber
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
tetapi ketika saya memeriksa di RUN lain atau bahkan di RUN yang sama perintah dengan melakukanssh-add -l
itu memberitahu saya bahwa "Agen tidak memiliki identitas". Mulai mencabut rambut saya, ada pikiran?Untuk menyuntikkan kunci ssh Anda, dalam sebuah wadah, Anda memiliki beberapa solusi:
Menggunakan Dockerfile dengan
ADD
instruksi, Anda bisa menyuntikkannya selama proses build AndaCukup melakukan sesuatu seperti
cat id_rsa | docker run -i <image> sh -c 'cat > /root/.ssh/id_rsa'
Menggunakan
docker cp
perintah yang memungkinkan Anda untuk menyuntikkan file saat wadah sedang berjalan.sumber
apt-get install openssh-server
dan meletakkan kunci saya di /root/.ssh/id_rsa dan bekerja dengan baik. Gambar apa yang Anda gunakan?Salah satu solusi lintas-platform adalah menggunakan bind mount untuk membagikan
.ssh
folder host ke kontainer:Mirip dengan penerusan agen pendekatan ini akan membuat kunci publik dapat diakses oleh wadah. Sisi positif tambahannya adalah ia bekerja dengan pengguna non-root juga dan akan membuat Anda terhubung ke GitHub. Satu peringatan untuk dipertimbangkan, bagaimanapun, adalah bahwa semua konten (termasuk kunci pribadi) dari
.ssh
folder akan dibagikan sehingga pendekatan ini hanya diinginkan untuk pengembangan dan hanya untuk gambar kontainer tepercaya.sumber
docker build
hanya selamadocker run
docker-compose up
di Windows 10. lokal saya. Bagaimana saya harus menggunakan solusi Anda dalam skenario itu?Kontainer Docker harus dilihat sebagai 'layanan' mereka sendiri. Untuk memisahkan masalah Anda harus memisahkan fungsi:
1) Data harus dalam wadah data: gunakan volume tertaut untuk mengkloning repo. Wadah data itu kemudian dapat dihubungkan ke layanan yang membutuhkannya.
2) Gunakan sebuah wadah untuk menjalankan tugas kloning git, (yaitu hanya pekerjaan kloning) yang menghubungkan wadah data ke dalamnya ketika Anda menjalankannya.
3) Sama untuk ssh-key: letakkan itu volume (seperti yang disarankan di atas) dan tautkan ke layanan git clone saat Anda membutuhkannya
Dengan begitu, baik tugas kloning dan kuncinya adalah fana dan hanya aktif bila diperlukan.
Sekarang jika aplikasi Anda sendiri adalah antarmuka git, Anda mungkin ingin mempertimbangkan API REST github atau bitbucket secara langsung untuk melakukan pekerjaan Anda: untuk itulah mereka dirancang.
sumber
Baris ini merupakan masalah:
Saat menentukan file yang ingin Anda salin ke dalam gambar, Anda hanya dapat menggunakan jalur relatif - relatif terhadap direktori tempat Dockerfile Anda berada. Jadi, Anda sebaiknya menggunakan:
Dan letakkan file id_rsa ke direktori yang sama dengan Dockerfile Anda.
Lihat ini untuk lebih jelasnya: http://docs.docker.io/reference/builder/#add
sumber
docker cp
hanya menaruhnya di wadah dan bukan gambar, kan?Kami memiliki masalah yang sama ketika melakukan npm install di docker build time.
Terinspirasi dari solusi dari Daniel van Flymen dan menggabungkannya dengan git url menulis ulang , kami menemukan metode yang lebih sederhana untuk mengotentikasi instalasi npm dari repositori github pribadi - kami menggunakan token oauth2 alih-alih kunci.
Dalam kasus kami, dependensi npm ditentukan sebagai "git + https://github.com/ ..."
Untuk otentikasi dalam wadah, url harus ditulis ulang agar sesuai untuk otentikasi ssh (ssh: //[email protected]/) atau otentikasi token (https: // $ {GITHUB_TOKEN} @ github.com /)
Membangun perintah:
Sayangnya, saya di buruh pelabuhan 1.9, jadi --squash opsi belum ada, akhirnya perlu ditambahkan
Dockerfile:
sumber
Teruskan soket otentikasi ssh ke wadah:
Script Anda akan dapat melakukan a
git clone
.Ekstra: Jika Anda ingin file yang dikloning milik pengguna tertentu yang perlu Anda gunakan
chown
karena menggunakan pengguna lain selain root di dalam wadah akan membuatgit
gagal.Anda dapat melakukan penerbitan ini ke lingkungan kontainer beberapa variabel tambahan:
Setelah Anda mengkloning, Anda harus menjalankan
chown $OWNER_USER:$OWNER_GROUP -R <source_folder>
untuk mengatur kepemilikan yang tepat sebelum Anda meninggalkan wadah sehingga file dapat diakses oleh pengguna non-root di luar wadah.sumber
-u root:$(id -u $USER)
setidaknya memiliki file yang dimiliki oleh kelompok utama yang sama dengan pengguna Anda, yang seharusnya membuat semuanya setidaknya dapat dibaca tanpasudo
kecuali ada sesuatu yang membuatnya dengan0600
izin.-u root:$(id -u $USER)
seharusnya-g
./tmp/ssh_auth.sock: No such file or directory
sekarang itu/tmp/ssh-vid8Zzi8UILE/agent.46016
pada mesin host saya/tmp
dalam wadah Anda. Atau salah ketik pada perintah docker run. Pastikan bahwa pernyataan binding sudah benar-v $SSH_AUTH_SOCK:/tmp/ssh_auth.sock
: Urutan itu penting dan titik koma juga penting. Silakan periksa dokumentasi buruh pelabuhan untuk bantuan lebih lanjut.Seperti eczajk sudah mengomentari jawaban Daniel van Flymen itu tampaknya tidak aman untuk menghapus kunci dan menggunakan
--squash
, karena mereka masih akan terlihat dalam sejarah (docker history --no-trunc
).Sebagai gantinya dengan Docker 18.09, Anda sekarang dapat menggunakan fitur "build secrets". Dalam kasus saya, saya menggandakan repo git pribadi menggunakan kunci SSH host saya dengan yang berikut di Dockerfile saya:
Untuk dapat menggunakan ini, Anda harus mengaktifkan backend BuildKit baru sebelum menjalankan
docker build
:Dan Anda perlu menambahkan
--ssh default
parameter kedocker build
.Info lebih lanjut tentang ini di sini: https://medium.com/@tonistiigi/build-secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066
sumber
ssh-add ~/.ssh/id_rsa
dan 2) tambahkan host git ke known_hosts, yaitu untuk bitbucket:RUN ssh-keyscan -H bitbucket.org >> ~/.ssh/known_hosts
Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access and the repository exists.
Ini meskipun melewati--ssh default
flag di build docker saya, dan menggunakan--mount=type=ssh
dalam menjalankan perintah di mana sayagit clone
. Saya dapat mengkloning repo yang sama tidak ada masalah pada mesin build. Itu hanya gagal di buruh pelabuhan membangun kontainer. Saya menduga bahwa versi mac Docker sebenarnya tidak melewati klien ssh.Masalah ini benar-benar menyebalkan. Karena Anda tidak dapat menambahkan / menyalin file apa pun di luar konteks dockerfile, yang berarti tidak mungkin untuk hanya menautkan ~ / .ssh / id_rsa ke /root/.ssh/id_rsa gambar, dan ketika Anda benar-benar memerlukan kunci untuk melakukan beberapa hal sshed seperti git klon dari tautan repo pribadi ..., selama pembuatan gambar buruh pelabuhan Anda.
Bagaimanapun, saya menemukan solusi untuk menyelesaikannya, tidak begitu membujuk tetapi berhasil bagi saya.
di dockerfile Anda:
skrip yang harus dilakukan dalam satu pemotretan:
kapan saja Anda harus menjalankan sebuah wadah dari gambar ini dengan beberapa persyaratan ssh, cukup tambahkan -v untuk perintah jalankan, seperti:
run docker -v ~ / .ssh / id_rsa: /root/.ssh/id_rsa - nama perintah wadah image
Solusi ini tidak menghasilkan kunci pribadi di sumber proyek Anda dan gambar buruh pelabuhan yang dibangun, jadi tidak ada masalah keamanan yang perlu dikhawatirkan lagi.
sumber
docker cp
? Ini digunakan untuk "Menyalin file / folder antara wadah dan host Anda."docker cp
bisa melakukan triknya. Namun dalam situasi ini, saya memerlukan ssh_key selama gambar sedang dibangun, dan tidak ada wadah pada saat itu ... akan memperbarui ekspresi saya yang tidak jelas, terima kasih.Saya mengalami masalah yang sama hari ini dan sedikit memodifikasi versi dengan posting sebelumnya saya menemukan pendekatan ini lebih bermanfaat bagi saya
(Perhatikan bahwa hanya baca flag sehingga kontainer tidak akan mengacaukan kunci ssh saya.)
Di dalam wadah sekarang saya dapat menjalankan:
Jadi saya tidak mendapatkan
Bad owner or permissions on /root/.ssh/..
kesalahan yang dicatat oleh @krosssumber
ssh-agent bash -c "ssh-add..."
. Saya kemudian bisa meneruskannya ke docker. Semua contoh sebelumnya yang saya temukan digunakaneval ssh-agent
, diikuti oleh ssh-add dan saya tidak dapat menemukan cara untuk melewatkannyaeval
melalui perintah run docker.'Anda dapat secara selektif membiarkan server jauh mengakses agen ssh lokal Anda seolah-olah itu berjalan di server'
https://developer.github.com/guides/using-ssh-agent-forwarding/
sumber
Anda juga dapat menautkan direktori .ssh Anda antara tuan rumah dan wadah, saya tidak tahu apakah metode ini memiliki implikasi keamanan tetapi mungkin metode yang paling mudah. Sesuatu seperti ini seharusnya bekerja:
Ingatlah bahwa buruh pelabuhan menjalankan dengan sudo (kecuali jika Anda tidak), jika ini adalah kasus Anda akan menggunakan kunci ssh root.
sumber
Bad owner or permissions on /root/.ssh/config
.docker run
, tetapi tidak selamadocker build
.Mulai dari
docker API 1.39+
(Periksa versi API dengandocker version
) docker build memungkinkan--ssh
opsi dengan soket agen atau kunci untuk memungkinkan Docker Engine meneruskan koneksi agen SSH.Bangun Komando
Dockerfile
Info lebih lanjut:
sumber
could not parse ssh: [default=~/.ssh/id_rsa]: stat ~/.ssh/id_rsa: no such file or directory
. Gunakan jalur lengkap jika itu tidak berhasil.Jika Anda tidak peduli dengan keamanan kunci SSH Anda, ada banyak jawaban bagus di sini. Jika ya, jawaban terbaik yang saya temukan adalah dari tautan di komentar di atas ke komentar GitHub ini oleh diegocsandrim . Sehingga orang lain lebih mungkin melihatnya, dan kalau-kalau repo itu hilang, berikut adalah versi yang diedit dari jawaban itu:
Sebagian besar solusi di sini akhirnya meninggalkan kunci pribadi dalam gambar. Ini buruk, karena siapa pun yang memiliki akses ke gambar memiliki akses ke kunci pribadi Anda. Karena kita tidak cukup tahu tentang perilaku
squash
, ini mungkin masih menjadi masalah bahkan jika Anda menghapus kunci dan menekan lapisan itu.Kami membuat URL pre-sign untuk mengakses kunci dengan aws s3 cli, dan membatasi akses selama sekitar 5 menit, kami menyimpan URL pre-sign ini ke dalam file di direktori repo, kemudian di dockerfile kami menambahkannya ke gambar.
Di dockerfile kami memiliki perintah RUN yang melakukan semua langkah ini: gunakan URL pra-sing untuk mendapatkan kunci ssh, jalankan npm install, dan hapus kunci ssh.
Dengan melakukan ini dalam satu perintah tunggal kunci ssh tidak akan disimpan dalam lapisan apa pun, tetapi URL pra-tandatangan akan disimpan, dan ini bukan masalah karena URL tidak akan valid setelah 5 menit.
Skrip build terlihat seperti:
Dockerfile terlihat seperti ini:
sumber
Dalam versi selanjutnya dari buruh pelabuhan (17.05) Anda dapat menggunakan multi stage builds . Yang merupakan opsi paling aman karena bangunan sebelumnya hanya dapat digunakan oleh bangunan berikutnya dan kemudian dihancurkan
Lihat jawaban untuk pertanyaan stackoverflow saya untuk info lebih lanjut
sumber
Tinjauan singkat tentang tantangan SSH di dalam wadah Docker dirinci di sini . Untuk menghubungkan ke remote yang terpercaya dari dalam sebuah wadah tanpa membocorkan rahasia ada beberapa cara:
~/.ssh
ke wadah. (Hanya pengembangan, berpotensi tidak aman)Selain itu ada juga kemungkinan menggunakan key-store yang berjalan di wadah buruh pelabuhan terpisah yang dapat diakses saat runtime saat menggunakan Compose. Kelemahan di sini adalah kompleksitas tambahan karena mesin yang diperlukan untuk membuat dan mengelola keystore seperti Vault oleh HashiCorp .
Untuk penggunaan kunci SSH dalam wadah Docker yang berdiri sendiri lihat metode yang ditautkan di atas dan pertimbangkan kelemahan masing-masing tergantung pada kebutuhan spesifik Anda. Namun, jika Anda menjalankan di dalam Compose dan ingin membagikan kunci ke aplikasi saat runtime (mencerminkan praktik OP) coba ini:
docker-compose.env
file dan tambahkan ke file Anda.gitignore
file .docker-compose.yml
dan tambahkanenv_file
layanan yang memerlukan kunci.process.node.DEPLOYER_RSA_PUBKEY
dalam kasus aplikasi Node.js.Pendekatan di atas ideal untuk pengembangan dan pengujian dan, meskipun bisa memenuhi persyaratan produksi, dalam produksi Anda lebih baik menggunakan salah satu metode lain yang diidentifikasi di atas.
Sumber daya tambahan:
sumber
Anda dapat menggunakan multi stage build untuk membangun kontainer Ini adalah pendekatan yang dapat Anda ambil: -
Tahap 1 membangun gambar dengan ssh
Tahap 2: bangun wadah Anda
tambahkan atribut env di file penulisan Anda:
lalu berikan args dari skrip build seperti ini:
Dan lepaskan wadah perantara untuk keamanan. Ini akan membantu Anda bersorak.
sumber
Cara sederhana dan aman untuk mencapai ini tanpa menyimpan kunci Anda di lapisan gambar Docker, atau melalui senam ssh_agent adalah:
Sebagai salah satu langkah di Anda
Dockerfile
, buat.ssh
direktori dengan menambahkan:RUN mkdir -p /root/.ssh
Di bawah ini menunjukkan bahwa Anda ingin memasang direktori ssh sebagai volume:
VOLUME [ "/root/.ssh" ]
Pastikan bahwa wadah Anda
ssh_config
tahu di mana menemukan kunci publik dengan menambahkan baris ini:RUN echo " IdentityFile /root/.ssh/id_rsa" >> /etc/ssh/ssh_config
Paparkan
.ssh
direktori pengguna lokal Anda ke wadah saat runtime:docker run -v ~/.ssh:/root/.ssh -it image_name
Atau di
dockerCompose.yml
add Anda ini di bawah tombol volume layanan:- "~/.ssh:/root/.ssh"
Final Anda
Dockerfile
harus berisi sesuatu seperti:sumber
Saya mencoba mengatasi masalahnya dengan cara lain: menambahkan kunci ssh publik ke gambar. Tetapi dalam percobaan saya, saya menemukan bahwa "buruh pelabuhan cp" adalah untuk menyalin DARI wadah ke host. Butir 3 dalam jawaban dengan berderit sepertinya mengatakan Anda dapat menggunakan buruh pelabuhan untuk menyuntikkan file ke dalam wadah. Lihat https://docs.docker.com/engine/reference/commandline/cp/
kutipan
sumber
Anda bisa memasukkan kunci yang diotorisasi ke wadah Anda menggunakan folder bersama dan mengatur izin menggunakan file buruh pelabuhan seperti ini:
Dan menjalankan docker Anda berisi sesuatu seperti berikut ini untuk berbagi direktori auth pada host (memegang authorised_keys) dengan wadah kemudian buka port ssh yang akan dapat diakses melalui port 7001 pada host.
Anda mungkin ingin melihat https://github.com/jpetazzo/nsenter yang tampaknya merupakan cara lain untuk membuka shell pada wadah dan menjalankan perintah dalam wadah.
sumber
Terlambat untuk pesta, bagaimana dengan ini yang akan membuat kunci sistem operasi host Anda tersedia untuk root di dalam wadah, dengan cepat:
Saya tidak mendukung penggunaan Dockerfile untuk menginstal kunci karena iterasi wadah Anda dapat meninggalkan kunci pribadi.
sumber
Saya mencoba mencari cara menambahkan kunci masuk ke wadah untuk digunakan selama runtime (bukan membangun) dan menemukan pertanyaan ini. Rahasia Docker tampaknya menjadi solusi untuk kasus penggunaan saya, dan karena tidak ada yang menyebutkannya, saya akan menambahkannya.
sumber
Dalam kasus saya, saya punya masalah dengan nodejs dan 'npm i' dari repositori jarak jauh. Saya memperbaikinya menambahkan pengguna 'simpul' ke wadah nodejs dan 700 ke ~ / .ssh dalam wadah.
Dockerfile:
run.sh:
docker-compose.yml:
setelah itu mulai bekerja
sumber
Cara paling sederhana, dapatkan akun launchpad dan gunakan: ssh-import-id
sumber
ssh-import-id
Sepertinya itu hanya mengimpor kunci publik.Dalam wadah buruh pelabuhan yang sedang berjalan, Anda dapat mengeluarkan ssh-keygen dengan opsi buruh pelabuhan -i (interaktif). Ini akan meneruskan wadah meminta untuk membuat kunci di dalam wadah buruh pelabuhan.
sumber
Untuk debian / root / berwenang_kunci:
sumber