GNU/Linux >> Belajar Linux >  >> Panels >> Docker

Cara Membangun Gambar Docker Dalam Pipeline CI GitLab

Satu kasus penggunaan umum untuk pipeline CI adalah membangun image Docker yang akan Anda gunakan untuk men-deploy aplikasi Anda. GitLab CI adalah pilihan tepat untuk ini karena mendukung layanan pull proxy terintegrasi, yang berarti saluran pipa yang lebih cepat, dan registri bawaan untuk menyimpan gambar yang Anda buat.

Dalam panduan ini, kami akan menunjukkan cara menyiapkan build Docker yang menggunakan kedua fitur di atas. Langkah-langkah yang perlu Anda ambil sedikit berbeda tergantung pada jenis pelaksana GitLab Runner yang akan Anda gunakan untuk pipeline Anda. Kami akan membahas eksekutor Shell dan Docker di bawah ini.

Membangun Dengan Pelaksana Shell

Jika Anda menggunakan eksekutor Shell, pastikan Anda telah menginstal Docker di mesin yang menghosting runner Anda. Pelaksana bekerja dengan menjalankan perintah shell biasa menggunakan docker biner di host Runner.

Buka repositori Git untuk proyek yang ingin Anda buat gambarnya. Buat .gitlab-ci.yml file di root repositori. File ini mendefinisikan pipeline GitLab CI yang akan berjalan saat Anda mendorong perubahan ke proyek Anda.

Tambahkan konten berikut ke file:

stages:
  - build

docker_build:
  stage: build
  script:
    - docker build -t example.com/example-image:latest .
    - docker push example.com/example-image:latest

Konfigurasi sederhana ini cukup untuk mendemonstrasikan dasar-dasar pembuatan gambar yang didukung oleh pipeline. GitLab secara otomatis mengkloning repositori Git Anda ke dalam lingkungan build jadi jalankan docker build akan menggunakan Dockerfile proyek Anda dan membuat konten repositori tersedia sebagai konteks build.

Setelah build selesai, Anda dapat docker push gambar ke registri Anda. Kalau tidak, itu hanya akan tersedia untuk instalasi Docker lokal yang menjalankan build. Jika Anda menggunakan registri pribadi, jalankan docker login pertama yang memberikan detail autentikasi yang tepat:

script:
  - docker login -u $DOCKER_REGISTRY_USER -p $DOCKER_REGISTRY_PASSWORD

Tentukan nilai dari dua variabel kredensial dengan menuju ke Pengaturan> CI/CD> Variabel di UI web GitLab. Klik tombol biru “Tambah variabel” untuk membuat variabel baru dan menetapkan nilai. GitLab akan membuat variabel ini tersedia di lingkungan shell yang digunakan untuk menjalankan tugas Anda.

Membangun Dengan Eksekutor Docker

Pelaksana Docker GitLab Runner biasanya digunakan untuk menyediakan lingkungan yang sepenuhnya bersih untuk setiap pekerjaan. Pekerjaan akan dijalankan dalam wadah yang terisolasi sehingga docker biner pada host Runner tidak akan dapat diakses.

Eksekutor Docker memberi Anda dua kemungkinan strategi untuk membangun image Anda:gunakan Docker-in-Docker, atau ikat soket Docker host ke lingkungan build Runner. Anda kemudian menggunakan image container Docker resmi sebagai image pekerjaan Anda, membuat docker perintah yang tersedia di skrip CI Anda.

Docker-in-Docker

Menggunakan Docker-in-Docker (DinD) untuk membangun gambar Anda memberi Anda lingkungan yang sepenuhnya terisolasi untuk setiap pekerjaan. Proses Docker yang menjalankan build akan menjadi anak dari container yang dibuat GitLab Runner di host untuk menjalankan tugas CI.

Anda perlu mendaftarkan pelaksana GitLab Runner Docker Anda dengan mode istimewa yang diaktifkan untuk menggunakan DinD. Tambahkan --docker-privileged tandai saat Anda mendaftarkan pelari Anda:

sudo gitlab-runner register -n 
  --url https://example.com 
  --registration-token $GITLAB_REGISTRATION_TOKEN 
  --executor docker 
  --description "Docker Runner" 
  --docker-image "docker:20.10" 
  --docker-volumes "/certs/client" 
  --docker-privileged

Di dalam pipeline CI Anda, tambahkan docker:dind gambar sebagai layanan. Ini membuat Docker tersedia sebagai gambar terpisah yang ditautkan ke gambar pekerjaan. Anda akan dapat menggunakan docker perintah untuk membuat gambar menggunakan instance Docker di docker:dind wadah.

services:
  - docker:dind

docker_build:
  stage: build
  image: docker:latest
  script:
    - docker build -t example-image:latest .

