什么是Docker
Docker是一个开源的应用容器引擎,基于Go语言开发的。Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口,更重要的是容器性能开销极低。
Docker和虚拟技术的不同
- 传统虚拟机,虚拟一套硬件,运行一个完整的操作系统,然后再这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机的内核,容器是没有自己的内核,也没有虚拟我们的硬件,所以就性能开销比较 小
- 每个容器间是相互隔离,每个容器都有一个属于自己的文件系统,互不影响
Docker对开发过程中产生的影响
应用更快速的交付和部署
传统:一堆帮助文档,安装程序
Docker:打报镜像,发布测试,一键运行
更便捷的升级和扩缩容
更简单的系统运维
更高效的计算资源利用
Docker安装
镜像(image):
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像==>run==>tomcat01容器(提供服务),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在这个容器中)。
容器(conrainer):
Docker利用容器技术,独立运行一个或者一个组应用,通过镜像来创建的。
启动,停止,删除,基本命令
当前为止,我们可以把容器理解为一个简易的linux系统
仓库(repository)
仓库就是存放镜像的地方,仓库分为公有仓库和私有仓库(类似于GitHub)
Docker Hub(默认为国外的仓库)
阿里云等都有容器服务器(配置镜像加速)
安装Docker
Linux:
首先我们进入官网[官网](Get Docker | Docker Documentation),选择Docker For Linux 我们这里是CentOs 所以我们选择这个版本,建议根据官方文档来安装Docker
官方文档建议我们首先卸载旧版本的Docker
1 | sudo yum remove docker \ |
然后安装 yum-utils
1 | sudo yum install -y yum-utils |
然后设置仓库
1 | sudo yum-config-manager \ |
这里建议将仓库地址换成国内仓库
1 | Docker中国区官方镜像: |
然后开始运行Docker
1 | sudo systemctl start docker |
学习开始必不可少 hello world
1 | sudo docker run hello-world |
当然我们刚开始运行时没有这个镜像的,会从仓库中拉去这个
当我们看见这个的时候说明我们的第一步已经完成了,顺便看一下我们下载的这个镜像
1 | docker images |
Docker的官方文档可以说是十分的详细了,不仅为我们介绍了怎么安装,同样也为我们说明了怎么卸载docker
Docker 运行原理图
Docker的常用命令
帮助命令
1 | docker version # 查看docker 版本相关信息 |
镜像命令
docker images
查看所有本地的主机上的镜像
1 | bestrookie@bestrookiedeMac-mini ~ % docker images |
docker search
搜索镜像
docker pull
下载镜像
1 | 下载镜像 docker pull 镜像名:[版本] |
docker rmi
删除镜像
1 | docker rmi -f 镜像id #删除指定镜像 |
容器命令
我们有了镜像才可以创建容器,我们下载一个centos镜像来测试学习
1 | docker pull centos |
新建容器并启动
1 | docker run [可选参数] image |
docker ps
列出所有的运行的容器
1 | docker ps 命令 |
退出容器
1 | exit #直接退出容器 |
删除容器
1 | docker rm 容器id #删除指定容器 |
启动和停止容器的操作
1 | docker start 容器id #启动容器 |
常用其他命令
后台启动容器
1 | 命令 docker run -d 镜像名 |
查看日志
1 | docker logs -tf --tail 日志条数(不加查看所有) 容器id |
查看容器中进程信息
1 | [root@bestrookie bestrookie]# docker top 容器id |
查看容器的元数据
1 | docker inspect 容器id |
进入当前正在运行的容器
1 | docker exec -it 容器id bashSell #进入容器后开启一个新的终端,可以在里面操作(常用) |
将文件拷贝到主机
1 | docker cp 容器id:地址 要拷贝到目录 |
Docker练习 安装nginx
首先我们先搜索在仓库中有没有这个仓库
1 | docker search nginx |
建议从官网搜索,可以更好的查看版本信息
然后我们下载镜像
1 | docker pull nginx |
下载完镜像我们创建并运行容器,这里我们可以设置端口号等信息
1 | docker run -d --name nginx01 -p 3344:80 nginx |
查看是否成功
我们也可以从浏览器地址访问。
Docker可视化面板
1 | docker run -d -p 8088:9000 \ |
Docker镜像
镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
所有的应用,直接打包docker镜像,就可以直接跑起来。
如何得到镜像
- 从远程仓库下载
- 从别处拷贝
- 自己制作一个镜像DockerFile
Docker镜像加载原理
UnionFs(联合文件系统)
UnionFs(联合文件系统):UnionFS文件系统是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。UnionFS文件系统是Docker镜像的基础。镜像可以通过分层来进项集成,基于基础镜像,可以制作各种具体的应用镜像。
特性:椅子同时加载多个文件系统,但从外面开起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终文件系统会包含所有底层的文件和目录
Docker镜像加载原理
docker的镜像实际上由一层层的文件系统组成,这种层级的文件系统UnionFS。
bootfs主要包含BootLoader和kernel,BootLoader主要引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们经典的Linux、Unix系统是一样,包括boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
roofs,在bootfs之上,在bootfs之上。包含的警示典型的Linux系统中的/dev/proc/bin/etc等标准目录和文件。rootfs就是各种不同的操作系统发型版,如Ubuntu,Centos等等。
分层理解
分层的镜像
我们在下载镜像的时候我们发现,镜像是一层一层下载的
分层下载的最大好处就是资源共享,比如多个镜像都从相同的Base镜像构建而来的,那么宿主机只需要在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层可以被共享。
可以通过docker image inspect 镜像名称
查看镜像封层
理解:
所有的Docker镜像都起始于一个基础镜像,当进行修改或增加新的内容是,就会在当前镜像层之上,创建新的镜像层,例如一个基于Ubuntu16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python镜像,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
该镜像当前已经包含三个镜像层
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下推中举一个简单例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本
这种情况下,上层镜像层中的文件覆盖了底层镜像中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像中。Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统.
Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker在Windows 上仅支持windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW[1]。下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
下图展示了系统显示相同的三层进行改那个。所有镜像堆叠合并,对外提供统一的视图
特点:Docker镜像层都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层就是我们常说的容器层,容器之下的都叫镜像层
Commit镜像
1 | docker commit 提交容器成为一个新的副本 |
容器数据卷
现在我们将镜像打包成一个容器,那么我们将容器删除,我们使用的数据就会丢失,容器数据卷就是为了解决这个问题。容器数据卷就是将我们的容器的文件目录挂载到我们的主机的一个目录上,可以说是实现了双向绑定。
也就是说:容器数据卷实现了容器的持久化和同步操作
1 | docker run -it -v 主机目录: 容器内目录 |
然后我们使用命令docker inspect
查看容器挂载信息
如果挂载信息不对,说明我们没有挂载成功
配置mysql镜像
1 | docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 |
成功启动以后我们测试一下
在本地用我们的数据库可视化工具链接我们的数据库,并且创建一个数据看看我们挂载文件路径下能否同步。
具名挂载和匿名挂载
匿名挂载
1 | -v 容器内路径 |
具名挂载
1 | -v 卷名:容器内路径 |
查看所有挂载
1 | docker volume ls |
初识Dockerfile
Dockerfile就是用来构建docker镜像额构建文件,就是一个命令脚本
通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个一个的命令,每个命令都是一层
1 | 创建一个dockerfile文件,名字可以随机 建议dockerfile |
然后通过命令构建
1 | docker build -f dockerfile1 -t bestrookie/centos . |
运行一下这个容器然后查看容器信息
可以发现已经挂载了我们在,脚本中设置的两个文件,这里使用的匿名挂载
数据卷容器
主要的作用是实现容器中的数据同步。
1 | docker run -it --name 名称 --volumes-from 父容器名称 镜像 |
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止,但是一旦你持久化到本地,这个时候,本地的数据是不会删除的。
DockerFile
dockerfile是用来构建docker奖项的文件,就是命令脚本
构建步骤:
1、编写一个dockerfile文件
2、docker build 构建成为一个镜像
3、docker run 运行进行镜像
4、docker push 发布镜像
DockerFile构建过程
基础知识:
1、每个保留关键字(指令)都必须是大写字母
2、执行从上到下
3、#表示注释
4、每一个执行都会创建提交一个新的镜像层,并提交
DockerFile的质量
1 | FROM # 基础镜像,一切从这里开始构建 |
实战测试
我们尝试创建一个centos镜像
1 | 编写DockerFile文件 |
通过命令构建这个镜像
1 | docker build -f mydockerfile -t mycentos:1.0 . |
实战:Tomcat镜像
1、首先准备压缩包
2、编写DockerFile文件,官方命名Dockerfile
,build会自动寻找这个文件,无需-f指定
1 | FROM centos |
3、构建这个镜像
1 | docker build -t diytomcat . |
4、运行镜像
1 | docker run -d -p 9090:8080 --name bestrookietomcat2 -v /home/bestrookie/rookie/tomcatfile:/usr/local/apache-tomcat-9.0.54/webapps/test -v /home/bestrookie/rookie/logs/:/usr/local/apache-tomcat-9.0.54/logs diytomcat |
发布自己的镜像
DockerHub
1、官方仓库注册自己的账号
2、在我们服务器上提交自己的镜像
3、登录账号
1 | docker login -u |
4、上传镜像
1 | docker push |
阿里云镜像服务上
1、登录阿里云
2、找到容器镜像服务
3、创建命名空间
4、创建仓库:记得选本地仓库
5、参考官方地址
Docker网络
理解Docker0
首先我们将我们的Dcoker环境清理干净,删除掉所有的镜像和容器,然后查看我们的网络的ip
ip addr
我们发现存在docker0:这样一个地址,这就是为我们分配的docker网络,同样
原理
1、我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个docker0桥接模式,使用的技术是evth-pair技术。
我们再次查看ip 发现图上这个ip
我们发现这个容器带的网卡,都是一对对的,evth-pair就是一对的虚拟设备端口,他们都是成对出现的,一段连着协议,一段彼此相连,正式有这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备。
–link
正常情况下两个容器可以通过ip来进行网络的联通,但是不可以使用容器的名字进行网络联通,而--link
则解决了这个问题
1 | 例如 |
这样我们的tomcat03可以直接ping tomcat02
,但是不能反向的ping tomcat02 ping 不通tomcat03,这时因为–link其实就是改了tomcat03host
文件,而tomcat02的文件并没有修改,所以无法起作用。
自定义网络
网络模式
桥接模式:就是搭桥访问
none:不配置网络
host:和宿主机共享网络
创建自己的网络
1 | docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet |
使用自己创建的网络
1 | docker run -d -P --name tomcat01 --net mynet tomcat |
只要使用我们自定义网络的容器,我们不需要--link
去连接网络,因为我们自定义的网络docker都已经帮我们维护好对应的关系了。
网络联通
docker network connect 网络名 容器名
连通之后就是将tomcat01 放到了我们定义的网络下,也就是一个容器两个ip
SpringBoot项目打包Dcoker
1、首先创建一个简单的SpringBoot项目。
2、打包应用
3、编写Dockerfile
1 | FROM java:8 |
4、构建镜像
1 | docker build -t springdocke . |
5、发布运行
1 | docker run -d -P --name spring springdocker |