Docker基础
Docker基础概念
Docker核心概念
Docker大部分的操作都围绕着它的三大核心概念:镜像、容器和仓库。因此,准确把握这三大核心概念对于掌握Docker技术尤为重要。
Docker底层原理
为什么docker会比vm虚拟机快。
1.docker比虚拟机有更少的抽象层。
- docker并不是通过虚拟了硬件资源,而是直接使用物理机的硬件资源,所以速度很快。
2.docker使用了宿主机的内核,而不需要加载操作系统。
- vm创建虚拟机时直接创建整个操作系统。但docker不是,他是直接利用宿主机的操作系统,省略了返回过程。
Docker和虚拟机之间的不同
- 传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件。
- Dokcer容器内应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了很多
- 每个容器之间是相互隔离的,每个容器内有一个属于自己的文件系统,互不影响。
DevOps(开发,运维)
应用更快速的交付和部署
更快捷的升级和缩容
跟简单的系统运维
更高效的资源利用
Docker镜像的分层概念
- 镜像是什么
- 是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
- 分层的镜像
- 以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载。
- UnionFS(联合文件系统)
- UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
- 特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
- Docker镜像加载原理
- docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
- Docker镜像层都是只读的,容器层是可写的
- 当容器启动时,一个新的可写层被加载到镜像的顶部。 这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”

Docker的安装
Linux下载安装
http://get.daocloud.io/
安装docker环境依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io -y
启动docker
systemctl start docker && systemctl enable docker
索引缓存
yum makecache fast
设置内核
net.bridge.bridge-nf-call-ip6tables = 1net.bridge.bridge-nf-call-iptables = 1net.ipv4.ip_forward = 1
一键安装
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
阿里云镜像加速器
如果不进行配置,很有可能会卡顿。这里建议使用阿里云镜像加速,免费的。
在阿里云中找到镜像加速,在路径/etc/docker/daemon.json 复制进去。
{
“registry-mirrors”: [“https://zamu0pih.mirror.aliyuncs.com“]
}
Docker run hello-world
当docker run 执行后,这个run都干了什么。

Docker命令
可以使用命令在dockerhub上进行搜索,默认也是dockerhub上搜索。
帮助类命令
docker version #镜像信息docker 命令 --help #查看帮助文档docker info #docker信息
镜像命令
docker images #列出本地镜像REPOSITORY TAG IMAGE ID CREATED SIZEwuhu/nginx v1 04066b822951 24 hours ago 375MB
REPOSITORY:镜像仓库名称
TAG:镜像标签
IMAGE:镜像ID
CREATED:镜像创建时间
SIZE:大小
-a 列出所有镜像
-q 只显示镜像的ID
docker search centos #搜索镜像--filter=START=3000docker pull centos:tag #拉取/下载镜像docker rmi -f neginx #删除镜像docker rmi -f ${docker images -aq} #递归删除所有镜像systemctl daemon-reload && systemctl restart docker #重启dockerdocker load -i /root/centos.tar.gz #解压镜像docker save -o test.tar.gz centos:latest #打包镜像
查看docker统计信息
docker system dfTYPE TOTAL ACTIVE SIZE RECLAIMABLEImages 3 1 185.5MB 185.5MB (99%)Containers 3 0 0B 0BLocal Volumes 0 0 0B 0BBuild Cache 0 0 0B 0B
容器类命令
拉取和运行
docker pull centos #拉取镜像,有镜像才能运行容器docker run [可选参数] images#参数说明--name="Name" 容器名称,nginx,tomcat1。-d 后台运行-it 使用交互方式运行/进入容器查看内容-p 指定容器端口, 80:80-P 随机指定端口docker run -it centos /bin/bash #以前台交互的模式启动并进入容器docker run -d centos #以后台守护式启动Ctrl + P + Q #退出容器并在后台运行
列出运行的容器
docker ps #列出当前正在运行的容器-a #列出全部容器-n [数字] #列出最近的n个容器-q #只显示容器的编号
退出容器
exit #退出容器ctrl+P+Q #退出并继续运行容器
删除容器
docker rmi 容器id #删除指定容器,但无法删除正在运行的容器docker rmi -rf 容器id #强制删除docker rmi -f $(docker ps -aq) #递归删除所有启动/启动过的容器docker ps -a|xargs docker rmi #递归删除所有容器
启动和停止容器
docker start|restart|stop|kill 容器id #启动|重启|停止|杀掉 容器
后台部署应用
docker run -d centos#docker ps 会发现centos停止了!!!#docker容器后台运行必须要有一个前台进程,docker发现没有应用就会自动停止。#例如:nginx容器启动后,发现自己没有提供服务,就会立刻停止。
查看日志
docker logs 容器ID #查看容器日志docker logs -tf --tail 10 容器ID #查看容器前10行的日志--tail number #显示日志条数
查看容器的进程信息
docker top 容器ID
查看镜像的源数据
docker inspect 容器ID
进入当前正在运行的容器
docker exec -it 容器ID /bin/bash #以交互形式进入容器,类似新开一个界面#exec 使用exit进入退出不会停止docker attach -it 5d8e48e4b792 #进入正在运行的容器命令行#attach 退出了会停止容器
镜像的保存与导入
docker save -o test.tar myapp:v0.1 #保存镜像docker save fe8c52043b39 > test.tar #保存镜像#此时就会创建一个tar包,其中就是镜像文件docker load < test.tar #导入镜像docker load -i test.tar #导入镜像#将tar包导入,就可以运行使用了。
容器文件拷贝到主机上
#在主机上输入该命令docker cp 容器ID:文件路径 目的主机路径
容器备份与解压
备份运行时的容器镜像
docker export 517d619c4d55 > test.tar #将你的整个容器做成tar备份cat test.tar | docker import - test/redis:0.1 #将tar备份文件转换为可用镜像

命令总结
| 命令 | 作用 |
|---|---|
| attach | 当前 shell 下 attach 连接指定运行镜像 |
| build | 过 Dockerfile 定制镜像 |
| commit | 提交当前容器为新的镜像 |
| cp | 容器中拷贝指定文件或者目录到宿主机中 |
| create | 创建一个新的容器,同 run,但不启动容器 |
| diff | 查看 docker 容器变化 |
| events | 从 docker 服务获取容器实时事件 |
| exec | 在已存在的容器上运行命令 |
| export | 导出容器的内容流作为一个 tar 归档文件 |
| history | 展示一个镜像形成历史 |
| images | 列出系统当前镜像 |
| import | 从tar包中的内容创建一个新的文件系统映像 |
| info | 显示系统相关信息 |
| inspect | 查看容器/数据卷/网卡的详细信息 |
| kill | kill 指定 docker 容器 |
| load | 从一个 tar 包中加载一个镜像 |
| login | 注册或者登陆一个 docker 源服务器 |
| logout | 从当前 Docker registry 退出 |
| logs | 输出当前容器日志信息 |
| port | 查看映射端口对应的容器内部源端口 |
| pause | 暂停容器 |
| ps | 列出容器列表 |
| pull | 从docker镜像源服务器拉取指定镜像或者库镜像 |
| push | 推送指定镜像或者库镜像至docker源服务器 |
| restart | 重启运行的容器 |
| rm | 移除一个或者多个容器 |
| rmi | 移除一个或多个镜像 |
| run | 创建一个新的容器并运行一个命令 |
| save | 存一个镜像为一个 tar 包 |
| search | 在 docker hub 中搜索镜像 |
| start | 启动容器 |
| stop | 停止容器 |
| tag | 给源中镜像打标签 |
| top | 查看容器中运行的进程信息 |
| unpause | 取消暂停容器 |
| version | 查看 docker 版本号 |
| wait | 截取容器停止时的退出状态值 |
| volume | 数据卷 |
Dockerfile
1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数
2:指令按照从上到下,顺序执行
3:#表示注释
4:每条指令都会创建一个新的镜像层并对镜像进行提交
构建流程:
- docker从基础镜像运行一个容器
- 执行一条命令并对容器做出修改
- 执行类似docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新容器
- 执行dockerfile中的下一条命令知到所有命令都执行完毕
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
Dockerfile是软件的原材料
Docker镜像是软件的交付品
Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
dockerfile命令
| 命令 | 命令的作用 | 常见用法 |
|---|---|---|
| FROM | 指定基础镜像 | FROM centos |
| MAINTAINER | 指定镜像作者,姓名+邮箱 | MAINTAINER liao |
| RUN | 镜像构建时需要运行的命令 | RUN yum install vim -y |
| ADD | 添加文件,比如添加一个tomcat压缩包 | ADD test.tar /root/ |
| WORKDIR | 设置镜像的工作目录 | WORKDIR /usr/local |
| VOLUME | 设置容器卷,设置挂载目录位置 | |
| EXPOSE | 指定对外的端口。和-p一样。 | EXPOSE 80 |
| CMD | 指定容器启动时候要运行的命令,只有最后一个生效,并且可被替代 | CMD [“catalina.sh”,”run”] |
| ENTRYPOINT | 和CMD一样,可以直接追加命令。 | ENTRYPOINT[‘ps’] docker run —rm test -ef |
| ONBUILD | 当构建一个被继承dockerfile这个时候会运行 ONBUILD 的指令 触发指令 | |
| COPY | 类似ADD,将文件拷贝到镜像中 | CMD /bin/bash |
| ENV | 构建时设置环境变量 | ENV MY_PATH /usr/mytest |
| ARG | 设置编译变量 |

CMD和ENTRYPOINT的区别
CMD:追加命令是直接占用了CMD整个占位符
CMD常用来写在最后,然后用来启动服务。比如安装好了tomcat,最后用CMD启动脚本。
#运行完镜像后,执行ls -a命令FROM centosCMD ["ls","-a"]docker build -t centos-test:v0.1 -f Dockerfile . #构建镜像docker run -d 7149c87c748f #此时运行就是启动了centos 并且在其中执行命令ls -adocker run -d 7149c87c748f /bin/bash #此时运行就是启动了centos,并且在其中执行命令 /bin.bash
ENTRYPOINT:追加命令只是占用了“-a”的占位符
FROM centosENTRYPOINT ["mc.sh","start"]docker run -d 7149c87c748f #此时运行就是启动了centos,并且默认执行mc.sh的start内部脚本 mc.sh startdocker run -d 7149c87c748f log #此时运行就是启动centos,并且执行了mc.sh的log内部脚本 mc.sh log
实例:构建centos
1.创建文件并准备需要用到的安装包
mkdir -p /root/dockerfile #创建文件夹cd /root/dockerfilevim Dockerfile #创建Dockerfile,这里D要大写FROM centos #指定使用的镜像MAINTAINER liao #指定作者ENV MYPATH /usr/local #创建变量WORKDIR $MYPATH #设置工作路径RUN yum install -y vim net-tools glibc.i686 #安装工具包RUN mkdir /usr/local/java #创建文件夹ADD jdk-17_linux-x64_bin.tar.gz /usr/local/java #添加并解压压缩包到指定文件夹ENV JAVA_HOME /usr/local/java/jdk-17.0.2 #设置变量ENV JRE_HOME /usr/local/java/jreENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATHENV PATH $JAVA_HOME/bin:$PATHEXPOSE 80 #设置端口CMD echo $MYPATHCMD echo "success-----------ok"CMD /bin/bash
虚悬镜像node
在构建或者删除镜像的时候出现了错误,导致镜像仓库和标签都为none。
docker images ls -f dangling=true #查看所有的虚悬镜像
docker image prune #删除所有的虚悬镜像
实例:构建tomcat
- 准备tomcat压缩包和jdk压缩包
- 编写dockerfile文件
```shell FROM centos #指定基础包 MAINTAINER liao1182350036@qq.com #作者信息 COPY readme.txt /usr/local/readm.txt #复制文件到容器路径 /usr/local/readm.txt
ADD jdk-8u301-linux-x64.tar.gz /usr/local/ #添加并解压文件到 /usr/local/ ADD apache-tomcat-8.5.70.tar.gz /usr/local/
RUN yum install vim net-tools -y
ENV MYPATH /usr/local #配置环境变量 WORKDIR $MYPATH #设置工作目录
ENV JAVA_HOME /usr/local/jdk1.8.0_301 #设置变量 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.70 ENV CATLINA_BASH /usr/local/apache-tomcat-8.5.70 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.70/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.70.tar.gz/bin/logs/catalina.out
3. 启动镜像```shelldocker run -d -p 9090:8080 --name tomcats123 -v /dockers1/tomcat/:/usr/local/apache-tomcat-8.5.70/webapps/tomcat -v /dockers1/tomcatlogs/:/usr/local/apache-tomcat-8.5.70/logs da668652083f
web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"></web-app>
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>docker</title></head><body><h3>hello,docker</h3><%System.out.println("hello, dockerlogs");%></body></html>
