docker 知识点汇总

什么是 Docker

Docker 简介

Docker 核心概念以下:html

  1. Docker 引擎 (Docker Engine)
  2. Docker 客户端 (Docker Client)
  3. Docker 镜像 (Docker Images)
  4. Docker 容器 (Docker Containers)
  5. Docker 镜像注册中心 (Docker Registry)

Docker 的特色

  1. 快速运行java

  2. 节省资源python

    Docker 容器直接运行在 Docker 引擎之上,可直接利用宿主机硬件资源,无需占用过多的系统开销mysql

  3. 便于交付linux

    Docker 的交付物是镜像,镜像不只封装了程序,还包含了运行程序的环境web

  4. 容易管理spring

    经过 Docker 客户端直接操做 Docker 引擎,很是方便的管理 Docker 镜像和容器sql

如何使用 Docker

镜像的经常使用操做

  1. 列出镜像docker

    [root@dev ~]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
    centos              latest              ab9a80ab07d0        2 weeks ago         201.8 MB

    以上表格包含 5 个字段,其中

    • REPOSITORY 镜像仓库的名称
    • TAG 镜像的标签,通常带有版本或别名,这里的 lastest 表示最新版本
    • IMAGE ID 表示镜像的标识符,称为镜像 ID ,具有惟一性
    • created 表示镜像的建立时间
    • SIZE 大小
  2. 拉取镜像 docker pull

  3. 搜索镜像

    执行上面的命令,会输出带有 centos 关键字的镜像仓库。

    [root@dev ~]# docker search centos
    
    NAME                               DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    centos                             The official build of CentOS.                   5070      [OK]
    ansible/centos7-ansible            Ansible on Centos7                              119                  [OK]
    jdeathe/centos-ssh                 CentOS-6 6.10 x86_64 / CentOS-7 7.5.1804 x...   104                  [OK]
    consol/centos-xfce-vnc             Centos container with "headless" VNC sessi...   73                   [OK]
    imagine10255/centos6-lnmp-php56    centos6-lnmp-php56                              48                   [OK]
    centos/mysql-57-centos7            MySQL 5.7 SQL database server                   45
    tutum/centos                       Simple CentOS docker image with SSH access      43
    gluster/gluster-centos             Official GlusterFS Image [ CentOS-7 +  Glu...   38                   [OK]
    openshift/base-centos7             A Centos7 derived base image for Source-To...   37
    centos/postgresql-96-centos7       PostgreSQL is an advanced Object-Relationa...   36
    centos/python-35-centos7           Platform for building and running Python 3...   33
    kinogmt/centos-ssh                 CentOS with SSH                                 25                   [OK]
    openshift/jenkins-2-centos7        A Centos7 based Jenkins v2.x image for use...   20
    centos/php-56-centos7              Platform for building and running PHP 5.6 ...   17
    pivotaldata/centos-gpdb-dev        CentOS image for GPDB development. Tag nam...   10
    openshift/wildfly-101-centos7      A Centos7 based WildFly v10.1 image for us...   6
    openshift/jenkins-1-centos7        DEPRECATED: A Centos7 based Jenkins v1.x i...   4
    darksheer/centos                   Base Centos Image -- Updated hourly             3                    [OK]
    pivotaldata/centos-mingw           Using the mingw toolchain to cross-compile...   2
    pivotaldata/centos                 Base centos, freshened up a little with a ...   2
    blacklabelops/centos               CentOS Base Image! Built and Updates Daily!     1                    [OK]
    pivotaldata/centos-gcc-toolchain   CentOS with a toolchain, but unaffiliated ...   1
    smartentry/centos                  centos with smartentry                          0                    [OK]
    pivotaldata/centos7-build          CentosOS 7 image for GPDB compilation           0
    pivotaldata/centos7-test           CentosOS 7 image for GPDB testing               0

    字段的意义以下

    1. NAME 表示镜像仓库的名称
      1. 不带 / 表示 Docker 官方发布的仓库
      2. 其余仓库表示我的仓库
    2. DESCRIPTION 表示镜像仓库描述
    3. STARS 表示镜像的收藏数,该数字体现该仓库的受欢迎程度
    4. OFFICAL 是否为官方仓库,官方仓库具备更高的安全性
    5. AUTOMATED 是否自动构建镜像仓库,用户能够将本身的 Docker Hub 绑定到 GitHub 或者 BitBucket 上,当代码提交后,能够自动构建镜像仓库
  4. 导出和导入镜像

    [root@dev docker]# docker save centos > centos.tar
    [root@dev docker]# docker load < centos.tar

当获取镜像后,就能基于镜像启动相应的容器。

容器的经常使用操做

  1. 建立并启动容器

    [root@dev docker]# docker run -i -t centos /bin/bash
    • -i 选项: 表示启动容器后,打开标准输入设备 (STDIN) ,可以使用键盘进行输入
    • -t 选项: 表示启动容器后,分配一个伪终端,与服务器奖励一个会话
    • centos 参数: 表示须要运行的镜像名称,标准格式为 centos:latest ,若为 latest 版本,能够省略
    • /bin/bash 参数: 表示运行容器中的 bash 应用程序

    执行该命令后,会首先从本地拉取 centos 镜像,若是本地没有此镜像,就会从 docker hub 上拉取并存放在本地,随后就能根据镜像建立并启动 centos 容器。

    此时能够参考容器的命令提示符:

    [root@5b51855797e3 /]#

    其中

    • root 表示当前登陆的用户名,默认都是以超级管理员身份登陆的
    • 5b51855797e3 表示容器的标识符,通常称为 “容器 ID"
    • / 表示当前路径

    可在 # 符号后输入 Linux 命令,执行 exit 命令退出容器

  2. 列出容器

    [root@dev ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    5b51855797e3        centos              "/bin/bash"         17 minutes ago      Up 17 minutes                           sharp_mccarthy

    结果字段的具体意义以下

    1. CONTAINER ID 表示容器 ID
    2. IMAGE 镜像名称
    3. COMMAND 启动容器时运行的命令,Docker 要求在启动容器时须要运行一个命令
    4. CREATED 容器建立时间
    5. STAUS 表示容器运行的状态
      1. Up 表示运行中
      2. Existed 表示已退出
    6. PORTS 表示容器须要对外暴露的端口号
    7. NAMES 容器的名称

    docker ps 命令包括一些经常使用选项,描述以下

    • -a 列出全部的容器,包含全部的状态
    • -l 表示列出最近建立的容器,包括全部的状态
    • -n 表示列出 n 个 最近建立的容器,包括全部的状态
    • -q 表示仅仅列出 CONTAINER ID 字段
    • -s 表示在输出表格中增长一个 SIZE 字段
  3. 进入容器

    [root@dev ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    c6e7132314fd        centos              "/bin/bash"         2 minutes ago       Up 2 minutes                            happy_colden
    [root@dev ~]# docker attach c6e7132314fd
    [root@c6e7132314fd /]#

    只能进入运行中的数据,不能进入已中止的数据。

  4. 执行命令

    使用如下命令像运行中的容器执行具体的命令

    [root@dev ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    e5fa12acb939        centos              "/bin/bash"         20 seconds ago      Up 19 seconds                           pensive_fermat
    [root@dev ~]# docker exec -i -t e5fa12acb939 ls -l
    total 56
    -rw-r--r--   1 root root 12076 Dec  5 01:37 anaconda-post.log
    lrwxrwxrwx   1 root root     7 Dec  5 01:36 bin -> usr/bin
    drwxr-xr-x   5 root root   380 Dec 26 09:52 dev
    drwxr-xr-x  47 root root  4096 Dec 26 09:52 etc
    drwxr-xr-x   2 root root  4096 Apr 11  2018 home
    lrwxrwxrwx   1 root root     7 Dec  5 01:36 lib -> usr/lib
    lrwxrwxrwx   1 root root     9 Dec  5 01:36 lib64 -> usr/lib64
    drwxr-xr-x   2 root root  4096 Apr 11  2018 media
    drwxr-xr-x   2 root root  4096 Apr 11  2018 mnt
    drwxr-xr-x   2 root root  4096 Apr 11  2018 opt
    dr-xr-xr-x 192 root root     0 Dec 26 09:52 proc
    dr-xr-x---   2 root root  4096 Dec  5 01:37 root
    drwxr-xr-x  11 root root  4096 Dec  5 01:37 run
    lrwxrwxrwx   1 root root     8 Dec  5 01:36 sbin -> usr/sbin
    drwxr-xr-x   2 root root  4096 Apr 11  2018 srv
    drwxr-xr-x  13 root root     0 Dec 26 09:45 sys
    drwxrwxrwt   7 root root  4096 Dec  5 01:37 tmp
    drwxr-xr-x  13 root root  4096 Dec  5 01:36 usr
    drwxr-xr-x  18 root root  4096 Dec  5 01:36 var
  5. 中止容器

    使用下面命令中止运行中的容器(须要指定 ID 或者容器名称):

    docker stop e5fa12acb939

    该命令会想容器发送 SIGTERM 信号,将等待很短的时间,再对容器发送 SIGKILL 信号,会当即终止容器。

  6. 终止容器

    docker kill e5fa12acb939
  7. 启动容器

    能够启动已经中止的容器

    docker start e5fa12acb939
  8. 重启容器

    docker restart e5fa12acb939
  9. 删除容器

    docker rm e5fa12acb939

    不能删除正在运行的容器,只能将它中止后,再删除。

  10. 导入和导出容器

    docker export e5fa12acb939 > centos.tar
    docker import foo.tar reycg/centos:latest

Docker 命令汇总

docker help

手工制做 java 镜像

总体步骤

  1. 容器启动前, 准备一个 JDK 压缩包,并存放在宿主机的 ~/software 目录下
  2. 容器启动时,经过数据卷的方式,将宿主机的 ~/software 目录挂载到容器的 /mnt/software 目录
  3. 容器启动后,先解压 JDK 压缩包,随后建立 JDK 符号连接
  4. 使用 docker commit 命令,提交当前容器为 reycg/java 的镜像
  5. 运行 reycg/java 镜像,启动一个 java 容器,并输出 java 版本号,从而验证镜像是否可用,最后自动删除当前容器

具体命令以下,前 3 个步骤

[root@dev software]# ls
jdk-8u121-linux-x64.tar.gz
[root@architecture01.general.dev.tj1 software]# docker run -i -t -v ~/software/:/mnt/software centos /bin/bash
[root@b3d2064d1a3d /]# ls
anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@b3d2064d1a3d /]# ll /mnt/software/
total 178956
-rw-r--r-- 1 root root 183246769 Dec 26 12:41 jdk-8u121-linux-x64.tar.gz
[root@b3d2064d1a3d /]# tar -zxf /mnt/software/jdk-8u121-linux-x64.tar.gz -C /opt/
[root@b3d2064d1a3d /]# ll /opt/
total 4
drwxr-xr-x 8 10 143 4096 Dec 13  2016 jdk1.8.0_121
[root@b3d2064d1a3d /]# ln -s /opt/jdk1.8.0_121 /opt/jdk
[root@b3d2064d1a3d /]# ll /opt/jdk
lrwxrwxrwx 1 root root 17 Dec 26 12:44 /opt/jdk -> /opt/jdk1.8.0_121
[root@b3d2064d1a3d /]# /opt/jdk/bin/java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

步骤 4, 5

[root@dev software]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
reycg/java          latest              d3c1df69ffb2        13 seconds ago      571.9 MB
centos              latest              ab9a80ab07d0        2 weeks ago         201.8 MB
[root@dev software]# docker run --rm reycg/java /opt/jdk/bin/java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

上面过程是手工完成的,除了这种方式,咱们还能够写一段脚本,让其自动运行一样能够生成镜像,这就是下面讲的 Dockerfile。

使用 Dockerfile 制做镜像

Dockerfile 脚本文件,包括一些指令,经过学习这些指令,能够快速的编写镜像的构建脚本,从而让构建镜像作到自动化。下面先了解下 Docker file 的基本结构。

Dockerfile 的基本结构

  1. 设置基础镜像

    FROM centos:latest

    FROM 指令的值有固定的格式,即“仓库名:标签名”,若使用基础镜像的最新版本,则 latest 签名能够省略,不然须要指定基础镜像的具体版本。

  2. 设置维护者信息

    MAINTAINER "reycg"<reycg2017@163.com>

    MAINTAINER 指令没有固定格式,建议使用姓名与邮箱的格式,能够同时指定多我的

  3. 设置须要添加到容器中的文件

    ADD jdk-8u121-linux-x64.tar.gz /opt

    ADD 指令的第一个参数是宿主机的来源路径(可以使用相对路径),第二个参数是容器的目标路径(必须为绝对路径)。

    ADD 指令还能够自动解压来源路径中的压缩包,将解压后的文件复制到目标路径中。

    除了 ADD 指令,还有一个相似的 COPY 指令,只是它只能完成简单的复制,而没有自动解压的功能。

  4. 设置镜像制做过程当中须要执行的命令

    RUN ln -s /opt/jdk1.8.0_121 /opt/jdk

    使用 RUN 指令能够执行一系列构建镜像所需的命令,若是要执行多条命令,可使用多行 RUN 命令,但最好是经过 \ 换行符合并成一条,这样可以减少所构建的镜像的体积。

  5. 设置容器启动时须要执行的命令

    CMD /opt/jdk/bin/java -version

    若是在使用 docker run 命令时指定了须要执行的命令,会覆盖 Dockerfile CMD 指令。

    在 Dockerfile 还有一个相似的 ENTRYPOINT 指令,只是后者所执行的指令不能被 docker run 覆盖。

了解了 Dockerfile 的基本结果后,后面咱们使用 Dockerfile 构建一个 java 镜像。

使用 Dockerfile 构建镜像

将上一节的 Dockerfile 指令整理一下,获得汇总的文件内容:

FROM centos:latest
MAINTAINER "reycg"<reycg2017@163.com>
ADD jdk-8u121-linux-x64.tar.gz /opt
RUN ln -s /opt/jdk1.8.0_121 /opt/jdk
CMD /opt/jdk/bin/java -version

下面就使用 docker build 命令读取 Dockerfile 文件,并构建一个镜像:

[root@dev software]# docker build -t reycg/java .
Sending build context to Docker daemon 183.2 MB
Sending build context to Docker daemon 
Step 0 : FROM centos:latest
 ---> ab9a80ab07d0
Step 1 : MAINTAINER "reycg"<reycg2017@163.com>
 ---> Running in ae37609d29d2
 ---> 51911673bc4a
Removing intermediate container ae37609d29d2
Step 2 : ADD jdk-8u121-linux-x64.tar.gz /opt
 ---> e4743bdb5bcd
Removing intermediate container 4ef5335f53e0
Step 3 : RUN ln -s /opt/jdk1.8.0_121 /opt/jdk
 ---> Running in 513ba2d0d2ff
 ---> 097586ce97cd
Removing intermediate container 513ba2d0d2ff
Step 4 : CMD /opt/jdk/bin/java -version
 ---> Running in cde9191ea078
 ---> cd4c35cfb8ac
Removing intermediate container cde9191ea078
Successfully built cd4c35cfb8ac

当执行成功后,将输出最终的镜像 ID (d3c1df69ffb2 ),此时可经过 docker images 查看最终生成的镜像

[root@dev software]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
reycg/java          latest              cd4c35cfb8ac        27 minutes ago      571.9 MB
<none>              <none>              d3c1df69ffb2        56 minutes ago      571.9 MB
centos              latest              ab9a80ab07d0        2 weeks ago         201.8 MB

此时可以使用 docker tag 命令来修改镜像的仓库名和标签名。

docker tag d3c1df69ffb2 reycg/java:1.0

此时再查看当前的镜像

[root@dev software]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
reycg/java          latest              cd4c35cfb8ac        33 minutes ago      571.9 MB
reycg/java          1.0                 d3c1df69ffb2        About an hour ago   571.9 MB

安装 jdk 后都须要设置一个 JAVA_HOME 和 PATH 环境变量,这样就能够在命令行中直接使用 Java 命令了。可使用 ENV 指令来完成。

ENV JAVA_HOME /opt/jdk
ENV PATH $JAVA_HOME/bin:$PATH

这样完整的 Dockerfile 指令以下

FROM centos:latest
MAINTAINER "reycg"<reycg2017@163.com>
ADD jdk-8u121-linux-x64.tar.gz /opt
RUN ln -s /opt/jdk1.8.0_121 /opt/jdk
ENV JAVA_HOME /opt/jdk
ENV PATH $JAVA_HOME/bin:$PATH
CMD java -version

与 Spring Boot 整合

在微服务架构中,交付方式由应用程序转变为 Docker 镜像,将服务及其运行环境封装在 Docker 镜像中。若须要发布服务时,只须要根据镜像启动相应的容器便可。

搭建 Spring Boot 应用程序框架

标准的 Spring Boot 应用程序的 Maven 配置以下

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>demo.msa</groupId>
  <artifactId>mesa-hello</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mesa-hello</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  
  <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>1.3.3.RELEASE</version>
  </parent>

  <dependencies>
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  
  <build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
  </build>
</project>

因为使用了 spring-boot-maven-plugin 插件,在 mvn package 打包后将生成一个直接运行的 jar 包,生成的 jar 包默认文件名格式为 ${project.build.finalName} ,它是一个 maven 属性,至关于 ${project.artifactId}:${project.version}.

添加 Dockerfile

咱们的应用是基于 Maven 构建的,Maven 规范要求咱们将全部的资源放在 src/main/resources 资源目录下。 Dockerfile 也是资源文件,所以也须要放在该目录下。完整的文件内容以下:

FROM java
MAINTAINER "ReyCG"<reycg2017@163.com>
ADD mesa-hello-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
CMD java -jar app.jar

默认状况下, Spring Boot 开启的是 8080 端口,所以使用 ExPOSE 指令暴露出来。

最后使用 java -jar app.jar 执行 jar 包。

使用 Maven 构建 Docker 镜像

Dockerfile 建立成功了,下一步就是读取 Dockerfile,并构建 Docker 镜像。而这些则是由 spotfy 公司的 docker-maven-plugin 插件来完成的。具体 maven 配置以下:

<plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>0.4.10</version>
            <configuration>
                <imageName>${project.groupId}/${project.artifactId}:${project.version}</imageName>
                <dockerDirectory>${project.build.outputDirectory}</dockerDirectory>
                <resources>
                    <resource>
                        <directory>${project.build.directory}</directory>
                        <include>${project.build.finalName}.jar</include>
                    </resource>
                </resources>
            </configuration>
        </plugin>

下面来解释下 configuration 片断

  • imageName Docker 镜像名称,它由 ${project.groupId} 仓库名,${project.artifactId} 镜像名和 ${project.version} 标签名组成
  • dockerDirectory 指定 Dockerfile 文件所在的目录
  • resources/resource/directory 指定须要复制的根目录,其中 ${project.build.directory} 则表示 target 目录
  • resources/resource/directory 指定须要复制的文件

执行 mvn docker:build 便可编译镜像。编译成功后,查看一下

[tomcat@ root]$ docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
demo.msa/mesa-hello   0.0.1-SNAPSHOT      67b94db5ac60        About an hour ago   657 MB

启动 Spring Boot 的 Docker 容器

在后台运行容器,并将容器的 8080 端口绑定到宿主机 58080 端口上。

docker run -d -p 58080:8080 demo.msa/mesa-hello:0.0.1-SNAPSHOT

经过浏览器访问 localhost:8080 请求来验证下。

调整 Docker 内存限制

可使用以下 Docker 命令监控 Docker 容器的运行状况

[tomcat@ root]$ docker ps
CONTAINER ID        IMAGE                                COMMAND                CREATED             STATUS              PORTS                     NAMES
eb8659f31ca3        demo.msa/mesa-hello:0.0.1-SNAPSHOT   "/bin/sh -c 'java -j   37 minutes ago      Up 37 minutes       0.0.0.0:58080->8080/tcp   sharp_hodgkin       
[tomcat@ root]$ docker stats eb8659f31ca3
CONTAINER           CPU %               MEM USAGE/LIMIT     MEM %               NET I/O
eb8659f31ca3        0.10%               540.2 MB/8.128 GB   6.65%               5.024 kB/7.208 kB

由此命令能够看出容器的 CPU 使用率,内存使用状况与使用率,网络 IO 使用状况等信息。

从内存使用状况来看,启动容器后默认分配了 8.128 GB 的内存,其中已经使用了 540.2 MB。由此咱们能够估算出容器应用程序的最大内存,对启动容器所需分配的内存作出限制,能够节省更多的宿主机内容。从而能够启动更多的容器。

docker run 命令中添加 -m 参数就能够调整容器的内存限制。

[tomcat@ root]$ docker run -d -m 800m -p 58080:8081 demo.msa/mesa-hello:0.0.1-SNAPSHOT 
40c7c49d0002c08c72034d97bb39d0b415df7a7eef0bfa959853649c88c8e77c
[tomcat@ root]$ docker ps 
CONTAINER ID        IMAGE                                COMMAND                CREATED             STATUS              PORTS                     NAMES
40c7c49d0002        demo.msa/mesa-hello:0.0.1-SNAPSHOT   "/bin/sh -c 'java -j   4 seconds ago       Up 3 seconds        0.0.0.0:58080->8081/tcp   dreamy_mcclintock   
[tomcat@root]$ docker stats 40c7c49d0002
CONTAINER           CPU %               MEM USAGE/LIMIT     MEM %               NET I/O
40c7c49d0002        105.87%             531.8 MB/838.9 MB   63.39%              468 B/558 B

问题记录

  1. centos 6 如何安装 docker

    https://www.liquidweb.com/kb/how-to-install-docker-on-centos-6/

  2. docker 不能链接问题

    Get http:///var/run/docker.sock/v1.19/images/json: dial unix /var/run/docker.sock: no such file or directory. Are you trying to connect to a TLS-enabled daemon without TLS?

    解决方案 http://www.cnblogs.com/ashinliu/p/5477259.html

    http://tinylab.org/use-docker-without-sudo/

参考

  1. 《架构探险—轻量级微服务架构》
  2. https://www.liquidweb.com/kb/how-to-install-docker-on-centos-6/
  3. http://www.cnblogs.com/ashinliu/p/5477259.html
相关文章
相关标签/搜索