docker 入门

什么是docker

Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 开放容器联盟(OCI)。

Docker 自开源后受到广泛的关注和讨论,至今其 GitHub 项目 已经超过 5 万 4 千个星标和一万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker。

Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。

基本概念

镜像

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

容器

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。也因为这种隔离的特性,很多人初学 Docker 时常常会混淆容器和虚拟机。

仓库

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。

一个 Docker Registry 中可以包含多个 仓库(Repository);每个仓库可以包含多个 标签(Tag);每个标签对应一个镜像。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

安装

Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。

Docker CE 分为 stable test 和 nightly 三个更新频道。每六个月发布一个 stable 版本 (18.09, 19.03, 19.09…)。

安装指南

镜像加速器

国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了国内加速器服务,例如:

对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)

1
{
2
  "registry-mirrors": [
3
    "https://dockerhub.azk8s.cn",
4
    "https://hub-mirror.c.163.com"
5
  ]
6
}

检查加速器是否生效

执行 $ docker info,如果从结果中看到了如下内容,说明配置成功。

1
Registry Mirrors:
2
 https://dockerhub.azk8s.cn/

使用镜像

从 Docker 镜像仓库获取镜像的命令是 docker pull。其命令格式为:

1
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

具体的选项可以通过 docker pull –help 命令看到

比如:

1
$ docker pull nginx
2
c4f8e1e649d2: Pull complete 
3
a9d89e55a67d: Pull complete 
4
678d4c685f23: Pull complete 
5
Digest: sha256:8aa7f6a9585d908a63e5e418dc5d14ae7467d2e36e1ab4f0d8f9d059a3d071ce
6
Status: Downloaded newer image for nginx:latest
7
docker.io/library/nginx:latest

运行

1
$ docker run -d -p 3000:80 nginx
2
9261cb157d8515343d8c105dcf851e69d245b4fcfb412196ddb09a873ba0ca66

docker run 就是运行容器的命令,参数简要说明

  • -d:后台运行
  • -p: 端口映射
  • nginx: 用 nginx 镜像为基础来启动容器

使用 docker ps 查看

1
$ docker ps
2
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
3
9261cb157d85        nginx               "nginx -g 'daemon of…"   8 minutes ago       Up 7 minutes        0.0.0.0:3000->80/tcp   festive_hermann

列出镜像

要想列出已经下载下来的镜像,可以使用 docker images 或 docker image ls 命令。

1
$ docker image ls
2
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
3
nginx               latest              de6f1e0379c8        8 days ago          97.9MB

列表包含了 仓库名、标签、镜像 ID、创建时间 以及 所占用的空间。

镜像体积

1
$ docker system df

查找镜像

使用 docker search 命令可以搜索 Docker Hub 官方仓库中的镜像。
语法为 docker search [option] keyword 。
支持的命令选项主要包括:

-f, –filter filt er: 过滤输出内容;
–format string: 格式化输出内容;
–limit int:限制输出结果个数, 默认为 25个;
–no-trunc: 不截断输出结果。

删除本地镜像

使用 docker rmi 或 docker image rm 命令可以删除镜像

1
$ docker image rm [选项] <镜像1> [<镜像2> ...]

使用 id 、镜像名、摘要删除镜像

比如

1
$ docker image ls
2
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
3
nginx               latest              c7460dfcab50        11 days ago         126MB
4
$ docker image rm c7
5
Untagged: nginx:latest
6
Untagged: nginx@sha256:8aa7f6a9585d908a63e5e418dc5d14ae7467d2e36e1ab4f0d8f9d059a3d071ce
7
Deleted: sha256:c7460dfcab502275e9c842588df406444069c00a48d9a995619c243079a4c2f7
8
Deleted: sha256:3e51598e49c550f8b212a07c6ff2ed47a09eeb637f67d1b3c5468e9a8ee646e3
9
Deleted: sha256:a8b9a5643b3cc8082997d3d2fbaf4b53213ff80aa4169226be8b3768ae6e3605
10
Deleted: sha256:556c5fb0d91b726083a8ce42e2faaed99f11bc68d3f70e2c7bbce87e7e0b3e10

清理镜像

使用Docker 一 段时间后, 系统中可能会遗留一些临时的镜像文件, 以及 一 些没有被使用的镜像, 可以通过docker image prune命令来进行清理。

支待选项包括:

-a, -all: 删除所有无用镜像, 不光是临时镜像;
-filter filter: 只清理符合给定过滤器的镜像;
-f, -force: 强制删除镜像, 而不进行提示确认。

创建镜像

创建镜像的方法主要有三种: 基于已有镜像的容器创建、 基千本地模板导入、 基于 Dockerfile 创建。

基于已有镜像的容器创建

命令格式为 docker [container] commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]], 主要选项包括:

-a, –autor=””: 作者信息;
-c, –change=[] : 提交的时候执行 Dockerfile 指令, 包括 CMD I ENTRYPOINT | ENV I EXPOSE I LABEL I ONBU I LDIUSER I VOLUME I WORKDIR 等;
-m, - -message=”” : 提交消息;
-p, –pause=true: 提交时暂停容器运行。

例:

1
docker [container] commit -m "Added a new file" -a "Docker Newbee" a9 test:0.1

基千本地模板导入

使用 docker [container] import 命令导入本地模板。

要导入一个镜像,可以使用 OpenVZ 提供的模板来创建。OpenVZ 下载地址

例:

1
$ cat ubuntu-18.04-x86_64-minimal.tar.gz | docker import - ubuntu:l8.04

基于 Dockerfile 创建

基于 Dockerrfile 创建是最常见的方式。Dockerfile 是文本文件,利用给定的命令描述基于某个父镜像创建新镜像的过程。

比如构成 nginx 镜像:

Dockerfile 文件

1
FROM nginx
2
ADD ./ /usr/share/nginx.html/

在当前文件夹下创建 index.html 文件

1
hello world!
1
$ docker build -t test .
2
$ docker run -d -p 100:80 test

存出和载入镜像

使用 docker save 和 docker load 命令来存出和载入镜像

存出镜像

使用 docker sava 命令导出镜像到本地文件。

例:

1
$ docker save test >test.tar

载入镜像

使用 docker load 命令将导出的 tar 文件导入到本地镜像库。

1
$ docker load -i test.tar

或者:

1
$ docker load < test.tar

上传镜像

使用 docker push 命令上传镜像到仓库,默认上传到 Docker Hub 官方仓库。

例:

1
$ docker push test

第一次上传时,会提示输入登录信息或进行注册,之后登录信息会记录到本地 ~/.docker 目录下。