בדף הזה נסביר איך ליצור תמונות Docker קטנות יותר.
יצירת קונטיינרים יעילים יותר
כשמכניסים אפליקציה לקונטיינר, יכול להיות שקבצים שלא נדרשים בזמן הריצה, כמו תלות בזמן הבנייה וקבצים זמניים, ייכללו בטעות בקובץ אימג' של קונטיינר. הקבצים האלה לא נחוצים, והם יכולים להגדיל את הגודל של קובץ האימג' של הקונטיינר. כתוצאה מכך, התהליך של העברת האימג' בין מאגר Docker לבין זמן הריצה של הקונטיינר ייקח יותר זמן ויעלה יותר כסף.
כדי לעזור להקטין את הגודל של קובץ אימג' של קונטיינר, צריך להפריד בין בניית האפליקציה, כולל הכלים שמשמשים לבנייה, לבין הרכבת הקונטיינר של זמן הריצה.
Cloud Build מספק סדרה של קונטיינרים של Docker עם כלים נפוצים למפתחים כמו Git, Docker ו-Google Cloud CLI. אפשר להשתמש בכלים האלה כדי להגדיר קובץ תצורת build עם שלב אחד לבניית האפליקציה, ושלב נוסף להרכבת סביבת זמן הריצה הסופית שלה.
לדוגמה, אם אתם מפתחים אפליקציית Java שדורשת קבצים כמו קוד המקור, ספריות האפליקציה, מערכות build, תלות במערכת build ו-JDK, יכול להיות שקובץ ה-Dockerfile שלכם ייראה כך:
FROM java:8
COPY . workdir/
WORKDIR workdir
RUN GRADLE_USER_HOME=cache ./gradlew buildDeb -x test
RUN dpkg -i ./gate-web/build/distributions/*.deb
CMD ["/opt/gate/bin/gate"]
בדוגמה שלמעלה, Gradle, שמשמש ליצירת החבילה, מוריד מספר גדול של ספריות כדי לפעול. הספריות האלה חיוניות לבניית החבילה, אבל לא נדרשות בזמן הריצה. כל התלויות בזמן הריצה כלולות בחבילה.
כל פקודה ב-Dockerfile יוצרת שכבה חדשה במאגר. אם נתונים נוצרים בשכבה הזו ולא נמחקים באותה פקודה, אי אפשר לשחזר את המרחב. במקרה הזה, Gradle מוריד מאות מגה-בייט של ספריות לספרייה cache כדי לבצע את הבנייה, אבל הספריות לא נמחקות.
דרך יעילה יותר לבצע את הבנייה היא להשתמש ב-Cloud Build כדי להפריד בין בניית האפליקציה לבין בניית שכבת זמן הריצה שלה.
בדוגמה הבאה, השלב של בניית אפליקציית Java מופרד מהשלב של הרכבת קונטיינר זמן הריצה:
YAML
-
מפתחים את האפליקציה: ב-
cloudbuild.yaml, מוסיפים שלב לפיתוח האפליקציה.הקוד הבא מוסיף שלב שיוצר את תמונת
java:8, שמכילה את קוד Java.steps: - name: 'java:8' env: ['GRADLE_USER_HOME=cache'] entrypoint: 'bash' args: ['-c', './gradlew gate-web:installDist -x test']
- הרכבת מאגר התגים של זמן הריצה: ב-
cloudbuild.yaml, מוסיפים שלב להרכבת מאגר התגים של זמן הריצה.הקוד הבא מוסיף שלב בשם
gcr.io/cloud-builders/dockerשמרכיב את מאגר הזמן הריצה. הוא מגדיר את מאגר זמן הריצה בקובץ נפרד בשםDockerfile.slim.בדוגמה נעשה שימוש בשכבת הבסיס של Alpine Linux
openjdk:8u111-jre-alpine, שהיא מאוד רזה. בנוסף, הוא כולל את JRE, במקום JDK מגושם יותר שהיה נחוץ לבניית האפליקציה.cloudbuild.yaml steps: - name: 'java:8' env: ['GRADLE_USER_HOME=cache'] entrypoint: 'bash' args: ['-c', './gradlew gate-web:installDist -x test'] - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest', '-f', 'Dockerfile.slim', '.' ] Dockerfile.slim FROM openjdk:8-jre-alpine COPY ./gate-web/build/install/gate /opt/gate CMD ["/opt/gate/bin/gate"] - יוצרים את קובצי האימג' של Docker: ב-
cloudbuild.yaml, מוסיפים שלב ליצירת קובצי האימג'.steps: - name: 'java:8' env: ['GRADLE_USER_HOME=cache'] entrypoint: 'bash' args: ['-c', './gradlew gate-web:installDist -x test'] - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest', '-f', 'Dockerfile.slim', '.'] images: - 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA' - 'gcr.io/$PROJECT_ID/$REPO_NAME:latest'
JSON
-
יצירת גרסת build של האפליקציה: ב-
cloudbuild.json, מוסיפים שלב ליצירת גרסת build של האפליקציה.הקוד הבא מוסיף שלב בשם
java:8לבניית קוד Java.{ "steps": [ { "name": "java:8", "env": [ "GRADLE_USER_HOME=cache" ], "entrypoint": "bash", "args": [ "-c", "./gradlew gate-web:installDist -x test" ] }, } -
הרכבת מאגר התגים של זמן הריצה: ב-
cloudbuild.json, מוסיפים שלב להרכבת מאגר התגים של זמן הריצה.הקוד הבא מוסיף שלב בשם
gcr.io/cloud-builders/dockerשמרכיב את מאגר הזמן הריצה. הוא מגדיר את מאגר זמן הריצה בקובץ נפרד בשםDockerfile.slim.בדוגמה נעשה שימוש בשכבת הבסיס של Alpine Linux
openjdk:8u111-jre-alpine, שהיא מאוד רזה. בנוסף, הוא כולל את JRE, במקום JDK מגושם יותר שהיה נחוץ לבניית האפליקציה.cloudbuild.json: { "steps": [ { "name": "java:8", "env": [ "GRADLE_USER_HOME=cache" ], "entrypoint": "bash", "args": [ "-c", "./gradlew gate-web:installDist -x test" ] }, { "name": "gcr.io/cloud-builders/docker", "args": [ "build", "-t", "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA", "-t", "gcr.io/$PROJECT_ID/$REPO_NAME:latest", "-f", "Dockerfile.slim", "." ] } ], } Dockerfile.slim: FROM openjdk:8u111-jre-alpine COPY ./gate-web/build/install/gate /opt/gate CMD ["/opt/gate/bin/gate"] - יצירת קובצי האימג' של Docker: ב-
cloudbuild.json, מוסיפים שלב ליצירת קובצי האימג'{ "steps": [ { "name": "java:8", "env": [ "GRADLE_USER_HOME=cache" ], "entrypoint": "bash", "args": [ "-c", "./gradlew gate-web:installDist -x test" ] }, { "name": "gcr.io/cloud-builders/docker", "args": [ "build", "-t", "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA", "-t", "gcr.io/$PROJECT_ID/$REPO_NAME:latest", "-f", "Dockerfile.slim", "." ] } ], "images": [ "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA", "gcr.io/$PROJECT_ID/$REPO_NAME:latest" ] }