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 = 1
net.bridge.bridge-nf-call-iptables = 1
net.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 SIZE
wuhu/nginx v1 04066b822951 24 hours ago 375MB
REPOSITORY:镜像仓库名称
TAG:镜像标签
IMAGE:镜像ID
CREATED:镜像创建时间
SIZE:大小
-a 列出所有镜像
-q 只显示镜像的ID
docker search centos #搜索镜像
--filter=START=3000
docker pull centos:tag #拉取/下载镜像
docker rmi -f neginx #删除镜像
docker rmi -f ${docker images -aq} #递归删除所有镜像
systemctl daemon-reload && systemctl restart docker #重启docker
docker load -i /root/centos.tar.gz #解压镜像
docker save -o test.tar.gz centos:latest #打包镜像
查看docker统计信息
docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 3 1 185.5MB 185.5MB (99%)
Containers 3 0 0B 0B
Local Volumes 0 0 0B 0B
Build 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 centos
CMD ["ls","-a"]
docker build -t centos-test:v0.1 -f Dockerfile . #构建镜像
docker run -d 7149c87c748f #此时运行就是启动了centos 并且在其中执行命令ls -a
docker run -d 7149c87c748f /bin/bash #此时运行就是启动了centos,并且在其中执行命令 /bin.bash
ENTRYPOINT:追加命令只是占用了“-a”的占位符
FROM centos
ENTRYPOINT ["mc.sh","start"]
docker run -d 7149c87c748f #此时运行就是启动了centos,并且默认执行mc.sh的start内部脚本 mc.sh start
docker run -d 7149c87c748f log #此时运行就是启动centos,并且执行了mc.sh的log内部脚本 mc.sh log
实例:构建centos
1.创建文件并准备需要用到的安装包
mkdir -p /root/dockerfile #创建文件夹
cd /root/dockerfile
vim 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/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 80 #设置端口
CMD echo $MYPATH
CMD 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. 启动镜像
```shell
docker 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/javaee
http://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>