דלגו לתוכן

Docker בסיס

  • docker build על ה-runner יוצר image: אין Pod, אין cluster.
  • ה-kubelet מושך את ה-image ומריץ אותו כ-container בזמן ריצה.
  • "service" בהקשר ה-build = תיקיית microservice עם Dockerfile, לא Kubernetes Service.

docker build -f DOCKERFILE CONTEXT: כל COPY מתייחס ל-context, לא למיקום ה-Dockerfile.

file tree (TRIDENT source)
services/
common/trident/ shared package
ingest-api/
Dockerfile COPY ingest-api/requirements.txt ./ / COPY common/trident ./trident
app/
runs on: any shell
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.

anatomy
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 לא משתמשים בו.
runs on: CI job
echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
docker push "<IMAGE>:<CANDIDATE>"
runs on: VM
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.

runs on: VM
docker image ls --format '{{.Repository}}:{{.Tag}}'
docker info --format '{{.Driver}}'

.Driver = overlay2 (store קלאסי) או overlayfs (containerd store, ראה כרטיס 2).

runs on: VM
docker image inspect <IMAGE>:<CANDIDATE> --format '{{.Id}} {{.Created}}'
docker manifest inspect <IMAGE>:<CANDIDATE>
docker system df
docker 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 לא יכולים להשתמש בו.

runs on: VM
readlink -f /etc/resolv.conf
cat /etc/resolv.conf
resolvectl status | grep -i 'DNS Servers'

הפקודה האחרונה מציגה את שרתי ה-DNS האמיתיים של ה-uplink. ב-VM של התרגול: 192.168.242.2 (ועוד 8.8.8.8). על מכונה אחרת הערכים שונים: קח אותם מהפלט.

runs on: VM
sudo cat /etc/docker/daemon.json

אם הקובץ קיים, מזגו את המפתח בלי למחוק אחרים (ראה כרטיס 2). אם לא קיים:

runs on: VM
echo '{"dns":["192.168.242.2","8.8.8.8"]}' | sudo tee /etc/docker/daemon.json
sudo systemctl restart docker

(192.168.242.2 הוא ה-uplink של ה-VM בתרגול; החלף בערך שמצאת ב-resolvectl.)

איך מוודאים: ה-build עובר את שלב pip install, או בדיקה ישירה:

runs on: VM
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 לא מתמודד עם זה.

runs on: VM
docker info --format '{{.Driver}}'
docker info --format '{{json .DriverStatus}}'

driver-type = io.containerd.snapshotter.v1 (והדרייבר overlayfs) = containerd store. המטרה: store קלאסי, overlay2.

תיקון: קוד ה-pipeline לא משתנה. מוסיפים ל-daemon.json את features:

file: /etc/docker/daemon.json
{
"dns": ["192.168.242.2", "8.8.8.8"],
"features": { "containerd-snapshotter": false }
}
runs on: VM
sudo jq . /etc/docker/daemon.json
sudo systemctl restart docker
docker info --format '{{.Driver}}'

איך מוודאים: jq מדפיס את ה-JSON (תקין), ו-.Driver הוא overlay2.

אם Docker דחה את ההגדרה: docker buildx build --push מאחד build ו-push (דגל --push אומת). התקציר של שני הכרטיסים (לצד כרטיסי סביבה אחרים): debugging/env-cards.