- 容器运行时
- 云原生
【免费下载链接】docker-ce
:warning: This repository is deprecated and will be archived (Docker CE itself is NOT deprecated) see the https://github.com/docker/docker-ce/blob/master/README.md :warning:
docker rename是 Docker 引擎提供的一条容器管理命令,用于在不重建、不停止容器的情况下修改容器的名称。本指南以 rename.md 官方参考文档为核心,结合 docker-ce 仓库中 CLI、API 路由与 daemon 层的真实实现,完整讲解命令用法、名称校验规则、底层调用链、链接容器与网络沙箱的处理细节,以及常见错误与规避方式。
命令概览
docker rename的命令用法与参数说明如下(源自 rename.md):
Usage: docker rename CONTAINER NEW_NAME Rename a container Options: --help Print usage该命令接收两个位置参数:
CONTAINER:旧名称,可以是容器名称、完整容器 ID 或足够唯一的前缀 ID;NEW_NAME:要赋予该容器的新名称。
它没有任何业务性可选项,唯一的--help用于打印使用说明。这一点在 CLI 源码中得到印证:CLI 侧的 rename.go 中通过Args: cli.ExactArgs(2)强制要求恰好两个参数,并用Use: "rename CONTAINER NEW_NAME"定义了与文档一致的使用格式。
基本用法
官方文档给出的最小示例为:
$ docker rename my_container my_new_container命令成功后不会输出任何信息,仅返回退出码 0。如果重命名的是正在运行的容器,操作同样即时生效,容器无需停止或重启。
一个完整的实操示例:
# 1. 创建一个容器 $ docker run --name web -d nginx # 2. 查看当前名称 $ docker ps --format '{{.Names}}' web # 3. 重命名(容器保持运行) $ docker rename web web_v2 # 4. 验证新名称 $ docker ps --format '{{.Names}}' web_v2需要注意:容器的 ID 与镜像不会因重命名而改变,只有名称(name)字段被更新。重命名后,旧名称会被立即释放,可被其他新建容器复用。
参数校验与常见错误
CLI 侧校验
在 CLI 的 runRename 实现中,两个参数会先被strings.TrimSpace去除首尾空白,任一参数为空则直接报错:
Error: Neither old nor new names may be empty随后调用dockerCli.Client().ContainerRename(ctx, oldName, newName)。若底层调用失败,CLI 会先打印引擎返回的具体错误,再输出统一封装信息:
Error: failed to rename container named <旧名称>引擎侧校验
daemon 层的 ContainerRename 依次执行以下校验:
- 空名称检查:
oldName == "" || newName == ""时报Neither old nor new names may be empty; - 新旧同名检查:若新名称与当前名称完全相同,报
Renaming a container with the same name as its current name(源码位于 rename.go); - 名称格式校验:新名称必须匹配
^[a-zA-Z0-9][a-zA-Z0-9_.-]+$,即首字符必须为字母或数字,后续字符仅允许字母、数字、_、.与-。该约束来自 names.go 中定义的RestrictedNameChars与RestrictedNamePattern,非法名称(如包含:、/、空格)报Invalid container name; - 名称冲突检查:新名称已被其他容器占用时,返回
nameConflictError(定义于 errors.go),错误信息为:
Conflict. The container name "new_name" is already in use by container "xxxxxxxxxxxx". You have to remove (or rename) that container to be able to reuse that name.这些边界行为均可在集成测试中找到对应用例:rename_test.go 验证了非法名称(new:invalid)会被拒绝且原容器不受影响;L171-L184 验证了新旧同名与用同一容器 ID 重命名为原名称均会报错。
底层工作原理:一次重命名的完整调用链
从执行docker rename到生效,共经历四层:
docker CLI (rename.go) └─> 发送 POST /containers/{name}/rename?name=NEW_NAME └─> API Server 路由 (container.go / container_routes.go) └─> daemon.ContainerRename() (daemon/rename.go) ├─> 名称校验 + 名称保留 (reserveName/releaseName) ├─> 链接索引更新 (linkIndex) ├─> 状态持久化 (CheckpointTo) └─> 网络沙箱重命名 + 发送事件- CLI 发送请求:CLI 通过 client 包发起请求。 container_rename.go 将新名称写入 URL 查询参数
name,向/containers/{containerID}/rename发送 POST 请求; - API Server 路由:路由表在 container.go 中注册为
POST /containers/{name:.*}/rename;处理器 postContainerRename 从 URL 路径取旧名称、从表单参数name取新名称,调用backend.ContainerRename成功后返回HTTP 204 No Content; - daemon 执行重命名:核心逻辑集中在 rename.go,包含名称保留、链接更新、持久化与网络处理(详见下文);
- 事件与审计:重命名成功后 daemon 会记录一条
rename事件,并携带oldName属性(见 rename.go),docker events可用于追溯容器的改名历史。
名称保留与释放机制
重命名本质上是对「名称 → 容器 ID」映射关系的原子替换。daemon 通过内存事务库 memDB 维护一个全局唯一的名称保留表:
- ViewDB.ReserveName 将「名称 → 容器 ID」写入索引,若名称已被其他容器占用则返回
ErrNameReserved(name is reserved); - ReleaseName 释放名称,之后该名称才能被其他容器重新保留;
- 校验与保留的封装位于 names.go,返回的名称统一补上前缀
/(引擎内部名称均以/开头)。
容器查找规则
docker rename的第一个参数支持三种写法(见 GetContainer 的注释与实现):
- 完整容器 ID:精确匹配;
- 容器名称:经由 GetByName 精确匹配;
- 短 ID / 前缀 ID:通过
truncindex前缀索引匹配,只要前缀在存活容器中唯一即可。
集成测试 rename_test.go 中的TestRenameRunningContainerAndReuse同时验证了:重命名后旧名称立即释放,且可以用旧名称重新创建新容器。
链接容器(--link)的重命名处理
若被重命名的容器或被重命名的目标正与其他容器存在--link关系,重命名必须同步更新链接索引,否则其他容器的链接将指向失效名称。daemon 的处理集中在 rename.go:
- 遍历
daemon.linkIndex.children(container)找出以旧名称为前缀的子链接; - 校验链接容器确实以旧名称开头,否则报
Linked container %s does not match parent %s; - 重命名成功后,对每个子链接重新
ReserveName(newName+k, v.ID)并重建linkIndex链接,同时释放旧链接名称; - 整个过程在
defer中做了完整的失败回滚:任一环节出错都会恢复旧名称、重挂旧链接、释放新名称。
对应的集成测试TestRenameContainerWithLinkedContainer(rename_test.go,对应 GitHub issue #23973)验证了:重命名被链接的容器后,通过容器名/别名依然能正确解析到目标容器。TestRenameLinkedContainer(L24-L49,对应 issue #31392)则覆盖了「重命名链接目标后重建链接」的复杂场景。
重命名与网络:网络沙箱与匿名端点
重命名运行中容器时,还需要同步底层网络沙箱(sandbox)的名称,确保 DNS / 服务发现与名称一致。关键代码在 rename.go:
- 通过
container.NetworkSettings.SandboxID找到容器对应的 libnetwork 沙箱; - 调用
sb.Rename(strings.TrimPrefix(container.Name, "/"))将沙箱名称更新为新容器名; - 同时将
NetworkSettings.IsAnonymousEndpoint置为false(L62-L63),使匿名容器一旦重命名即具备可被服务发现解析的身份。
TestRenameAnonymousContainer(rename_test.go,对应 issue #22466)验证了这一行为:无名称的匿名容器重命名后,同一自定义网络中的其他容器可以直接使用新名称 ping 通它,确认了服务发现对改名容器生效。
重命名运行中容器与停止容器的差异
从实现上看,重命名对运行中与停止中的容器都适用,但存在一处差异:仅运行中的容器需要同步重命名网络沙箱。停止的容器没有激活的沙箱,完成名称保留与持久化后即可结束;而运行中的容器还需完成沙箱改名(rename.go),若此步骤失败,daemon 会通过defer回滚名称并再次CheckpointTo落盘(L99-L107)。
实践建议与注意事项
- 旧名称立即释放:重命名成功后旧名称即刻可复用,可用于「滚动替换」场景(先改名再以旧名建新容器);
- 名称具有全局唯一性:同一 daemon 上的所有容器共享名称空间,冲突时必须先移除或改名占用者;
- ID 与镜像不变:重命名只影响名称字段,依赖容器 ID 的脚本、卷挂载、网络端点均不受影响;
- 链接与别名同步更新:涉及
--link时引擎会自动迁移链接名称,但应避免在重命名期间并发操作同一容器; - 尽量使用规范名称:名称只能以字母/数字开头,允许
_、.、-,建议在 CI 脚本中先校验命名规则再执行重命名; - 审计与排障:通过
docker events --filter event=rename可以查看改名记录及oldName属性,配合docker inspect确认当前名称。
测试验证与进一步阅读
docker-ce 仓库在 rename_test.go 中提供了覆盖重命名全部关键路径的集成测试,包括:停止容器改名、运行容器改名及名称复用、非法名称拒绝、新旧同名拒绝、匿名容器改名后的服务发现、链接容器的元数据同步(对应 issue #22466、#23973、#31392)。
如需深入阅读相关源码,推荐按以下路径展开:
- 命令入口与 CLI 实现:components/cli/cli/command/container/rename.go
- 官方命令参考:components/cli/docs/reference/commandline/rename.md
- API 客户端实现:components/engine/client/container_rename.go
- API Server 路由与处理器:container.go 与 container_routes.go
- daemon 核心重命名逻辑:components/engine/daemon/rename.go
- 名称校验规则:components/engine/daemon/names.go 与 components/engine/daemon/names/names.go
- 名称保留存储层:components/engine/container/view.go
- 集成测试:components/engine/integration/container/rename_test.go
- 容器运行时
- 云原生
【免费下载链接】docker-ce
:warning: This repository is deprecated and will be archived (Docker CE itself is NOT deprecated) see the https://github.com/docker/docker-ce/blob/master/README.md :warning:
相关推荐
Docker CLI 容器重命名实战:docker rename 命令用法、底层实现与测试验证
Docker CLI 容器重命名实战:docker rename 命令用法、底层实现与测试验证 导读 本文围绕 Docker CLI(当前仓库 cli http
CLI开发工具Docker CLI `docker rename` 命令完全指南:容器重命名、别名与底层实现
Docker CLI docker rename 命令完全指南:容器重命名、别名与底层实现 导读 docker rename 是 Docker CLI 提供的容
CLI开发工具Buildah rename 命令详解:本地容器的命名与管理实战
Buildah rename 命令详解:本地容器的命名与管理实战 导读 buildah rename 是 Buildah 中用于为本地工作容器(working
云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考