Como executar contêineres em instâncias

É possível executar um contêiner do Docker em uma máquina que executa o Container-Optimized OS da mesma forma que faria na maioria das outras distribuições de imagem de nó: usando o comando docker run. Exemplo:

docker run --rm busybox echo "hello world"

A seguinte saída é exibida:

Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
. . .
Status: Downloaded newer image for busybox:latest
hello world
Ao gerenciar chaves SSH em metadados, todas as contas de usuário gerenciadas pelo Compute Engine na imagem cos são adicionadas ao grupo docker por padrão. Isso permite que qualquer usuário conectado execute comandos docker sem ter privilégios de raiz. Ao gerenciar chaves SSH usando o Login do SO, a conta de usuário precisa ser adicionada ao grupo docker manualmente. Caso contrário, o usuário precisará adicionar sudo para cada comando docker.

Como acessar imagens públicas no Container Registry ou no Artifact Registry

O suporte do Container Registry está integrado à imagem do nó cos. Para iniciar um contêiner a partir do Container Registry, execute:

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

A seguinte saída é exibida:

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

Como acessar imagens particulares no Artifact Registry ou no Container Registry

Com 60 versões iniciais, o docker-credential-gcr é pré-instalado em imagens do Container-Optimized OS. Essa é a maneira recomendada para acessar imagens particulares no Artifact Registry ou no Container Registry.

Para usar docker-credential-gcr, execute o seguinte comando:

Artifact Registry

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

Substitua LOCATION pelo local do seu repositório.

Container Registry

docker-credential-gcr configure-docker

A seguinte saída é exibida:

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

Para executar uma imagem do registro, use o seguinte comando:

Artifact Registry

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

Substitua LOCATION pelo local do seu repositório.

Container Registry

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

É possível usar os seguintes nomes de host do Container Registry:

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

Para usar o Docker com sudo, execute o comando a seguir. A flag de linha de comando -E faz com que o Docker use o arquivo .docker/config.json do diretório inicial de um usuário em vez do diretório inicial raiz.

Artifact Registry

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

Substitua LOCATION pelo local do seu repositório.

Container Registry

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

Os nomes de host do Container Registry suportados são:

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

Como alternativa, você pode buscar os tokens de acesso OAuth apropriados dos metadados do Compute Engine e usá-los com o comando docker login manualmente, conforme mostrado no exemplo a seguir:

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

Como usar cloud-init com o Container Registry

Este exemplo cloud-init usa o formato do Cloud Config para iniciar um contêiner do Docker a partir de uma imagem armazenada no Container Registry do Docker chamada DockerHub. O exemplo abaixo usa o formato do Cloud Config para iniciar um contêiner do Docker a partir de uma imagem armazenada no 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

Como configurar o daemon do Docker para extrair imagens do cache do registro

Configure os daemons do Docker para extrair imagens de um cache de registros usando espelhos de registro.

  1. Configure o daemon para usar a opção registry-mirror de uma das seguintes formas:

    • No arquivo /etc/default/docker, adicione a opção registry-mirror para o registro (por exemplo, https://mirror.gcr.io):
    echo 'DOCKER_OPTS="--registry-mirror=https://mirror.gcr.io"' | tee /etc/default/docker
    
    • No arquivo /etc/default/docker, anexe "--registry-mirror=https://mirror.gcr.io" ao DOCKER_OPTS atual:
    sed -i -e 's|"$| --registry-mirror=https://mirror.gcr.io"|' /etc/default/docker
    
  2. Depois de adicionar o espelho de registro, reinicie o daemon do Docker para que as alterações entrem em vigor:

    sudo systemctl daemon-reload
    sudo systemctl restart docker
    

A adição de uma configuração a /etc/default/docker não é permanente durante a reinicialização. Para garantir que sua configuração do Docker permaneça persistente entre as reinicializações, considere adicionar os comandos no script cloud-init dos metadados da instância no formato cloud-config ou startup script.

O exemplo a seguir usa o formato cloud-config para configurar um 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 mais informações sobre como configurar uma instância com cloud-init, consulte Como usar cloud-init com o formato de configuração do Cloud.

Solução de problemas

Como resolver conflitos de opção entre daemon.json do Docker e sinalizações

Ao configurar o daemon do Docker, se a mesma opção for definida com um arquivo daemon.json e com sinalizações, o Docker não começará com um erro semelhante a este:

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:

A solução recomendada para resolver esse conflito é modificar o daemon.json padrão, que está localizado em /etc/docker/daemon.json. Modificar esse arquivo permite alterar apenas as opções afetadas, mantendo as outras opções padrão. Isso pode ser feito usando cloud-init. Por exemplo, usando um cloud-config semelhante a:

#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