Apakah itu Docker: lawatan ringkas ke dalam sejarah dan abstraksi asas

Bermula pada 10 Ogos di Slurm Kursus video Docker, di mana kami menganalisisnya sepenuhnya - daripada abstraksi asas kepada parameter rangkaian.

Dalam artikel ini kita akan bercakap tentang sejarah Docker dan abstraksi utamanya: Image, Cli, Dockerfile. Kuliah ini bertujuan untuk pemula, jadi ia tidak mungkin menarik minat pengguna berpengalaman. Tidak akan ada darah, apendiks atau rendaman dalam. Yang paling asas.

Apakah itu Docker: lawatan ringkas ke dalam sejarah dan abstraksi asas

Apa itu Docker

Mari kita lihat definisi Docker dari Wikipedia.

Docker ialah perisian untuk mengautomasikan penggunaan dan pengurusan aplikasi dalam persekitaran kontena.

Tiada yang jelas daripada definisi ini. Sangat tidak jelas maksud "dalam persekitaran yang menyokong kontena". Untuk mengetahuinya, mari kita kembali ke masa lalu. Mari kita mulakan dengan era yang biasa saya panggil "Era Monolitik."

Zaman monolitik

Era monolitik adalah awal 2000-an, apabila semua aplikasi adalah monolitik, dengan banyak kebergantungan. Pembangunan mengambil masa yang lama. Pada masa yang sama, tidak banyak pelayan; kami semua mengenali mereka dengan nama dan memantau mereka. Terdapat perbandingan yang lucu:

Haiwan peliharaan adalah haiwan domestik. Dalam era monolitik, kami melayan pelayan kami seperti haiwan peliharaan, rapi dan dihargai, meniup habuk. Dan untuk pengurusan sumber yang lebih baik, kami menggunakan virtualisasi: kami mengambil pelayan dan memotongnya menjadi beberapa mesin maya, dengan itu memastikan pengasingan persekitaran.

Sistem virtualisasi berasaskan hipervisor

Semua orang mungkin pernah mendengar tentang sistem virtualisasi: VMware, VirtualBox, Hyper-V, Qemu KVM, dll. Mereka menyediakan pengasingan aplikasi dan pengurusan sumber, tetapi mereka juga mempunyai kelemahan. Untuk melakukan virtualisasi, anda memerlukan hypervisor. Dan hipervisor ialah overhed sumber. Dan mesin maya itu sendiri biasanya adalah sangat besar - imej berat yang mengandungi sistem pengendalian, Nginx, Apache, dan mungkin MySQL. Imejnya besar dan mesin maya menyusahkan untuk dikendalikan. Akibatnya, bekerja dengan mesin maya boleh menjadi perlahan. Untuk menyelesaikan masalah ini, sistem virtualisasi telah dicipta pada peringkat kernel.

Sistem virtualisasi peringkat kernel

Virtualisasi peringkat kernel disokong oleh sistem OpenVZ, Systemd-nspawn, LXC. Contoh yang menarik untuk virtualisasi tersebut ialah LXC (Linux Containers).

LXC ialah sistem virtualisasi peringkat sistem pengendalian untuk menjalankan berbilang contoh terpencil sistem pengendalian Linux pada satu nod. LXC tidak menggunakan mesin maya, tetapi mencipta persekitaran maya dengan ruang proses dan susunan rangkaiannya sendiri.

Pada asasnya LXC mencipta bekas. Apakah perbezaan antara mesin maya dan bekas?

Apakah itu Docker: lawatan ringkas ke dalam sejarah dan abstraksi asas

Bekas tidak sesuai untuk mengasingkan proses: kelemahan ditemui dalam sistem virtualisasi pada peringkat kernel yang membolehkan mereka melarikan diri dari bekas ke hos. Oleh itu, jika anda perlu mengasingkan sesuatu, lebih baik menggunakan mesin maya.

Perbezaan antara virtualisasi dan kontena boleh dilihat dalam rajah.
Terdapat hipervisor perkakasan, hipervisor pada bahagian atas OS dan bekas.

Apakah itu Docker: lawatan ringkas ke dalam sejarah dan abstraksi asas

Hipervisor perkakasan bagus jika anda benar-benar ingin mengasingkan sesuatu. Kerana ia adalah mungkin untuk mengasingkan pada tahap halaman memori dan pemproses.

