简介
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows 机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。
为什么需要Docker?
环境配置如此麻烦,换-一台机器,就要重来一次,费力费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。开发人员利用Docker可以消除协作编码时 “ 在我的机器上可正常工作 ” 的问题。
一次封装,处处运行
安装
Docker支持以下的CentOS版本
- CentOS 7(64-bit)
- CentOS 6.5 (64-bit) 或更高版本
前提条件
目前,CentOS 仅发行版本中的内核支持 Docker。
Docker运行在CentOS7上,要求系统为64位、系统内核版木为 3.10 以上。
Docker运行在Cent0S-6.5或更高的版本的CentOS.上,要求系统为64位、系统内核版本为2.6.32-431或者更高版本。
查看自己的内核
1 | uname -r |
1 | cat /etc/redhat-release |
Docker的基本组成
Docker架构图
镜像(image)
Docker镜像(Image)就是一个只读的模板。镜像可以用来创建Docker容器,一个镜像可以创建很多容器。
容器(container)
Docker利用容器(Container) 独立运行的一个或一组应用。容器是用镜像创建的运行实例。
它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
可以把容器看做是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等) 和运行在其中的应用程序。
容器的定义和镜像几乎一模-样,也是一堆层的统一视角, 唯一区别在于容器的最上面那一层是可读可写的。
仓库(repository)
仓库(Repository) 是集中存放镜像文件的场所。
仓库(Repository)和仓库注册服务器(Registry) 是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库(Public) 和私有仓库(Private) 两种形式。
最大的公开仓库是Docker Hub https://hub.docker.com/
存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云、网易云等
CentOS安装
安装软件包
1 | yum install -y yum-utils \ |
设置存储库
1 | yum-config-manager \ |
安装 Docker Engine
1 | yum install docker-ce docker-ce-cli containerd.io |
启动Docker
1 | systemctl start docker |
没报错就完事了
使用阿里云镜像加速
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
输入命令
1 | sudo mkdir -p /etc/docker |
没报错就完事了
测试运行Hello-world
启动Docker
1 | systemctl start docker |
运行hello-world
1 | docker run hello-world |
run 作用
Docker底层原理
Docker是怎么工作的?
Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接 从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。容器,是一个运行时环境,就是我们前面说到的集装箱
为什么Docker比虚拟机快?
- docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化, 运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
- docker利用的是宿主机的内核,而不需要Guest OS,因此当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虑拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个过程,因此新建一个docker容器只需要几秒钟。
Docker常用命令
帮助命令
验证docker信息
docker version
docker安装后描述docker信息
docker info
帮助
docker –help
镜像命令
列出本地的镜像
docker images
组合: 例如 docker images -a
- -a 列出本地所有的镜像(含中间映像层)
- -q 只显示镜像ID
- -qa 显示所有镜像ID
- –digests 显示镜像的摘要信息
- –no-trunc 显示完整的镜像信息
从Docker Hub 上查询某个 xxx 镜像
docker search
组合命令
- -s number 用于筛选 stars 例如 docker search -s 30 tomcat ,查找 stars 数超过 30 的tomcat
- –no-trunc 显示完整的镜像信息
- –automated 只列出 automated build类型的镜像
下载镜像
docker pull xxx名字
组合命令
- docker pull xxx:版本号 如果不写就是最新版 latest
删除镜像
docker rmi xxx
xxx 可以是 ID 或者 唯一镜像名
组合命令
- docker rmi xxx:版本号 不写就是删除最新版 latest
- docker rmi -f xxx 强制删除
- docker rmi -f xxx1 xxx2… 一次删除多个,也可以写版本号 xxx1:latest
- docker rmi -f $(docker images -qa) 批量删除,删除所有镜像 $()为表达式
容器命令
有镜像才能创建容器,这是根本前提
在docker上pull一个centos 进行演示
新建并启动容器
docker run
docker run [OPTIONS] IMAGE [COMMAND] [ARG….]
OPTIONS说明
- –name=”容器新名字” 命名
- -d 后台运行容器,并返回容器ID,也即启动守护式进程
- -i 以交互模式运行容器,通常与 -t 同时使用
- -t 为容器重新分配一个伪输入终端,通常与 -i 同时使用
- -P 随机端口映射
- -p 指定端口映射,有以下四种格式
- ip:hostPort:containerPort
- ip::containerPort
- hostPort:containerPort
- containerPort
pull好 centos 之后 使用命令 启动
1 | docker run -it centos 可以是镜像ID |
启动后
可以看到 @后面的字符串变了,这就相当于 你运行了一个centos容器,并打开了docker下centos的终端
通过上图可以看到docker 下的centos 目录和 虚拟机下centos目录是一样的
列出Docker运行的容器
docker ps
docker ps [OPTIONS] 不填options 的话默认显示正在运行的容器
OPTIONS说明(常用)
- -a 列出当前所有正在运行的容器 + 历史上运行过的
- -l 显示最近创建的容器
- -n 显示最近 n 个创建的容器 如 docker ps -n 3
- -q 静默模式,只显示容器编号
- –no-trunc 显示完整信息
- CONTAINER ID 对应终端ID
- IMAGE 对应 镜像ID
- COMMAND 以什么方式登录
- CREATED 什么时候创建
- STATUS 状态
- PORTS 端口
- NAMES 容器名字
退出容器
exit
使用exit后容器也会随之关闭
ctrl+P+Q
容器不停止退出
启动容器
docker start
docker start 容器ID或者容器名
获得已创建容器ID
重启
停止容器
docker stop
docker stop 容器ID或者容器名
强制停止容器
docker kill
docker kill 容器ID或者容器名
删除已停止的容器
docker rm
docker rm 容器ID
docker rmi 删除镜像, docker rm 删除容器
一次性删除多个容器
docker rm -f $(docker ps -a -q) 删除所有容器
docker ps -a -q | xargs docker rm
| 为Linux管道符命令,xargs 可变参数
意思是:docker ps -a -q 放回的值作为参数被xargs 接收 然后执行删除
进阶命令
启动守护式容器
docker run -d
docker run -d 容器名或者ID
查看容器日志
docker logs -f -t –tail
docker logs -f -t –tail 容器ID
- -t 是加入时间
- -f 跟随最新的日志打印
- –tail 数字 显示最后多少条
使用命令循环打印日志,可以让守护式容器防止被杀
1 | docker run -d centos /bin/sh -c "while true;do echo hello centos;sleep 2;done" |
查看容器内运行的进程
docker top 容器ID
查看容器内部细节
docker inspect
docker inspect 容器ID
进入正在运行的容器,并已命令行交互
docker exec -it
docker exec -it 容器ID
docker attach
重新进入docker attach 容器ID
上述两个区别
- attach 直接进入容器启动命令的终端,不会启动新的进程 在容器外对容器进行操作
- exec 是在容器中打开新的终端,并且可以启动新的进程 进入容器后才能操作容器
从容器内拷贝文件到主机上
docker cp
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等标准目录和文件。roofs就是各种不同的操作系统发行版,比如Ubuntu, Centos 等等。
分层的镜像
为什么Docker 镜像要采用这种分层结构呢
最大的一个好处就是共享资源
比如: 有多个镜像都从相同的base镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时内存中也只需加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
特点
Docker镜像都是只读的
当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层通常被称作 “容器层”, “容器层”之下的都叫”镜像层
Docker 镜像commit 操作补充
docker commit 提交容器副本使之成为一个新的镜像
docker commit -m=”提交的描述信息” -a=”作者” 容器ID 要创建的目标镜像名:[标签名]
案例演示
从Hub上下载tomcat镜像到本地并成功运行
1
docker run -it -p 8080:8080 tomcat
-p 主机端口 :docker 容器端口
-P 大写P 随机分配端口
i 交互
t 终端
浏览器输入 localhost:8080直接访问
你可以进入 tomcat 随便改
1
docker exec -it 容器ID /bin/bash
改完后退出来
1
ctrl + p + q
提交你改完的新 tomcat
1
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
然后查看镜像
完成,这就是你提交的新的镜像
Docker 容器数据卷
是什么?
能干吗?
容器持久化
容器间继承 + 数据共享
数据卷
容器内添加
直接命令添加
命令
1 | docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名 |
查看数据卷是否挂载成功
1 | docker inspect 容器ID |
容器和宿主机之间的数据共享
这个时候已经实现了容器与宿主机的数据共享
容器停止后,主机修改后数据是否同步
命令(带权限)
1 | docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名 |
创建好文件共享后,容器内只能读,不能写,宿主机拥有所有权限
DockerFile 添加
直接命令添加
DockerFile添加
根目录下新建mydocker文件夹并进入
备注
数据卷容器
是什么
命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器
容器间传递共享(–volumes-from)
1 | docker run -it --name xxx --volumes-from xxx 容器名或ID |
根据一个使用DockerFile添加数据卷的镜像分别创建三个不同的容器,使用上述命令连接
例如
1 | docker run -it --name aaa --volumes-from bbb 容器名或ID |
连接成功之后,数据卷的内容互通
DockerFile解析
是什么
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
DockerFile构建过程解析
DockerFile内容基础知识
- 每条保留字指令都必须为大写字母,而且后面要跟随至少一个参数
- 指令按照从上到下顺序执行
- #表示注解
- 每条指令都会创建一个新的镜像层,并对镜像进行提交
Docker执行DockerFile的大致流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新容器
- 执行dockerfile中的下一条指令直到所有指令都执行完成
小总结
DockerFile体系结构
保留字指令
FROM
基础镜像,当前镜像是基于那个镜像
MAINTAINER
镜像维护者的姓名和邮箱地址
RUN
容器构建时需要运行的命令
EXPOSE
当前容器对外暴露出的端口号
WORKDIR
指定在创建容器后,终端默认登录的进来的工作目录,一个落脚点
ENV
用来在构建镜像的过程中设置环境变量
ADD
将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
COPY
类似ADD,拷贝文件和目录到镜像中。
将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
COPY src dest
COPY [“src”,”dest”]
VOLUME
容器数据卷,用于数据保存和持久化工作
CMD
指定一个容器启动时要运行的命令
DockerFile中可以有多个CMD 指令,但只有最后一个生效,CMD会被docker run之后的参数替换
ENTRYPOINT
指定一个容器启动时要运行的命令
ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数,但是它指定的命令不会被最后一个替换,而是追加
ONBUILD
当构建一个被继承的DockerFile时运行命令,父镜像在被子类继承后父类镜像的onbuild被触发
小总结
案例
Base镜像(scratch)
DockerHub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的
自定义镜像mycentos
编写
Hub默认CentOS镜像什么情况
准备编写DockerFile 文件
- ![](Docker/准备编写DockerFile 文件.png)
myCentOS内容 DockerFile
1
2
3
4
5
6
7
8
9
10
11
12
13
14FROM centos
MAINTAINER duxiu<1839743406@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "success-----------------ok"
CMD /bin/bash
构建
1
docker build -f /DockerFile文件路径 -t 新镜像名字:TAG .
运行
列出镜像的变更历史
1
docker history 镜像ID
CMD/ENTRYPOING 镜像案例
制作CMD版可以查询IP信息的容器
在根目录下的mydocker目录下创建DockerFile3
1 | FROM centos |
crul命令解释
使用CMD 执行除 curl以外的命令会报错,如
docker run myip -i
而使用ENTRYPOING 就可以执行
Docker常用安装
安装MySQL8.0.19
1 | docker run -p 12345:3306 mysql -v /duxiu/mysql/conf:/etc/mysql/conf.d -v /duxiu/mysql/logs:/logs -v /duxiu/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=1234 -d mysql:8.0.19 |
进入容器
1 | docker exec -it bd39192d9fa8 /bin/bash |
执行登录命令
1 | mysql -uroot -p密码 |
完事
安装Redis
复制redis.conf到/opt/data/redis目录下
执行下面的命令
1 | docker run -p 6379:6379 --name myredis -v /opt/data/redis/redis.conf:/etc/redis/redis.conf -v /opt/data/redis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes |
将本地镜像推送到阿里云
创建容器仓库
https://cr.console.aliyun.com/repository/cn-hangzhou/huohuo/myimages/images
创建本地仓库
1 | sudo docker login --username=惑惑惑惑惑惑惑惑惑惑 registry.cn-hangzhou.aliyuncs.com |