安装
卸载旧版本
$ sudo apt-get remove docker docker-engine docker.io containerd runc
更新 apt 包索引
$ sudo apt-get update
安装 apt 依赖包,用于通过HTTPS来获取仓库
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
添加 Docker 的官方 GPG 密钥
$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
详见菜鸟教程
什么是docker
为了解决环境和配置对代码运行的影响,docker应运而生,docker将代码/数据/配置/操作系统一层一层封装到一个容器中,运维只需要拉取镜像就可以在和开发同样的环境下运行代码。
优点:
1. 上手快
2. 开发与运维的逻辑分类更清楚
3. 快速高效
4. 面向服务的架构(微服务)
docker与虚拟机的不同
虚拟机: 服务器 本机操作系统 虚拟层硬件(可以虚拟出各种硬件) 虚拟机(虚拟机里包括虚拟操作系统、二进制库、软件)
可以虚拟出不同与本机的操作系统
每个虚拟机之间相互独立,比较占用内存,因而虚拟的环境受到限制,启动速度慢。
虚拟机面向硬件运维者。
docker:服务器 本机操作系统 docker引擎 容器 (容器里包括 二进制库、软件)
docker不虚拟出硬件和操作系统,而是直接利用宿主机的操作系统;
容器里的操作系统依赖于本机操作系统 (本机操作系统必须与容器的操作系统一致)
通过docker 引擎划分不同的Name space来实现不同容器环境的隔离,占用体积小,启动速度快
docker面向软件开发者。
docker如何实现不同容器环境的隔离?
Docker的Namespace和Cgroup是实现容器隔离和资源限制的关键技术。
Docker主要就是借助 Linux 内核技术Namespace来做到隔离的,文件的隔离,资源的隔离都是在新的命名空间下通过挂载mount的方式来隔离的。
Cgroup,是另一个关键的技术,它负责对一组进程所使用的资源进行限制和优先级分配。通过Cgroup,可以有效控制容器内进程的资源使用情况,如CPU、内存等。
Cgroup通过关联多个cgroup子系统来限制容器资源。
通过clone函数在容器中克隆出一个进程:
- 让执行的程序内部重新编号
PID
,也就是从1
号进程开始 - 克隆新的挂载环境出来,通过在子进程内部重新挂载
proc
文件夹,可以屏蔽父进程的进程信息,这样容器内就只有容器的进程了。
bootfs用于处理内核,rootfs主要是一些基本的命令、工具、程序库等。
docker使用宿主机的bootfs层,镜像内的操作系统只需要提供rootfs。
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个或多个完整操作系统,在该系统上再运行所需应用进程 。
而Docker内的应用进程利用docker引擎直接运行于宿主的内核,容器内没有自己的操作系统内核,没有进行硬件虚拟。
因此容器要比传统虚拟机更为轻便 ,更高效的利用系统资源。
overlay网络和underlay网络
underlay:容器通过宿主机的物理网络进行通信(给容器分配同一网段来直接通信)
overlay:容器通过组件(Flannel)对数据包封装header来进行通信(封装容器的宿主机IP以及目标容器的宿主机IP,到达目标主机后解包)
docker组件
docker服务端: 管理docker 容器
docker客户端:用来连接docker守护进程(docker服务端)
docker服务端与docker客户端可以在一台机器上,也可以在不同的机器上(远程连接)。
Docker 采用了 C/S 架构,分为 Docker 客户端(Docker 可执行程序)与 Docker 守护进程,Docker 客户端通过命令行和 API 的形式与 Docker 守护进程进行通信,Docker 守护进程则提供 Docker 服务。因此,我们操作的各种 docker 命令实际上都是由 docker 客户端发送到 docker 守护进程上去执行。
我们在构建一个镜像时,不可避免的需要将一些本地文件拷贝到镜像中,用户在构建镜像时,需要指定构建镜像的上下文路径, docker build 在获得这个路径之后,会将路径下的所有内容打包,然后上传给 Docker 引擎。
docker demon启动
docker启动
service docker start
重启docker服务
service docker restart
关闭docker
service docker stop
查看镜像加速器是否配置成功
ps -ef|grep docker
docker文件系统
unionFS(联合文件系统):是把其他文件系统联合到一个联合挂载点的文件系统服务。最主要的功能是将多个不同位置的目录联合挂载(union mount)到同一个目录下。
overlayFS: 文件系统驱动,unionFS的一种实现,docker主流的存储引擎;通过将底层文件系统中不同的目录进行“合并”,遇到相同目录/文件时上层会覆盖下层。
镜像与容器
镜像是构建docker的基石,用户基于镜像来运行自己的容器。镜像也是docker生命周期中的“构建”部分。镜像是基于联合文件系统的一种层式结构,由一系列指令一步一步构建出来。(镜像是运行容器的集合,既是一种逻辑结构,通过镜像来构建容器,镜像的n层都是只读的,在最上层为容器,是可读可写的)
拉取镜像时,也是一层一层地拉取,每一层镜像都可以共享(拉取镜像时如果某一层之前的镜像拉取过就不需要再拉取,通过cow写时复制实现)
容器在启动或者创建时,必须指定一个镜像的名称或者 id ,其实,这时镜像所扮演的角色就是容器的模版,不同的镜像可以构造出不同的容器,同一个镜像,我们也可以通过配置不同参数来构造出不通的容器。
仓库
类似于github,装载有一些镜像
dockerfile
Dockerfile 就是一个普通的文本文件,其内包含了一条条的指令,每一条指令都会构建一层。
docker中需要注意的点
docker镜像是一层一层的构建,从内核开始一层一层构建外层软件需要的环境;
拉取镜像时,也是一层一层地拉取,每一层镜像都可以共享(拉取镜像时如果某一层之前的镜像拉取过就不需要再拉取)
容器运行在镜像上,镜像相当于一个模板,可以有多个容器同时运行在一个镜像上。
镜像是只读的,在镜像上运行的容器(最外层镜像)是读写的。
可以通过commit发布容器的副本,发布一个新镜像(这样就可以不断地完善迭代镜像)。
镜像命令
查看镜像:docker images
搜索镜像: docker search + 关键字
拉取镜像: docker pull + 镜像名称
删除镜像:(删除镜像时,若有容器正在运行,则无法删除)
按照镜像id删除:docker rmi 镜像id
删除所有镜像: docker rmi `docker i mages -q` (` 为Esc下键位)
- 容器命令(容器通过镜像来运行,一个镜像可以创建多个容器)
查看当前运行的容器: docker ps
查看所有的容器:docker ps -a
创建与启动容器:
创建容器:docker run
- -i 以交互模式运行容器,通常与 -t 同时使用;
- -t 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
- --name 为创建的容器命名
- -v 表示目录映射关系
- -d 会创建一个守护式容器在后台运行(日志不打印在命令行)
- - p 表示端口映射,前者是宿主机端口(docker对外暴露的端口),后者是容器内的映射端口(docker内镜像应用的端口,比如mysql3306)。可以使用多个-p做多个端口映射。
- -P 随机分配端口
-it交互式创建容器:docker run -it --name=容器名称 镜像名称:标签
-d守护方式创建容器: docker run -di --name=容器名称 镜像名称:标签
- 守护式退出容器后,容器状态仍为运行
/bin/bash(bash命令为打开命令行):
表示载入容器后运行bash(命令语言解释程序),因为docker中必须要保持一个进程(运行的程序)的运行,要不然整个容器就会退出。
所以说,bash就担任起了docker中运行的那个进程的角色!而/bin/bash则是bash在linux下的位置
进入容器:docker exec -it 容器名称 /bin/bash “隔空取物式”
退出当前容器:
停止与启动容器
停止:docker stop 容器id或容器名称
启动: docker start 容器id或容器名称
容器提交
docker commit -a 作者 -m “容器描述” 容器id 镜像名称:标签
文件拷贝(dir命令:查看目录下有什么文件)
拷进容器 : docker cp 需要拷贝的文件或目录 容器名称:容器目录
eg:docker cp 文件名 容器名称:/usr/local
从容器拷出去: docker cp 容器名称:容器目录 需要拷贝的文件或目录
目录挂载
在创建容器的时候,将宿主机的目录与容器内的目录进行映射,这样我们就可以通过修改宿主机某个目录的文件去影响容器。
创建容器添加-v参数 后边为 宿主机目录:容器目录
eg:docker run -di -v /usr/local:/usr/local --name=mycentos3 centos:7
如果出现权限不足的问题,可以添加参数 --privileged=true 来解决
查看容器的ip地址
docker inspect 容器名称(容器id)
docker inspect --format= '{{.NetworkSettings.IPAddress}}' 容器名称(只查看IP地址)
容器的删除
docker rm 容器名称(删除时要先停止容器)
容器数据卷
前提:运行在内存中的数据在机器断电后,就会消失,为了使这些数据保存下来,有了容器数据卷的概念。
作用:1. 容器数据的持久化:保存容器中产生的数据 2. 容器间继承+共享数据
在容器内添加数据卷:
1. 直接命令添加
docker run -it -v /宿主机绝对路径目录 : /容器内目录 镜像名
将两个文件夹映射(挂载),容器和宿主机共享这个文件夹内的数据,即使容器退出,数据也会共享。
docker run -it -v /宿主机绝对路径目录 : /容器内目录:ro 镜像名 以只读的方式映射(容器只可以读,不可以写;主机可读写)
2.dockerfile添加
VOLUME这一行表示在容器内创建了两个挂载目录
与这两个目录对应的主机目录可以用docker inspect查看
数据卷容器
命名的容器挂载数据卷,其他容器挂载到这个容器(父容器)上,以达到数据共享,挂载数据卷的容器叫做数据卷容器。
dc02继承dc01(实际是使用一块共享内存,父容器被删除后,子容器们仍旧可以共享这个内存)
子容器与父容器共享数据
容器之间配置信息的传递,数据卷的生命周期一直持续到没有没有容器使用它为止,只要有一个容器,整个数据卷都可以全量备份。
使用场景:
当主机更改html文件后,容器内启动的web页面也会更改(实现实时修改)。
dockerfile
dockerfile 是用来构建docker镜像的构建文件,是由一系列命令和参数构成的脚本。
构建三步骤:
1. 编写dockerfile文件
2. docker build执行
3. docker run 执行
dockerfile的大致流程:
总结
dockerfile保留字指令
ENTRYPOINT和CMD都是指定一个容器启动时要运行的命令
CMD: docker run之后的参数会覆盖CMD里的命令。(相当于追加一条CMD命令,而在docker run时,只有最后一条CMD命令会被执行。)
ENTRYPOINT不会被docker run 之后的参数替换,而是追加:docker run 之后的参数会被当做参数传递给ENTRYPOINT,之后形成新的命令组合。
CMD设定的命令会在ENTRYPOINT之后执行。
ONBUILD 当构建一个被继承的dockerfile时运行命令,父镜像在被子镜像继承后,父镜像触发ONBUILD命令。(父镜像如何被继承?在子镜像中from父镜像。)
curl
docker exec “隔空取物” 在不进入容器的情况下对容器进行操作
docker exec 容器id 命令
eg: