Docker בסיס
build מול run
Section titled “build מול run”docker buildעל ה-runner יוצר image: אין Pod, אין cluster.- ה-kubelet מושך את ה-image ומריץ אותו כ-container בזמן ריצה.
- "service" בהקשר ה-build = תיקיית microservice עם
Dockerfile, לא Kubernetes Service.
build context ו-COPY paths
Section titled “build context ו-COPY paths”docker build -f DOCKERFILE CONTEXT: כל COPY מתייחס ל-context, לא למיקום ה-Dockerfile.
services/ common/trident/ shared package ingest-api/ Dockerfile COPY ingest-api/requirements.txt ./ / COPY common/trident ./trident app/docker build -t <IMAGE>:<CANDIDATE> -f services/<SERVICE>/Dockerfile services/ה-context הוא services/ (לא services/<SERVICE>) כי ה-Dockerfile מעתיק common/trident, תיקיית אחות. נתיבי ה-COPY נכתבים יחסית ל-services/.
איך מוודאים: הפקודה מסתיימת ב-naming to …, ו-docker image ls <IMAGE> מציג את ה-tag.
מבנה שם image
Section titled “מבנה שם image”registry.gitlab.com / trident-lab00/trident-source/ingest-api : dev-20261001-78e24670└── server (before FIRST "/") └── repository path (everything in between) └── tag (after the LAST ":")| חלק | איך מזהים | דוגמה | placeholder |
|---|---|---|---|
| server | עד ה-/ הראשון | registry.gitlab.com | <REGISTRY> |
| repository path | בין ה-/ הראשון ל-: האחרון | trident-lab00/trident-source/ingest-api | חלק מ-<IMAGE> |
| tag | אחרי ה-: האחרון | dev-20261001-78e24670 | <CANDIDATE> |
<IMAGE>:<CANDIDATE>=registry.gitlab.com/trident-lab00/trident-source/ingest-api:dev-20261001-78e24670.- שם ה-service (
ingest-api) הוא חלק מה-path, לא מה-tag. - אם ל-server יש port (
host:5000/...), ה-:של ה-port לפני ה-/ולא נחשב tag. ה-tag הוא ה-:האחרון שאחרי ה-/האחרון. - בלי tag Docker מניח
latest. ב-GitOps לא משתמשים בו.
login ו-push
Section titled “login ו-push”echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"docker push "<IMAGE>:<CANDIDATE>"cat <TOKEN_FILE> | docker login -u <USER> --password-stdin <REGISTRY>docker push <IMAGE>:<CANDIDATE>docker logout <REGISTRY>--password-stdinמוציא את ה-token משורת הפקודה וה-history.docker pushמקבל רקNAME[:TAG]. דגלי build (-t,-f, context) שייכים ל-docker build.- אין login =
denied: access forbiddenב-push. - ה-loop של שלושת ה-services: ci/patterns. credentials ל-push ול-pull: gitlab/registry.
איך מוודאים: docker push מסיים ב-digest: sha256:… size: …, והתג מופיע ב-Project → Deploy → Container registry.
לראות מה יש מקומית
Section titled “לראות מה יש מקומית”docker image ls --format '{{.Repository}}:{{.Tag}}'docker info --format '{{.Driver}}'.Driver = overlay2 (store קלאסי) או overlayfs (containerd store, ראה כרטיס 2).
docker image inspect <IMAGE>:<CANDIDATE> --format '{{.Id}} {{.Created}}'docker manifest inspect <IMAGE>:<CANDIDATE>docker system dfdocker logout <REGISTRY>image inspect בודק image מקומי (id, תאריך יצירה). manifest inspect שואל את ה-registry בלי למשוך (דורש login; ב-tag שלא קיים: no such manifest). system df קורא בלבד: כמה מקום תופסים images ו-containers. logout מנקה credentials מ-~/.docker/config.json.
ב-shell executor ה-images נשארים על המכונה בין jobs (אותו daemon), ולכן build ו-publish יכולים להיות jobs נפרדים. עם docker executor לא. אל תריץ docker system prune על ה-VM של הקורס: הוא מוחק גם images ו-cache של שאר המערכת.
כרטיס סביבה 1: DNS ב-docker build
Section titled “כרטיס סביבה 1: DNS ב-docker build”תסמין: docker build נכשל ב-pip install עם Temporary failure in name resolution.
סיבה: /etc/resolv.conf מצביע על ה-stub של systemd-resolved (nameserver 127.0.0.53, loopback) וקונטיינרים של build לא יכולים להשתמש בו.
readlink -f /etc/resolv.confcat /etc/resolv.confresolvectl status | grep -i 'DNS Servers'הפקודה האחרונה מציגה את שרתי ה-DNS האמיתיים של ה-uplink. ב-VM של התרגול: 192.168.242.2 (ועוד 8.8.8.8). על מכונה אחרת הערכים שונים: קח אותם מהפלט.
sudo cat /etc/docker/daemon.jsonאם הקובץ קיים, מזגו את המפתח בלי למחוק אחרים (ראה כרטיס 2). אם לא קיים:
echo '{"dns":["192.168.242.2","8.8.8.8"]}' | sudo tee /etc/docker/daemon.jsonsudo systemctl restart docker(192.168.242.2 הוא ה-uplink של ה-VM בתרגול; החלף בערך שמצאת ב-resolvectl.)
איך מוודאים: ה-build עובר את שלב pip install, או בדיקה ישירה:
docker run --rm --entrypoint getent <IMAGE>:<CANDIDATE> hosts registry.gitlab.comמודפסת כתובת IP. לאחר systemctl restart docker, containers רצים עלולים להיעצר (אלא אם live-restore מוגדר).
כרטיס סביבה 2: blob unknown to registry ב-push
Section titled “כרטיס סביבה 2: blob unknown to registry ב-push”תסמין: ה-image הראשון נדחף, השני נכשל: blob unknown to registry - sha256:… (blob של ה-config, שדולג עליו כ-cross-repo mount).
סיבה: Docker 29 משתמש כברירת מחדל ב-containerd image store. ה-pusher שלו מנסה mount בין repositories, ו-registry של gitlab.com לא מתמודד עם זה.
docker info --format '{{.Driver}}'docker info --format '{{json .DriverStatus}}'driver-type = io.containerd.snapshotter.v1 (והדרייבר overlayfs) = containerd store. המטרה: store קלאסי, overlay2.
תיקון: קוד ה-pipeline לא משתנה. מוסיפים ל-daemon.json את features:
{ "dns": ["192.168.242.2", "8.8.8.8"], "features": { "containerd-snapshotter": false }}sudo jq . /etc/docker/daemon.jsonsudo systemctl restart dockerdocker info --format '{{.Driver}}'איך מוודאים: jq מדפיס את ה-JSON (תקין), ו-.Driver הוא overlay2.
אם Docker דחה את ההגדרה: docker buildx build --push מאחד build ו-push (דגל --push אומת). התקציר של שני הכרטיסים (לצד כרטיסי סביבה אחרים): debugging/env-cards.