Terdapat hypervisor sebagai program, dan terdapat bekas, dan kami akan membincangkannya dengan lebih lanjut. Sistem kontena tidak mempunyai hipervisor, tetapi terdapat Enjin Kontena yang mencipta dan mengurus bekas. Perkara ini lebih ringan, jadi disebabkan bekerja dengan teras terdapat kurang overhed atau tiada langsung.

Apa yang digunakan untuk kontena di peringkat kernel

Teknologi utama yang membolehkan anda mencipta bekas yang diasingkan daripada proses lain ialah Ruang Nama dan Kumpulan Kawalan.

Ruang nama: PID, Rangkaian, Lekap dan Pengguna. Terdapat lebih banyak lagi, tetapi untuk memudahkan pemahaman kami akan memberi tumpuan kepada perkara ini.

Ruang Nama PID mengehadkan proses. Apabila, sebagai contoh, kita mencipta Ruang Nama PID dan meletakkan proses di sana, ia menjadi dengan PID 1. Biasanya dalam sistem PID 1 ialah systemd atau init. Oleh itu, apabila kami meletakkan proses dalam ruang nama baharu, ia juga menerima PID 1.

Ruang Nama Rangkaian membolehkan anda mengehadkan/mengasingkan rangkaian dan meletakkan antara muka anda sendiri di dalamnya. Mount adalah had sistem fail. Penggunaβ€”sekatan ke atas pengguna.

Kumpulan Kawalan: Memori, CPU, IOPS, Rangkaian - kira-kira 12 tetapan secara keseluruhan. Jika tidak, mereka juga dipanggil Cgroups (β€œC-groups”).

Kumpulan Kawalan mengurus sumber untuk bekas. Melalui Kumpulan Kawalan kita boleh mengatakan bahawa kontena tidak boleh menggunakan lebih daripada jumlah sumber tertentu.

Untuk kontena berfungsi sepenuhnya, teknologi tambahan digunakan: Keupayaan, Salin dalam tulis dan lain-lain.

Keupayaan adalah apabila kita memberitahu proses apa yang boleh dan tidak boleh dilakukan. Pada peringkat kernel, ini hanyalah peta bit dengan banyak parameter. Sebagai contoh, pengguna root mempunyai keistimewaan penuh dan boleh melakukan segala-galanya. Pelayan masa boleh menukar masa sistem: ia mempunyai keupayaan pada Kapsul Masa, dan itu sahaja. Menggunakan keistimewaan, anda boleh mengkonfigurasi sekatan untuk proses secara fleksibel, dan dengan itu melindungi diri anda.

Sistem Copy-on-write membolehkan kami bekerja dengan imej Docker dan menggunakannya dengan lebih cekap.

Docker pada masa ini mempunyai isu keserasian dengan Cgroups v2, jadi artikel ini memfokuskan secara khusus pada Cgroups v1.

Tetapi mari kita kembali kepada sejarah.

Apabila sistem virtualisasi muncul di peringkat kernel, ia mula digunakan secara aktif. Overhed pada hipervisor hilang, tetapi beberapa masalah kekal:

  • imej besar: mereka menolak sistem pengendalian, perpustakaan, sekumpulan perisian yang berbeza ke dalam OpenVZ yang sama, dan pada akhirnya imej itu masih ternyata agak besar;
  • Tiada standard biasa untuk pembungkusan dan penghantaran, jadi masalah kebergantungan kekal. Terdapat situasi apabila dua keping kod menggunakan perpustakaan yang sama, tetapi dengan versi yang berbeza. Mungkin ada konflik antara mereka.

Untuk menyelesaikan semua masalah ini, era seterusnya telah tiba.

Era bekas

Apabila Era Kontena tiba, falsafah bekerja dengan mereka berubah:

  • Satu proses - satu bekas.
  • Kami menghantar semua kebergantungan yang diperlukan oleh proses kepada bekasnya. Ini memerlukan pemotongan monolit kepada perkhidmatan mikro.
  • Lebih kecil imej, lebih baik - terdapat lebih sedikit kemungkinan kelemahan, ia dilancarkan dengan lebih cepat, dan seterusnya.
  • Kejadian menjadi fana.

Ingat apa yang saya katakan tentang haiwan peliharaan vs lembu? Dahulu, keadaan seperti haiwan ternakan, tetapi kini telah menjadi seperti lembu. Sebelum ini, terdapat monolit - satu aplikasi. Kini 100 perkhidmatan mikro, 100 bekas. Sesetengah bekas mungkin mempunyai 2-3 replika. Ia menjadi kurang penting bagi kita untuk mengawal setiap bekas. Apa yang lebih penting bagi kami ialah ketersediaan perkhidmatan itu sendiri: apa yang dilakukan oleh set bekas ini. Ini mengubah pendekatan kepada pemantauan.

