镜像和仓库
# Docker 镜像
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含 运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
# Docker镜像操作常用命令
docker search --no-trunc=false [镜像名称] #搜索关于Archlinux镜像,输出信息不截断显示
#仓库名(Repository) 或者 标签名[不指定着默认latest,即最新]
docker pull name/[repository[:tag]] #获取Hub镜像如果不指定TAG将默认选择仓库中最新颁布的镜像
docker push DockerHubUser用户/test:latest #上传到docker仓库
docker images #列出本机已有镜像
docker tag 原仓库[:标签] 新仓库名[:标签] #为本地镜像添加一个新标签 [注意仓库名称必须小写]
docker tag <image id> username/name:devel #修改镜像的标签
docker inspect [image id] #获取镜像的详细信息
docker inspect -f {{".Architecture"}} 550(images Id 前面3位) #-f 获取单个属性 返回JSON
docker rmi [<image id>|<repository> ] #删除镜像 镜像id|仓库名称
docker rmi -f <images id> #不建议强行删除正在容器中运行的镜像文件
docker save -o 保存文件名.tar [repository[:tag]] #将镜像文件打包存出到磁盘
docker save [repository[:tag]] > 保存文件名 #将镜像文件打包存出到磁盘
docker load --input 保存文件名.tar #将打包的镜像文件进行载人
docker load < 保存文件名.tar
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Docker镜像加载原理
UnionFS (联合文件系统)
UnionFS 是一种分层、轻量级并且高性能的文件系统, 它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
典型的Linux文件系统由bootfs和rootfs两部分组成
bootfs(boot file system)主要包含 bootloader 和 kernel , bootloader 主要是引导加载 kernel, Linux 刚启动时会加载bootfs文件系统,在Docker镜像的最底层是 bootfs。这一层与我们典型的 Linux/Unix 系统是 一样的,包含boot 加载器和内核。当 boot 加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs 转交给内核,此时系统也会卸载 bootfs。
rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?
对于一个精简的系统,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就可以了。由此可见对于不同的 linux 发行版, bootfs 基本是一 致的, rootfs 会有差别, 因此不同的发行版可以公用 bootfs。
# 分层理解
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层一层的在下载!
为什么Docker镜像要采用这种分层的结构呢?
最大的好处,莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过 docker image inspect
命令!
docker image inspect tomcat:latest
所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于 Ubuntu Linux 16.04 创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
该镜像当前已经包含 3 个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了 一个简单的例子,每个镜像层包含 3 个文件,而镜像包含了来自两个镜像层的 6 个文件。
上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有 6 个文件,这是因为最上层中的文件 7 是文件 5 的一个更新版本。
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统 一的文件系统。
Linux 上可用的存储引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。顾名思义,每种存储引擎都基于 Linux 中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker 在 Windows 上仅支持 windowsfilter 一种存储引擎,该引擎基于 NTFS 文件系统之上实现了分层和 CoW。
下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
特点:
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
# 提交镜像
docker commit:提交容器副本,使之成为一个新的镜像
语法:
docker commit -m="提交的描述信息" -a="作者" 容器id 要创建的目标镜像名:[标签名]
1
测试
1、从Docker Hub 下载 tomcat 镜像到本地并运行
-it 交互终端 -p 端口映射
docker run -it -p 8888:8080 tomcat
2、访问地址
访问localhost:8888发现404 Not Found
docker启动官方tomcat镜像的容器,发现404是因为使用了加速器,而加速器里的 tomcat的webapps下没有root等文件!
[root@VM-0-6-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8b6aff64fa3 tomcat "catalina.sh run" 8 minutes ago Up 8 minutes 0.0.0.0:8888->8080/tcp, :::8888->8080/tcp silly_feynman
[root@VM-0-6-centos ~]# docker exec -it tomcat /bin/bash
root@a8b6aff64fa3:/usr/local/tomcat# ls
BUILDING.txt CONTRIBUTING.md LICENSE NOTICE README.md RELEASE-NOTES RUNNING.txt bin conf lib logs native-jni-lib temp webapps webapps.dist work
2
3
4
5
6
进入 tomcat 查看 cd 到 webapps 下发现全部空的,反而有个 webapps.dist 里有对应文件
root@a8b6aff64fa3:/usr/local/tomcat# cd webapps.dist
root@a8b6aff64fa3:/usr/local/tomcat/webapps.dist# ls
ROOT docs examples host-manager manager
2
3
我们可以 cp -r
复制文件到webapps下!
root@a8b6aff64fa3:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@a8b6aff64fa3:/usr/local/tomcat# cd webapps
root@a8b6aff64fa3:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
2
3
4
此时再次访问,则不是404
**3、提交修改后的镜像为 tomcat02 **
下次则可以直接启动这个
#进入容器把docs文件夹删掉
[root@localhost ~]# docker exec -it upbeat_cohen /bin/bash
root@6268a6b08d66:/usr/local/tomcat# cd webapps
root@6268a6b08d66:/usr/local/tomcat/webapps# ls
ROOT examples host-manager manager
2
3
4
5
注意:commit的时候,容器的名字不能有大写,否则报错:invalid reference format
[root@localhost /]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6268a6b08d66 tomcat "catalina.sh run" 13 minutes ago Up 13 minutes 0.0.0.0:8888->8080/tcp, :::8888->8080/tcp upbeat_cohen
[root@localhost /]# docker commit -a="zdk" -m="newTomcat" 6268a6b08d66 tomcat02:1.1
sha256:fdbda644d465e2635f8879b341c0eca8f4c4d1662a7caa6e6b04441fe4012049
[root@localhost /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02 1.1 fdbda644d465 5 seconds ago 681MB
tomcat latest fb5657adc892 5 months ago 680MB
centos latest 5d0da3dc9764 8 months ago 231MB
2
3
4
5
6
7
8
9
10
启动新的镜像看看,首页可访问
[root@localhost /]# docker run -it -p 8080:8080 tomcat02:1.1
访问8080端口
因为新镜像制作前把webapp找那个的docs删掉了,所以访问404
还可以以后台方式启动
[root@localhost ~]# docker run -d -p 7777:8080 tomcat02:1.1 6845790a2a621f5ba0525be08e34bc0182a215e79cb48e4b03e8670f68243764 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6845790a2a62 tomcat02:1.1 "catalina.sh run" 6 seconds ago Up 5 seconds 0.0.0.0:7777->8080/tcp, :::7777->8080/tcp practical_lalande fe007dd20ab8 tomcat02:1.1 "catalina.sh run" 40 minutes ago Up 40 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp practical_kirch 6268a6b08d66 tomcat "catalina.sh run" 57 minutes ago Up 57 minutes 0.0.0.0:8888->8080/tcp, :::8888->8080/tcp upbeat_cohen [root@localhost ~]#
1
2
3
4
5
6
7
8同样可以正常访问
# Docker 仓库
# DockerHub
注册dockerhub https://hub.docker.com/signup
1、登录
docker login -u 用户名
2、将镜像发布出去
[root@VM-0-6-centos logs]# docker push hello-world
Using default tag: latest
The push refers to repository [docker.io/library/hello-world]
f22b99068db9: Layer already exists
errors:
denied: requested access to the resource is denied
unauthorized: authentication required
2
3
4
5
6
7
错误:请求的资源访问被拒绝
问题:本地镜像名无帐号信息,解决加 tag 即可
[root@VM-0-6-centos logs]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 3 months ago 13.3kB
[root@VM-0-6-centos logs]# docker tag d1165f221234 用户名/hello-world:1.0
2
3
4
3、再次push
[root@VM-0-6-centos logs]# docker push 用户名/hello-world:1.0
访问:https://hub.docker.com/ 可看到提交的镜像
# Docker私服
下载镜像Docker Registry
[root@localhost /]# docker pull registry Using default tag: latest latest: Pulling from library/registry 79e9f2f55bf5: Pull complete 0d96da54f60b: Pull complete 5b27040df4a2: Pull complete e2ead8259a04: Pull complete 3790aef225b9: Pull complete Digest: sha256:169211e20e2f2d5d115674681eb79d21a217b296b43374b8e39f97fcf866b375 Status: Downloaded newer image for registry:latest docker.io/library/registry:latest
1
2
3
4
5
6
7
8
9
10
11运行私有库Registry,相当于本地有个私有Docker hub
[root@localhost /]# docker run -d -p 5000:5000 -v /zdk/myregistry/:/tmp/registry --privileged=true registry 72f11516b202413a0f8983d9e124818869f0fd93d22d5bffe3e2c37ae37cfd75 [root@localhost /]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 72f11516b202 registry "/entrypoint.sh /etc…" 5 seconds ago Up 4 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp silly_rhodes
1
2
3
4
5创建一个新镜像
[root@localhost /]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fff48c485e66 eeb6ee3f44bd "/bin/bash" 11 seconds ago Up 10 seconds tender_bose 72f11516b202 registry "/entrypoint.sh /etc…" 5 minutes ago Up 5 minutes 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp silly_rhodes [root@localhost /]# docker commit -a="zdk" -m="test private" fff48c485e66 testpri:1.0 sha256:57e158dd87c104b4394d4b49958b9107588a11c5fd3154dbcff4a85a5e0af7e6 [root@localhost /]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE testpri 1.0 57e158dd87c1 9 seconds ago 204MB
1
2
3
4
5
6
7
8
9查看本地私服库有什么镜像
[root@localhost /]# curl -XGET http://211.69.238.105:5000/v2/_catalog {"repositories":[]}
1
2将新镜像
testpri:1.0
修改为符合私服规范的tag(相当于改名克隆了一下)按照公式:docker tag 镜像:Tag Host:Port/Repository:Tag
[root@localhost /]# docker tag testpri:1.0 211.69.238.105:5000/testpri:1.0 [root@localhost /]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE testpri 1.0 57e158dd87c1 6 minutes ago 204MB 211.69.238.105:5000/testpri 1.0 57e158dd87c1 6 minutes ago 204MB
1
2
3
4
5修改配置文件使私服库支持http
修改daemon.json文件为下面的内容 ip换为当前的
[root@localhost /]# vim /etc/docker/daemon.json [root@localhost /]# cat /etc/docker/daemon.json { "registry-mirrors": ["https://zm5ewolg.mirror.aliyuncs.com"], "insecure-registries":["211.69.238.105:5000"] }
1
2
3
4
5
6push推送到私服库
[root@localhost /]# systemctl restart docker [root@localhost /]# docker run -d -p 5000:5000 -v /zdk/myregistry/:/tmp/registry --privileged=true registry d40be42cc3f6830fb77bc16b3a342e4e67287c68d96cb1fa67a516aa081fe186 [root@localhost /]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE 211.69.238.105:5000/testpri 1.0 57e158dd87c1 13 minutes ago 204MB testpri 1.0 57e158dd87c1 13 minutes ago 204MB registry.cn-hangzhou.aliyuncs.com/my_docker_name_space/vimcentos 1.0 abd576592235 2 hours ago 559MB tdockerfile/centos latest 53967da74cd1 4 hours ago 231MB tomcat02 1.1 fdbda644d465 6 hours ago 681MB tomcat latest fb5657adc892 5 months ago 680MB registry latest b8604a3fe854 6 months ago 26.2MB centos 7 eeb6ee3f44bd 8 months ago 204MB centos latest 5d0da3dc9764 8 months ago 231MB [root@localhost /]# docker push 211.69.238.105:5000/testpri:1.0 The push refers to repository [211.69.238.105:5000/testpri] 174f56854903: Pushed 1.0: digest: sha256:c71d8d38ff1874c6096ef32865f2954f26c1d796ff8c82b10d888802cc8978ad size: 529
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18curl验证私服库上有什么镜像
[root@localhost /]# curl -XGET http://211.69.238.105:5000/v2/_catalog {"repositories":["testpri"]}
1
2pull到本地运行
[root@localhost /]# docker pull 211.69.238.105:5000/testpri:1.0 1.0: Pulling from testpri 2d473b07cdd5: Already exists Digest: sha256:c71d8d38ff1874c6096ef32865f2954f26c1d796ff8c82b10d888802cc8978ad Status: Downloaded newer image for 211.69.238.105:5000/testpri:1.0 211.69.238.105:5000/testpri:1.0 [root@localhost /]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE 211.69.238.105:5000/testpri 1.0 57e158dd87c1 17 minutes ago 204MB registry.cn-hangzhou.aliyuncs.com/my_docker_name_space/vimcentos 1.0 abd576592235 2 hours ago 559MB tdockerfile/centos latest 53967da74cd1 4 hours ago 231MB tomcat02 1.1 fdbda644d465 6 hours ago 681MB tomcat latest fb5657adc892 5 months ago 680MB registry latest b8604a3fe854 6 months ago 26.2MB centos 7 eeb6ee3f44bd 8 months ago 204MB centos latest 5d0da3dc9764 8 months ago 231MB #运行成功 [root@localhost /]# docker run -it 211.69.238.105:5000/testpri:1.0 [root@f90b5a222e6c /]#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 阿里云镜像服务
首先我们先在一个centos上安装一下vim,然后将它commit,再上传到阿里云
在yum install vim -y时,发生这个错误
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
解决办法:
首先,进入到yum的repos目录
cd /etc/yum.repos.d/
1修改centos文件内容
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
1
2生成缓存更新
yum makecache
1运行yum update并重新安装vim
yum update -y yum -y install vim
1
2
然后提交制作新的镜像
[root@localhost /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tdockerfile/centos latest 53967da74cd1 3 hours ago 231MB
tomcat02 1.1 fdbda644d465 5 hours ago 681MB
tomcat latest fb5657adc892 5 months ago 680MB
centos 7 eeb6ee3f44bd 8 months ago 204MB
centos latest 5d0da3dc9764 8 months ago 231MB
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
50e7e07f8976 centos "/bin/bash" 5 minutes ago Up 5 minutes centos777
[root@localhost /]# docker commit -m="vimcentos" -a="zdk" 50e7e07f8976 vimcentos:1.0
sha256:abd576592235cbc3ad199d289d5146c246028ec9710af3c0614a77f95c09507f
2
3
4
5
6
7
8
9
10
11
12
登录阿里云 -> 找到容器镜像服务 -> 创建命名空间 -> 创建镜像仓库
点击进入这个镜像仓库,可以看到所有的信息
指令:
测试:推送 vimcentos
[root@VM-0-6-centos ~]# docker login --username=风竹不留雪 registry.cn-hangzhou.aliyuncs.com
[root@VM-0-6-centos ~]# docker tag abd576592235 registry.cn-hangzhou.aliyuncs.com/my_docker_name_space/vimcentos:1.0
[root@VM-0-6-centos ~]# docker push registry.cn-hangzhou.aliyuncs.com/my_docker_name_space/vimcentos:1.0
2
3
提交成功
尝试重新拉取:
[root@localhost /]# docker pull registry.cn-hangzhou.aliyuncs.com/my_docker_name_space/vimcentos:1.0
1.0: Pulling from my_docker_name_space/vimcentos
a1d0c7532777: Already exists
bf8d9a42a5b9: Pull complete
Digest: sha256:3b92b8caf8104ab96899d53d4ec09a65d2571910f648df270e30ef2d55394586
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/my_docker_name_space/vimcentos:1.0
registry.cn-hangzhou.aliyuncs.com/my_docker_name_space/vimcentos:1.0
[root@localhost /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.cn-hangzhou.aliyuncs.com/my_docker_name_space/vimcentos 1.0 abd576592235 50 minutes ago 559MB
#.........
2
3
4
5
6
7
8
9
10
11