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 nos 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 do docker sem precisar de 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. Ou então, o usuário precisa 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

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 a cloud-init, consulte Como usar o cloud-init com o formato de configuração do Cloud.

Executar um cluster Kubernetes

A abordagem recomendada para executar um cluster do Kubernetes no Google Cloud é usar o Google Kubernetes Engine (GKE). Entretanto, se você quiser executar uma versão autogerenciada do Kubernetes de código aberto, siga estas instruções.

  1. Abra a porta 443 no seu firewall para garantir que seu Kubernetes mestre possa ser acessado.
  2. Faça o download dos binários da versão do Kubernetes, descompacte e abra o cluster da seguinte maneira:

    # Download and extract the latest kubernetes release.
    cd <empty-dir>
    KUBERNETES_VERSION="v1.4.6"
    curl -sSL -o kubernetes.tar.gz https://github.com/kubernetes/kubernetes/releases/download/${KUBERNETES_VERSION}/kubernetes.tar.gz
    tar xzf kubernetes.tar.gz
    cd kubernetes
    
    # Configure environment to use Container-Optimized OS
    export KUBE_OS_DISTRIBUTION=cos
    
    # Start up a cluster and verify that it is running:
    cluster/kube-up.sh
    cluster/kubectl.sh get nodes
    cluster/kubectl.sh get pods --namespace=kube-system
    
  3. Agora você pode executar seu aplicativo no cluster. Por exemplo, você pode iniciar um cluster Redis usando o seguinte exemplo:

    cluster/kubectl.sh create -f \
      examples/guestbook/all-in-one/guestbook-all-in-one.yaml
    cluster/kubectl.sh get pods
    cluster/kubectl.sh describe pods redis-master-pod-name
    

Para instâncias em execução como parte de um cluster GKE, os logs do Docker e do Kubelet também são exportados automaticamente para o log do conjunto de operações do Google Cloud. Os logs do Docker, Kubelet e kube-proxy estão disponíveis no conjunto de operações do Google Cloud em Instância de VM do Compute Engine ao usar o Console do Google Cloud.

Quando você não precisar mais do cluster, exclua-o:

cluster/kube-down.sh

Solução de problemas

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

Ao configurar o daemon 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

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

    opts = {}
    with open(DAEMON_OPTS_FILE) as f:
        opts = json.load(f)
    # 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