在实例上运行容器

您可以在运行 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