KUBERNETES / DƏRS 02Pulsuz dərs

Konteyner image-ləri və Docker build

Tətbiqin mənbə kodundan Kubernetes node-unun işlədə biləcəyi image-ə.

Orkestrasiyadan əvvəl artefaktı tanı: image layları, Dockerfile, registry və konteyner runtime-ı.

Təxminən 20 dəq.Bir tətbiq, iki build
MƏNBƏ KODUNDAN RUNTIME-A
Mənbə kodu + Dockerfiledocker build
Image → Registry → Node
Image istinadıacademy-web:1.0

Image-i yarat, paylaş, sonra ondan konteynerlər başlat.

Dərsdən sonra nəyi izah edə biləcəksən?

  • Image, konteyner, tag və digest arasındakı fərqi izah etmək.
  • Dockerfile-ı oxumaq və çoxmərhələli build-in faydasını anlamaq.
  • Image-in registry-dən CRI-yə uyğun runtime-a qədər yolunu izləmək.

Oxumaq üçün quraşdırma lazım deyil. Kod nümunələri üçün Linux konteynerləri işlədən Docker, internet bağlantısı və boş lokal 8081, 8082 portları lazımdır.

Konteyner image-ləri

Image konteynerin başladılması üçün lazım olan fayl sistemi və konfiqurasiya paketidir. Konteyner isə həmin image-dən yaradılan, öz proses vəziyyəti və yazıla bilən layı olan instansiyadır. Tətbiqi yenidən build etmədən eyni image-dən bir neçə konteyner başlatmaq mümkündür.

Image tam virtual maşın deyil. Konteynerlər host-un əməliyyat sistemi nüvəsini paylaşır; Docker Desktop adətən Linux konteynerlərini Linux virtual maşınının içində işlədir. Image işləyəcəyi platformaya uyğun olmalıdır: linux/arm64 üçün yaradılan image linux/amd64 node-u üçün avtomatik uyğun sayılmır.

Fayl sistemi layları dəyişiklikləri saxlayır və image-lər arasında paylaşıla bilir. İşləyən konteynerin yazıla bilən layındakı dəyişikliklər ilkin image-i dəyişmir. Konteyner silindikdən sonra da qalmalı olan məlumat uyğun volume-da və ya xarici servisdə saxlanmalıdır.

academy-web:1.0 kimi tag insan üçün oxunaqlı istinaddır və sonradan başqa məzmuna yönəldilə bilər. Digest isə məzmunu müəyyən edir. Oxunaqlılıq üçün versiya tag-ından, yerləşdirmədə konkret image-i seçmək üçün yoxlanmış digest-dən istifadə et. latest sadəcə tag adıdır, yeniliyə zəmanət vermir.

Docker ilə tətbiq image-inin yaradılması

Nümunə yalnız Go standart kitabxanasından istifadə edən kiçik HTTP servisidir. Kompilyator Docker daxilində işlədiyi üçün host-a Go quraşdırmaq tələb olunmur. Aşağıdakı fayllar eyni qovluğa aiddir. Konteyner şəbəkəsindən müraciət qəbul etmək üçün servis :8080 ünvanını dinləyir.

Dockerfile build-in necə aparılacağını təsvir edir. FROM başlanğıc image-i seçir, WORKDIR iş qovluğunu təyin edir, COPY mənbə fayllarını əlavə edir, RUN isə build zamanı proqramı kompilyasiya edir. ENTRYPOINT sonradan konteyner işə salınanda başlayacaq prosesi göstərir. USER root olmayan rəqəmsal istifadəçi identifikatorunu seçir; adlı hesab yaratmır.

docker build əmrinin sonundakı nöqtə build context-i, yəni build-ə verilən qovluğu göstərir. COPY həmin kontekstə daxil olan faylları oxuya bilir. .dockerignore lazımsız və məxfi faylları kənarda saxlayır, amma daxil edilən faylların yoxlanmasını əvəz etmir. Məxfi məlumatı image-ə köçürüb sonrakı layda silmək təhlükəsiz deyil. Özəl asılılıqlar üçün məxfi məlumatı ARG və ya ENV ilə vermək əvəzinə BuildKit secret mount istifadə et.

Bu ilk image işləyir, amma kompilyatoru və build mühitini də saxlayır. EXPOSE tətbiqin portunu sənədləşdirir, host-da port açmır. Aşağıdakı -p seçimi host-un 8081 portunu konteynerin 8080 portuna bağlayır və yalnız lokal loopback ünvanında açır. Image-in yaradılması ilə konteynerin başladılması ayrı əməliyyatlardır.

