文章目录



简介

Docker 是一个开源的应用容器引擎,基于 ​​Go 语言​​ 并遵从 Apache2.0 协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。

基本组成


  1. Docker Client 客户端
  2. Docker daemon 守护进程
  3. Docker Image 镜像
  4. Docker Container 容器
  5. Docker Registry 仓库


docker image镜像


镜像是容器的基石,容器基于镜像启动和运行。镜像就好像容器的源代码,保存了容器各种启动的条件。镜像是一个层叠的只读文件系统。


docker container 容器


容器通过镜像来启动,容器是docker的执行来源,可以执行一个或多个进程。镜像相当于构建和打包阶段,容器相当于启动和执行阶段。容器启动时,Docker容器可以运行、开始、停止、移动和删除。每一个Docker容器都是独立和安全的应用平台。


docker registry 仓库


docker仓库用来保存镜像。docker仓库分为公有和私有。docker公司提供公有仓库docker hub,网址:​​https://hub.docker.com/​​​。我们也可以创建自己私有的仓库。

docker总结_nginx

体系结构

docker总结_redis_02

Docker 是一个 C/S 模式的架构,后端是一个松耦合架构,模块各司其职。


  1. 用户是使用 Docker Client 与 Docker Daemon 建立通信,并发送请求给后者。
  2. Docker Daemon 作为 Docker 架构中的主体部分,首先提供 Docker Server 的功能使其可以接受 Docker Client 的请求。
  3. Docker Engine 执行 Docker 内部的一系列工作,每一项工作都是以一个 Job 的形式的存在。
  4. Job 的运行过程中,当需要容器镜像时,则从 Docker Registry 中下载镜像,并通过镜像管理驱动 Graphdriver 将下载镜像以 Graph 的形式存储。
  5. 当需要为 Docker 创建网络环境时,通过网络管理驱动 Networkdriver 创建并配置 Docker容器网络环境。
  6. 当需要限制 Docker 容器运行资源或执行用户指令等操作时,则通过 Execdriver 来完成。
  7. Libcontainer 是一项独立的容器管理包,Networkdriver 以及 Execdriver 都是通过 Libcontainer 来实现具体对容器进行的操作。

镜像管理

docker镜像是一个不包含Linux内核的操作系统。

[root@data docker]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 8c9ca4d17702 2 days ago 109MB

镜像由docker公司的公共镜像仓库下载 ​​https://hub.docker.com/explore​


镜像与容器关系



  • 通过docker history <id/name>查看镜像中各层的内容及大小,每层对应着dockerfile中的一个指令,docker镜像默认存储在/var/lib/dockerk/中。
  • 容器其实就是在镜像的最上面加了一层读写层,在运行容器里做的任何修改,都会写到这个读写层。如果容器删除了,最上面的读写层数据也就丢失了。docker使用存储驱动管理镜像每层内容及可读写的容器层。


存储驱动



  • Ubuntu
  • aufs devicemapper overlay2 overlay zfs vfs
  • Debian
  • aufs devicemapper overlay2 vfs overlay
  • centos(6)
  • devicemapper vfs overlay(7)
  • fedora
  • devicemapper overlay2 overlay vfs
  • overlay overlay2 - ext4,xfs
  • aufs -ext4,xfs
  • devicemapper - direct-lvm
  • btrfs -btrfs
  • zfs -zfs

docker镜像管理常用的命令


ls列出镜像


[root@data docker]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 8c9ca4d17702 2 days ago 109MB


build构建镜像(来自dockerfile)



history查看镜像历史(执行了那些步骤)


[root@data docker]# docker image history nginx:latest
IMAGE CREATED CREATED BY SIZE COMMENT
8c9ca4d17702 2 days ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
<missing> 2 days ago /bin/sh -c #(nop) STOPSIGNAL SIGTERM 0B
<missing> 2 days ago /bin/sh -c #(nop) EXPOSE 80 0B
<missing> 2 days ago /bin/sh -c ln -sf /dev/stdout /var/log/nginx… 22B
<missing> 2 days ago /bin/sh -c set -x && apt-get update && apt… 54MB
<missing> 2 days ago /bin/sh -c #(nop) ENV NJS_VERSION=1.15.9.0.… 0B
<missing> 2 days ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.15.9-… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:5a6d066ba71fb0a47… 55.3MB


inspect显示一个或多个镜像详细信息


