Dockerfile构建Docker镜像。Dockerfile是一个文本文件,其中包含了若干条指令,指令描述了构建镜像的细节。
1)准备一个文件,名为Dockerfile:
FORM nginx RUN echo 'test' > /usr/share/nginx/html/index.html
FORM、RUN都是Dockerfile的指令。FROM指令用于指定基础镜像,RUN指令用于执行命令。
2)在Dockerfile所在路径执行以下命令构建镜像
docker build -t nginx:my .
其中,命令最后的点(.)用于路径参数传递,表示当前路径。
3)执行以下命令,即可使用该镜像启动一个Docker容器
docker run -d -p 92:80 nginx:my
4)访问
ADD指令用于复制文件
ADD... ADD [" ",... " "]
从src目录复制文件到容器dest。其中src可用是Dockerfile所在目录的相对路径,也可以是一个URL,还可以是一个压缩包。
注:src必须在构建的上下文内,不能使用例如ADD …/somehine /something这样的命令,因为docker build命令首先会将上下文路径和其子目录发送到docker daemon。
如果src是一个URL,同时dest不以斜杠结尾,dest将被视为文件,src对应内容文件将被下载到dest。
如果src是一个URL,同时dest以斜杠结尾,dest将被视为目录,src对应内容将被下载到dest目录。
如果src是一个目录,那么整个目录下的内容将被复制,包括文件系统元数据。
如果文件是可识别的压缩包格式,则docker会自动解压。
ADD microservice-discovery-eureka.jar app.jarARG设置构建参数
ARG指令用于设置构建参数,类似于ENV。和ENV不同的是,ARG设置的是构建时的环境变量,在容器运行时是不会存在这些变量的。
ARG user1=someuserCMD容器启动命令
CMD指令用于为执行容器提供默认值。每个Dockerfile只有一个CMD命令,如果指定了多个CMD命令,那么只有最后一条会被执行,如果启动容器时指定了运行的命令,则会覆盖CMD指定的命令。
CMD ["executable","param1","param2"](推荐使用) CMD ["param1","param2"] (为ENTRYPOINT指令提供预设参数) CMD command param1 param2 (在shell中执行)
CMD echo "This is a test." | wc -COPY复制文件
COPY... COPY [" ",... " "]
复制本地端的src到容器的dest。COPY指令和ADD指令类似,COPY不支持URL和压缩包
ENTRYPOINT入口点ENTRYPOINT ["executable","param1","param2"] ENTRYPOINT command param1 param2
ENTRYPOINT和CMD指令的目的一样,都是指定Docker容器启动时执行的命令,可多次设置,但只有最后一个有效。
ENV设置环境变量ENV指令用于设置环境变量
ENVENV = ...
ENV JAVA_JOME /path/to/java
EXPOSE声明暴露的端口EXPOSE指令用于声明在运行时容器提供服务的端口,格式为EXPOSE
需要注意的是,这只是一个声明,运行时并不会因为该声明就打开相应端口,该指令的作用主要是帮助镜像使用者理解该镜像服务的守护端口;其次是当运行时使用随机映射时,会自动映射EXPOSE的端口。
#声明暴露一个端口示例 EXPOSE port1 #相应的运行容器使用的命令 docker run -p port1 image #声明暴露多个端口示例 EXPOSE port1 port2 port3 #相应的运行容器使用的命令 docker run -p port1 -p port2 -p port3 image #也可指定需要映射到宿主机器上的端口号 docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 imageFROM指定基础镜像
使用FROM指令基础镜像,FROM指令有点像Java里面的extends关键字。需要注意的是,FROM指令必须指定且需要写在其他指令之前。FROM指令后的所有指令都依赖于该指定的镜像。
FROMLABEL为镜像添加元数据FROM : FROM @
LABEL指令用于为镜像添加元数据。
格式为LABEL
使用"""和”“转换命令行
LABEL "com.example.vendor"="ACME Incorporated" LABEL com.example.lable-with-value="foo" LABEL version="1.0" LABEL description="This text illustrates that label-values can span multiple lines."MAINTAINER指定维护者的信息
MAINTAINER指令用于指定维护者的信息,用于为Dockerfile署名。
格式为MAINTAINER
RUNRUN ["executable","param1","param2"]
RUN
该指令用于设置启动镜像时的用户或者UID,写在该指令后的RUN,CMD以及ENTRYPOINT指令都将使用该用户执行命令。
USER daemonVOLUME指定挂载点
该指令使容器中的一个目录具有持久化存储的功能,该目录可被容器本身使用,也可共享给其他容器。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令。
VOLUME /data
WORKDIR /path/to/workdir
切换目录指令,类似于cd命令,写在该指令后的RUN、CMD以及ENTRYPOINT指令都将该目录作为当前目录,并执行相应的命令。
其他Dockerfile还有一些其他的指令,例如STOPSINGAL、HEEALTHCHECK、SHELL等。不常用略。
使用Dockerfile构建镜像 准备工作以项目microservice-discovery-eureka为例,首先执行以下命令,将项目构建成jar包:microservice-discovery-eureka-0.0.1-SNAPSHOT.jar
mvn clean package #使用Maven打包项目镜像构建
1)在jar包所在目录,创建名为Dockerfile的文件。
touch Dockerfile
在Dockerfile中添加以下内容。
#基于哪个镜像 FROM java:8 #将本地文件夹挂载到当前容器 VOLUME /tmp #复制文件到容器 ADD microservice-discovery-eureka-1.0-SNAPSHOT.jar app.jar RUN bash -c 'touch /app.jar' #声明需要暴露的端口 EXPOSE 8761 #配置容器启动后执行的命令 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
3)使用docker build命令构建镜像
docker build -t example/microservice-discovery-eureka:0.0.1 . #格式:docker build -t 仓库名称/镜像名称(:标签) Dockerfile的相对位置
测试
1)启动镜像
docker run -d -p 8761:8761 example/microservice-discovery-eureka:0.0.1
2)访问http://Docker宿主机IP:8761/,可正常显示Eureka Server首页。
至此,已经构建了Docker镜像,并将微服务运行在Docker之上。但是,一个完整的应用系统可能包含上百个微服务,那就可能对应着上百个镜像,如果考虑各个微服务的版本,那么可能会构建更多的镜像。这些镜像该如何管理呢?
使用Docker Hub管理镜像Docker Hub是Docker官方维护的Docker Registry,上面存放着很多优秀的镜像。不仅如此,Docker Hub还提供认证、工作组结构、工作流工具、构建触发器等工具来简化工作。
注册与登录Docker Hub的使用非常简单,只需注册一个Docker Hub账号,就可正常使用了。登录后,可看到Docker Hub的主页。
也可使用docker login命令登录Docker Hub。输入该命令并按照提示输入账号和密码,即可完成登录。
单击Docker Hub主页上的Create Repository按钮,按照提示填入信息即可创建一个仓库。只需填入相关信息,并单击Create按钮,就可创建一个名为microservice-discovery-eureka的公共仓库。
下面来将前文构建的镜像推送到Docker Hub。使用以下命令
docker push example/microservice-discovery-eureka:0.0.1
经过一段时间的等待,就可推送成功。这样,就可在Docker Hub查看已推送的镜像。
很多场景下,需使用私有仓库管理Docker镜像。相比Docker Hub,私有仓库有以下优势
- 节省带宽,对于私有仓库中已有的镜像,无须从Docker Hub下载,只需从私有仓库中下载即可。
- 更加安全。
- 便于内部镜像的统一管理
Docker Registry 2.0的搭建非常简单,只需执行以下命令即可新建并启动一个Docker Registry 2.0
docker run -d -p 5000:5000 --restart=always --name registry2 registry:2将镜像推送到私有仓库
前文使用了docker push命令将镜像推送到了Docker Hub,现在将前文构建的容器推送到私有仓库
docker push localhost:5000/example/microservice-discovery-eureka:0.0.1
执行以上命令,发现推送并没有成功,且提示以下内容:
Docker Hub默认的Docker Registry,所以example/microservice-discovery-eureka:0.0.1相当于docker.io/example/microservice-discovery-eureka:0.0.1。因此,想要将推送到私有仓库,需要修改镜像标签。
docker tag example/microservice-discovery-eureka:0.0.1 localhost:5000/example/microservice-discovery-eureka:0.0.1
修改标签后,再次执行
注:Docker Registry2.0需要Docker版本高于1.6
还可为私有仓库配置域名、SSL登录、认证等。
Docker Registry 2.0能够满足大部分场景下的需求,但它不包含界面、用户管理、权限控制等功能。如果想要使用这些功能,可使用Docker Trusted Registry。
Maven是一个强大的项目管理与构建工具。如果可以使用Maven构建Docker镜像,工作就能得到进一步的简化。
这里使用一款由Spotify公司开发的Maven插件
# vim /usr/lib/systemd/system/docker.service [Service] ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
“unix:///var/run/docker.sock”:unix socket,本地客户端将通过这个来连接 Docker Daemon。
“tcp://0.0.0.0:2375”:tcp socket,表示允许任何远程客户端通过 2375 端口连接 Docker Daemon。
可以看到已经docker启动了一个新的守护进程。
vim /etc/docker/daemon.json
{ "insecure-registries":["192.168.238.10:5000"], #是registries不是registry }将java8上传到私有仓库里
启动仓库
docker start registry:2
给java:8镜像修改标签并上传
docker tag java:8 192.168.185.120:5000/java docker push 192.168.185.120:5000/java快速入门
以项目microservice-discovery-eureka为例
1)在pom.xml中添加Maven的Docker插件。
com.spotify docker-maven-plugin0.4.13 example/microservice-discovery-eureka:0.0.1 http://192.168.185.120:2375 192.168.185.120:5000/java ["java","-jar","/${project.build.finalName}.jar"] / ${project.build.directory} ${project.build.finalName}
- imageName:用于指定镜像名称,其中example是仓库名称,microservice-discovery-eureka是镜像名称,0.0.1是标签名称。
- baseImage:用于指定基础镜像,类似于Dockerfile中的FROM指令。
- entrypoint:类似于Dockerfile的ENTRYPOINT指令。
- resources.resource.directory:用于指定需要复制的根目录,${project.build.directory}表示target目录。
- resources.resource.include:用于指定需要复制的文件。${project.build.finalName}.jar指的是打包后的jar包文件。
2)执行以下命令,构建Docker镜像。
mvn clean package docker:build
首先在/microservice-discovery-eureka/src/main/docker目录下,新建一个Dockerfile文件
#基于哪个镜像 FROM java:8 #将本地文件夹挂载到当前容器 VOLUME /tmp #复制文件到容器 ADD microservice-discovery-eureka-1.0-SNAPSHOT.jar app.jar RUN bash -c 'touch /app.jar' #声明需要暴露的端口 EXPOSE 8761 #配置容器启动后执行的命令 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
修改pom.xml
com.spotify docker-maven-plugin1.0.0 example/microservice-discovery-eureka:0.0.1 http://192.168.2.120:2375 ${project.basedir}/src/main/docker / ${project.build.directory} ${project.build.finalName}.jar
可以看到,不再指定baseImage和entrypoint,而是使用dockerDirectory指定Dockerfile所在的路径。这样,就可以使用Dockefiler构建Docker镜像了。
很多场景下,有这样的需求,执行例如mvn clean package时,插件就自动为构建Docker镜像。要想实现这点,执行将插件goal绑定在某个phase即可。
phase和goal可以这样理解:maven命令格式是mvn phase:goal,例如mvn package docker build。那么package docker都是phase,build则是goal。
com.spotify docker-maven-plugin1.0.0 build-image package build example/microservice-discovery-eureka:0.0.1 http://192.168.2.120:2375 ${project.basedir}/src/main/docker / ${project.build.directory} ${project.build.finalName}.jar
由配置可知,只需添加如下配置
build-image package build
就可将插件绑定在package这个phase上。
推送镜像前文使用docker push命令实现了镜像的推送,也可使用Maven插件推送镜像。不妨使用Maven插件推送一个Docker镜像到Docker Hub。
1)修改Maven的全局配置文件settings.xml,在其中添加以下内容,配置Docker Hub的用户信息。
docker-hub repouser repopwd
2)修改pom.xml
com.spotify docker-maven-plugin1.0.0 build-image package build 18332104715/microservice-discovery-eureka:0.0.1 http://192.168.2.120:2375 ${project.basedir}/src/main/docker / ${project.build.directory} ${project.build.finalName}.jar docker-hub
3)执行以下命令,添加pushImage的标识,表示推送镜像。
mvn clean package docker:build -DpushImage
同理,也可推送镜像到私有仓库,只需要将imageName指定成类似
localhost:5000/microservice-discovery-eureka:0.0.1
注:以上实例是通过imageName指定镜像名称和标签的
localhost:5000/microservice-discovery-eureka:0.0.1
也可借助imageTags元素更为灵活地指定镜像名称和标签
example/microservice-discovery-eureka 0.0.5 latest
这样就可为同一个镜像指定两个标签。
也可在构建命令时,使用dockerImageTags参数指定标签名称
mvn clean pachage docker:build -DpushImageTags -DdockerImageTags=latest -DdockerImageTags=another-tag
如需重复构建相同标签名称地镜像,可将forceTags设为true,这样就会覆盖构建相同标签的镜像。
true
Spotify是全球最大的正版流媒体音乐服务平台。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)