Pada 2014-2015, Docker berkembang pesat - teknologi yang akan kita bincangkan sekarang.

Docker mengubah falsafah dan pembungkusan aplikasi piawai. Menggunakan Docker, kami boleh membungkus aplikasi, menghantarnya ke repositori, memuat turunnya dari sana dan menggunakan aplikasi tersebut.

Kami meletakkan semua yang kami perlukan ke dalam bekas Docker, jadi masalah pergantungan diselesaikan. Docker menjamin kebolehulangan. Saya rasa ramai orang telah mengalami ketidakbolehhasilan semula: semuanya berfungsi untuk anda, anda menolaknya ke pengeluaran, dan di sana ia berhenti berfungsi. Dengan Docker masalah ini hilang. Jika bekas Docker anda bermula dan melakukan perkara yang perlu dilakukan, maka dengan tahap kebarangkalian yang tinggi ia akan bermula dalam pengeluaran dan melakukan perkara yang sama di sana.

Penyimpangan mengenai overhed

Selalu ada pertikaian mengenai kos. Sesetengah orang percaya bahawa Docker tidak membawa beban tambahan, kerana ia menggunakan kernel Linux dan semua prosesnya yang diperlukan untuk kontena. Seperti, "jika anda mengatakan bahawa Docker adalah overhead, maka kernel Linux adalah overhead."

Sebaliknya, jika anda pergi lebih dalam, memang terdapat beberapa perkara dalam Docker yang, dengan regangan, boleh dikatakan sebagai overhead.

Yang pertama ialah ruang nama PID. Apabila kita meletakkan proses dalam ruang nama, ia diberikan PID 1. Pada masa yang sama, proses ini mempunyai PID lain, yang terletak pada ruang nama hos, di luar bekas. Sebagai contoh, kami melancarkan Nginx dalam bekas, ia menjadi PID 1 (proses induk). Dan pada hos ia mempunyai PID 12623. Dan sukar untuk mengatakan berapa banyak overhed ia.

Perkara kedua ialah Cgroups. Mari kita ambil Cgroups mengikut ingatan, iaitu keupayaan untuk mengehadkan ingatan bekas. Apabila ia didayakan, pembilang dan perakaunan memori diaktifkan: kernel perlu memahami berapa banyak halaman yang telah diperuntukkan dan berapa banyak yang masih kosong untuk bekas ini. Ini mungkin overhed, tetapi saya tidak melihat sebarang kajian tepat tentang cara ia mempengaruhi prestasi. Dan saya sendiri tidak perasan bahawa aplikasi yang berjalan di Docker tiba-tiba mengalami kehilangan prestasi yang mendadak.

Dan satu lagi nota tentang prestasi. Beberapa parameter kernel dihantar dari hos ke bekas. Khususnya, beberapa parameter rangkaian. Oleh itu, jika anda ingin menjalankan sesuatu yang berprestasi tinggi di Docker, sebagai contoh, sesuatu yang akan menggunakan rangkaian secara aktif, maka anda sekurang-kurangnya perlu melaraskan parameter ini. Beberapa nf_conntrack, sebagai contoh.

Mengenai konsep Docker

Docker terdiri daripada beberapa komponen:

  1. Docker Daemon ialah Enjin Kontena yang sama; melancarkan kontena.
  2. Docker CII ialah utiliti pengurusan Docker.
  3. Dockerfile - arahan tentang cara membina imej.
  4. Imej β€” imej dari mana bekas itu dilancarkan.
  5. bekas.
  6. Pendaftaran Docker ialah repositori imej.

Secara skematik ia kelihatan seperti ini:

Apakah itu Docker: lawatan ringkas ke dalam sejarah dan abstraksi asas

Daemon Docker berjalan pada Docker_host dan melancarkan bekas. Terdapat Klien yang menghantar arahan: bina imej, muat turun imej, lancarkan bekas. Daemon Docker pergi ke registri dan melaksanakannya. Pelanggan Docker boleh mengakses kedua-dua secara tempatan (ke soket Unix) dan melalui TCP dari hos jauh.

Mari kita lihat setiap komponen.

