docker学习
docker学习
1.虚拟机技术
虚拟机技术是虚拟化技术的一种,虚拟机它可以在一种操作系统里面运行另一种操作系统,比如在Windows 系统里面运行Linux 系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。也就是说虚拟机是以软件的方式模拟硬件设备。这类虚拟机完美的运行了另一套系统,能够使应用程序,操作系统和硬件三者之间的逻辑不变。
2.docker虚拟技术
传统虚拟机是虚拟出一整套的操作系统,体积相对较大。导致资源占用多,启动慢。虚拟机Linux 容器技术的出现就解决了这样一个问题,而 Docker 就是在它的基础上发展过来的。将应用运行在 Docker 容器上面,而 Docker 容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。docker没有硬件虚拟化层,并且于主机共享OS资源,可以说docker是轻量化的Linux虚拟机。
docker的基本组件
三大组件:镜像,容器,仓库。(docker引擎)
镜像
Docker 镜像就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。可以类比成Java的类,Java的类模板能创建出很多的实例。可以把镜像看成轻量级的虚拟机镜像文件再包装几层镜像文件的.iso文件。
容器
就如上面说的,容器时通过镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。容器和镜像的唯一区别在于容器的最上面那一层是可读可写的。也就是说,容器实质是镜像动态运行的实例。
仓库
仓库(Repository)是集中存放镜像文件的场所。我们可以通过仓库来拉取镜像来创建我们的运行模板,然后通过模板来创建运行实例。仓库分为公开仓库(Public)和私有仓库(Private)两种形式。并且有分仓库(Repository)和仓库注册服务器(Registry)。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。其实跟GitHub仓库是一个概念。果然你使用过git,那么理解这个仓库就不难了。
最大公开仓库是 Docker Hub(https://hub.docker.com/),当然也有一些商家提供庞大的镜像供用户下载,如阿里云,网易云。
UnionFS联合文件系统
Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。
Docker镜像加载原理:
dockers镜像实质是由一层一层的文件系统组成,每个镜像一层,一层一层的往外包,而我们看到的是暴露在最外面的镜像。我们可以重dockers仓库拉取一个Linux虚拟机镜像,看看其镜像的大小。可以发现我们拉取的虚拟机镜像只有几百M,而我们平时在本地安装虚拟机的时候会发现,虚拟机的.iso镜像文件通常都是几GB,为什么这里的镜像文件会这么小呢。现在必须说一下什么是bootfs(boot file system)和rootfs (root file system) 。
bootfs
主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含bootloader(加载器)和kernel(内核)。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system)
在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
我们前面说过docker没有硬件虚拟化层,并且于主机共享OS资源,不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。所以我们只需要提供 rootfs 就行了。所以拉取的Linux系统镜像会这么小。
镜像图(静,不可写)
容器图(多了最外的可写的容器层)
容器层让镜像变得可以修改(动)可运行。
安装docker
之前安装过Ubuntu系统下的docker,如果需要可以看我的博客https://blog.csdn.net/qq_43203949/article/details/104522367。
这里我使用的是CentOS系统,所有下面的安装教程将基于CentOS7系统下
首先查看CentOS的系统版本,docker支持6.8以上的CentOS系统。
cat /etc/redhat-release //查看etc文件加下的文件,文件里面记录了版本号
开始安装docker
#1.首先跟新一下yum
yum update
#2.然后安装需要的软件包
yum install -y yum-utils device-mapper-persistent-data lvm2
#3.添加yum源(这里给找到的阿里云的源)
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#备注:如果你已经用其他的源安装,而且特别慢,建议用Ctrl+C中断安装,换个源再装。要不特别地慢。
#4.可以查看所有仓库中所有docker版本(为了找到自己合适的版本)
yum list docker-ce --showduplicates | sort -r
#5.安装docker社区版
yum install docker-ce //直接安装默认的(好像是最新的)
yum install 指定版本号 //安装自己指定的版本
#6.启动docker
systemctl start docker
#7.设计开机启动
systemctl enable docker
#8.查看版本号
docker version //会显示两个版本号,一个是客户端Client,一个是服务端Server
docker 配置加速源
这里我有自己阿里云的加速源。
#这里是再阿里云开发者社区找到的
针对Docker客户端版本大于 1.10.0 的用户
您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["自己的加速源地址"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker hello world
新学东西先来hello world。
#在命令行中输入
docker run hello-world
#运行容器hello-world
会得到下面返回的结果
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
...
...
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
...
#结果分析:从开头的两句话中我们可以知道,docker运行容器时会先查找本地是否有符合的容器,如果没有,那将去docker Hub上查找进行,并将镜像拉取回来并生成容器,并运行。
docker是一个CS结构的系统,也就客户端——服务端结构。
docker基本命令
#查看本地镜像
docker images -a
#展示的信息有 PEPOSITORY:镜像仓库源 TAG:标签(版本) ID:镜像ID #CREATED:创建时间 SIZE:大小
#去官网查找仓库(返回仓库列表)
docker search 仓库名
#拉取仓库镜像
docker pull tomcat //默认拉取最新版本
docker pull tomcat:版本号
#删除镜像
docker rmi tomcat //默认删除最新
docker rmi tomcat:版本号
docker rmi -f tomcat //强制删除
#---------------------------这里开始操作容器--------------------
#新建并运行容器
docker run 镜像名或者镜像ID
docker run -it centos //通过centos镜像创建容器,并运行
#-it是以交互式方式启动,此时将进入到容器里面,使用exit退出,Ctrl+q+p键up状态
#-i 交互 -t终端
#-d 守护进程方式启动
#-p 主机端口:dockers端口 端口映射
#-v 主机绝对路径:容器内绝对路径:ro 宿主机(本地主机)与容器挂载共享文件(容器数据卷)
#ro容器只读(选)
#查看在运行的容器
docker ps //展示正在运行的容器
dockers ps -a //所有容器,包括曾经运行的容器
#启动容器或重启
docker start 容器名或者容器ID //将exit状态的容器启动
dockers restart 容器名或者容器ID //重启容器
#停止容器或者杀死容器
docker stop 容器名或者容器ID
docker kill 容器名或者容器ID
#删除已经停止的容器
docker rm 容器号 //-f为强删
#查看容器日志
docker logs -t -f 容器ID
#查看容器内进程
docker top 容器ID
#查看容器内部细节
docker inspect 容器ID
#重新进入到up状态的容器
docker attach 容器ID
#不进入容器中,在容器中运行命令
docker exec -it 容器ID 运行命令
#拷贝容器里的东西到本地
docker cp 本地地址 容器ID:容器内地址
#提交容器把容器提交成为一个镜像
docker commit -m="描述信息" -a="作者" 容器ID 镜像名:标签
#-m="描述信息" -a="作者"
#以DockerFile文件描述创建镜像
docker build -f DockerFile文件路径 -t 自定义镜像名
#会以DockerFile中的指令一层一层地镜像叠加(unionFS),也就是对文件系统的修改作为镜像叠加
#回顾前面所讲
/*
联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层
的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。
*/
#关联父容器的共享文件的方式创建所有关联容器间的共享文件(容器数据卷)
docker run -it --name 子容器名 --volumes-from 父容器名 镜像名
//这里有点饶,我分步解释。
//-it 交互终端
//--name 命名容器名
//--volumes-from 关联父容器的共享文件
//run 以某镜像为模板启动容器
//docker run -it --name mycentos2 --volumes-from mycentos centos
/*
解释:以centos镜像为模板并关联上名为mycentos上的容器数据卷(跟宿主机共享文件夹差不多),最后把启动容器命名为mytomecat2。
注:容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用为止(共享文件夹的容器全部死光了)
*/
网上的经典docker命令图
编写dockerfile
什么是dockerfile?
dockerfile是用来构建docker镜像的构造文件,用一系列命令和参数构成的脚本。通过dockerfile,我们可以构建出自己的镜像文件。
构建三步:编写dockerfile文件,docker build命令生成镜像,docker run创建并运行容器
dockerfile可以说是描述这个docker镜像是怎么层层叠加。前面我们也说过:Union 文件系统是 Docker 镜像的基础,dockers镜像实质是由一层一层的文件系统组成,每个镜像一层,一层一层的往外包,而我们看到的是暴露在最外面的镜像。
基础指令
#在讲Dockerfile指令前先重复一下docker build命令
docker build -f /mydocker/Dockerfile -t mydockerimage:1.5 .
docker build -t mydockerimage:1.5 .
#docker build 以Dockerfile创建镜像
#-f 指定Dockerfile文件路径
#-t 终端显示
#(.)在当前路径下
#最后镜像名
#---------------------------dockerfile指令---------------
#基础镜像,以镜像centos的基础上构建镜像
FROM centos(镜像名)
#标注作者相关的信息,告知镜像来源(选)
MAINTAINER 作者信息
#镜像构建过程中需要运行的命令,这里装个vim编辑器
RUN yum -y install vim
#对生成容器时对外开放端口(8080端口)
EXPOSE 8080
#定义工作目录(进入容器时的起始位置)
WORKDIR /home
#配置环境变量
ENV JAVA_HOME /home/user/java
#将宿主机文件拷贝到镜像中并解压
ADD jkd压缩包
#将宿主机文件拷贝到镜像中
COPY 宿主机文件地址 容器地址
COPY["宿主机文件地址","容器地址"] #传参方式
#构建容器数据卷
VOLUME 数据卷路径
#容器启动时运行命令,不可追加式,会被最后的CMD命令覆盖
CMD ls -l
#容器启动时运行命令,可追加式
ENTRYPOINT ls
#启动容器时可以:docker run -t myimage -l 同:docker run -t myimage(上面)
#-l 追加的参数
#父镜像在被子继承时后会触发父镜像ONBUILD的命令(继承父镜像时会运行ONBUILD后面的命令)
ONBUILD RUN echo "father is building..."
编写属于自己的tomcat镜像
学习了dockerfile文件的编写,我们可以尝试编写一个自己的dockerfile文件来创建属于自己的Tomcat进行。