一文带你全面了解 docker 的概念与使用

2022-06-27 16:37:23 浏览数 (1)

1. 引言

docker 凭借其易于使用和部署的优势以及高效的资源利用率已经成为了服务部署、运行维护的首选利器。

本文,我们就来全面了解一下 docker 是什么,以及如何构建和使用 docker。

2. 什么是 docker

2.1 docker 镜像

docker 通常指 docker 镜像,docker 镜像包含了所有 docker 容器运行所需要的文件和指令,是一个或一个以上 docker 容器的封装。

docker 镜像就是我们最终用来部署的可移植、可运行 docker 程序。

他通过 Dockerfile 配置打包过程的各种参数。Dockerfile 就是 docker 的配置文件,它包含一系列 docker 命令行工具执行的命令行指令,换句话说,docker 镜像正是在 docker 命令行工具执行 Dockerfile 后生成的。

2.2 docker 命令行工具

上面提到了 docker 命令行工具,他是一组随着 docker 一起被安装到系统的命令集合。通过执行这些命令行工具,就可以通过 Dockerfile 构建出 docker 镜像,同时,也可以实现将 docker 镜像上传到 docker 仓库、从 docker 仓库下载 docker 镜像,以及启动或终止 docker 容器等多种操作。

2.3 docker 仓库

这里提到了 docker 仓库,docker 仓库就是一个存储 docker 镜像的仓库,十分类似 java 的 maven 仓库或是 python 的 pip 仓库,在我们完成 docker 镜像构建后,上传到 docker 镜像仓库以后,就可以实现镜像的备份、共享或是管理了。

一个公有的 Docker 仓库,是运行潜在用户下载、安装和运行软件的很好的方式,只需要将应用程序打包为 Docker 镜像,上传到公有的 Docker 仓库中,你的用户就可以访问并使用它。

Docker 公司已将 Docker 仓库作为一项托管服务,提供了私有和公有两种服务。一些云服务商,比如 AWS、AZure 和 Google,也提供了 Docker 仓库服务器,可以上传自己的 Docker 镜像。很容易的就能在云基础设施上的虚拟机或 Kubernetes 中使用这些镜像。

一旦 docker 镜像打包好,他就可以被部署启动了,每个运行的实例,就被成为是一个 docker 容器。

实际上,linux 操作系统本身有一系列的容器化特性,支持应用相互隔离、容器化的使用资源,docker 便是这些特性的封装。这是他和虚拟机最大的不同。

2.4 Docker Compose

Docker Compose 提供将多个 Docker 容器链接成一个组合的功能,这个组合中的所有容器可以被一次性全部部署、启动或停止。

3. 为什么使用 docker

3.1 Docker 容器 vs 虚拟机

提到操作系统虚拟化的应用,我们最先想到的一定是虚拟机技术了,那么 docker 容器和虚拟机又有什么不同呢?

对于虚拟机来说,每个虚拟机内是必须要运行一个独立的操作系统的,而 docker 容器则不然,他内部并不具有一个操作系统,虽然 docker 容器内部的文件系统是独立的,但容器是直接运行在 linux 操作系统上的,因此,docker 容器相比于虚拟机,占用空间是很小的。同时,由于没有了占用很大资源的虚拟操作系统,docker 的运行效率也得以显著提升。

3.2 docker 的优势

通过上面的描述,我们知道了 docker 是什么,那么我们为什么要使用 docker 呢?

  1. 易于使用 -- 先前服务是如何配置的,使用 docker 后也按同样方式配置 Dockerfile 即可。
  2. 一处配置处处使用 -- 如果你需要把同样的镜像部署到多个机器上,你只需要把镜像上传上去然后启动即可。
  3. 便于管理 -- k8s、docker swarm 等集群管理工具都可以非常轻松的管理 docker 组成的集群,除此之外,很多云平台都是以 docker 容器为单位进行服务的治理的,这让普通用户去搭建云服务变得非常轻松。
  4. 有利于商业应用 -- 对于商业应用来说,使用 docker 让你可以轻松的把自己的服务安装在客户的服务器上,而不用去顾虑千差万别的实际环境。

4. Dockerfile

要创建 docker 镜像,我们首先需要配置 dockerfile,Dockerfile 相当于是构建 docker 镜像的一个清单,他包含以下信息:

  1. 用于构建 docker 镜像的基础镜像;
  2. docker 镜像包含的一系列工具和应用信息;
  3. 需要放入 docker 镜像的文件;
  4. 需要在防火墙中打开的网络协议及端口等信息。

在把种种信息描述全部写入到 Dockerfile 以后,docker 已经完全清楚如何去构建你的 docker 镜像了,这就是 Dockerfile 存在的意义。

5. 构建 DockerFile

下面是一个 Dockerfile 的例子:

代码语言:javascript复制
 # The base image
 FROM ubuntu:latest
 
 # More instructions here that install software and copy files into the image.
 COPY   /myapp/target/myapp.jar   /myapp/myapp.jar
 
 # The command executed when running a Docker container based on this image.
 CMD echo Starting Docker Container

5.1 基础镜像

docker 镜像可以被分为多层,每一层都是可以分开的 docker 镜像。因此,你的 docker 镜像需要包含一个或多个 docker 镜像作为基础镜像。

FROM 命令定义构建镜像的基础镜像,这条配置必须是dockerfile的首个命令。

FROM <image>FROM <image>:<tag>FROM <image>:<digest>

官方提供了很多 docker 基础镜像,比如 nginx、php、mysql 等,对于这些应用,直接引用即可。

其他官方没有给出的,一般可以设置 debian:jessie、alpine、ubuntu 等作为 FROM 的参数。

