Docker学习心得记录系列之Docker基本概念和基本操作
上一篇记录了Docker的安装,接下来将记录我从网上和书上学习的Docker的基本操作和基本概念。
一、Docker基本概念
上手操作前,需要对Docker有概念性的认识,下面先整体介绍,然后分别对image、container、daemon、registry进行说明。
1.1 Docker组成部分
Docker 使用的是 C/S 结构,即客户端/服务器体系结构,一张非常经典的架构图如下(图片来自 Docker.com):
此外,在官网还有另外一张比较简单的体系结构介绍图:
这张图的意思就是:Docker Client通过REST API与Docker Server即Docker Daemon交互,从而完成对container、image、network、data volumes的管理。
但显然这两张图都描述的都比较笼统,具体怎么交互怎么管理基本没有体现出来,所以下面将从更细致的视角介绍。
- 在浙江大学SEL著的书有更详细的描述[1],下面是该书中给的架构总览,它是从代码架构的角度去介绍的:
Docker容器实质上就是一个或者多个进程,而容器的父进程就是Docker守护进Daemon。通过上图可以看出,Docker Daemon是Docker的核心,它提供了API Server介绍来自Docker Client的请求,其后,根据不同请求,分发给不同模块执行相应的工作。
需要注意,Docker为了将自己解耦,对运行时、volume、镜像、网络的具体实现都已放在daemon以外的模块或项目中。
具体的各个模块的功能与原理,可以翻阅该书,里面有详细介绍。 - 另外一篇文章,则从工作流的角度,对Docker的架构原来进行了介绍[2]:
可以看出,Daemon分为Docker Server、Engine和Job三个部分。三者的关系大致如下:Docker Daemon通过Docker Server模块接收Docker Client的请求,并在Engine处理请求,然后根据请求类型,创建出指定的Job并运行。Docker Daemon 运行在 Docker Host 上,负责创建、运行、监控容器,构建、存储镜像。
其中,运行过程包含以下几个方面: - 向 Docker Registry 获取镜像;
- 通过 graphdriver 执行容器镜像的本地化操作;
- 通过 networkdriver执行容器网络环境的配置;
- 通过 execdriver 执行容器内部运行的各项执行工作,execdriver承担了最重要的工作。
1.2 registry、image、container说明
1) registry
Docker registry就是镜像仓库,可以自己搭建私有的registry,也可以使用官方公有库即Docker Hub。Docker Hub分为两种类型,用户仓库和顶层仓库,前者由普通用户创建,后者是由官方维护提供官方版本镜像。
Docker Hub由一系列repository组成,而repository是镜像的集合,如ubuntu:14.04、ubuntu:12.04都属于ubuntu这个repository。用户仓库下的repository命名包括两部分,中间以"/"隔开,即username/repository_name的形式,而顶层仓库下的repository则直接用repository_name表述。
用户可以从Docker registry上拉取与上传镜像,如果选择Docker Hub,需要先注册,然后在推送前登陆。与registry相关的命令如下[3]:
#docker登陆
docker login
# 镜像拉取
docker pull [OPTIONS] NAME:[TAGS|@DIGEST]
# 镜像推送
docker push [OPTIONS] NAME[:TAG]
2) image 与 container
Docker image存储的是镜像的相关元数据信息,主要包括镜像的架构(如amd64)、镜像默认配置信息、构建镜像的容器配置信息、包含所有镜像层信息的rootfs。
镜像层即layer,Docker 镜像是由多个文件系统(只读层)叠加而成,每个层仅包含了前一层的差异部分。当我们启动一个容器(container)的时候,Docker 会加载镜像层并在其上添加一个可写层,容器与镜像最大的区别就在于可写层上。容器上所做的任何更改,譬如新建文件、更改文件、删除文件,都将记录与可写层上。容器层与镜像层的结构如下图所示[4]。
下面一张图则以一个具体的例子来说明,可以对image和container有更直观的感受。
最底下的是linux的内核空间,上面是base 镜像,它有两层含义:(i)不依赖其他镜像,从 scratch 构建;(ii)其他镜像可以之为基础进行扩展。可以称作 base 镜像的通常都是各种 Linux 发行版的 Docker 镜像,比如 Ubuntu, Debian, CentOS 等。
Linux启动到运行需要两个FS,bootfs + rootfs。对于 base 镜像来说,底层直接用 Host kernel 的bootfs,自己只需要提供 rootfs 就行了。 也正是因为这个原因,Docker 才可以同时支持多种 Linux镜像,模拟出多种操作系统环境[5]。
下面是一个简单的Dockerfile,展示了如何在Docker中运行Java程序,可以从中看到上面提到的image的相关概念:
常用的与image相关的Docker命令大概有以下几个:
# 显示镜像列表
docker images [OPTIONS] [REPOSITORY[:TAG]]
# 镜像删除
docker rmi [OPTIONS] IMAGE [IMAGE...]
# 容器删除
docker rm [OPTIONS] CONTAINER [CONTAINER...]
# 将容器保存为镜像
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
1.3 Docker的常用操作(持续补充)
# 连接容器进行交互
docker attach [OPTIONS] CONTAINER
# 查看容器和镜像的详细信息
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
## 查看容器IP地址
docker inspect --format='{{.NetworkSettings.IPAddress}}' NAME
## 批量查看IP地址
for i in `docker ps -q`; do echo -n "$i "; docker inspect $i --format='{{.NetworkSettings.IPAddress}}'; done
# 查看容器的相关信息
docker ps [OPTIONS]
options:
-a: 全部显示
-l: 只查看最新创建的容器
# 打印实时系统事件
docker events [OPTIONS]
# 打印镜像的历史版本信息
docker history [OPTIONS] IMAGE
# 打印容器中的进程日志
docker logs [OPTIONS] CONTAINER
参考资料:
[1]. Docker容器与容器云-Docker and kubernetes under the Hood(第二版),浙江大学SEL实验室著.
[2]. https://www.jsdaima.com/blog/177.html, 这可能是最为详细的Docker入门吐血总结.
[3]. https://blog.csdn.net/mi_xiaoxian/article/details/88659241, Docker >>『Docker容器与容器云』读书笔记-1.
[4]. https://www.cnblogs.com/autopenguin/p/7390239.html, Docker-v17 的层级(layer)概念.
[5]. https://blog.csdn.net/runner668/article/details/80955381, Docker分层原理与内部结构.