- 容器三大特征(要素):
- docker安装
- Centos6.8安装docker
- Centos7安装docker
- 镜像加速
- Docker底层原理
- Docker 命令(部分)
- Docker容器数据卷(做数据持久化)
- 能干嘛
- 数据卷
- 数据卷容器
- DockerFile解析
- DockerFile体系结构(保留关键字)
- 案例
- 小总结
容器三大特征(要素):
镜像(image)
容器(container)
仓库(repository)
仓库(Repository)是集中存放镜像的场所。 仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放多个仓库,每个仓库中又包含了多个镜像,每个镜像有不通的标签(tag)。、 仓库分为公开仓库(public)和私有仓库(private)两种形式。 最大的公开仓库是Docker Hub(https://hub.docker.com),存放了数量庞大的镜像提供用户下载。 国内的公开仓库包括阿里云,网易云等。
三要素小结
docker安装
支持Centos版本
Centos6.5(64-bit)版本及以上。 Centos7内核版本要求3.10以上. Centos6.5或更高的系统,内核版本要求2.6.32-431以上。 查看自己的内核: uname -r
docker 架构图
Centos6.8安装docker
# 1、安装epel
yum install -y epel-release
# 2、安装docker
yum install -y docker-io
# 3、安装后的配置文件
/etc/sysconfig/docker
# 4、启动docker后台服务。
service docker start
# 5、验证
docker version
Centos7安装docker
https://docs.docker.com/engine/install/centos/#prerequisites
镜像加速
# 阿里云(推荐)
https://dev.aliyun.com
Centos6配置方法
vim /etc/sysconfig/docker
将获得的自己账户下的阿里云加速地址配置进
other_args="--registry-mirror=https://自己的账号加速信息.mirror.aliyuncs.com"
保存退出,重启docker
service restart docker
验证是否成功:
ps -ef | grep docker
Centos7 ++配置方法
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://e53aervw.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
Docker run hello-world
run干了什么?
Docker底层原理
Docker是怎么工作的
Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户端访问,守护进程从客户端接收命令并管理运行在主机上的容器。容器,是一个运行时环境,就是鲸鱼背上的集装箱。
为什么Docker比较VM快
1、docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在cpu,内存利用率上docker将会在效率上有明显优势。
2、docker利用的是宿主机的内核,而不需要Guest OS.因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。从而避免引寻,加载操作系统内核这个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个过程,因此新建一个docker容器只需要几秒钟。
Docker 命令(部分)
帮助命令
# 查看docker基本信息
docker version
# 查看docker信息,比version更详细
docker info
# docker帮助命令
docker --help
镜像命令
列出本地主机上的镜像
docker images [options]
options 选项:
-a : 列出本地所有的镜像(包含中间映像层)
-q : 只显示镜像ID
--digests : 显示镜像的摘要信息
--no-trunc : 显示完整的镜像信息
各选项说明
- REPOSITORY : 表示镜像的仓库员
- TAG : 镜像的标签
- IMAGE ID : 镜像ID
- CREATED : 镜像创建时间
- SIZE : 镜像大小
同一个仓库源可以有多个TAG,代表这个仓库的不同个版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。如果不指定一个镜像的版本标签,例如只是用ubuntu,docker将默认使用Ubuntu:latest镜像。
docker search 某个镜像的名字
查询仓库中的镜像。
网址:https://hub.docker.com
docker search [options] 镜像名字
options选项:
--no-trunc : 显示完整的镜像描述
-s : 列出收藏数不小于指定值的镜像
--automated : 只列出 automated build 类型的镜像
docker pull 某个镜像名字
下载镜像
docker pull tomcat[:TAG]
# docker pull tomcat 等价于 docker pull tomcat:latest
docker rmi 某个镜像名字ID
删除某个镜像
docker rmi -f 镜像ID(或唯一镜像名) # 删除单个
docker rmi -f 镜像名1:TAG 镜像名2:TAG # 删除多个
docker rmi -f $(docker images -qa) # 删除全部
容器命令
有镜像才能创建容器,所以我们需要下载一个镜像(centos镜像) docker pull centos
docker run [options] image [command] [arg]
新建并启动容器
启动交互是容器
docker run [options] image [command] [arg]
options 选项(常用):
--name="容器新名字" : 为容器指定一个名称
-d : 后台运行容器,并返回容器id,即启动守护式容器
-i : 以交互模式运行容器,通常与 -t 参数一起使用 ( 常用 )
-t : 为容器重新分配一个伪输入终端,通常与 -i 参数一起使用( 常用 )
-P : 随机端口映射
-p : 指定端口映射,有以下四种格式
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
例:启动一个Centos容器
docker run -it --name mycentos01 831691599b88 # 以交互模式启动一个名称为mycentos01的容器,启动容器使用的镜像id为831691599b88
docker run it 831691599b88 # 不指定容器名称,直接以交互模式启动容器,并且进入伪终端。
docker ps [options]
列出当前所有正在运行的容器
docker ps [options]
options选项(常用):
-a : 列出当前所有正在运行的容器+历史上运行过的
-l : 显示最近创建的容器
-n : 显示最近 n 个创建的容器
-q : 静默模式,只显示容器编号
--no-trunc : 不截断输出
退出容器的两种方式
容器停止退出
exit
容器不停止退出
ctrl+p+q
docker start 容器ID或容器名称
docker restart 容器ID或容器名称
docker stop 容器id或者容器名称
docker kill 容器id或者名称
docker rm 容器ID
删除已停止的容器
一次性删除多个容器
docker -rm -f $(docker ps -aq)
docker ps -aq | xargs docker rm
启动守护式容器
docker run -d 容器名(个人觉得这里应该写的是镜像名称,老师笔记有点问题)
# 使用镜像 centos:latest 以后台模式启动一个容器
问题:然后使用docker ps -a
进行查看,发现容器已经退出。
很重要的一个说明:Docker容器后台运行,就必须有一个前台进程。
容器运行的命令如果不是那些一直挂起的命令(比如top,tail),就是会自动退出。
这个是docker的机制问题,比如web容器,我们以nginx为例,正常情况下,我们配置启动服务只需要启动响应的service即可。例如service nginx start。
但是,这样做NGINX为后台进程模式运行,就导致docker前台没有运行的应用,这样的容器后台启动后,会立即自杀,因为它觉得它没事可做了。
所以,最佳的解决方案是将要运行的程序以前台进程的形式运行。
查看docker日志
docker logs -f -t --tail 容器ID
-t : 加入时间戳
-f : 跟随最新的日志打印
--tail 数字 : 显示最后多少行
例:使用如下命令跑一个docker容器
docker run -d centos /bin/sh -c "while true;do echo hello lhh;sleep 2;done"
然后使用 docker ps
命令查出容器ID
通过 docker logs -f --tail 3 容器id
查看日志
查看容器内运行的进程
docker top 容器ID
查看容器内部细节
docker inspect 容器ID
进入正在运行的容器并以命令行交互
docker exec -it 容器ID bashShell
docker attach 容器ID # 重新进入
上述两个命令的区别
attach
直接进入容器启动命令的终端,不会启动新的进程
进入容器启动命令打开的终端。
exec
是在容器中打开新的终端,并且可以启动新的进程
执行完之后直接将bashShell命令的结果返回到宿主机的终端。docker exec -it 容器ID /bin/bash
打开一个新的容器终端。效果同 attach
将容器内的内容拷贝到宿主机上
docker cp 容器ID:容器内路径 目的主机路径
容器命令小结
………………
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。 rootfs(root file system)在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如 Ubuntu,Centos等等。
问题:平时我们安装进虚拟机的Centos都是好几个G,为什么docker这里才215M?
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就行了。由此可见针对不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同发行版可以公用bootfs。
分层镜像
以pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的下载。
为什么Docker镜像要采用这种分层结构呢
最大的一个好处就是—共享资源 比如:有多个镜像都是从相同的base镜像构建而来,那么宿主机只需要在磁盘上保存一份base镜像,同事内存中也只需要加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层可以被共享。
特点
Docker镜像都是只读的 当容器启动时,一个新的可写层被加载到镜像的顶部。 这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
Docker镜像commit操作补充
- docker commit 提交容器副本,使之成为一个新的镜像
- docker commit -m=”提交的描述信息” -a=”作者” 容器ID 要创建的目标镜像名:[标签名]
- 案例演示
1、从Hub上下载tomcat镜像到本地并成功运行
docker run -it -p 8888:8080 tomcat
-p 主机端口:docker容器端口
-P 随机分配端口
-i 交互
-t 终端
docker run -it -P tomcat
-P 随机端口
2、故意删除上一步镜像生产tomcat容器的文档
3、也即当前的Tomcat运行实例是一个没有文档内容的容器,以它为模板commit一个没有doc的tomcat新镜像atguigu/tomcat2
#由于版本问题,最新的tomcat中默认就没有那些文件,所以我自己在目录中创建了一个index.html
# 作者名 描述 容器id 命名空间 镜像名 版本号
docker commit -a="xuliang" -m="add index.html" 7154d4cf4d2a atxuliang/tomcat01:1.1
Docker容器数据卷(做数据持久化)
- 容器数据卷用 v 命令添加
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
是什么
有点类似于redis里面的rdb和aof
docker理念:
- 将运用于运行的环境打包成容器运行,运行可以伴随着容器,但是我们对数据的要求希望是持久化的
- 容器之间希望有可能共享数据
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据作为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。 为了能保存数据,在docker中我们使用卷。
能干嘛
1、容器的持久化
2、容器间继承+共享数据
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能绕过Union File System 提供一些用于持续存储或共享数据的特性:
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此docker不会在容器删除的时候删除其挂载的数据卷。
特点: 1、数据卷可在容器之间共享或重用数据 2、卷中的更改可以直接生效 3、数据卷中的更改不会包含在镜像的更新中 4、数据卷的生命周期一直持续到没有容器使用它为止
数据卷
在容器内添加数据卷
1、直接命令添加
1.1 命令
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
docker run -it -v /myDataVolume:/dataVolumeContainer centos
#执行命令的时候宿主机绝对路径目录和容器内的目录不必要一定存在,docker会自动帮助我们创建。
1.2 查看数据卷是否挂载成功
docker inspect 容器id
1.3容器和宿主机之间数据共享
当确认数据卷挂载成功之后即可在指定的目录中记录数据,此时无论是在容器中记录还是再宿主机上记录,他们的数据都将共享。
1.4命令(带权限)
docker run -it -v /宿主机绝对路径目录:/容器内目录:``ro `` 镜像名
如果不带权限的话,创建的数据卷读写权限为true,如下图:
权限:只读 read only 简写 ro
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
docker run -it -v /myDataVolume:/dataVolumeContainer:ro centos
如果带权限的话,容器数据卷的权限将根据设定的值来定,如:
docker run -it -v /myDataVolume:/dataVolumeContainer:ro centos
启动容器之后,数据卷的权限如下图:
2、DockerFile添加
需求
1、根目录下新建mydocker文件夹进入
2、可在Dockerfile中使用VOLUME指令给镜像添加一个或多个数据卷
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2","/dataVolumeContainer3"]
说明:使用 VOLUME 指令添加数据卷 只指定容器内的 出于可移植和分享的考虑, 用-v 主机目录:容器目录
这种方法不能够直接在Dockerfile中实现 由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。
3、File构建
# volume test
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished,------success1"
CMD /bin/bash
# 将上面的Dockerfile 翻译成docker命令大致如下
# docker run -it -v /host1:/dataVolumeContainer1 -v /host2:/dataVolumeContainer2 centos /bin/bash
4、build后生成镜像。——> 获得一个新镜像xuliang/centos
docker build -f /mydocker/Dockerfile -t xuliang/centos .
5、run运行容器
docker run -it 8fd3faa5af7c
6、通过上述步骤,容器内的卷目录地址已经知道,对应的主机目录地址在哪?
![]()
- Docker挂载主机目录Docker访问出现 cannot open directory .: Permission denied
解决办法: 在挂载目录后面多加一个
--privileged=true
参数即可。 例:docker run -it -v /myDataVolume:/dataVolumeContainer ----privileged=true 镜像名
7、主机对应默认地址
数据卷容器
是什么
命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。
总体介绍
以上一步新建的镜像 xuliang/centos 为模板并运行容器dc01,dc02,dco3 它们已经具有容器卷: /dataVolumeCentainer1 /dataVolumeCentainer1
容器间传递共享( —volumes-from)
1、先启动一个父容器 ——> 在dataVolumeContainer2新增内容
2、dc02/dc03继承自dc01
--volumes-from
命令
3、回到dc01可以看到02、03各自添加的都能共享了
4、删除dc01、dc02修改后dc03可否访问? 可以
5、删除dc02后dc03可否访问 可以
6、新建dc04继承dc03后再删除dc03 可已
7、结论:容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。
DockerFile解析
是什么
DockerFile是用来构建Docker镜像的构建文件,是有一系列命令和参数构成的脚本。
构建三步骤:
- 编写Dockerfile文件
- docker buile
- docker run
文件什么样?如下:
# volume test
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished,------success1"
CMD /bin/bash
DockerFile构建过程解析
DockerFile内容基础知识
1、每条保留字指令都必须为大写字母且后面至少要跟随一个参数
2、指令从上到下,顺序执行
3、# 表示注释
4、每条指令都会创建一个新的镜像层,并对镜像进行提交
Docker执行DockerFile的大致流程
1、docker从基础镜像运行一个容器
2、执行一条指令并对容器作出修改
3、执行类似docker commit的操作提交一个新的镜像层
4、docker再基于刚提交的镜像运行一个新容器
5、执行dockerfiel中的下一条指令,直到所有指令都执行完成。
小总结
从应用软件的角度来看,Dockerfile,Docker镜像与Docker容器分别代表软件的三个不同阶段,
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器则可以认为是软件的运行态
DockerFile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系基石。
DockerFile体系结构(保留关键字)
- FROM : 基础镜像,当前新镜像是基于哪个镜像的
- MAINTAINER : 镜像维护者的姓名和邮箱地址
- RUN : 容器构建时需要运行的命令
- EXPOSE :当前容器对外暴露出的端口
- WORKDIR :指定在创建容器后,终端默认登录进来工作目录,一个落脚点。
- ENV :用来在构建镜像过程中设置环境变量
- ADD :将宿主机目录下的文件拷贝进镜像,且ADD命令会自动处理URL和解压tar包。
- COPY :a、类似ADD,拷贝文件和目录到镜像中。b、将从构建上下文目录中<源路径>的文件/目录复制到新的一层镜像内的<目标路径>位置
- VOLUME :容器数据卷,用于数据保存和持久化工作
- CMD :a、指定一个容器启动时要运行的命令。b、DockerFile 中可以有多个CMD命令,但只有最后一个生效,CMD会被docker run之后的参数替换
- ENTRYPOINT :a、指定一个容器启动时要运行的命令。b、ENTRYPOINT和CMD一样,都是在指定容器启动程序及参数。
- ONBUILD :当构建一个被继承的DockerFile时运行命令,父镜像在被子继承后,父镜像的onbuild被触发。
案例
Base镜像
docker hub中99%的镜像都是通过在baes镜像中安装和配置需要的软件构建出来的
自定义镜像mycentos
- 编写
Hub默认Centos镜像什么情况?
准备编写dockerfile文件,大致内容如下
FROM centos
ENV mypath /tmp
WORKDIR $mypath
RUN yum -y install vim
RUN yum install -y net-tools
EXPOSE 80
CMD /bin/bash
myCentos内容Dockerfile 内容如下:
FROM centos
MAINTAINER xuliang<xuliang_in@163.com>
ENV mypath /usr/local
WORKDIR $mypath
RUN yum install -y net-tools vim
RUN yum clean all
EXPOSE 80
CMD echo $mypath
CMD echo "success-------ok"
CMD /bin/bash
- 构建 ——>
docker build -t 新镜像名字:TAG .
![]()
- 运行
docker run -it 新镜像名字:TAG
- 列出镜像的变更历史
docker history 镜像id
CMD/ENTRYPOINT镜像案例
1、都是指定一个容器启动时要运行的命令 2、CMD Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换 case —> tomcat的讲解演示 |
docker run it -p 7777:8080 tomcat ls -l
这样执行之后tomcat是没有启动的。 3、ENTRYPO docker run 之后的参数会被当做参数传递给 ENTRYPOINT ,之后形成新的命令组合。 case : a、制作CMD版可以查询IP信息的容器
FROM centos
RUN yum install -y curl
CMD [ "curl","-s","http://ip.cn" ]
b、问题 c、WHY d、制作ENTROYPOINT版查询IP信息的容器
自定义镜像tomcat9
1、mkdir -p /zzyyuse/mydockerfile/tomcat9
2、在上述目录下touch c.txt
3、将jdk和tomcat安装的压缩包拷贝进上一步目录apache-tomcat-9.0.37.tar.gz jdk-14.0.2_linux-x64_bin.tar.gz
4、在/zzyyuse/mydockerfile/tomcat9目录下新建Dockerfile文件
5、构建
6、run
7、验证
8、结合前述的容器卷将测试的web服务test发布。