一、docker 架构
Docker的三个基本概念
从上图我们可以看到,Docker
中包括三个基本的概念:
Docker
中包括三个基本的概念:
Image
(镜像)Container
(容器)Repository
(仓库)
Image (镜像)
那么镜像到底是什么呢?
Docker
镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
镜像(Image)
就是一堆只读层(read-only layer)
的统一视角,也许这个定义有些难以理解,下面的这张图能够帮助读者理解镜像的定义。
从左边我们看到了多个只读层,它们重叠在一起。除了最下面一层,其它层都会有一个指针指向下一层。这些层是Docker
内部的实现细节,并且能够在主机的文件系统上访问到。统一文件系统 (union file system)
技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。我们可以在图片的右边看到这个视角的形式。
Container (容器)
容器 (container)
的定义和镜像 (image)
几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
由于容器的定义并没有提及是否要运行容器,所以实际上,容器 = 镜像 + 读写层。
Repository (仓库)
Docker
仓库是集中存放镜像文件的场所。镜像构建完成后,可以很容易的在当前宿主上运行,但是, 如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry
(仓库注册服务器)就是这样的服务。有时候会把仓库 (Repository)
和仓库注册服务器 (Registry)
混为一谈,并不严格区分。Docker
仓库的概念跟 Git
类似,注册服务器可以理解为 GitHub
这样的托管服务。实际上,一个 Docker Registry
中可以包含多个仓库 (Repository)
,每个仓库可以包含多个标签 (Tag)
,每个标签对应着一个镜像。所以说,镜像仓库是 Docker
用来集中存放镜像文件的地方类似于我们之前常用的代码仓库。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。我们可以通过<仓库名>:<标签>
的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest
作为默认标签.。
仓库又可以分为两种形式:
public
(公有仓库)private
(私有仓库)
Docker Registry
公有仓库是开放给用户使用、允许用户管理镜像的 Registry
服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry
。Docker
官方提供了 Docker Registry
镜像,可以直接使用做为私有 Registry
服务。当用户创建了自己的镜像之后就可以使用 push
命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull
下来就可以了。
我们主要把 Docker
的一些常见概念如 Image
, Container
, Repository
做了详细的阐述,也从传统虚拟化方式的角度阐述了 docker
的优势,我们从下图可以直观地看到 Docker
的架构:
Docker
使用 C/S
结构,即客户端/服务器体系结构。 Docker
客户端与 Docker
服务器进行交互,Docker服务端负责构建、运行和分发 Docker
镜像。 Docker
客户端和服务端可以运行在一台机器上,也可以通过 RESTful
、 stock
或网络接口与远程 Docker
服务端进行通信。
这张图展示了 Docker
客户端、服务端和 Docker
仓库(即 Docker Hub
和 Docker Cloud
),默认情况下Docker
会在 Docker
中央仓库寻找镜像文件,这种利用仓库管理镜像的设计理念类似于 Git
,当然这个仓库是可以通过修改配置来指定的,甚至我们可以创建我们自己的私有仓库。
二、常用命令
基础命令
启动 Docker
sudo systemctl start docker
停止 Docker
sudo systemctl stop docker
重启 Docker
sudo systemctl restart docker
修改配置后重启 Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
显示 Docker 版本信息
docker version
显示 Docker 系统信息,包括镜像和容器数
docker info
帮助
docker COMMAND --help
镜像命令
查看 Docker 上已经安装的镜像
docker images
搜索 Docker hub 上面的镜像
docker search 镜像的名称
# 以tomcat为例
docker search tomcat
下载镜像
docker pull [选项] [docker 镜像地址:标签]
# 以下载tomcat为例
docker pull tomcat[:version]
删除镜像
# 以删除tomcat为例
docker rmi tomcat[:version]
# 通过镜像ID删除
docker rmi -f 镜像ID
# 通过镜像ID删除多个
docker rmi -f 镜像名1:TAG 镜像名2:TAG
# 删除全部
# docker images -qa : 获取所有镜像ID
docker rmi -f $(docker images -qa)
容器命令
启动容器
docker run [options] image [command] [arg...]
常用参数:
-d: 后台运行容器,并返回容器ID
-it: 这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
--name: 为容器指定一个名称
--rm:这个参数是说容器退出后随之将其删除。
-P: 随机端口映射(大写)
-p: 指定端口映射(小写),一般可以有四种写法 hostPort:containerPort (常用)
-h: 指定容器的hostname
-v: 容器挂载存储卷,挂载到容器的某个目录
--dns 8.8.8.8: 为容器指定一个dns服务器,默认与宿主一致
实例
# 创建myubuntu容器,并且后台运行(单纯使用-d不可以,必须使用-itd)
docker run --name myubuntu -itd ubuntu:18.04 bash
这是指用 ubuntu:18.04 镜像为基础来启动容器。 如果只写ubuntu则是用ubuntu:latest作为基础镜像
# 映射多个端口
docker run -p 80:80/udp-p 90:90 -v /data:/data -d nginx
查看正在运行的Docker 容器
docker ps
常用参数:
-a # 显示所有容器,包括当前没有运行的容器
-l # 显示最近创建的容器
-n # 显示最近创建的N个容器
-q # 静默模式,只显示容器ID
--no-trunc # 不截断输出
查看容器的cpu内存和网络状态
docker stats 容器ID或容器名称
查看容器终端输出
# 查看最后10条的终端输出
docker logs -tf --tail 10 容器ID或容器名称
参数说明:
-t # 加入时间戳
-f # 跟随最新的日志打印
--tail 行数 # 输出最后几行的日志
查看容器/镜像的元数据
docker inspect 容器id /镜像id
退出容器
# 退出并停止
exit
# 容器不停止退出
ctrl+P+Q
启动容器
docker start 容器ID或容器name
重启容器
docker restart 容器ID或容器name
停止容器
docker stop 容器ID或容器name
强制停止容器
docker kill 容器ID或容器name
删除容器
# 删除已经停止的容器
docker rm 容器ID或容器name
# 强制删除已经停止或正在运行的容器
docker rm -f 容器ID或容器name
#一次性删除所有正在运行的容器
docker rm -f $(docker ps -qa)
从容器拷贝文件到宿主机
docker cp 容器ID或容器名称:/文件路径与文件名 宿主机地址
实例:
# 拷贝容器coco的tmp文件夹下的info.txt到宿主机的当前位置
docker cp coco:/tmp/info.txt .
进入正在运行的容器
docker exec -it 容器ID或容器名称 /bin/bash
docker attach 容器id
# exec 是在容器中打开新的终端,并且可以启动新的进程
# attach 直接进入容器启动命令的终端,不会启动新的进程
从容器创建镜像
docker commit -m="提交的描述信息" -a="作者" 容器id 要创建的目标镜像名:[标签名]