目录
Docker 私有仓库
1. 简介
2. 构建 Docker 私有仓库
(1)部署环境
(2)服务端部署
(3)客户端配置
(4)私有镜像仓库测试
Dockerfile
1. 概述
2. Dockerfile 的组成
3. Dockerfile 的指令分类
4. Dockerfile 指令详解
(1)FROM
(2)MAINTAINER
(3)RUN
(4)CMD
(5)EXPOSE
(6)ENV
(7)ADD
(8)COPY
(9)ENTRYPOINT
(10)VOLUME
(11)USER
(12)WORKDIR
(13)ONBUILD
5. 通过 Dockerfile 快速构建镜像
(1)编辑 Dockerfile 文件
(2)构建过程
(3)通过构建的镜像启动容器
Docker 镜像仓库分为共有仓库与私有仓库。当我们执行docker pull 命令时,Docker 默认是从 registry.docker.com 地址去查找我们需要的镜像文件,然后执行下载操作。这类镜像仓库就是Docker默认的共有仓库。
Docker 私有仓库
1. 简介
私有仓库,就是本地(内网环境)组建的一个与公网共有仓库功能相似的镜像仓库,组建好之后,我们就可以将已打包的镜像提交到私有仓库中,这样内网的其他用户也可以使用这个镜像文件。
构建私有仓库原因:
(1)访问性能:Docker Hub 是公网的共有仓库,企业内部上传下载都需要通过公网,性能有时比较低下。
(2)安全性高:内网与外网隔离,可以保障私有镜像的安全。
2. 构建 Docker 私有仓库
使用官方提供的 registry 镜像来组建企业内网的私有镜像仓库。
(1)部署环境
服务器规划
服务器角色 IP地址 用途 服务端 192.168.65.130 私有仓库服务器,运行registry容器 客户端 192.168.65.128 客户端,用于测试镜像文件的上传、下载服务端与客户端都需要有Docker环境,环境查看如下:
[root@localhost ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
[root@localhost ~]# uname -r
3.10.0-1160.el7.x86_64
[root@localhost ~]# docker --version
Docker version 1.13.1, build 7d71120/1.13.1
(2)服务端部署
1)下载官方 registry 镜像文件
下载时如果出现错误 Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? ,启动docker服务即可,service docker start
[root@localhost ~]# docker pull registry
Using default tag: latest
Trying to pull repository docker.io/library/registry ...
latest: Pulling from docker.io/library/registry
ca7dd9ec2225: Pull complete
c41ae7ad2b39: Pull complete
1ed0fc8a6161: Pull complete
21df229223d2: Pull complete
626897ccab21: Pull complete
Digest: sha256:ce14a6258f37702ff3cd92232a6f5b81ace542d9f1631966999e9f7c1ee6ddba
Status: Downloaded newer image for docker.io/registry:latest
[root@localhost ~]# docker images|grep registry
docker.io/registry latest 81c944c2288b 7 weeks ago 24.1 MB
2)运行 registry 容器
mkdir -p 如果不存在就新建,如果存在就不新 建
[root@localhost ~]# mkdir /docker/registry -p
[root@localhost ~]# docker run -itd -v /docker/registry/:/docker/registry -p 5000:5000 --restart=always --name registry registry:latest
1c94e7fb4c69de7d037028f064294662f56ffdc577da185f77df7be3240c4e1b
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c94e7fb4c69 registry:latest "/entrypoint.sh /e..." 9 seconds ago Up 5 seconds 0.0.0.0:5000->5000/tcp registry
运行参数说明如下:
-itd:在容器中打开一个伪终端进行交互操作,并在后台运行。(上一篇介绍过)
-v:把宿主机的 /docker/registry 目录绑定到容器 /docker/registry 目录(这个目录是registry容器存放镜像文件的目录),来实现数据的持久化
#容器中镜像文件在物理机的存放目录
[root@localhost registry]# pwd
/docker/registry
-p:映射端口。访问宿主机的5000端口就访问到registry容器的服务了。
--restart=always:这是重启的策略,假如这个容器异常退出,会自动重启容器。
--name registry:创建容器并命名为 registry ,可以自定义任何名称。
registry:latest:这是刚才pull 下来的镜像。
3)查看远程仓库镜像文件
[root@localhost ~]# curl http://localhost:5000/v2/_catalog
{"repositories":[]}
也可以使用浏览器访问,结果也是空的
(3)客户端配置
客户端配置很简单,只需要修改默认下载的镜像源文件
[root@localhost ~]# vim /etc/docker/daemon.json
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# cat /etc/docker/daemon.json
{
"registry-mirrors":["https://registry.docker-cn.com"]
}
(4)私有镜像仓库测试
构建完私有镜像仓库之后,通过客户端的镜像上传、下载来测试私有镜像仓库是否可用。
1)客户端测试环境准备
下载测试镜像
[root@localhost ~]# docker pull nginx
Using default tag: latest
Trying to pull repository docker.io/library/nginx ...
latest: Pulling from docker.io/library/nginx
3f4ca61aafcd: Pull complete
50c68654b16f: Pull complete
3ed295c083ec: Pull complete
40b838968eea: Pull complete
88d3ab68332d: Pull complete
5f63362a3fa3: Pull complete
Digest: sha256:0047b729188a15da49380d9506d65959cce6d40291ccfb4e039f5dc7efd33286
Status: Downloaded newer image for docker.io/nginx:latest
给镜像打标签
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.65.130:5000/nginx v1 1403e55ab369 12 days ago 142 MB
docker.io/nginx latest 1403e55ab369 12 days ago 142 MB
2)上传镜像
客户端上传镜像文件
[root@localhost ~]# docker push 192.168.65.130:5000/nginx:v1
The push refers to a repository [192.168.65.130:5000/nginx]
Get https://192.168.65.130:5000/v1/_ping: http: server gave HTTP response to HTTPS client
注意这里报错,说需要使用 https 的方式才能上传,解决方案:修改daemon.json文件
[root@localhost ~]# cat /etc/docker/daemon.json
{
"registry-mirrors":["https://registry.docker-cn.com"],
"insecure-registries":["192.168.65.130:5000"]
}
然后重启docker服务
[root@localhost ~]# systemctl restart docker
然后再重新上传
[root@localhost ~]# docker push 192.168.65.130:5000/nginx:v1
The push refers to a repository [192.168.65.130:5000/nginx]
c72d75f45e5b: Pushed
9a0ef04f57f5: Pushed
d13aea24d2cb: Pushed
2b3eec357807: Pushed
2dadbc36c170: Pushed
8a70d251b653: Pushed
v1: digest: sha256:9a821cadb1b13cb782ec66445325045b2213459008a41c72d8d87cde94b33c8c size: 1570
3)服务端查看镜像仓库
[root@localhost ~]# curl http://localhost:5000/v2/_catalog
{"repositories":["nginx"]}
[root@localhost ~]# curl http://localhost:5000/v2/nginx/tags/list
{"name":"nginx","tags":["v1"]}
4)下载镜像
首先删除客户端主机之间之前从公有仓库下载的镜像文件。
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.65.130:5000/nginx v1 1403e55ab369 12 days ago 142 MB
docker.io/nginx latest 1403e55ab369 12 days ago 142 MB
[root@localhost ~]# docker image rmi -f 1403e55ab369
Untagged: 192.168.65.130:5000/nginx:v1
Untagged: 192.168.65.130:5000/nginx@sha256:9a821cadb1b13cb782ec66445325045b2213459008a41c72d8d87cde94b33c8c
Untagged: docker.io/nginx:latest
Untagged: docker.io/nginx@sha256:0047b729188a15da49380d9506d65959cce6d40291ccfb4e039f5dc7efd33286
Deleted: sha256:1403e55ab369cd1c8039c34e6b4d47ca40bbde39c371254c7cba14756f472f52
Deleted: sha256:0274f249eda4c376bde7cbe0b719ea3aef10201846d7262f37f7a0fc0b4fcf90
Deleted: sha256:e01fc49cb889c5dd6b11390e9863ba00f886315c5a403ee5955fb5c88d2aa576
Deleted: sha256:b2a367ee540c5d40c704fdece005b422f55f85a61b96a25bd99d6847669958a0
Deleted: sha256:2c1c6d39cbcc4767b0798aacc03f203951057e77c5edebca1fdfbcd4997f2919
Deleted: sha256:d260638126e1d2d3202dec36b67f124624fbcdad3afedd334e7260bf75dad8da
Deleted: sha256:8a70d251b65364698f195f5a0b424e0d67de81307b79afbe662abd797068a069
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
此时客户端所有的镜像文件全部删除,接下来从私有仓库下载镜像。
[root@localhost ~]# docker pull 192.168.65.130:5000/nginx:v1
Trying to pull repository 192.168.65.130:5000/nginx ...
v1: Pulling from 192.168.65.130:5000/nginx
3f4ca61aafcd: Pull complete
50c68654b16f: Pull complete
3ed295c083ec: Pull complete
40b838968eea: Pull complete
88d3ab68332d: Pull complete
5f63362a3fa3: Pull complete
Digest: sha256:9a821cadb1b13cb782ec66445325045b2213459008a41c72d8d87cde94b33c8c
Status: Downloaded newer image for 192.168.65.130:5000/nginx:v1
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.65.130:5000/nginx v1 1403e55ab369 12 days ago 142 MB
可以看到客户端可以从远端服务器拉取所需要的镜像文件。至此,搭建内网私有镜像仓库就完成了。
总结:
对于服务端,需要先下载官方的 registry 镜像文件,然后运行 registry 容器,指定端口为5000,访问服务器宿主机的5000端口就能访问 registry 容器的服务。
对于客户端,只需要修改 daemon.json 文件即可。
然后客户端先从公共仓库下载一个nginx镜像,修改标签之后成为自己的自定义镜像。然后客户端将改自定义镜像可以上传到服务端的仓库,上传之后,客户端把本地镜像都删除,再从服务端私有仓库拉取刚才上传的自定义镜像,也可以拉取下来。
Dockerfile
1. 概述
Dockerfile 是一个文本格式的配置文件,我们可以使用Dockerfile 快速创建自定义的镜像文件。
Docker 镜像的构建与定制,实际上就是构建和定制每一层的配置文件。我们可以把每一层的修改、安装、操作、构建命令都写入一个脚本,用这个脚本来构建和定制Dokcer镜像,这个脚本就是Dockerfile。
Docker 可以使用 Dockerfile 的内容来自动构建镜像。Dockerfile也是一个文件,其中有创建镜像和运行指令等一系列的命令,并且每行只支持一个运行命令。每一条命令构建一层,这条命令的内容就是描述如何构建该层。
2. Dockerfile 的组成
Dockerfile 由以下四部分组成:
(1)基础镜像信息
(2)维护者信息
(3)镜像操作指令
(4)容器启动时执行的命令
Dockerfile 指令忽略大小写建议大写,每行只支持一条指令,指定可以带多个参数。
3. Dockerfile 的指令分类
分为两类:
(1) 构建指令:用于构建 image,其指定的操作不会在运行 image 的容器中执行。
(2)设置指令:用于设置 image 的属性,其指定的操作会在运行 image 的容器中执行。
4. Dockerfile 指令详解
(1)FROM
功能:用来指定基础镜像,然后在基础镜像上构建新的镜像,基础镜像一般有远程和本地仓库。Dockerfile 文件第一行必须是 FROM 指令,如果一个 Dockerfile 需要创建多个镜像,那么可以使用多个 FROM 指令。
使用方法:
FROM <image_name> #默认是latest版本
FROM <image:version> #指定版本
(2)MAINTAINER
功能:指定镜像创建者的信息。
使用方法:
MAINTAINER <name>
(3)RUN
功能:运行所有基础镜像能支持的命令,同样也可以使用多条 RUN 指令,可以使用 “\” 来换行。
使用方法:
RUN <command>
RUN ["executable","param1","param2"...] (exec form)
(4)CMD
功能:用于容器启动时的指定操作,它既可以是命令,也可以是脚本,但只执行一次。如果有多个,默认只会执行最后一个。
使用方法:
CMD ["executable", "param1" , "param2"] #使用exec执行,推荐
CMD command param1 param2 #在/bin/sh上执行
(5)EXPOSE
功能:指定容器的端口映射(容器与物理机),运行容器时加上 -p 参数指定EXPOSE设置的端口,EXPOSE 可以设置多个端口号,相应地运行容器配套多次使用-p参数。可以通过 docker port + 容器需要映射的端口号和容器ID来参考宿主机的映射端口。
使用方法:
EXPOSE <port> [port1, port2 ...]
(6)ENV
功能:在镜像中用于设置环境变量。RUN命令可以使用这里设置的环境变量,在容器启动后通过docker inspect 命令查看环境变量, 通过docker run --env key=value 命令来设置或修改环境变量。
使用方法:
ENV <key> <value>
ENV JAVA_HOME /usr/local/jdk
(7)ADD
功能:复制指定的源文件、目录、URL到容器的指定目录中。所有复制到容器中的文件和文件夹的权限为0755,UID和GID为0。
ADD <源> <目标>
注意:
1)如果源时一个目录,那么会将该目录下所有文件添加到容器中,不包括目录;如果源文件时可以识别的压缩格式,则Docker会帮忙解压缩。
2)如果源是文件且目标目录中不使用斜杠结束,则会将目标目录视为文件,源的内容会写入目标目录。
3)如果源是文件且目标目录中使用斜杠结束,则会将源文件复制到目标目录下。
(8)COPY
功能:复制本地主机的源(默认为Dockerfile所在的目录)到容器的目标中,目标路径不存在时会自动创建。
使用方法:
COPY <源> <目标>
COPY web/index.html /var/web/
注意:
1)路径必须时绝对路径,如果不存在,会自动创建对应目录
2)路径必须时Dockerfile 所在路径的相对路径
3)如果时一个目录,只会复制目录下的内容,而目录本身不会被复制。
(9)ENTRYPOINT
功能:指定容器启动后执行的命令,如果有多行,只执行最后一行,并且不可以被docker run 提供的参数覆盖。
ENTRYPOINT "command" "param1" "param2"
(10)VOLUME
功能:创建一个可以从本地主机或其他容器挂载的挂载点,一般用于存放数据。docker run -v 命令也可实现此功能。
使用方法:
VOLUME [directory_name]
VOLUME /docker_data
(11)USER
功能:指定容器运行时使用的用户或UID,后面RUN、CMD、ENTRYPOINT指令都会使用此用户来运行命令。
使用方法:
USER [username/uid]
(12)WORKDIR
功能:指定RUN、CMD、ENTRYPOINT指定的命令的运行目录。可以使用多个WORKDIR指令,后序参数如果是相对路径,则会基于之前的命令指定的路径。例如,WORKDIR/data WORKDIR work,最终的路径就是 /data/work。path路径也可以是环境变量
使用方法:
WORKDIR [path]
(13)ONBUILD
功能:配置当前所创建的镜像作为其他新建镜像的基础镜像时,所执行的操作命令。也就是说,这个镜像创建后,如果其他镜像以这个镜像为基础,那么先会执行这个镜像的ONBUILD命令。
使用方法:
ONBUILD [INSTRUCTION]
5. 通过 Dockerfile 快速构建镜像
下面通过构建一个 Tomcat 镜像来演示 Dockerfile的使用方法。
(1)编辑 Dockerfile 文件
[root@localhost tomcat]# pwd
/root/docker/tomcat
[root@localhost tomcat]# ll
total 195504
-rw-r--r-- 1 root root 10371538 Jan 2 21:27 apache-tomcat-8.5.55.tar.gz
-rw-r--r-- 1 root root 25 Jan 2 21:29 index.jsp
-rw-r--r-- 1 root root 189815615 Jan 2 21:27 jdk-8u162-linux-x64.tar.gz
[root@localhost tomcat]# vim Dockerfile
index.jsp文件内容如下:
[root@localhost tomcat]# cat index.jsp
welcome to zy's web site
Dockerfile内容如下:
FROM centos
MAINTAINER zhangyin
#add jdk and tomcat software
ADD jdk-8u162-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.55.tar.gz /usr/local/
ADD index.jsp /usr/local/apache-tomcat-8.5.55/webapps/ROOT/
#config java and tomcat ENV
ENV JAVA_HOME /usr/local/jdk1.8.0_162
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.55/
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin
#config listen port of tomcat
EXPOSE 8080
#config startup command of tomcat
CMD /usr/local/apache-tomcat-8.5.55/bin/catalina.sh run
(2)构建过程
[root@localhost tomcat]# docker build -t tomcat-web .
Sending build context to Docker daemon 200.2 MB
Step 1/11 : FROM centos
Trying to pull repository docker.io/library/centos ...
latest: Pulling from docker.io/library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for docker.io/centos:latest
---> 5d0da3dc9764
Step 2/11 : MAINTAINER zhangyin
---> Running in c72022edc947
---> 571c6b6221b2
Removing intermediate container c72022edc947
Step 3/11 : ADD jdk-8u162-linux-x64.tar.gz /usr/local/
---> 353beddc8cd7
Removing intermediate container 5578aacc3675
Step 4/11 : ADD apache-tomcat-8.5.55.tar.gz /usr/local/
---> 96f99bccbc6f
Removing intermediate container 622a8ba095a8
Step 5/11 : ADD index.jsp /usr/local/apache-tomcat-8.5.55/webapps/ROOT/
---> 416e813420d4
Removing intermediate container 1be080edf574
Step 6/11 : ENV JAVA_HOME /usr/local/jdk1.8.0_162
---> Running in 9d652049f6c2
---> 71a1e6458611
Removing intermediate container 9d652049f6c2
Step 7/11 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
---> Running in 315ea663ad93
---> f845e23d60d3
Removing intermediate container 315ea663ad93
Step 8/11 : ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.55/
---> Running in 2ad363335be4
---> 768ebbc07078
Removing intermediate container 2ad363335be4
Step 9/11 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin
---> Running in 5ce4bfb07bb7
---> 0fcb0729a9dc
Removing intermediate container 5ce4bfb07bb7
Step 10/11 : EXPOSE 8080
---> Running in 503681d5b636
---> 80e15a5e9ece
Removing intermediate container 503681d5b636
Step 11/11 : CMD /usr/local/apache-tomcat-8.5.55/bin/catalina.sh run
---> Running in 99e8f2859c39
---> ebb0fa533cef
Removing intermediate container 99e8f2859c39
Successfully built ebb0fa533cef
Successfully built ebb0fa533cef 表明已经构建成功
查看镜像
[root@localhost tomcat]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat-web latest ebb0fa533cef 6 minutes ago 630 MB
docker.io/registry latest 81c944c2288b 7 weeks ago 24.1 MB
docker.io/centos latest 5d0da3dc9764 15 months ago 231 MB
(3)通过构建的镜像启动容器
[root@localhost tomcat]# docker run -d -p 8080:8080 tomcat-web
03a4f5322685630951dc8f4fa5642b2f0d94fd879eb1a909736040031010ad25
[root@localhost tomcat]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03a4f5322685 tomcat-web "/bin/sh -c '/usr/..." 12 seconds ago Up 5 seconds 0.0.0.0:8080->8080/tcp blissful_blackwell
1c94e7fb4c69 registry:latest "/entrypoint.sh /e..." 3 hours ago Up 3 hours 0.0.0.0:5000->5000/tcp registry
通过浏览器访问容器: