Docker命令+仓库镜像标签等等踩坑疑问

@LoyFan

仓库

1
2
3
4
5
6
7
8
9
10
# 登陆/注销docker
docker login --username=[ 用户名 ]

# 更改tag
docker tag [ 原镜像名 or 镜像 id ] [ 用户名 ]/[ 仓库 ]:[ tag ]
# [ 用户名 ]/[ 仓库 ]这个部分是可以任意取名的,写什么都可以,这个部分会作为REPOSITORY属性。
# 但是如果要推送到某仓库,则必须是[ 用户名 ]/[ 仓库 ]这样,推送上去之后如果仓库在这个用户下不存在则会新建一个这个名字的仓库。

# 推送镜像到仓库
docker push [ 用户名 ]/[ 仓库 ]:[ tag ]

镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查找镜像
docker search [ 条件 ]

# 查询三颗星及以上名字包含alpine的镜像
docker search -f=stars=3 alpine

# 登陆/退出第三方仓库
docker [ login/logout ] [ 仓库地址 ]

# 获取镜像
docker pull [ 仓库 ]:[ tag ]
#仓库格式为 [仓库url]/[用户名]/[应用名] , 除了官方仓库外的第三方仓库要指定 url, 用户名就是在对应仓库下建立的账户, 一般只有应用名的仓库代表 官方镜像, 如 ubuntu、tomcat 等, 而 tag 表示镜像的版本号, 不指定时默认为 latest

# 推送镜像到仓库
docker push [ 仓库 ]:[ tag ]

本地镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看本地镜像
docker images

# 删除镜像
docker rmi [ 镜像名 or 镜像 id ]

# 删除指定镜像(当存在同一个ID的不同镜像时)
docker rmi [ 仓库 ]:[ tag ]

# 查看镜像详情
docker inspect [ 镜像名 or 镜像 id ]

# 打包本地镜像
docker save [ 镜像名 or 镜像 id ] > [ 文件路径 ]

# 导入镜像
docker load < [ 文件路径 ]

# 修改镜像tag
docker tag [ 镜像名 or 镜像 id ] [ 新镜像名 ]:[ 新 tag ]

本地容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 查看本地运行中的容器
docker ps

# 查看本地所有容器
docker ps -a

# 查看容器详情
docker inspect [ 容器名 or 容器 id ]

# 创建容器
docker run --name [ 容器名 ] -it -p 8888:8888 -v [本地目录]:[新建容器的目录] [ 仓库名 ]:[ tag ]

# 关闭容器(发送SIGTERM信号,做一些'退出前工作',再发送SIGKILL信号)
docker stop [ 容器名 or 容器 id ]

# 强制关闭容器(默认发送SIGKILL信号, 加-s参数可以发送其他信号)
docker kill [ 容器名 or 容器 id ]

# 启动容器
docker start [ 容器名 or 容器 id ]

# 重启容器
docker restart [ 容器名 or 容器 id ]

# 进入容器命令行
docker exec -it [ 容器名 or 容器 id ] bash
# 或者
docker attach [ 容器名 or 容器 id ]

# 将容器保存为镜像
docker commit [ 容器名 or 容器 id ] [ 镜像名 ]:[ tag ]

# 使用dockfile构建镜像
docker build -t [ 镜像名 ]:[ tag ] -f [ DockerFile 名 ] [ DockerFile 所在目录 ]

一个创建+启动tensorflow容器的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 下载镜像
docker pull tensorflow/tensorflow

# 创建容器
docker run --name [ 容器名 ] -it -p 8888:8888 -v ~/tensorflow:/notebooks/data tensorflow/tensorflow
# 通用形式
docker run --name [ 容器名 ] -it -p 8888:8888 -v [本地目录]:[新建容器的目录] [ 仓库名 ]:[ tag ]

#docker run运行镜像,
#--name为容器创建别名,
#-it保留命令行运行,
#-p 8888:8888将本地的8888端口http://localhost:8888/映射,
#-v ~/tensorflow:/notebooks/data 将本地的~/tensorflow文件夹挂载到新建容器的/notebooks/data下(这样创建的文件可以保存到本地~/tensorflow)
#tensorflow/tensorflow为指定的镜像,默认标签为latest(即tensorflow/tensorflow:latest)


Q1
根本不存在“镜像名”这个东西吧,只有“镜像所在的仓库名”、“标签”、“镜像ID”吧!==所说的“镜像名”是指镜像所在的仓库名称吗??== 这样很不合理吧。。
A1
在一个教程上看到:

同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如ubuntu仓库源里,有15.10、14.04等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。

按这意思应该是 [ REPOSITORY : TAG ] 这样就表示一个镜像了,也就是所谓的镜像名。


Q2
我在自己的账户下新建了一个仓库,里面没有什么镜像的名字,只有tag,意思是这个==仓库的所有镜像都是同一个名字?只有tag的不同?==
A2
不是的,[ REPOSITORY : TAG ]表示的应该是某个镜像的名字,同一个镜像(同一个ID)会有多个名字,同一个仓库的不同标签表示的镜像可能是同一个ID也可能是不同的ID。


Q3
docker ps -a 列出容器列表的时候,容器会有真正自己的“name”也有“ID”,但是第二个属性是“Image”,里面是镜像的仓库名称。。。???所以真的就是仓库名称就代表了镜像名称了??但是==没有tag怎么知道是哪一个image??== 另:在新建容器的时候确实是需要tag的,没有写默认latest。
A4
未知。


Q4
当某指令要写[ 镜像名or镜像ID ]时,==当ID有重复的时候,可以用镜像名,就是指仓库名吗?还是指[ 仓库名 ]:[ tag ]这样?==
A4
经过尝试,镜像名就是指[ REPOSITORY : TAG ]。


Q5
当我使用docker tag [ 镜像名 or 镜像 id ] [ 新镜像名 ]:[ 新 tag ],==是新建了一个image还是只是多指定了一个“指向这个ID”的tag而已?==
实际操作的时候会在docker images里面多生成一行记录,原本的不变,而且在我镜像ID有重复、存在多个的时候这条指令并不会报错,==说明这些ID相同、仓库和tag不同的images根本就是同一个image??==
另外,这条指令中的[ 新镜像名 ]似乎是可以随意取的,命令完成之后再查看,这个[ 新镜像名 ]成为了一个新的仓库名,这是什么意思?
A5
经过多次尝试这条指令

1
>> docker tag [ 镜像名 or 镜像 id ] [ 新镜像名 ]:[ 新 tag ]

有一些结论:

  • 这条指令里的 [ 镜像名 or 镜像 id ] 可以是[ REPOSITORY : TAG ],也可以写ID,没有报错,因此确实这些ID相同、仓库和tag不同的images根本就是同一个image。
  • 这条指令只是一个修改镜像名(即[ REPOSITORY : TAG ])的指令,并不会生成一个新的image,原来的名字也依然存在。
  • 另外,当我尝试两次执行这条指令, [ 新镜像名 ]:[ 新 tag ]完全相同, [ 镜像名 or 镜像 id ] 采用不同的,再docker images查看,结果是新生成两行images,但是第一条指令的tag变为none,第二条指令的正常。
  • 在删除镜像指令

    1
    >> docker rmi [ REPOSITORY : TAG ]

    执行的时候也不是删除这个镜像,只是删除[ REPOSITORY : TAG ]指向这个镜像的关系,当某镜像ID确认唯一的时候使用指令

    1
    >> docker rmi [ 镜像ID ]

    才是删除这个镜像。

  • 关于这个[ 新镜像名 ],又把我搞混乱了。。镜像名应该是[ REPOSITORY : TAG ]啊,那这个新取的名字变成了一个仓库名,是新建了一个仓库的意思?
    是的,这个[ 新镜像名 ],如果是之前不存在的,那么是新建了一个仓库名,标准的应该是[ 用户名 / 仓库名 ],这样推送的时候就会在用户下新建这个仓库,也可以使用原来的仓库,新的标签。


自问自答结束=_=