5.2 MAINTAINER

MAINTAINER 是一个可有可无的配置,它用来声明作者的信息,可以放在文件的任何位置:

MAINTAINER <messages>

5.3 CMD

CMD <commands>

CMD 是一个关键的配置,他表示容器启动时执行操作,例如:

CMD echo Docker container started.

如果一个Dockerfile中有多个CMD命令,那么只有最后一个CMD命令生效。

CMD的指令可以在 docker run 的时候被参数覆盖。

5.4 COPY

COPY <src>... <dest> COPY ["<src>",... "<dest>"]

COPY 指令用于将本地文件复制到 docker 镜像内,只能用于本地文件的复制。

5.5 ADD

ADD <src>... <dest> ADD ["<src>",... "<dest>"]

ADD 指令用于将源目录、文件或远程文件复制到 docker 镜像内。

如果 src 是一个压缩文件,ADD 指令会自动将解压结果放入 dest 位置,而如果 src 是一个 url,则会自动下载文件。例如:

ADD http://jenkov.com/myapp.jar /myapp/

5.6 ENV

ENV <key> <value> ENV <key>=<value>

ENV 指令用于设置 docker 镜像的环境变量,可以在构建镜像时使用,也可以在运行的容器中使用,使用键值对的形式,可以一次指定多个。

ENV MY_VAR 123

5.7 RUN

RUN <commands> RUN ["executable", "param1", "param2"] (exec form)

RUN 指令用来执行系统命令,例如:

RUN apt-get install some-needed-app

上面提到,docker 镜像是分层的,没执行一次 RUN 指令,docker 镜像就会被分出新的一层,因此建议一个 dockerfile 中只加入一个 RUN 指令,如果需要执行多个系统命令,则使用 && 连接起来。

5.8 ARG

ARG <name>[=<default value>]

Dockerfile 指令允许定义参数,在 Dockerfile 构建 Docker 文件时,通过 --build-arg 参数传递给 Docker,例如:

docker build --build-arg tcpPort=8080 .

而在 Dockerfile 中,只需要通过 ARG 指定的参数名使用参数即可。例如:

ARG tcpPort=8080ARG useTls=true CMD start-my-server.sh -port {useTls}

5.9 WORKDIR

WORKDIR 指令指定了 Docker 图像中的工作目录。工作目录将针对指令后的所有命令生效。

例如:

WORKDIR /java/jdk/bin

5.10 EXPOSE

EXPOSE 指令声明了需要向外暴露的网络端口,例如:

EXPOSE 8080

也可以指定协议:

EXPOSE 8080/tcp 9999/udp

5.11 VOLUME

VOLUME ["/data","/opt"]

由于 docker 容器不能持久化存储数据,因此需要使用卷来管理数据,卷分为宿主目录、数据卷、容器卷。

VOLUME 指令就是用来设置卷的,在启动容器的时候 Docker 会在 /var/lib/docker/ 目录下创建一个卷,以保存容器中产生的数据。若没有申明则不会创建。

5.12 ENTRYPOINT

ENTRYPOINT ["cmd"]

ENTRYPOINT 指定了 docker 镜像的入口点。

入口点就是当 Docker 容器启动时执行的应用程序或命令,在 Dockerfile 中设置后不可被外部修改,并且只能有一个生效。

5.13 HEALTHCHECK

docker 允许定期执行健康检查命令行命令,以监控在 Docker 容器内运行的应用程序的健康状况。

如果命令行命令在退出时返回值为 0,Docker 认为应用程序和容器是健康的。如果命令行命令返回值为 1,Docker 认为应用程序和容器不健康。

例如:

HEALTHCHECK java -cp /apps/myapp/healthcheck.jar com.jenkov.myapp.HealthCheck https://localhost/healthcheck

健康检查还可以加入几个额外参数:

  1. 健康检查间隔 -- --interval=60s
  2. 健康检查开始时间 -- 默认健康检查会在 docker 镜像启动后立即执行,可以通过 --start-period=300s 参数让健康检查在启动 300s 后执行。
  3. 健康检查超时 -- --start-period=300s
  4. 健康检查重试次数 -- --retries=5

6. Docker 指令

6.1 构建 docker 镜像 -- docker build

首先,我们需要通过上面一系列指令编辑了 Dockerfile,接下来就需要通过 Dockerfile 构建 docker 镜像了。

只需要执行:

docker build .

6.2 列出 docker 镜像列表 -- docker images

执行 docker images 命令可以列出本机上所有已注册的 docker 镜像,例如:

代码语言:javascript复制
 REPOSITORY       TAG       IMAGE ID       CREATED         SIZE
 hello-world     latest     fce289e99eb9   9 months ago     1.84kB

6.3 执行镜像 -- docker run

以 docker 镜像为参数执行 docker run 命令就可以让 docker 运行起来了。

6.4 查看 docker 运行信息 -- docker ps

执行 docker ps 命令,可以看到当前机器上正在运行着的 docker 镜像信息。

7. 后记

本文翻译整理自 Jakob Jenkov 的三篇系列博客:

  1. http://tutorials.jenkov.com/docker/index.html
  2. http://tutorials.jenkov.com/docker/dockerfile.html
  3. http://tutorials.jenkov.com/docker/docker-commands.html

主要介绍了 docker 的基本概念、原理与用法,主要用于初学者、普通开发人员等非运维岗位的人对 docker 有基本的了解,可以通过 docker 指令构建、运行和管理自己的 docker 镜像,如果对 docker 有兴趣或生产环境的使用需要,推荐阅读 docker 官方文档及相应的书籍。

0 人点赞