Daemon Docker - ini ialah bahagian pelayan, ia berfungsi pada mesin hos: memuat turun imej dan melancarkan bekas daripadanya, mencipta rangkaian antara bekas, mengumpul log. Apabila kita berkata "buat imej," syaitan juga melakukan itu.

Docker CLI β€” Bahagian klien Docker, utiliti konsol untuk bekerja dengan daemon. Saya ulangi, ia boleh berfungsi bukan sahaja secara tempatan, tetapi juga melalui rangkaian.

Perintah asas:

docker ps - tunjukkan bekas yang sedang berjalan pada hos Docker.
imej docker - tunjukkan imej yang dimuat turun secara tempatan.
docker search <> - cari imej dalam registry.
docker pull <> - muat turun imej dari registri ke mesin.
binaan buruh pelabuhan < > - kumpulkan gambar.
docker run <> - lancarkan bekas.
docker rm <> - keluarkan bekas.
log docker <> - log kontena
docker start/stop/restart <> - bekerja dengan bekas

Jika anda menguasai arahan ini dan yakin untuk menggunakannya, pertimbangkan diri anda 70% mahir dalam Docker di peringkat pengguna.

Dockerfile - arahan untuk mencipta imej. Hampir setiap arahan arahan adalah lapisan baharu. Mari kita lihat satu contoh.

Apakah itu Docker: lawatan ringkas ke dalam sejarah dan abstraksi asas

Beginilah rupa Dockerfile: arahan di sebelah kiri, argumen di sebelah kanan. Setiap arahan yang ada di sini (dan biasanya ditulis dalam Dockerfile) mencipta lapisan baharu dalam Imej.

Walaupun melihat sebelah kiri, anda boleh memahami secara kasar apa yang berlaku. Kami berkata: "buat folder untuk kami" - ini adalah satu lapisan. "Jadikan folder berfungsi" ialah lapisan lain, dan seterusnya. Kek lapis menjadikan hidup lebih mudah. Jika saya mencipta fail Docker lain dan menukar sesuatu dalam baris terakhir - saya menjalankan sesuatu selain daripada "python" "main.py", atau memasang kebergantungan daripada fail lain - maka lapisan sebelumnya akan digunakan semula sebagai cache.

Image - ini adalah pembungkusan bekas; bekas dilancarkan daripada imej. Jika kita melihat Docker dari sudut pandangan pengurus pakej (seolah-olah kita bekerja dengan pakej deb atau rpm), maka imej pada dasarnya adalah pakej rpm. Melalui pemasangan yum kita boleh memasang aplikasi, memadamkannya, mencarinya dalam repositori, dan memuat turunnya. Ia lebih kurang sama di sini: bekas dilancarkan daripada imej, ia disimpan dalam pendaftaran Docker (serupa dengan yum, dalam repositori), dan setiap imej mempunyai cincang SHA-256, nama dan teg.

Imej dibina mengikut arahan daripada Dockerfile. Setiap arahan daripada Dockerfile mencipta lapisan baharu. Lapisan boleh digunakan semula.

Pendaftaran Docker ialah repositori imej Docker. Sama seperti OS, Docker mempunyai pendaftaran standard awam - dockerhub. Tetapi anda boleh membina repositori anda sendiri, pendaftaran Docker anda sendiri.

Bekas - apa yang dilancarkan daripada imej. Kami membina imej mengikut arahan daripada Dockerfile, kemudian kami melancarkannya dari imej ini. Bekas ini diasingkan daripada bekas lain dan mesti mengandungi semua yang diperlukan untuk aplikasi berfungsi. Dalam kes ini, satu bekas - satu proses. Ia berlaku bahawa anda perlu melakukan dua proses, tetapi ini agak bertentangan dengan ideologi Docker.

Keperluan "satu bekas, satu proses" berkaitan dengan Ruang Nama PID. Apabila proses dengan PID 1 bermula dalam Ruang Nama, jika ia mati secara tiba-tiba, maka keseluruhan bekas juga akan mati. Jika dua proses sedang berjalan di sana: satu masih hidup dan satu lagi mati, maka bekas itu akan terus hidup. Tetapi ini adalah persoalan Amalan Terbaik, kami akan membincangkannya dalam bahan lain.

Untuk mengkaji ciri dan program penuh kursus dengan lebih terperinci, sila ikuti pautan: β€œKursus video Docker'.

Pengarang: Marcel Ibraev, pentadbir Kubernetes bertauliah, jurutera berlatih di Southbridge, penceramah dan pembangun kursus Slurm.

Sumber: www.habr.com

Tambah komen