Masalah pembersihan "pintar" imej kontena dan penyelesaiannya dalam werf

Masalah pembersihan "pintar" imej kontena dan penyelesaiannya dalam werf

Artikel tersebut membincangkan masalah pembersihan imej yang terkumpul dalam daftar kontena (Docker Registry dan analognya) dalam realiti saluran paip CI/CD moden untuk aplikasi asli awan yang dihantar ke Kubernetes. Kriteria utama untuk perkaitan imej dan kesukaran yang terhasil dalam mengautomasikan pembersihan, menjimatkan ruang dan memenuhi keperluan pasukan diberikan. Akhir sekali, menggunakan contoh projek Sumber Terbuka tertentu, kami akan memberitahu anda bagaimana kesukaran ini boleh diatasi.

Pengenalan

Bilangan imej dalam daftar kontena boleh berkembang dengan pesat, mengambil lebih banyak ruang storan dan dengan itu meningkatkan kosnya dengan ketara. Untuk mengawal, mengehadkan atau mengekalkan pertumbuhan ruang yang boleh diterima yang diduduki dalam pendaftaran, ia diterima:

  1. gunakan bilangan tag yang tetap untuk imej;
  2. entah bagaimana membersihkan imej.


Had pertama kadangkala sah untuk pasukan kecil. Jika pembangun mempunyai teg berterusan yang mencukupi (latest, main, test, boris dll.), registri tidak akan membengkak dalam saiz dan untuk masa yang lama anda tidak perlu berfikir tentang membersihkannya sama sekali. Lagipun, semua imej yang tidak berkaitan dipadamkan, dan tiada kerja lagi untuk pembersihan (semuanya dilakukan oleh pemungut sampah biasa).

Walau bagaimanapun, pendekatan ini sangat mengehadkan pembangunan dan jarang digunakan untuk projek CI/CD moden. Bahagian penting pembangunan itu ialah automasi, yang membolehkan anda menguji, menggunakan dan menyampaikan fungsi baharu kepada pengguna dengan lebih pantas. Sebagai contoh, dalam semua projek kami, saluran paip CI dibuat secara automatik dengan setiap komit. Di dalamnya, imej dipasang, diuji, dilancarkan ke pelbagai litar Kubernetes untuk penyahpepijatan dan semakan yang tinggal, dan jika semuanya baik-baik saja, perubahan itu sampai kepada pengguna akhir. Dan ini bukan lagi sains roket, tetapi kejadian setiap hari untuk ramai - kemungkinan besar untuk anda, kerana anda membaca artikel ini.

Memandangkan pembetulan pepijat dan membangunkan fungsi baharu dijalankan secara selari, dan keluaran boleh dilakukan beberapa kali sehari, adalah jelas bahawa proses pembangunan disertai dengan sejumlah besar komitmen, yang bermaksud sejumlah besar imej dalam pendaftaran. Akibatnya, isu mengatur pembersihan pendaftaran yang berkesan timbul, i.e. mengalih keluar imej yang tidak berkaitan.

Tetapi bagaimana anda menentukan sama ada imej itu relevan?

Kriteria untuk perkaitan imej

Dalam kebanyakan kes, kriteria utama adalah:

1. Yang pertama (yang paling jelas dan paling kritikal) ialah imej yang kini digunakan dalam Kubernetes. Memadamkan imej ini boleh mengakibatkan kos masa henti pengeluaran yang ketara (contohnya, imej mungkin diperlukan untuk replikasi) atau membatalkan usaha pasukan yang sedang menyahpepijat pada mana-mana gelung. (Atas sebab ini, kami juga membuat yang istimewa Pengeksport Prometheus, yang menjejaki ketiadaan imej sedemikian dalam mana-mana kelompok Kubernetes.)

2. Yang kedua (kurang jelas, tetapi juga sangat penting dan sekali lagi berkaitan dengan eksploitasi) ialah imej yang diperlukan untuk pemulangan semula sekiranya pengesanan masalah serius dalam versi semasa. Contohnya, dalam kes Helm, ini ialah imej yang digunakan dalam versi keluaran yang disimpan. (Dengan cara ini, secara lalai dalam Helm hadnya ialah 256 semakan, tetapi tidak mungkin sesiapa benar-benar perlu menyimpan ini sebilangan besar versi?..) Lagipun, kami, khususnya, menyimpan versi supaya kami boleh menggunakannya kemudian, i.e. "gulung semula" kepada mereka jika perlu.