[root@data docker]# docker image inspect nginx:latest
[
{
"Id": "sha256:8c9ca4d17702c354fa41432be278d8ce6c0761b1302608034fa3ad49c6da43f9", "RepoTags": [
"nginx:latest"
],
"RepoDigests": [ "nginx@sha256:18c0755594af107923baa2e65fcef35aea4ab0cea7862d19c27aa127bacb458e"
],


pull从镜像仓库拉取镜像


[root@data docker]# docker pull nginx:1.11 ----<name:version>
Using default tag: latest
latest: Pulling from library/nginx
Digest: sha256:18c0755594af107923baa2e65fcef35aea4ab0cea7862d19c27aa127bacb458e
Status: Image is up to date for nginx:latest
[root@data docker]# docker image pull nginx
Using default tag: latest
latest: Pulling from library/nginx
Digest: sha256:18c0755594af107923baa2e65fcef35aea4ab0cea7862d19c27aa127bacb458e
Status: Image is up to date for nginx:latest


push推送一个镜像到仓库(需要登录)



rm删除镜像


[root@data docker]# docker image rm httpd:latest
Untagged: httpd:latest
Untagged: httpd@sha256:5e7992fcdaa214d5e88c4dfde274befe60d5d5b232717862856012bf5ce31086
Deleted: sha256:d3a13ec4a0f1157fb3502ec1248f2b1e7dbeeb6a2e21e0c1d3f43b7a494221ed
Deleted: sha256:ffda16bd6375fb3b126592485a714e2ff95575600128c4ef2d34207573284206
Deleted: sha256:61d9f00c32aab3132c865ccf069bfeead749a949df6f96f6e3bb800eef193c46
Deleted: sha256:c8a247f5bfa5b62fc08f2f18df0e6a4873e0a3eceb15abb906092eecaa84d9fc
Deleted: sha256:04eb6e2a1ea13cc4832d2b15e7ba5295b0fbf5c9f9f40e0a27fd0be1c7b3a1c7


prune移除未使用的镜像。没有被标记或被任何容器引用



tag创建一个引用镜像标记目标镜像


[root@data docker]# docker image tag nginx:latest nginx:1.15
[root@data docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx 1.15 8c9ca4d17702 2 days ago 109MB
nginx latest 8c9ca4d17702 2 days ago 109MB


save保存一个或多个镜像到一个tar归档文件


docker image save nginx:1.15 > /tmp/nginx15.tar


load加载镜像来自tar归档或标准输入


docker image load < /tmp/nginx15.tar

容器管理


创建容器常用项


docker总结_nginx_03


管理容器常用指令


docker总结_nginx_04

Dockerfile

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

Dockerfile定制镜像


1.定制一个 nginx 镜像(构建好的镜像内会有一个 /usr/share/nginx/html/index.html 文件)
在一个空目录下,新建一个名为 Dockerfile 文件,并在文件内添加以下内容:


FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html

docker总结_redis_05


2.From和RUN指令的作用


FROM:定制的镜像都是基于FROM的镜像,这里的nginx就是定制需要的基础镜像。后续的操作都是基于nginx。

RUN:用于执行后面跟着的命令行命令(两种格式):

  • shell
RUN <命令行命令>  # <命令行命令> 等同于,在终端操作的 shell 命令。
  • exec格式
RUN ["可执行文件",  "参数1",  "参数2"]  # 例如:  # RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline


注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。


FROM centos  
RUN yum install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
以上执行会创建 3 层镜像。可简化为以下格式:
FROM centos
RUN yum install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz

如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

构建镜像

在 Dockerfile 文件的存放目录下,执行构建动作。

以下示例,通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)。

:最后的 . 代表本次执行的上下文路径。

$ docker build -t nginx:v3 .

docker总结_docker_06


上下文路径


有提到指令最后一个 . 是上下文路径

docker build -t nginx:v3 .

上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。

解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。

如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。

注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。

指令

docker总结_redis_07

Compose

Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。


docker-compose.yml


version: "3"
services:
web:
image: beginor/geoserver:2.11.1
container_name: geoserver-web
hostname: geoserver-web
ports:
- 8080:8080
volumes:
- ./web/data_dir:/geoserver/data_dir
- ./web/logs:/geoserver/logs
restart: unless-stopped
links:
- database:database
database:
image: beginor/postgis:9.3
container_name: postgis
hostname: postgis
ports:
- 5432:5432
volumes:
- ./database/data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: 1q2w3e4R
restart: unless-stopped

上面的 ​​docker-compose.yml​​ 文件定义了两个服务 web 和 database, 一个服务在运行时对应一个容器的实例, 上面的文件表示要启动两个实例。

在部署时, 通常将 ​​docker-compose.yml​​ 文件放到一个目录, 表示一个应用, docker 会为这个应用创建一个独立的网络, 便于和其它应用进行隔离。

要运行这个程序, 只要在这个目录下执行 ​​docker-compose up -d​​ 命令, 就会按照上面的配置启动两个容器的实例:

$ docker-compose up -d
Creating network "geoserver_default" with the default driver
Creating geoserver_database_1
Creating geoserver_web_1

要停止上面的容器, 只需要输入 ​​docker-compose down​​ 命令:

$ docker-compose down
Stopping geoserver_web_1 ... done
Stopping geoserver_database_1 ... done
Removing geoserver_web_1 ... done
Removing geoserver_database_1 ... done
Removing network geoserver_default

从上面的命令可以看出, docker-compose 不仅可以根据配置文件 ​​docker-compose.yml​​​ 自动创建网络, 启动响应的容器实例, 也可以根据配置文件删除停止和删除容器实例, 并删除对应的网络, 确实是 ​​docker run​​ 命令更加方便, 因此推荐在测试环境或者生产环境中使用。

管理应用程序数据


将数据从宿主机到容器的三种方式



  • volumes:docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)保存数据的最佳方式
  • bind mounts 将宿主机上的任意位置的文件或者目录挂在到容器 (–mount type=bind,src=源目录,dst=目标目录)
  • tmpfs:挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久存储在任何位置,可以使用
    tmpfs,同时避免写入容器可写层提高性能。

管理应用程序示例

docker总结_redis_08