Docker入门与实践
Docker容器化技术
对比虚拟机技术
虚拟机技术虚拟出一套硬件资源,在此上安装操作系统进而运行一些软件
而容器虚拟化出的容器都是直接使用宿主机硬件资源,基于宿主机的内核上进行运行,不用虚拟出来一套硬件资源,从而更快,更节约存储空间
虚拟机与容器化
1.两者是相辅相成的,可以共同使用的
2.云服务提供商通常采用虚拟机技术隔离不同的用户。而 Docker 通常用于隔离不同的应用
Docker特点
1.所有的容器都基于宿主机内核,启动很快
2.镜像使用文件层系统构建的,包含了代码、完整的运行时环境、系统工具、系统库和设置;同时能够共享一些公共资源,占用资源更少;
3.隔离性不仅限于容器与容器之间,而且还各自独立于底层基础设施
4.Docker镜像提供了除内核外完整的运行时环境,保证了在任何机器上服务环境是一致的
镜像
是一个类似于Linux中的root文件系统。实际上是一个多层文件系统联合组成。
镜像在构建过程中,是一层一层的构建。同时也能复用之前构建好的镜像,然后添加新的分层定制自己的内容,成为一个新镜像
容器
是镜像的实体,能够运行的进程,有自己的生命周期,它是运行于自己独立命名空间。
它和镜像一样也是有自己的存储层,生命周期和容器是一样的,容器在则属于自己的存储层,消失都消失,容器存储层应该保持无状态化。所以不能向容器存储层写入任何数据,否则会有丢失数据的问题。所有数据写入,应该使用数据卷或者绑定到宿主机,能够持久化
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。
科普:无状态化说白了就是不依赖其他事务或数据,是独立的;有状态是需要依赖其他事务,会受其他事务影响的
仓库
负责存储镜像的地方
数据卷
作用:
能够实现宿主机与容器数据文件共享,也就是说宿主机数据文件修改后会影响到容器相应的内容
数据卷的生命周期独立于容器的
两种方式:
- 指定目录方式
-v 宿主机绝对路径:容器内的位置
在启动容器时,会将指定宿主机目录下的文件数据同步到容器指定的位置中,如果不存在Docker会自动创建它
docker run -d -p 8080:8080 --name tomcat01 -v /opt/apps:/usr/local/tomcat/webapps tomcat:8.0-jre8
- 匿名数据卷方式
-v 数据卷名字:容器内的位置
在启动容器时,将指定容器的目录文件同步到自定义数据卷中
docker run -d -p 8080:8080 --name tomcat01 -v aa:/usr/local/tomcat/webapps tomcat:8.0-jre8
- 删除无用的数据卷
docker volume prune
常用命令
对某个镜像或者容器操作时,可以使用短id或者id的前3个标识符即可
-
查看镜像、容器、数据卷所占用的空间
docker system df
-
强制删除当前所有的正在运行的容器
docker rm -f $(docker ps -qa)
-
查看容器实时日志
docker logs -ft containerId
-
查看所有容器资源占用详情
docker stats -a
-
查看容器磁盘占用情况
docker system df
Dockerfile指令
作用:用清晰指令来构建镜像
注意:Dockerfile中的每个操作指令都会新建一层文件
- From:指定基础镜像,必须是Dockerfile文件中第一个指定。也可以指定一个虚拟的概念镜像FROM scratch
#以java8为基础镜像
From Java:8
- Run:在构建当前镜像时要执行的 shell 或 exec 命令
#执行shell命令创建/usr/src/redis目录
RUN mkdir -p /usr/src/redis
- VOLUME:用于指定容器内匹配挂载宿主机匿名卷的位置,当容器启动时会自动在宿主机创建一个匿名卷与当前指定的位置进行挂载匹配。
# 如VOLUME指定/data,容器内会生成一个/data目录,会在宿主机/var/lib/docker/volumes/xxxxx/_data进行挂载
VOLUME /data
- COPY:会将构建上下文中的文件/目录拷贝到镜像指定的位置。目标路径不需要事先创建,当指定的位置不存在会自动创建的,如果COPY上边指令已经使用了WORKDIR,都是相对与容器内WORKDIR的路径操作的
# COPY ./app.jar /app.jar
ADD:有COPY的功能,同时也可以解压,可以下载链接的文件
在 Docker 官方的 Dockerfile 最佳实践文档 中要求,尽可能的使用 COPY
,因为 COPY
的语义很明确,就是复制文件而已,而 ADD
则包含了更复杂的功能,其行为也不一定很清晰。最适合使用 ADD
的场合,就是所提及的需要自动解压缩的场合。
- CMD:是在构建容器的时候要执行的 shell 或 exec 命令。
如果docker run 指定了shell命令,那么该Dockerfile中CMD命令会失效。
在与ENTRYPOINT配合使用时,会被当做ENTRYPOINT参数使用,相当于 "
" "
注意CMD与RUN指令的区别:CMD是在启动容器
时使用,RUN是构建镜像
时使用
- ENTRYPOINT:类似于CMD,在启动容器时指定的shell命令,但与CMD配合使用时,会将CMD当做参数传递给ENTRYPOINT
ENTRYPOINT ["java","-jar","testApp.jar"]
-
EXPOSE:仅仅声明了当前容器暴露的端口
-
WORKDIR:指令用于设置容器内部的工作目录(Working Directory)。
该指令的作用是在容器内部创建一个指定的目录,并将该目录设置为后续命令的默认工作路径。注意
# 指定工作目录后,以后各层操作的当前目录就被改为指定的目录
Dockerfile文件案例
FROM openjdk:8-jre
# 指定容器时区与宿主机时区同步
ENV TZ Asia/Shanghai
#定义变量,类似于java中的变量,供上下文使用
ENV dir /opt/lk/project
#联系邮箱
MAINTAINER party_abu@163.com
#镜像创建时候执行的命令:
#创建镜像中的目录结构。一旦镜像构建完成并且你基于这个镜像运行了一个容器,这些目录也会包含在容器内部
RUN mkdir -p $dir
#指定工作目录后,以后各层的当前目录就被改为指定的目录
WORKDIR $dir
#将构建上下文中的文件拷贝到镜像中(上文中已经指定过workdir了,
#这里镜像中的位置是相对于workdir目录/opt/lk/project来说的),并重命名为app.jar
COPY ./docker-demo.jar app.jar
#指定容器内部的的数据卷位置
VOLUME $dir/data
#启动容器时执行的shell命令[也是相对于workdir中 即/opt/lk/project/目录下执行
#java -Xms256m -Xmx256m -jar app.jar]
ENTRYPOINT ["java","-Xms256m","-Xmx256m","-jar","app.jar"]
#提示服务端口是8080
EXPOSE 8080
注:
1.
CMD 指令的格式和 RUN 相似,也是两种格式:
shell 格式:CMD <命令>
exec 格式:CMD ["可执行文件", "参数1", "参数2"...]
2.
在指令格式上,一般推荐使用 exec 格式,这类格式在解析时会被解析为 JSON 数组,因此一定要使用双引号 ",而不要使用单引号。
Dockerfile构建镜像
docker build
docker build -t 新镜像名字:标签名 .
docker run
运行镜像成为一个容器
docker run --name 容器名 -d -t 镜像id
进入容器内部
docker exec -it 容器id bash