Docker入门:私有库(Docker Registry)简介及使用方法(防踩坑)
一、私有库的应用场景
- 像Dockerhub、阿里云这样的公共镜像仓库有的时候用起来不太方便:Dockerhub网速太慢;阿里云需要花钱买云主机。
- 另外,涉及内部资源的保密性,有的机构不太可能将镜像提供给公网,因此需要创建一个基于内部项目镜像,构造本地私人仓库供给团队使用。
因此,Docker提供了Dcoker Registry工具,可以用于构建私有镜像仓库。
二、准备工作
为了实现本地镜像发布到私有仓库Registry,准备工作主要包括:
- (1)首先,安装Reistry和验证安装成功;
- (2)然后,创建一个本地的新镜像,用于发布到私有仓库Registry。
2.1 下载镜像Docker Registry
Docker Registry工具也是个docker镜像,它的功能就是用于创建私服版本个人企业版的docker hub。输入如下命令下载Docker Registry:
docker pull registry
2.2 运行私有库Registry——相当于本地有个私有Docker hub
1、运行私有库Registry的方法
通过上一步我们已经具有了Registry镜像了,这里需要run
该镜像,构建一个本地私有服务器容器,并将本地镜像发送上去,命令如下所示:
docker run -d -p 5000:5000 -v /liang/my_registry/:/tmp/registry --privileged=true registry
默认情况下,仓库创建在容器的/var/lib/registry
目录下,也就是说每次我们上传到registry的私人服务器仓库的文件就存储到/var/lib/registry
目录下。考虑到权限管理问题,在实际应用中通常需要自定义容器卷映射,以便与宿主机联调。
上面指令中参数的具体含义:
- (1)
-d
:设置Reigistry容器后台运行模式; - (2)
-p
:网络端口映射,指定容器端口绑定到主机相应主机端口;默认情况下Docker开放了5000端口(Python Flask端口)映射到主机端口32769上,这里的-p 5000:5000
是将Docker内部默认端口映射到主机端口5000上,第一个5000是主机端口;第二5000是容器端口。 - (3)
-v
:添加数据卷,格式为:-v /宿主机目录:/容器内目录
。需要注意的是,指令执行后会自动创建文件夹。 - (4)
--privileged=true
:Docker挂载主机目录Docker访问出现cannot open directory .: Permission denied
的解决办法。 - (5)
registry
:docker registry镜像。
防踩坑:上面的指令
-p 5000:5000
端口,并没有指定端口的绑定网络地址,这时候系统会默认主机的绑定网络地址为0.0.0.0
。也就是说,我们访问主机上私有仓库Registry时候需要通过网络地址0.0.0.0
2、验证私有库Registry的运行
执行完上面指令后,在本地的/liang/my_registry/
目录下创建了数据卷。
使用docker ps
命令查看正在运行的registry的容器ID,需要之一的是COMMAND
与别的容器不太一样。
防踩坑:在进入registry容器的时候的命令参数不能使用
/bin/bash
,而要使用:bin/sh
、bash
、sh
三个中的一个。输入命令进入registry容器:
docker exec -it c4ff108b25e0 /bin/sh
然后可以看到在registry容器中的/tmp
文件夹下就有了一个registry
文件夹,至此说明运行私有库Registry成功。
2.3 制作一个新镜像
- 我们首先对一个容器进行升级,让它具有更多的功能,然后提交这个镜像,制作成一个具有新功能的镜像;
- 然后将这个具有新功能的镜像提交给私有库Registry。
1、由下载的镜像创建容器并对容器进行功能加强
这里以ubuntu16.04为例演示创建一个镜像的过程。这里我已经下载了ubuntu16.04镜像,使用命令docker run -itd --name='liang-ubuntu16.04' ubuntu:16.04
创建一个名字为liang-ubuntu16.04
的容器。
使用指令docker exec -it liang-ubuntu16.04
以交互式方式进入容器liang-ubuntu16.04,由于容器只有ubuntu16.04内核系统,所以这里安装vim
和net-tool
两个工具包。在容器内部,安装这两个包的命令为:
apt-get update
apt-get install vim
apt-get install net-tool
完成上面的操作后,输入exit
命令退出容器liang-ubuntu16.04.
2、提交容器副本为镜像
使用命令docker commit
来提交容器副本,命令如下:
docker commit -m="ubuntu advanced version" -a="liang" liang-ubuntu16.04 ubuntu-advanced:v1
docker commit
指令中的参数说明:
- (1)
-m
:自定义的提交描述信息; - (2)
-a
:指定镜像作者; - (3)
liang-ubuntu16.04
:容器名字,这里也可以用容器ID代替; - (4)
ubuntu-advanced:v1
:指定要创建目标镜像的自定义名字(这里为unbuntu-advanced)和自定义版本(v1)。
这样就将具有vim
、net-tools
的ubuntu-advanced镜像就构建成功了,有关它的具体信息如上图所示。
三、 本地新建镜像发布到私有仓库Registry流程
3.1 curl验证私服库Registry上有什么镜像
指令格式如下所示:
curl -XGET http://主机映射的网络地址:主机映射网络端口/v2/_catalog
防踩坑:如果记得自己映射的主机Registy网络地址就可以直接输入;如果不记得,可以使用
docker ps -a
查看私服库Registry的网络映射信息(映射网络地址和映射端口)。
如下图所示,我的本地私有库Registry的网络地址为0.0.0.0
,映射端口为5000
。
所以,使用curl验证私服库Registry上有什么镜像的指令为:
curl -XGET http://0.0.0.0:5000/v2/_catalog
可以看出,目前本地私有库为空仓库。
3.2 将新镜像修改为符合私服规范的Tag
使用命令docker tag
指令格式如下所示:
docker tag 镜像ID或镜像名:Tag Host:Port/Repository:Tag
上面代码的参数含义如下所示:
- (1)
镜像ID或镜像名
:要上传到私有库Registry的镜像ID或名字; - (2)
Tag
:要上传的镜像版本号; - (3)
Host
:本地私有库的映射网址(本文为0.0.0.0); - (4)
Post
:本地私有库的映射端口(本文为5000); - (5)
Repository:Tag
:上传到私有库Registry后自定义的镜像名字、版本号。
根据需要上传的镜像:
这里的具体代码如下所示:
docker tag ubuntu-advanced:v1 0.0.0.0:5000/ubuntu-advanced:v1
这样就将ubuntu-advanced:v1
镜像修改为符合私服规范的Tag了:
3.3 修改配置文件使docker支持http
由于docker的私服库作了安全加固,通常是不支持http
的推送,所以这里需要配置取消该限制,代码如下所示:
首先查看,安装的docker支持的可访问的支持http:
cat /etc/docker/daemon.json
由上图可以看出,安装的docker只支持阿里云镜像加速网址的http连接,为了实现镜像上传到私有库Registry,我们还要配置支持本地安装私有库Registry的http连接,代码如下:
修改/etc/docker/daemon.json
配置文件,在终端输入sudo gedit /etc/docker/daemon.json
,打开配置文件添加如下内容(注意不要遗漏,
):
在终端输入systemctl restart docker
命令重启docker,配置完成。
3.4 push推送到私服库
命令格式为:
docker push 符合私服规范的Tag的镜像名称或ID:版本号
查看要推送的镜像:
具体代码为:
docker push 0.0.0.0:5000/ubuntu-advanced:v1
上传私服库完成,在终端输入命令curl -XGET http://0.0.0.0:5000/v2/_catalog
查看私服库上是否有推送的镜像,由下图可以看出已经存在unbunt-advanced
镜像了。
防踩坑:由于上一步在配置支持http的时候,重启了docker,所以应该保证Registy是启动状态,才能上传成功,不然会出现如下错误:
3.5 将私有库的镜像拉取到本地并运行
使用docker pull
命令从私有库拉取镜像到docker中:
docker pull Registry的网络映射:Registry的端口映射/私有库中的镜像名字:版本号
上面的Registry的网络映射与Registry的端口映射可由docker ps
命令查看:
使用curl -XGET http://0.0.0.0:5000/v2/_catalog
查看私服库上的镜像名字:
防踩坑:上面的
curl
指令只显示了私服库上的镜像名字,如为了获得版本号,需要如下指令,需要注意的ubuntu-advanced
是要拉取的镜像名字:
curl -XGET http://0.0.0.0:5000/v2/ubuntu-advanced/tags/list
因此,这里的具体拉取指令如下所示:
docker pull 0.0.0.0:5000/ubuntu-advanced:v1
如下图所示,拉取完成(需要注意的是,实现应该删除有关images)。
Docker启动交互式/守护式容器和进入正在运行的容器的总结_docker交互式容器和守护式容器区别-CSDN博客
一、容器的启动
1.前台交互式启动docker容器:docker run -it image:tag /bin/bash
2.后台守护式启动docker容器:docker run -d image:tag /bin/bash
3.前台交互式启动与后台守护式启动适应场景:
前台交互式启动适合ubuntu,nginx 。,因为ubuntu,nginx没有前台进程,如果使用后台守护式启动会导致容器立即自杀,它觉得没事可做了。这是docker机制的问题,所以最佳解决方案是以前台交互式启动,表示我还要交互操作。
后台守护式启动适合redis这些有前台进程的镜像,因为容器不会自动挂掉,并且若redis使用前台交互式启动,被操作人员不小心关掉终端(如exit,ctrl+c),会导致穿透、雪崩等一系列问题。所以redis适合后台守护式启动。
docker机制:docker容器后台运行,就必须有一个前台进程
二、退出容器的方式
1. exit:run进去容器,exit退出,容器停止
2. ctrl+p+q:run进去容器,ctrl+p+q退出,容器不停止
三、进入已运行的容器
1. docker exec -it 容器ID /bin/bash
exec 是在容器中打开新的终端,并且可以启动新的进程
因为是新终端,用exit退出,不会导致容器的停止。
2. docker attach 容器ID
attach 直接进入容器启动命令的终端,不会启动新的进程
如果进入前台交互式启动容器,,用exit退出,会导致容器的停止。用ctrl+p+q,不会导致容器停止。
如果进入后台守护式启动容器,不仅无法进行交互,并且ctrl+c会导致守护式进程停止。
工作中我们一般使用 docker run -d image:tag /bin/bash启动容器,再通过docker exec -it 容器ID /bin/bash,最为安全可靠。
执行docker image导入时,提示
“Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?”
执行docker ps时,提示
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
没有任何进程。
此时已确定Docker本身已经安装正常。
问题原因是因为docker服务没有启动,所以在相应的/var/run/ 路径下找不到docker的进程。
执行
service docker start
命令,启动docker服务。
执行docker ps ,仍然没有任何进程。
解决方法:
1.首先要查看docker daemon是否在运行。
ps aux | grep docker
2.docker deamon正在运行,则停止docker服务,再启动
service docker stop
ps aux | grep docker
service docker start
3.切换用户测试一下:
sudo docker info,问题解决。再次加载image成功。