הפעלת קונטיינרים במופעים

אפשר להריץ קונטיינר של Docker במכונה שמריצה מערכת הפעלה שמותאמת לקונטיינרים, בדומה להרצה ברוב ההפצות האחרות של תמונות צמתים, באמצעות הפקודה docker run. לדוגמה:

docker run --rm busybox echo "hello world"

הפלט הבא מופיע:

Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
. . .
Status: Downloaded newer image for busybox:latest
hello world
כשמנהלים מפתחות SSH במטא-נתונים, כל חשבונות המשתמשים שמנוהלים על ידי Compute Engine בתמונה cos נוספים לקבוצה docker כברירת מחדל. כך כל משתמש שמחובר לחשבון יכול להריץ פקודות docker בלי הרשאות root. כשמנהלים מפתחות SSH באמצעות OS Login, צריך להוסיף ידנית את חשבון המשתמש לקבוצה docker. אחרת, המשתמש צריך להוסיף sudo לכל פקודה של docker.

גישה לתמונות ציבוריות ב-Container Registry או ב-Artifact Registry

התמיכה ב-Container Registry מוטמעת בקובץ האימג' של הצומת cos. כדי להפעיל קונטיינר מ-Container Registry, מריצים את הפקודה:

docker run --rm gcr.io/google-containers/busybox echo "hello world"

הפלט הבא מופיע:

Unable to find image 'gcr.io/google-containers/busybox:latest' locally
Pulling repository gcr.io/google-containers/busybox
. . .
Status: Downloaded newer image for gcr.io/google-containers/busybox:latest
hello world

גישה לתמונות פרטיות ב-Artifact Registry או ב-Container Registry

החל מגרסאות Milestone 60,‏ docker-credential-gcr מותקן מראש בתמונות של מערכת הפעלה שמותאמת לקונטיינרים. זו הדרך המומלצת לגשת לתמונות פרטיות ב-Artifact Registry או ב-Container Registry.

כדי להשתמש ב-docker-credential-gcr, מריצים את הפקודה הבאה:

Artifact Registry

docker-credential-gcr configure-docker --registries LOCATION-docker.pkg.dev

מחליפים את LOCATION במיקום של המאגר.

Container Registry

docker-credential-gcr configure-docker

הפלט הבא מופיע:

/home/username/.docker/config.json configured to use this credential helper

כדי להריץ אימג' מהמאגר, משתמשים בפקודה הבאה:

Artifact Registry

docker run --rm LOCATION-docker.pkg.dev/your-project/repository/your-image

מחליפים את LOCATION במיקום של המאגר.

Container Registry

docker run --rm gcr.io/your-project/your-image

אפשר להשתמש בשמות המארחים הבאים של Container Registry:

  • us.gcr.io
  • eu.gcr.io
  • asia.gcr.io

כדי להשתמש ב-Docker עם sudo, מריצים את הפקודה הבאה. הדגל -E בשורת הפקודה גורם ל-Docker להשתמש בקובץ .docker/config.json מספריית הבית של המשתמש במקום מספריית הבית של הבסיס.

Artifact Registry

sudo -E docker run --rm LOCATION-docker.pkg.dev/your-project/repository/your-image

מחליפים את LOCATION במיקום של המאגר.

Container Registry

sudo -E docker run --rm gcr.io/your-project/your-image

שמות המארחים הנתמכים ב-Container Registry הם:

  • us.gcr.io
  • eu.gcr.io
  • asia.gcr.io

לחלופין, אפשר לאחזר אסימוני גישה מתאימים של OAuth ממטא-נתונים של Compute Engine ולהשתמש בהם עם הפקודה docker login באופן ידני, כמו בדוגמה הבאה:

METADATA=http://metadata.google.internal/computeMetadata/v1
SVC_ACCT=$METADATA/instance/service-accounts/default
ACCESS_TOKEN=$(curl -H 'Metadata-Flavor: Google' $SVC_ACCT/token | cut -d'"' -f 4)
docker login -u oauth2accesstoken -p $ACCESS_TOKEN https://gcr.io
docker run  gcr.io/your-project/your-image

שימוש ב-cloud-init עם Container Registry

בדוגמה הזו של cloud-init נעשה שימוש בפורמט Cloud Config כדי להפעיל קונטיינר Docker מקובץ אימג' שמאוחסן במאגר קונטיינרים של Docker שנקרא DockerHub. בדוגמה שלמטה נעשה שימוש בפורמט Cloud Config כדי להפעיל קונטיינר Docker מקובץ אימג' שמאוחסן ב-Container Registry:

