Ejecutar contenedores en instancias

Puedes ejecutar un contenedor Docker en una máquina que ejecute Container-Optimized OS de forma muy similar a como lo harías en la mayoría de las demás distribuciones de imágenes de nodo, mediante el comando docker run. Por ejemplo:

docker run --rm busybox echo "hello world"

Aparecerá el siguiente resultado:

Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
. . .
Status: Downloaded newer image for busybox:latest
hello world
Al gestionar claves SSH en metadatos, todas las cuentas de usuario gestionadas por Compute Engine en la imagen cos se añaden al grupo docker de forma predeterminada. De esta forma, cualquier usuario que haya iniciado sesión puede ejecutar comandos docker sin privilegios de administrador. Cuando se gestionan las claves SSH mediante el inicio de sesión del SO, la cuenta de usuario debe añadirse manualmente al grupo docker. De lo contrario, el usuario tendrá que añadir sudo a cada comando docker.

Acceder a imágenes públicas en Container Registry o Artifact Registry

La compatibilidad con Container Registry está integrada en la imagen de nodo cos. Para iniciar un contenedor desde Container Registry, ejecuta el siguiente comando:

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

Aparecerá el siguiente resultado:

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

Acceder a imágenes privadas en Artifact Registry o Container Registry

A partir de las versiones de la fase 60, docker-credential-gcr está preinstalado en las imágenes de Container-Optimized OS. Es la forma recomendada de acceder a imágenes privadas en Artifact Registry o Container Registry.

Para usar docker-credential-gcr, ejecuta el siguiente comando:

Artifact Registry

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

Sustituye LOCATION por la ubicación de tu repositorio.

Container Registry

docker-credential-gcr configure-docker

Aparecerá el siguiente resultado:

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

Para ejecutar una imagen del registro, usa el siguiente comando:

Artifact Registry

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

Sustituye LOCATION por la ubicación de tu repositorio.

Container Registry

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

Puede usar los siguientes nombres de host de Container Registry:

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

Para usar Docker con sudo, ejecuta el siguiente comando. La marca de la línea de comandos -E hace que Docker use el archivo .docker/config.json del directorio principal de un usuario en lugar del directorio principal raíz.

Artifact Registry

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

Sustituye LOCATION por la ubicación de tu repositorio.

Container Registry

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

Los nombres de host de Container Registry admitidos son los siguientes:

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

También puedes obtener los tokens de acceso de OAuth adecuados de los metadatos de Compute Engine y usarlos manualmente con el comando docker login, como se muestra en el siguiente ejemplo:

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

Usar cloud-init con Container Registry

En este ejemplo de cloud-init se usa el formato Cloud Config para iniciar un contenedor Docker a partir de una imagen almacenada en el registro de contenedores de Docker, llamado DockerHub. En el ejemplo siguiente se usa el formato de configuración de Cloud para iniciar un contenedor de Docker a partir de una imagen almacenada en 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

Configurar el daemon de Docker para extraer imágenes de la caché del registro

Puedes configurar el daemon de Docker para que extraiga imágenes de una caché de registro mediante réplicas del registro.

  1. Configura el daemon para que use la opción registry-mirror de una de las siguientes formas:

    • En el archivo /etc/default/docker, añade la opción registry-mirror para el registro (por ejemplo, https://mirror.gcr.io):
    echo 'DOCKER_OPTS="--registry-mirror=https://mirror.gcr.io"' | tee /etc/default/docker
    • En el archivo /etc/default/docker, añade "--registry-mirror=https://mirror.gcr.io" al DOCKER_OPTS que ya tengas:
    sed -i -e 's|"$| --registry-mirror=https://mirror.gcr.io"|' /etc/default/docker
  2. Después de añadir la réplica del registro, reinicia el daemon de Docker para que los cambios surtan efecto:

    sudo systemctl daemon-reload
    sudo systemctl restart docker

Si añades una configuración a /etc/default/docker, no se conservará después de reiniciar. Para asegurarte de que tu configuración de Docker se mantenga persistente tras los reinicios, te recomendamos que añadas los comandos al script cloud-init de los metadatos de la instancia en formato cloud-config o startup script.

En el siguiente ejemplo se usa el formato cloud-config para configurar un registry-mirror:

#cloud-config

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

Para obtener más información sobre cómo configurar una instancia con cloud-init, consulta Usar cloud-init con el formato de configuración de nube.

Solución de problemas

Resolución de conflictos de opciones entre Docker daemon.json y las marcas

Al configurar el daemon de Docker, si se define la misma opción con un archivo daemon.json y con marcas, Docker no se iniciará y mostrará un error similar al siguiente:

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:

La solución recomendada para resolver este conflicto es modificar el valor predeterminado de daemon.json, que se encuentra en /etc/docker/daemon.json. Si modificas este archivo, solo podrás cambiar las opciones afectadas, pero se mantendrán las demás opciones predeterminadas. Esto se puede hacer con cloud-init, por ejemplo, con un cloud-config similar a este:

#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