使用容器

nerdctl 是一个与 Docker 兼容的容器 CLI。nerdctl 主要用于对 Docker 中不存在的 containerd 尖端功能进行试验。

Moby 是一个由 Docker 创建的开源项目,用于启用和加速软件容器化。组件包括容器构建工具、容器镜像仓库、编排工具和运行时等。Docker CLI 使用 Moby 运行时。

运行容器

要使用默认的 bridge CNI 网络 (10.4.0.0/24) 运行容器:

  • nerdctl
  • docker
  1. nerdctl run -it --rm alpine
  1. docker run -it --rm alpine

要使用 BuildKit 构建镜像:

  • nerdctl
  • docker
  1. nerdctl build -t foo /some-dockerfile-directory
  2. nerdctl run -it --rm foo
  1. docker build -t foo /some-dockerfile-directory
  2. docker run -it --rm foo

要使用 BuiltKit 进行构建并将输出发送到本地目录:

  • nerdctl
  • docker
  1. nerdctl build -o type=local,dest=. /some-dockerfile-directory
  1. docker build -o type=local,dest=. /some-dockerfile-directory

Docker Compose

Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。

  • nerdctl
  • docker

nerdctl-compose CLI 用于与 docker-compose 兼容:

  1. nerdctl compose up -d
  2. nerdctl compose down

Docker CLI 中的 compose 命令支持大多数 docker-compose 命令和标志。它有望成为 docker-compose 的直接替代品。

  1. docker compose up -d
  2. docker compose down

暴露端口

要为容器公开端口 8000:

  • nerdctl
  • docker
  1. nerdctl run -d -p 8000:80 nginx
  1. docker run -d -p 8000:80 nginx

然后,你可以在浏览器中访问 http://localhost:8000/ 来访问容器:

注意:默认情况下,暴露的端口可以在 macOS 和 Linux 上的所有网络接口上访问。然而,在 Windows 上,暴露的端口只能通过 localhost 网络接口访问(参见 issue #1180)。目前的一个解决方法是在 Windows 主机上配置 portproxy,从而将端口公开给其他网络接口

  1. netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=8080 connectaddress=localhost

暴露正在运行的容器端口

如果你忘记在 run 命令中公开端口,你可以按照以下步骤启动代理容器,将流量转发到原始容器。此技巧可以帮助你避免重启容器,并且在处理启动时间较长的容器化服务时特别有用。此技巧来自此 stackoverflow 讨论和此博客文章

  1. 假设你在没有发布端口的情况下(错误地)运行了一个容器。
  • nerdctl
  • docker
  1. nerdctl run -d --name rd-nginx nginx
  1. docker run -d --name rd-nginx nginx
  1. 设置要在后续命令中使用的端口变量。
  1. # Powershell
  2. $HOST_PORT=8080
  3. $CONTAINER_PORT=80
  4. # Bash
  5. export HOST_PORT=8080
  6. export CONTAINER_PORT=80
  1. 获取容器 IP 地址。如果你在启动时没有为容器指定名称,则可以在下面的命令中通过传递容器 id 来代替容器名称 rd-nginx
  • nerdctl
  • docker
  1. # Powershell
  2. $CONTAINER_IP=$(nerdctl inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' rd-nginx)
  3. # Bash
  4. export CONTAINER_IP=$(nerdctl inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' rd-nginx)
  1. # Powershell
  2. $CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' rd-nginx)
  3. # Bash
  4. export CONTAINER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' rd-nginx)
  1. 启动代理容器,从而将流量转发到原始容器。
  • nerdctl
  • docker
  1. nerdctl run --rm -p ${HOST_PORT}:${CONTAINER_PORT} alpine/socat TCP-LISTEN:${CONTAINER_PORT},fork TCP-CONNECT:${CONTAINER_IP}:${CONTAINER_PORT}
  1. docker run --rm -p ${HOST_PORT}:${CONTAINER_PORT} alpine/socat TCP-LISTEN:${CONTAINER_PORT},fork TCP-CONNECT:${CONTAINER_IP}:${CONTAINER_PORT}
  1. 代理容器成功运行后,你可以从主机通过 localhost:8080 访问 NGINX 服务器。

定位 Kubernetes 命名空间

你还可以通过 containerd 使用 --namespace 参数来定位 Kubernetes 命名空间。请注意 docker 不使用命名空间。

  • nerdctl
  1. nerdctl --namespace k8s.io build -t demo:latest /code/demos/rd/anvil-app
  2. nerdctl --namespace k8s.io ps