#cloud-config

write_files:
- path: /etc/systemd/system/cloudservice.service
  permissions: 0644
  owner: root
  content: |
    [Unit]
    Description=Start a simple docker container
    Wants=gcr-online.target
    After=gcr-online.target

    [Service]
    Environment="HOME=/home/cloudservice"
    ExecStartPre=/usr/bin/docker-credential-gcr configure-docker
    ExecStart=/usr/bin/docker run --rm --name=mycloudservice gcr.io/google-containers/busybox:latest /bin/sleep 3600
    ExecStop=/usr/bin/docker stop mycloudservice
    ExecStopPost=/usr/bin/docker rm mycloudservice

runcmd:
- systemctl daemon-reload
- systemctl start cloudservice.service

הגדרת Docker daemon למשיכת קובצי אימג' ממטמון המרשם

אפשר להגדיר את Docker daemon כך שימשוך תמונות ממטמון של registry באמצעות registry mirrors.

  1. כדי להגדיר את הדמון לשימוש באפשרות registry-mirror, אפשר להשתמש באחת מהשיטות הבאות:

    • בקובץ /etc/default/docker, מוסיפים את האפשרות registry-mirror לרישום (לדוגמה, https://mirror.gcr.io):
    echo 'DOCKER_OPTS="--registry-mirror=https://mirror.gcr.io"' | tee /etc/default/docker
    • בקובץ /etc/default/docker, מוסיפים את "--registry-mirror=https://mirror.gcr.io" ל-DOCKER_OPTS הקיים:
    sed -i -e 's|"$| --registry-mirror=https://mirror.gcr.io"|' /etc/default/docker
  2. אחרי שמוסיפים את שיקוף הרישום, מפעילים מחדש את ה-daemon של Docker כדי שהשינויים ייכנסו לתוקף:

    sudo systemctl daemon-reload
    sudo systemctl restart docker

הוספת הגדרה ל-/etc/default/docker לא נשמרת אחרי הפעלה מחדש. כדי לוודא שהגדרת Docker תישמר גם אחרי הפעלה מחדש, כדאי להוסיף את הפקודות לסקריפט cloud-init של המטא-נתונים של המופע בפורמט cloud-config או startup script.

בדוגמה הבאה נעשה שימוש בפורמט cloud-config כדי להגדיר registry-mirror:

#cloud-config

runcmd:
- echo 'DOCKER_OPTS="--registry-mirror=https://mirror.gcr.io"' | tee /etc/default/docker
- systemctl daemon-reload
- systemctl restart docker
Google Cloud

מידע נוסף על הגדרת מכונה באמצעות cloud-init זמין במאמר שימוש ב-cloud-init עם פורמט ההגדרות של Cloud.

פתרון בעיות

פתרון התנגשויות בין אפשרויות ב-Docker daemon.json לבין דגלים

כשמגדירים את Docker daemon, אם אותה אפשרות מוגדרת באמצעות קובץ daemon.json וגם באמצעות פלאגים, Docker לא יופעל ותוצג שגיאה דומה לזו:

unable to configure the Docker daemon with file /etc/docker/daemon.json:
the following directives are specified both as a flag and in the configuration file:

הפתרון המומלץ לפתרון הקונפליקט הזה הוא לשנות את ברירת המחדל של daemon.json, שנמצא ב-/etc/docker/daemon.json. שינוי הקובץ הזה מאפשר לשנות רק את האפשרויות המושפעות, תוך שמירה על אפשרויות ברירת המחדל האחרות. אפשר לעשות זאת באמצעות cloud-init, לדוגמה באמצעות cloud-config דומה ל:

#cloud-config

write_files:
- path: /tmp/modify_docker_daemon_opts.py
  permissions: 0744
  owner: root
  content: |
    import json, sys, os, logging

    DAEMON_OPTS_FILE = '/etc/docker/daemon.json'

    opts = {}
    if os.path.exists(DAEMON_OPTS_FILE):
      with open(DAEMON_OPTS_FILE) as f:
          try:
            opts = json.load(f)
          except:
            logging.info("json parsing failed, starting with empty config.")
            pass
    # Add your daemon option modifications here
    # For example,
    # opts['log-opts']['max-size'] = '100m'
    with open(DAEMON_OPTS_FILE, 'w') as f:
        json.dump(opts, f)

runcmd:
- python /tmp/modify_docker_daemon_opts.py
- rm -f /tmp/modify_docker_daemon_opts.py
- systemctl restart docker.service