在实例上运行容器

您可以在运行 Container-Optimized OS 的计算机上运行 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 组。这样一来,任何已登录用户都可以在没有 root 权限的情况下运行 docker 命令。使用 OS Login 管理 SSH 密钥时,需要手动将用户账号添加到 docker 组。否则,用户必须为每个 docker 命令添加 sudo

访问 Container Registry 或 Artifact Registry 中的公共映像

cos 节点映像内置 Container Registry 支持。要从 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 中的私有映像

从里程碑 60 版本开始,Container-Optimized OS 映像预先安装 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

此外,您还可以从 Compute Engine 元数据中获取适当的 OAuth 访问令牌,并通过 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 容器注册表 DockerHub 中的映像启动 Docker 容器。以下示例使用 Cloud Config 格式从存储在 Container Registry 中的映像启动 Docker 容器:

#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 守护程序以从注册表缓存中拉取映像

您可以配置 Docker 守护程序,以使用注册表镜像从注册表缓存中拉取映像。

  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. 添加注册表镜像后,重启 Docker 守护程序以使更改生效:

    sudo systemctl daemon-reload
    sudo systemctl restart docker
    

将配置添加到 /etc/default/docker 在重新启动后不再存在。要确保重新启动后 Docker 配置仍然存在,请考虑在采用 cloud-config 格式 的实例元数据的 cloud-init 脚本中或在 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

如需详细了解如何使用 cloud-init 配置实例,请参阅将 Cloud-init 与 Cloud 配置格式一起使用

问题排查

解决 Docker daemon.json 与标志之间的选项冲突

配置 Docker 守护程序时,如果使用 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:

此冲突的推荐解决方案是修改位于 /etc/docker/daemon.json 的默认 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