3. Ketiga - keperluan pemaju: Semua imej yang berkaitan dengan kerja semasa mereka. Sebagai contoh, jika kita sedang mempertimbangkan PR, maka masuk akal untuk meninggalkan imej yang sepadan dengan komit terakhir dan, katakan, komit sebelumnya: dengan cara ini pembangun boleh dengan cepat kembali ke sebarang tugas dan bekerja dengan perubahan terkini.

4. Keempat - imej yang sepadan dengan versi aplikasi kami, iaitu ialah produk akhir: v1.0.0, 20.04.01/XNUMX/XNUMX, sierra, dsb.

NB: Kriteria yang ditakrifkan di sini telah dirumus berdasarkan pengalaman berinteraksi dengan berpuluh-puluh pasukan pembangunan daripada syarikat yang berbeza. Walau bagaimanapun, sudah tentu, bergantung pada spesifik dalam proses pembangunan dan infrastruktur yang digunakan (contohnya, Kubernetes tidak digunakan), kriteria ini mungkin berbeza.

Kelayakan dan Penyelesaian Sedia Ada

Perkhidmatan popular dengan pendaftaran kontena, sebagai peraturan, menawarkan dasar pembersihan imej mereka sendiri: di dalamnya anda boleh menentukan syarat di mana teg dialih keluar daripada pendaftaran. Walau bagaimanapun, syarat ini dihadkan oleh parameter seperti nama, masa penciptaan dan bilangan tag*.

* Bergantung pada pelaksanaan pendaftaran kontena tertentu. Kami mempertimbangkan kemungkinan penyelesaian berikut: Azure CR, Docker Hub, ECR, GCR, GitHub Packages, GitLab Container Registry, Harbour Registry, JFrog Artifactory, Quay.io - setakat September'2020.

Set parameter ini cukup mencukupi untuk memenuhi kriteria keempat - iaitu, untuk memilih imej yang sepadan dengan versi. Walau bagaimanapun, untuk semua kriteria lain, seseorang perlu memilih beberapa jenis penyelesaian kompromi (dasar yang lebih sukar atau, sebaliknya, lebih lembut) - bergantung pada jangkaan dan keupayaan kewangan.

Sebagai contoh, kriteria ketiga - berkaitan dengan keperluan pembangun - boleh diselesaikan dengan mengatur proses dalam pasukan: penamaan imej khusus, mengekalkan senarai kebenaran khas dan perjanjian dalaman. Tetapi akhirnya ia masih perlu diautomatikkan. Dan jika keupayaan penyelesaian siap sedia tidak mencukupi, anda perlu melakukan sesuatu sendiri.

Situasi dengan dua kriteria pertama adalah serupa: mereka tidak boleh berpuas hati tanpa menerima data daripada sistem luaran - yang mana aplikasi digunakan (dalam kes kami, ini adalah Kubernetes).

Ilustrasi aliran kerja Git

Katakan anda bekerja seperti ini dalam Git:

Masalah pembersihan "pintar" imej kontena dan penyelesaiannya dalam werf

Ikon dengan kepala dalam rajah menandakan imej bekas yang sedang digunakan dalam Kubernetes untuk mana-mana pengguna (pengguna akhir, penguji, pengurus, dll.) atau digunakan oleh pembangun untuk nyahpepijat dan tujuan yang serupa.

Apa yang berlaku jika dasar pembersihan hanya membenarkan imej dikekalkan (tidak dipadamkan) dengan nama tag yang diberikan?

Masalah pembersihan "pintar" imej kontena dan penyelesaiannya dalam werf

Jelas sekali, senario sedemikian tidak akan menggembirakan sesiapa.

Perkara yang akan berubah jika dasar membenarkan tidak memadamkan imej mengikut selang masa tertentu / bilangan komitmen terakhir?

Masalah pembersihan "pintar" imej kontena dan penyelesaiannya dalam werf

Hasilnya telah menjadi lebih baik, tetapi masih jauh dari ideal. Lagipun, kami masih mempunyai pembangun yang memerlukan imej dalam pendaftaran (atau bahkan digunakan dalam K8) untuk menyahpepijat pepijat ...

Untuk meringkaskan keadaan pasaran semasa: fungsi yang tersedia dalam daftar kontena tidak menawarkan fleksibiliti yang mencukupi semasa pembersihan, dan sebab utama untuk ini adalah tiada cara untuk berinteraksi dengan dunia luar. Ternyata pasukan yang memerlukan fleksibiliti sedemikian terpaksa melaksanakan pemadaman imej secara bebas "dari luar", menggunakan API Pendaftaran Docker (atau API asli pelaksanaan yang sepadan).

Walau bagaimanapun, kami sedang mencari penyelesaian universal yang akan mengautomasikan pembersihan imej untuk pasukan yang berbeza menggunakan pendaftaran yang berbeza...

Laluan Kami ke Pembersihan Imej Universal

Dari mana datangnya keperluan sedemikian? Hakikatnya ialah kami bukanlah kumpulan pembangun yang berasingan, tetapi pasukan yang melayani ramai daripada mereka sekaligus, membantu menyelesaikan isu CI / CD secara menyeluruh. Dan alat teknikal utama untuk ini ialah utiliti Sumber Terbuka werf. Keistimewaannya ialah ia tidak melaksanakan satu fungsi, tetapi mengiringi proses penghantaran berterusan pada semua peringkat: dari pemasangan hingga penggunaan.

Menerbitkan imej ke registri* (sejurus selepas ia dibina) adalah fungsi yang jelas bagi utiliti sedemikian. Dan kerana imej diletakkan di sana untuk penyimpanan, maka - jika storan anda tidak terhad - anda perlu bertanggungjawab untuk pembersihan berikutnya. Bagaimana kami berjaya dalam ini, memenuhi semua kriteria yang diberikan, akan dibincangkan lebih lanjut.

* Walaupun pendaftaran itu sendiri mungkin berbeza (Docker Registry, GitLab Container Registry, Harbor, dll.), pengguna mereka menghadapi masalah yang sama. Penyelesaian sejagat dalam kes kami tidak bergantung pada pelaksanaan pendaftaran, kerana berjalan di luar pendaftaran itu sendiri dan menawarkan tingkah laku yang sama untuk semua orang.

Walaupun kami menggunakan werf sebagai contoh pelaksanaan, kami berharap pendekatan yang digunakan akan berguna kepada pasukan lain yang menghadapi kesukaran yang sama.

Jadi kami sibuk luaran pelaksanaan mekanisme untuk membersihkan imej - bukannya keupayaan yang telah dibina ke dalam pendaftaran kontena. Langkah pertama ialah menggunakan API Docker Registry untuk mencipta dasar primitif yang sama untuk bilangan teg dan masa penciptaannya (disebutkan di atas). Ditambah kepada mereka benarkan senarai berdasarkan imej yang digunakan dalam infrastruktur yang digunakan, iaitu Kubernetes. Untuk yang terakhir, cukup untuk melalui semua sumber yang digunakan melalui API Kubernetes dan mendapatkan senarai nilai image.