Menggunakan DinD memberi Anda build yang sepenuhnya terisolasi yang tidak dapat memengaruhi satu sama lain atau host Anda. Kelemahan utama adalah perilaku caching yang lebih rumit:setiap pekerjaan mendapatkan lingkungan baru di mana lapisan yang dibangun sebelumnya tidak akan dapat diakses. Anda dapat mengatasi hal ini sebagian dengan mencoba menarik versi gambar sebelumnya sebelum Anda membuat, lalu menggunakan --cache-from build flag untuk membuat lapisan gambar yang ditarik tersedia sebagai sumber cache:

docker_build:
  stage: build
  image: docker:latest
  script:
    - docker pull $CI_REGISTRY_IMAGE:latest || true
    - docker build --cache-from $CI_REGISTRY_IMAGE:latest -t $CI_REGISTRY_IMAGE:latest .

Socket Bind Mounts

Memasang soket Docker host Anda ke lingkungan pekerjaan Anda adalah opsi alternatif saat Anda menggunakan eksekutor Docker. Ini memberi Anda caching yang mulus dan menghilangkan kebutuhan untuk menambahkan docker:dind layanan ke konfigurasi CI Anda.

Untuk mengatur ini, daftarkan Runner Anda dengan docker-volumes flag yang mengikat soket Docker host ke /var/run/docker.sock di dalam wadah pekerjaan:

sudo gitlab-runner register -n 
  --url https://example.com 
  --registration-token $GITLAB_REGISTRATION_TOKEN 
  --executor docker 
  --description "Docker Runner" 
  --docker-image "docker:20.10" 
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

Sekarang pekerjaan yang dijalankan dengan docker gambar akan dapat menggunakan docker biner seperti biasa. Operasi akan benar-benar terjadi di mesin host Anda, menjadi saudara kandung dari wadah pekerjaan, bukan anak-anak.

Ini secara efektif mirip dengan menggunakan eksekutor shell dengan instalasi Docker host Anda. Gambar akan berada di host, memfasilitasi penggunaan docker build biasa tanpa kendala cache lapisan.

Meskipun pendekatan ini dapat menghasilkan kinerja yang lebih tinggi, konfigurasi yang lebih sedikit, dan tidak ada batasan DinD, pendekatan ini memiliki masalah uniknya sendiri. Yang paling menonjol di antaranya adalah implikasi keamanan:pekerjaan dapat mengeksekusi perintah Docker sewenang-wenang pada Host Runner Anda, sehingga proyek jahat di instans GitLab Anda mungkin menjalankan docker run -it malicious-image:latest atau docker rm -f $(docker ps -a) dengan konsekuensi yang menghancurkan.

GitLab juga memperingatkan bahwa pengikatan soket dapat menyebabkan masalah saat pekerjaan dijalankan secara bersamaan. Ini terjadi ketika Anda mengandalkan container yang dibuat dengan nama tertentu. Jika dua contoh pekerjaan berjalan secara paralel, yang kedua akan gagal karena nama penampung sudah ada di host Anda.

Anda harus mempertimbangkan untuk menggunakan DinD sebagai gantinya jika Anda mengharapkan salah satu dari masalah ini akan merepotkan. Meskipun DinD tidak lagi direkomendasikan secara umum, ini lebih masuk akal untuk instans GitLab yang menghadap publik yang menjalankan tugas CI secara bersamaan.

Mendorong Gambar ke Registri GitLab

Proyek GitLab memiliki opsi registri terintegrasi yang dapat Anda gunakan untuk menyimpan gambar Anda. Anda dapat melihat konten registri dengan menavigasi ke Packages &Registries> Container Registry di sidebar proyek Anda. Jika Anda tidak melihat tautan ini, aktifkan registri dengan masuk ke Pengaturan> Umum> Visibilitas, Proyek, Fitur &Izin dan aktifkan sakelar “Penampung registri”.

GitLab secara otomatis menetapkan variabel lingkungan dalam pekerjaan CI Anda yang memungkinkan Anda mereferensikan registri kontainer proyek Anda. Sesuaikan script bagian untuk masuk ke registri dan mendorong gambar Anda:

script:
  - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
  - docker build -t $CI_REGISTRY_IMAGE:latest .
  - docker push $CI_REGISTRY_IMAGE:latest

GitLab menghasilkan satu set kredensial yang aman untuk setiap pekerjaan CI Anda. $CI_JOB_TOKEN variabel lingkungan akan berisi token akses yang dapat digunakan pekerjaan untuk terhubung ke registri sebagai gitlab-ci-token pengguna. URL server registri tersedia sebagai $CI_REGISTRY .