go.mod
module example.com/academy-web

go 1.26.0
main.go
package main

import (
    "fmt"
    "log"
    "net/http"
    "time"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello from Proxy Academy")
    })
    server := &http.Server{
        Addr: ":8080",
        Handler: mux,
        ReadHeaderTimeout: 5 * time.Second,
    }
    log.Fatal(server.ListenAndServe())
}
Dockerfile
FROM golang:1.26-alpine
WORKDIR /src
COPY go.mod main.go ./
RUN CGO_ENABLED=0 go build -trimpath -o /server .
USER 65532:65532
EXPOSE 8080
ENTRYPOINT ["/server"]
.dockerignore
.git
.env
.env.*
*.pem
*.key
bin/
coverage/
Build və başlanma
docker build -t academy-web:single .
docker run -d --name academy-web-single -p 127.0.0.1:8081:8080 academy-web:single
HTTP cavabını yoxla
curl --fail http://127.0.0.1:8081/
Gözlənilən cavab
Hello from Proxy Academy

Çoxmərhələli image build-i

Çoxmərhələli Dockerfile tətbiqi yaratmaq üçün lazım olan alətlərlə onu işlətmək üçün lazım olan faylları ayırır. build mərhələsi servisi kompilyasiya edir. runtime mərhələsi scratch-dən başlayır və yalnız hazır binar faylı götürür. Kompilyator və mənbə kodu son image-ə daxil olmur.

Bu standart kitabxanalı Go servisi üçün CGO_ENABLED=0 C runtime-dan asılı olmayan binar fayl yaradır. scratch boş başlanğıcdır: shell, paket meneceri, sertifikat anbarı və saat qurşağı bazası yoxdur. Tətbiq bunlara ehtiyac duyursa, lazımi faylları əlavə et və ya uyğun minimal runtime image-i seç. Məsələn, Java tətbiqinə adətən Java runtime lazımdır.

Build cache dəyişməmiş işi təkrar istifadə edir. Xarici asılılığı olan layihələrdə əvvəl asılılıq manifestlərini köçürüb asılılıqları yüklə, daha tez-tez dəyişən mənbə kodunu isə sonra əlavə et. Asılılıq dəyişəndə uyğun cache yenilənməlidir. Cache-dən səmərəli istifadə yoxlanmış təhlükəsizlik düzəlişlərini almaq üçün yenidən build etməyi əvəz etmir.

Nümunədəki Go tag-ı öyrənmək üçün rahatdır, amma dəyişə bilər. Təkrarlana bilən buraxılış build-lərində baza image-ini yoxlanmış digest ilə sabitlə və planlı şəkildə yenilə. Kiçik image lazımsız paketləri azaldır; tətbiqin təhlükəsiz olduğunu sübut etmir.

Dockerfile.multistage
FROM golang:1.26-alpine AS build
WORKDIR /src
COPY go.mod main.go ./
RUN CGO_ENABLED=0 go build -trimpath -o /server .

FROM scratch AS runtime
COPY --from=build /server /server
USER 65532:65532
EXPOSE 8080
ENTRYPOINT ["/server"]
Runtime image-inin yaradılması
docker build -f Dockerfile.multistage -t academy-web:1.0 .
docker image ls academy-web
docker run -d --name academy-web-runtime -p 127.0.0.1:8082:8080 academy-web:1.0
Eyni tətbiq, daha kiçik runtime
curl --fail http://127.0.0.1:8082/
Gözlənilən cavab
Hello from Proxy Academy

Image-lərin uzaq registry-də saxlanması

Lokal image onu yaradan maşında və ya builder-də saxlanır. Kubernetes node-larının onu əldə edə bilməsi üçün paylama yolu lazımdır. Registry image-ləri saxlayıb paylayır, repository əlaqəli image-ləri qruplaşdırır, tag isə repository daxilində istinadı adlandırır. Məsələn, docker.io/YOUR_DOCKERHUB_USER/academy-web:1.0 registry, namespace, repository və tag-dan ibarətdir.

Aşağıdakı əmrlər Docker Hub-a yayımlamanı göstərir. YOUR_DOCKERHUB_USER hissəsini idarə etdiyin namespace ilə əvəz et və push-dan əvvəl repository-ni istədiyin görünmə qaydası ilə yarat. docker tag yeni istinad əlavə edir, image-i yenidən build etmir. docker push həmin image-i registry-yə göndərir. Bu, lokal build deyil, xarici mühitə yayımlama addımıdır.

docker login və dəstəklənən giriş axını ilə autentifikasiyadan keç. Parol və ya token-i Dockerfile-a yazma. Özəl repository üçün Kubernetes tərəfində də oxuma icazəsi lazımdır; noutbukundakı giriş məlumatları avtomatik olaraq bütün node-lara keçmir. Bu giriş adətən imagePullSecrets və ya platformanın credential provider-i ilə qurulur.

Yayımlamadan sonra yerləşdirmədə istifadə etmək üçün registry digest-ini qeyd et. Çoxplatformalı image indeksi müxtəlif arxitekturalara uyğun image-ləri seçə bilir. Təkcə ARM noutbukda build etmək AMD64 image yaratmır; klasterin tələb etdiyi platformaları ayrıca build edib yoxla.

Registry-yə yayımlama
docker login
docker tag academy-web:1.0 docker.io/YOUR_DOCKERHUB_USER/academy-web:1.0
docker push docker.io/YOUR_DOCKERHUB_USER/academy-web:1.0
docker pull docker.io/YOUR_DOCKERHUB_USER/academy-web:1.0

Container Runtime Interface

Docker image yaratmaq və lokal yoxlamaq üçün faydalıdır, amma Docker ilə yaradılmış image-i işlətmək üçün Kubernetes node-unda Docker Engine olması şərt deyil. OCI image spesifikasiyaları paketləmə və paylama formatlarını təsvir edir. CRI isə kubelet-in uyğun runtime-dan image və konteynerləri idarə etməsini necə istədiyini müəyyən edir. Bunlar ayrı məsələlərdir.

CRI kubelet ilə konteyner runtime-ı arasında gRPC interfeysidir. Kubelet image əməliyyatlarını onun image xidməti, Pod sandbox-larını və konteynerləri isə runtime xidməti vasitəsilə idarə edir. containerd və CRI-O uyğun reallaşdırmalar təqdim edir; runtime aşağı səviyyəli konteyner icrasını runc kimi komponentlərə həvalə edir.

Scheduler node-u seçir, konteynerləri icra etmir. Pod təyin olunduqdan sonra kubelet həmin node-dakı runtime ilə işləyir. Pod spesifikasiyası qəbul edilsə də, image-in tapılmaması, platforma uyğunsuzluğu və ya registry icazəsi problemi başlanmanı dayandıra bilər. Ardıcıllığı belə düşün: image istinadı → registry-yə giriş → image-in yüklənməsi → konteynerin başlanması.

Təmizləmə

Konteynerin, image-in, volume-un və build cache-in həyat dövrü ayrıdır. Konteyneri dayandırmaq onu diskdən silmir. Konteyner silinəndə onun yazıla bilən layı silinir, amma image-i və adlı volume-u silinmir. Lokal image-in silinməsi uzaq registry-dəki nüsxəni də silmir.

Nümunə təmizləmə yalnız iki demo konteynerini və onların image tag-larını göstərir. Silməzdən əvvəl konteynerləri dayandır. Əlavə registry tag-ı yaratmısansa, ehtiyac bitəndə həmin lokal tag-ı ayrıca sil. Paylaşılan inkişaf maşınında geniş prune əmrlərindən çəkin: əlaqəsiz resurslara hələ ehtiyac ola bilər.

Yalnız nümunə resurslarının silinməsi
docker stop academy-web-single academy-web-runtime
docker rm academy-web-single academy-web-runtime
docker image rm academy-web:single academy-web:1.0

Xülasə

Build image yaradır, run isə həmin image-dən konteyner başladır. Çoxmərhələli build alətləri runtime image-indən kənarda saxlayır. Registry hazır artefaktı başqa maşınlara çatdırır; tag və digest isə fərqli identifikasiya ehtiyaclarını qarşılayır.

Kubernetes bu artefaktı giriş kimi qəbul edir. Kubelet və CRI-yə uyğun runtime image istinadını seçilmiş node-da işləyən konteynerlərə çevirir. Növbəti dərsdə control plane-in bu işi necə əlaqələndirdiyini və arzu olunan vəziyyətə necə çatdığını öyrənəcəksən.

Mənbələr və əlavə oxu

Docker və Kubernetes sənədlərinə əsaslanan orijinal izahlar və nümunələr.