Penyelesaian remeh sedemikian menutup masalah paling kritikal (kriteria # 1), tetapi hanya permulaan perjalanan kami untuk memperbaiki mekanisme pembersihan. Langkah seterusnya - dan lebih menarik - adalah keputusannya pautkan imej yang diterbitkan ke sejarah Git.

Skim penandaan

Sebagai permulaan, kami memilih pendekatan di mana imej akhir harus menyimpan maklumat yang diperlukan untuk pembersihan, dan membina proses pada skema penandaan. Apabila menerbitkan imej, pengguna memilih pilihan penandaan tertentu (git-branch, git-commit atau git-tag) dan menggunakan nilai yang sesuai. Dalam sistem CI, nilai ini ditetapkan secara automatik berdasarkan pembolehubah persekitaran. Sebenarnya imej akhir dikaitkan dengan primitif Git tertentu, menyimpan data yang diperlukan untuk pembersihan dalam label.

Sebagai sebahagian daripada pendekatan ini, satu set dasar telah diperoleh yang membenarkan Git digunakan sebagai satu-satunya sumber kebenaran:

  • Apabila memadamkan cawangan/teg dalam Git, imej yang berkaitan dalam pendaftaran telah dipadamkan secara automatik juga.
  • Bilangan imej yang dikaitkan dengan teg dan komit Git boleh dikawal oleh bilangan teg yang digunakan dalam skema yang dipilih dan masa komit yang berkaitan.

Secara keseluruhan, pelaksanaan yang terhasil memenuhi keperluan kami, tetapi cabaran baharu tidak lama lagi menanti kami. Hakikatnya ialah semasa menggunakan skema penandaan berdasarkan primitif Git, kami menghadapi beberapa kelemahan. (Memandangkan penerangan mereka di luar skop artikel ini, semua orang boleh membiasakan diri dengan butirannya di sini.) Oleh itu, setelah membuat keputusan untuk beralih kepada pendekatan penandaan yang lebih cekap (penandaan berasaskan kandungan), kami terpaksa menyemak semula pelaksanaan pembersihan imej juga.

Algoritma baharu

kenapa? Dengan pengetegan berasaskan kandungan, setiap teg boleh memenuhi berbilang komitmen dalam Git. Apabila membersihkan imej, anda tidak boleh lagi menganggap sahaja daripada komit di mana teg baharu telah ditambahkan pada pendaftaran.

Untuk algoritma pembersihan baharu, ia telah memutuskan untuk beralih daripada skim penandaan dan membina proses pada meta-imej, setiap satunya menyimpan sekumpulan:

  • komitmen di mana penerbitan itu dilakukan (tidak kira sama ada imej itu ditambah, diubah atau kekal sama dalam pendaftaran kontena);
  • dan pengecam dalaman kami yang sepadan dengan imej terbina.

Dengan kata lain, disediakan memautkan teg yang diterbitkan dengan komit dalam Git.

Konfigurasi akhir dan algoritma umum

Semasa mengkonfigurasi pembersihan, pengguna mempunyai akses kepada dasar yang memilih imej sebenar. Setiap dasar tersebut ditakrifkan oleh:

  • banyak rujukan, i.e. Teg Git atau cawangan Git yang digunakan semasa pengimbasan;
  • dan had imej yang dikehendaki untuk setiap rujukan daripada set.

Untuk menggambarkan, berikut ialah rupa konfigurasi dasar lalai:

cleanup:
  keepPolicies:
  - references:
      tag: /.*/
      limit:
        last: 10
  - references:
      branch: /.*/
      limit:
        last: 10
        in: 168h
        operator: And
    imagesPerReference:
      last: 2
      in: 168h
      operator: And
  - references:  
      branch: /^(main|staging|production)$/
    imagesPerReference:
      last: 10

Konfigurasi ini mengandungi tiga dasar yang mematuhi peraturan berikut:

  1. Simpan imej untuk 10 teg Git terakhir (mengikut tarikh penciptaan teg).
  2. Simpan sehingga 2 imej yang diterbitkan pada minggu lepas untuk sehingga 10 cawangan dengan aktiviti pada minggu lepas.
  3. Simpan 10 imej untuk cawangan main, staging ΠΈ production.

Algoritma terakhir bermuara kepada langkah-langkah berikut:

  • Mendapatkan manifes daripada daftar kontena.
  • Tidak termasuk imej yang digunakan dalam Kubernetes, kerana Kami telah pun memilihnya terlebih dahulu dengan mengundi API K8s.
  • Mengimbas sejarah Git dan pengecualian imej mengikut dasar yang ditentukan.
  • Mengalih keluar imej yang tinggal.

Berbalik kepada ilustrasi kami, inilah yang berlaku dengan werf:

Masalah pembersihan "pintar" imej kontena dan penyelesaiannya dalam werf

Walau bagaimanapun, walaupun anda tidak menggunakan werf, pendekatan serupa untuk pembersihan imej lanjutan - dalam satu pelaksanaan atau yang lain (mengikut pendekatan pilihan untuk penandaan imej) - boleh digunakan dalam sistem/utiliti lain. Untuk melakukan ini, sudah cukup untuk mengetahui masalah yang timbul dan mencari peluang tersebut dalam timbunan anda yang membolehkan anda membina penyelesaiannya dengan paling lancar. Kami berharap laluan yang telah kami lalui akan membantu anda melihat kes tertentu anda dengan butiran dan pemikiran baharu.

Kesimpulan

  • Lambat laun, kebanyakan pasukan menghadapi masalah limpahan pendaftaran.
  • Apabila mencari penyelesaian, pertama sekali adalah perlu untuk menentukan kriteria untuk perkaitan imej.
  • Alat yang ditawarkan oleh perkhidmatan pendaftaran kontena popular membolehkan anda mengatur pembersihan yang sangat mudah yang tidak mengambil kira "dunia luar": imej yang digunakan dalam Kubernetes dan butiran aliran kerja pasukan.
  • Algoritma yang fleksibel dan cekap mesti mempunyai pemahaman tentang proses CI/CD dan beroperasi bukan sahaja dengan data imej Docker.

PS

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komen