Variabel terakhir, $CI_REGISTRY_IMAGE , menyediakan jalur lengkap ke registri penampung proyek Anda. Ini adalah dasar yang cocok untuk tag gambar Anda. Anda dapat memperluas variabel ini untuk membuat sub-repositori, seperti $CI_REGISTRY_IMAGE/production/api:latest .

Klien Docker lain dapat menarik gambar dari registri dengan mengautentikasi menggunakan token akses. Anda dapat menghasilkan ini di layar Pengaturan> Akses Token proyek Anda. Tambahkan read_registry lingkup, lalu gunakan kredensial yang ditampilkan untuk docker login ke registri proyek Anda.

Menggunakan Proksi Ketergantungan GitLab

Dependency Proxy GitLab menyediakan lapisan caching untuk gambar upstream yang Anda tarik dari Docker Hub. Ini membantu Anda tetap berada dalam batas kecepatan Docker Hub dengan hanya menarik konten gambar saat benar-benar berubah. Ini juga akan meningkatkan kinerja bangunan Anda.

Proxy Ketergantungan diaktifkan pada tingkat grup GitLab dengan menuju ke Pengaturan> Paket &Registri> Proksi Ketergantungan. Setelah diaktifkan, awali referensi gambar di .gitlab-ci.yml Anda file dengan $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX untuk menarik mereka melalui proxy:

docker_build:
  stage: build
  image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/docker:latest
  services:
    - name: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/docker:dind
      alias: docker

Itu saja! GitLab Runner secara otomatis masuk ke registri proxy dependensi sehingga tidak perlu memberikan kredensial Anda secara manual.

GitLab sekarang akan men-cache gambar Anda, memberi Anda peningkatan kinerja serta ketahanan terhadap pemadaman jaringan. Perhatikan bahwa services definisi juga harus disesuaikan – variabel lingkungan tidak berfungsi dengan formulir sebaris yang digunakan sebelumnya, jadi gambar lengkap name harus ditentukan, maka perintah alias untuk referensi di script . Anda bagian.

Sementara kami sekarang telah menyiapkan proxy untuk gambar yang langsung digunakan oleh tahapan pekerjaan kami, lebih banyak pekerjaan diperlukan untuk menambahkan dukungan untuk gambar dasar di Dockerfile untuk membangun. Instruksi biasa seperti ini tidak akan melalui proxy:

FROM ubuntu:latest

Untuk menambahkan bagian terakhir ini, gunakan argumen build Docker untuk membuat URL proxy dependensi tersedia saat menelusuri Dockerfile:

ARG GITLAB_DEPENDENCY_PROXY
FROM ${GITLAB_DEPENDENCY_PROXY}/ubuntu:latest

Kemudian ubah docker build . Anda perintah untuk menentukan nilai variabel:

script:
  >
    - docker build 
        --build-arg GITLAB_DEPENDENCY_PROXY=${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX} 
        -t example-image:latest .

Sekarang gambar dasar Anda juga akan ditarik melalui proxy dependensi.

Ringkasan

Build image Docker mudah diintegrasikan ke dalam pipeline GitLab CI Anda. Setelah konfigurasi Runner awal, docker build dan docker push perintah dalam script pekerjaan Anda bagian yang Anda butuhkan untuk membuat gambar dengan Dockerfile di repositori Anda. Registri penampung bawaan GitLab memberi Anda penyimpanan pribadi untuk gambar proyek Anda.

Di luar build dasar, ada baiknya mengintegrasikan proxy dependensi GitLab untuk mempercepat kinerja dan menghindari batas kecepatan Docker Hub. Anda juga harus memeriksa keamanan penginstalan Anda dengan menilai apakah metode yang Anda pilih mengizinkan proyek yang tidak tepercaya untuk menjalankan perintah pada host Runner Anda. Meskipun memiliki masalahnya sendiri, Docker-in-Docker adalah pendekatan teraman ketika instans GitLab Anda dapat diakses secara publik atau diakses oleh basis pengguna yang besar.


Docker
  1. Cara Memindahkan Gambar Docker antar Host

  2. Cara Mencari, Menarik, Mendaftar &Menghapus Gambar Docker di Linux

  3. Bagaimana membangun wadah Docker Ilmu Data Anaconda Python

  1. Cara Menggunakan Dockerfile untuk Membangun Gambar Docker

  2. Cara Berbagi Gambar Docker Dengan Orang Lain

  3. Pengantar Gambar Docker

  1. Cara Memodifikasi Gambar Docker

  2. Cara Membuat dan Mengonfigurasi Gambar Docker Kustom secara Otomatis dengan Dockerfile – Bagian 3

  3. Bagaimana cara menggunakan gambar buruh pelabuhan lokal dengan Minikube?