一、Docker 工作原理
二、Docker 容器和虚拟机对比
三、镜像容器管理
1、Docker 关键组件
2、Docker 架构
3、Docker 内部组件
镜像(Image)——一个特殊的文件系统 Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)
容器(Container)——镜像运行时的实体容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等
仓库(Repository)——集中存放镜像文件的地方镜像构建完成后,可以很容易的在当前宿主上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务
Docker 采用了 C / S 架构。客户端和服务端可以运行在一个机器上, 也可以通过 socket 或者 RESTful API 来进行通信。Docker Daemon:一般在宿主机后台运行, 等待接收客户端的消息 Docker Client:则为客户提供一系列可执行的命令, 用户使用这些命令跟 docker daemon 交互
Docker daemon:Docker daemmon 是 Docker 架构中的主要用户接口。首先,它提供了 API Server 用于接收来自 Docker client 的请求,其后根据不同的请求分发给 Docker daemon 的不同模块执行相应的工作
Image managerment:需要创建 DOcker 容器时,可通过镜像管理(image management)部分的 distribution 和 registry 模块从 Docker registry 中下载镜像,并通过镜像管理的 image、reference 和 layer 存储镜像的元数据,通过镜像存储驱动 graphdriver 将镜像文件存储于具体的文件系统中
Network:当需要为 Docker 容器创建网络环境时,通过网络模块 network 调用 libnetwork 创建并配置 Docker 容器的网络环境
Volume:当需要为容器创建数据卷 volume 时,则通过 volume 模块调用某个具体的 volumedrive,来创建一个数据卷并负责后续的挂载操作
Execdriver: 当需要限制 Docker 容器运行资源或执行用户指令操作时,则通过 execdrive 来完成
Libcontainer: 是对 cgroups 和 namespace 的二次封装,execdrive 是通过 libcontainer 来实现对容器的具体管理,包括利用 UTS、IPC、PID、Network、Mount、User 等 namespace 实现容器之间的资源隔离和利用 cgroups 实现对容器的资源限制. 当运行容器的命令执行完毕后,一个实际的容器就处于运行状态,该容器具有独立的文件系统、相对安全且相互隔离的运行环境.
1、用户是使用 Docker Client 与 Docker Daemon 建立通信,并发送请求给后者
2、Engine 执行 Docker 内部的一系列工作,每一项工作都是以一个 Job 的形式的存在。
3、Job 的运行过程中,当需要容器镜像时,则从 Docker Registry 中下载镜像,并通过镜像管理驱动 graphdriver 将下载镜像以 Graph 的形式存储;当需要为 Docker 创建网络环境时,通过网络管理驱动 networkdriver 创建并配置 Docker 容器网络环境;当需要限制 Docker 容器运行资源或执行用户指令等操作时,则通过 execdriver 来完成。libcontainer 是一项独立的容器管理包,networkdriver 以及 execdriver 都是通过 libcontainer 来实现具体对容器进行的操作。
1、容器和虚拟机对比
2、Docker 的优势
3、Docker 的劣势
4、Docker 的应用场景
Docker 的的优势:
持续部署和测试发到产品发布的整个过程中使用相同的容器来确保没有任何差异或者人工干预。Docker 可以保证测试环境、开发环境、生产环境的一致性。
可移植性容器可以移动到任意一台 Docker 主机上,而不需要过多关注底层系统。
弹性伸缩更快速配合 K8S 可以很容易的无状态应用的弹性伸缩,只需要改一个 yml 的数字即可。利用 docker 能在几秒钟之内启动大量的容器,这是虚拟机无法办到的,快速启动,秒级和分钟级的对比。
资源利用率高由于 docker 不需要 Hypervisor 实现硬件资源虚拟化,docker 容器和内核交互,几乎没有性能损耗,性能优于通过 Hypervisor 层与内核层的虚拟化。一台机器启动上前台容器也没问题。
对硬件无要求不需要 CPU 支持虚拟化
Docker 的的劣势
资源隔离 docker 是利用 cgroup 实现资源隔离的,只能限制资源消耗的最大值,而不能隔绝其他应用程序占用自己的资源;docker 属于进程之间的隔离,虚拟机可实现系统级别隔离;
安全性问题一个用户拥有执行 docker 的权限,可以删除任何用户创建的容器。
兼容性问题 docker 目前还在版本快速更新中,细节功能调整较大,一些核心的模块依赖于高版本的内核,存在兼容性的问题。
1、Docker 安装
2、认识镜像和容器
3、镜像容器管理
什么是镜像?镜像是一个多层的联合只读的文件系统。
什么是容器?容器是在镜像基础上加上读写层。容器即进程。
构建镜像的过程?镜像 -> 镜像 + 可写层 + 执行命令 ->commit 为新的镜像 (新的一层)-> 镜像 + 可写层 + 执行命令 ->commit 为新的镜像 (新的一层)->…
典型文件系统启动:一个典型的 Linux 文件系统由 bootfs 和 rootfs 两部分组成,
bootfs(boot file system)
主要包含 bootloader 和 kernel,bootloader 主要用于引导加载 kernel,当 kernel 被加载到内存中后 bootfs 会被 umount 掉
rootfs (root file system)
包含的就是典型 Linux 系统中的 /dev,/proc,/bin,/etc 等标准目录和文件
加载过程:bootfs 时会先将 rootfs 设为 read-only,然后在系统自检之后将 rootfs 从 read-only 改为 read-write,
Docker 文件系统启动:
Docker 在 bootfs 自检完毕之后并不会把 rootfs 的 read-only 改为 read-write,而是利用 union mount(UnionFS 的一种挂载机制)将 image 中的其他的 layer 加载到之前的 read-only 的 rootfs 层之上,每一层 layer 都是 rootfs 的结构,并且是 read-only 的。所以,我们是无法修改一个已有镜像里面的 layer 的!只有当我们创建一个容器,也就是将 Docker 镜像进行实例化,系统会分配一层空的 read-write 的 rootfs,用于保存我们做的修改
Dockerfile
FROM centos
ENV TZ “Asia/Shanghai”
ADD echo.sh /opt/echo.sh
RUN chmod +x /opt/echo.sh
CMD [“/opt/echo.sh”]
docker build -t test -f Dockerfile .
镜像工作原理:如果运行中的容器修改一个已经存在的文件,那么会将该文件从下面的只读层复制到读写层,只读层的这个文件就会覆盖(隐藏),但还存在。如果删除一个文件,在最上层会被标记隐藏,实际只读层的文件还存在。这就实现了文件系统隔离,当删除容器后,读写层的数据将会删除,只读镜像不变。
查看具体的挂载逻辑
[root@centos7 l]# mount|grep overlay
overlay on
/var/lib/docker/overlay2/56375ce93fd54484061ef08a48a7093905be680dd14754642970616127b30fca/merged type overlay (rw,relatime,seclabel,lowerdir=/var/lib/docker/overlay2/l/A6JYT4QIFZMKOPIGY675JWKS7F:/var/lib/docker/overlay2/l/4L4SUINS3DX6XPD5BL2J54JQDT,upperdir=/var/lib/docker/overlay2/56375ce93fd54484061ef08a48a7093905be680dd14754642970616127b30fca/diff,workdir=/var/lib/docker/overlay2/56375ce93fd54484061ef08a48a7093905be680dd14754642970616127b30fca/work)
Overlay 和 overlay2 的区别
overlay: 只挂载一层, 其他层通过最高层通过硬连接形式共享 (增加了磁盘 inode 的负担)
overlay2: 逐层挂载(最多 128 层)
基础镜像的层信息
docker pull centos
tree -L 2 /var/lib/docker/overlay2/
构建后镜像的层信息
cd layer_dockerfile/
docker build -t centos:test -f ./Dockerfile .
tree -L 2 /var/lib/docker/overlay2/
每一层都包含了”该层独有的文件”以及”和其低层共享的数据的连接”,在 Docker 1.10 之前的版本中,目录的名字和镜像的 UUID 相同,而 Docker 1.10 后则采用了新的存储方式,可以看到目录名和下载镜像的 UUID 并不相同
Diff 存放挂载点的具体的文件内容
Link 对应 l 目录的链接源的名称
Lower 根没有 lower,其它的 lower 指向的父层的链接
L:”l“目录包含一些符号链接作为缩短的层标识符. 这些缩短的标识符用来避免挂载时超出页面大小的限制
docker run -idt –name centos_con centos:test /bin/bash
tree -L 2 /var/lib/docker/overlay2/
多出的两层“……”为读写层,“…..-init”为初始层。
初始层:
初始层中大多是初始化容器环境时,与容器相关的环境信息,如容器主机名,主机 host 信息以及域名服务文件等。
读写层:
所有对容器做出的改变都记录在读写层
Diff 存放挂载点的具体的文件内容
Link 对应 l 目录的链接源的名称
Lower 根没有 lower,其它的 lower 指向的父层的链接
Merged 如果是读写层会有一个 Merged
Commit: 容器提交为镜像
docker run -idt –name test centos
Touch liwei
docker commit 6de test2
Create: 创建容器但是不启动
docker create –name nginx-con -p80:80 nginx:latest
Start: 启动容器
docker start nginx-con
Stop: 停止容器
docker stop nginx-con
Kill: 杀掉容器,和停止相比不友好
docker kill nginx-con
Pause: 暂停容器
docker pause nginx-con
Unpause: 恢复暂停的容器
docker unpause nginx-con
Run: 创建且启动容器
docker run -idt –restart=always –name nginx_con -v /tmp/:/mnt -p 88:80 -e arg1=arg1 nginxDocker attach nginx_conCtrl+^p+^q
CP: 宿主机和容器之间 copy 文件
docker cp docker_install.sh nginx_con:/opt
docker exec nginx_con ls /opt
docker cp nginx_con:/opt/docker_install.sh ./1.sh
Exec: 执行命令,也可附加到容器
docker exec nginx_con ls /opt
Attach:附加到容器
docker attach nginx_con
docker exec -it nginx_con /bin/bash
Logs: 查看容器日志
docker logs –f nginx_con
Inspect: 查看元数据,可以查看镜像和容器
docker inspect nginx_con
Port: 查看容器端口映射
docker port nginx_con
Top:查看容器中正在运行的进程
docker top nginx_con
Ps:查看容器
docker ps
docker ps -a
docker ps -aq
查看正在运行的容器,加上 - a 查看所有容器(包含停止和暂停状态的容器)
Rm:删除容器
docker rm nginx_con 删除容器
docker rm -f nginx_con 强行删除容器
Export:导出容器
docker pull busybox
docker run -itd busybox
docker export 983989307eef>busybox.tar
Import: 导入容器
docker import busybox.tar busybox:1.3
Save:导出镜像
docker save busybox:1.3>busybox1.3.tar
Load:导入镜像
docker load -i busybox1.3.tar
Tag:镜像打标签
docker tag busybox:1.3 192.168.199.160/test/busybox:latest
Build:从 dockerfile 构建镜像
FROM centos
ENV TZ “Asia/Shanghai”
ADD echo.sh /opt/echo.sh
RUN chmod +x /opt/echo.sh
CMD [“/opt/echo.sh”]
docker build -t centos:test -f Dockerfile .
Pull:从 registry 拉取镜像
docker pull nginx 从 dockerhub 上拉取
docker pull 192.168.199.160/test/nginx:latest 从内网 harbor 上拉取
Push: 推送镜像到仓库 [第一次需要输入密码,后续不需要了]
docker login 192.168.199.160
admin
Harbor12345
docker push 192.168.199.160/test/busybox:latest
Info、version、events
docker info 查看 docker 相关信息信息
Docker version 查看 docker 相关版本信息
Docker events 查看 docker 事件
【注】1、创建容器后防火墙不要再动
2、cmd 会被覆盖的问题,需要注意,可能会导致 /bin/bash 把启动命令覆盖了,启动不了的问题例如 docker run -idt –restart=always –name nginx_con -v /tmp/:/mnt -p 88:80 -e arg1=arg1 nginx /bin/bash
3、cmd 的命令都会在挂在后执行。