安装

下载

前提条件

  • Docker支持以下的CentOS版本:
    • 目前,CentOS 仅发行版本中的内核支持 Docker。
    • Docker 运行在 CentOS 7 上,要求系统为64位、系统内核版本为 3.10 以上。
    • Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系统为64位、系统内核版本为 2.6.32-431 或者更高版本。

查看内核

  • uname命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)。

    1
    2
    3
    4
    5
    6
    7
    [sun@zy01 ~]$ uname -r
    3.10.0-957.21.3.el7.x86_64

    [sun@zy01 ~]$ cat /etc/redhat-release
    CentOS Linux release 7.6.1810 (Core)

    [sun@zy01 ~]$ lsb_release -a(CentOS6.8有,CentOS7无该命令)
  • 查看已安装的CentOS版本信息



安装Docker

  1. 官网中文安装参考手册,英文参考:https://docs.docker.com/engine/install/centos/

  2. 确定你是CentOS7及以上版本

    cat /etc/redhat-release

  3. yum安装gcc相关

    sudo yum -y install gcc gcc-c++

  4. 卸载旧版本

    1
    2
    3
    4
    5
    6
    7
    8
    sudo yum remove docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine
  5. 安装需要的软件包

    sudo yum install -y yum-utils device-mapper-persistent-data lvm2

  6. 设置stable镜像仓库,大坑:

    1
    2
    3
    yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    # 推荐使用国内源:
    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  7. 更新yum软件包索引

    yum makecache fast

  8. 安装DOCKER CE

    yum -y install docker-ce

  9. 启动docker

    systemctl start docker

    systemctl enable docker

  10. 测试

    docker version

    docker run hello-world

  11. 配置镜像加速

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    1. mkdir -p /etc/docker

    2. vim /etc/docker/daemon.json

    #网易云
    {
    "registry-mirrors": ["http://hub-mirror.c.163.com"]
    }



    #阿里云
    {
    "registry-mirrors": ["https://{自已的编码}.mirror.aliyuncs.com"]
    }


    3. systemctl daemon-reload

    4.systemctl restart docker

卸载

  1. systemctl stop docker
  2. yum -y remove docker-ce
  3. rm -rf /var/lib/docker

Docker的基本组成

  • Docker 本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就似乎 image镜像文件。只有通过这个镜像文件才能生成 Docker 容器。

  • image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。image 文件生成的容器实例,本身也是一个文件,称为镜像文件。

  • 一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一个对应的运行实例,也就是我们的容器

  • 至于仓储,就是放了一堆镜像的地方,我们可以把镜像发布到仓储中,需要的时候从仓储中拉下来就可以了。

镜像(image)

  • Docker 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。类似Java中的类。

容器(container)

  • Docker 利用容器(Container)独立运行的一个或一组应用。容器是用镜像创建的运行实例。类似Java中类的实例化。

  • 它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。

  • 可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

  • 容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。

仓库(repository)

hello World

  • 启动Docker后台容器(测试运行 hello-world),输出下面这段提示以后,hello world就会停止运行,容器自动终止。docker run后做了什么?

  • run命令执行后的操作

底层原理

Docker如何工作

  • Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上, 然后通过Socket连接从客户端访问
  • 守护进程从客户端接受命令并管理运行在主机上的容器。
  • 容器,是一个运行时环境,就是我们前面说到的集装箱。

Docker与VM

  1. docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。

  2. docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。进而避免引寻、加载操作系统内核返个比较费时费资源的过程,因此新建一个docker容器只需要几秒钟

  3. 当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返个过程。

Docker容器 虚拟机(VM)
操作系统 与宿主机共享OS 宿主机OS上运行虚拟机OS
存储大小 镜像小,便于存储和传输 镜像庞大(vmdk,vdi等)
运行性能 几乎无额外性能损失 操作系统额外的CPU,内存消耗
移植性 轻便,灵活,适应于Linux 笨重,与虚拟化技术耦合度高
硬件亲和度 面向软件运维者 面向硬件运维者
部署速度 快速,秒级 较慢,10以上

常用命令

帮助命令

  1. docker version
  2. docker info
  3. docker --help

镜像命令

  1. docker images列出本地主机上的镜像

    • 显示说明:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      REPOSITORY:表示镜像的仓库源
      TAG:镜像的标签
      IMAGE ID:镜像ID
      CREATED:镜像创建时间
      SIZE:镜像大小

      同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。

      如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,
      docker 将默认使用 ubuntu:latest 镜像
    • OPTIONS说明:

      1
      2
      3
      4
      -a :列出本地所有的镜像(含中间映像层)
      -q :只显示镜像ID。
      --digests :显示镜像的摘要信息
      --no-trunc :显示完整的镜像信息
  2. docker search 某个XXX镜像名字

    • 从网站:https://hub.docker.com 上查找

    • 命令: docker search [OPTIONS] 镜像名字

    • OPTIONS说明

      1
      2
      3
      --no-trunc : 显示完整的镜像描述
      -s : 列出收藏数不小于指定值的镜像。
      --automated : 只列出 automated build类型的镜像;
  3. docker pull 某个XXX镜像名字下载镜像

    • docker pull 镜像名字[:TAG]
  4. docker rmi 某个XXX镜像名字ID删除镜像

  • 删除单个: docker rmi -f 镜像ID

  • 删除多个: docker rmi -f 镜像名1:TAG 镜像名2:TAG

  • 删除全部:docker rmi -f $(docker images -qa)

容器命令

  • 有镜像才能创建容器,这是根本前提(下载一个CentOS镜像演示docker pull centos)

新建并启动容器

  • docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

    • OPTIONS说明(常用):有些是一个减号,有些是两个减号

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      --name="容器新名字": 为容器指定一个名称;
      -d: 后台运行容器,并返回容器ID,也即启动守护式容器;

      -i:以交互模式运行容器,通常与 -t 同时使用;
      -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;

      -P(大写): 随机端口映射;
      -p: 指定端口映射,有以下四种格式

      ip:hostPort:containerPort
      ip::containerPort
      hostPort:containerPort
      containerPort
  • 启动交互式容器docker run -it centos /bin/bash

    • 默认使用镜像centos:latest,-it 以交互模式启动一个容器,在容器内执行/bin/bash命令。

列出运行的容器

  • docker ps [OPTIONS]

    • OPTIONS说明(常用):

      1
      2
      3
      4
      5
      -a :列出当前所有正在运行的容器+历史上运行过的
      -l :显示最近创建的容器。
      -n:显示最近n个创建的容器。
      -q :静默模式,只显示容器编号。
      --no-trunc :不截断输出。

退出容器

  • 两种退出方式
    1. exit,容器停止退出
    2. ctrl+P+Q容器不停止退出

启动容器

  • docker start 容器ID或者容器名

重启容器

  • docker restart 容器ID或者容器名

停止容器

  • docker stop 容器ID或者容器名

强制停止容器

  • docker kill 容器ID或者容器名

删除已停止的容器

  • docker rm 容器ID

  • 一次性删除多个容器

    • docker rm -f $(docker ps -a -q)
    • docker ps -a -q | xargs docker rm

重要容器命令

启动守护式容器

  • docker run -d 容器名

  • 启动一个centos容器

    1
    2
    #使用镜像centos:latest以后台模式启动一个容器
    docker run -d centos
  • 问题:然后docker ps -a 进行查看, 会发现容器已经退出

    • 说明很重要的一点: Docker容器后台运行,就必须有一个前台进程.
    • 容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。
    • 这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,我们配置启动服务只需要启动响应的service即可。
    • 例如service nginx start, 但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用, 最佳的解决方案是将你要运行的程序以前台进程的形式运行
  • 添加前台进程

    1
    docker run -d centos /bin/sh -c "while true;do echo hello zzyy;sleep 2;done"

查看容器日志

  • docker logs -f -t --tail 容器ID

    • -t 是加入时间戳
    • -f 跟随最新的日志打印
    • --tail 数字 显示最后多少条
  • 示例

    1
    docker logs -f -t --tail 10 44ca9

查看容器内运行的进程

  • docker top 容器ID

查看容器内部细节

  • docker inspect 容器ID

交互式进入运行的容器

  1. docker exec -it 容器ID bashShell

  2. 重新进入docker attach 容器ID

  • 上述两个区别:
    • attach 直接进入容器启动命令的终端,不会启动新的进程
    • exec 是在容器中打开新的终端,并且可以启动新的进程

容器内拷贝文件到主机上

  • docker cp 容器ID:容器内路径 目的主机路径

    1
    docker cp fsfa58c8c141:/usr/local/mycp/test.txt /tmp/a.txt

常用命令总结

命令 备注 说明
attach Attach to a running container 当前 shell 下 attach 连接指定运行镜像
build Build an image from a Dockerfile 通过 Dockerfile 定制镜像
commit Create a new image from a container changes 提交当前容器为新的镜像
cp Copy files/folders from the containers filesystem to the host path 从容器中拷贝指定文件或者目录到宿主机中
create Create a new container 创建一个新的容器,同 run,但不启动容器
diff Inspect changes on a container’s filesystem 查看 docker 容器变化
events Get real time events from the server 从 docker 服务获取容器实时事件
exec Run a command in an existing container 在已存在的容器上运行命令
export Stream the contents of a container as a tar archive 导出容器的内容流作为一个 tar 归档文件[对应 import ]
history Show the history of an image 展示一个镜像形成历史
images List images 列出系统当前镜像
import Create a new filesystem image from the contents of a tarball 从tar包中的内容创建一个新的文件系统映像[对应export]
info Display system-wide information 显示系统相关信息
inspect Return low-level information on a container 查看容器详细信息
kill Kill a running container kill 指定 docker 容器
load Load an image from a tar archive 从一个 tar 包中加载一个镜像[对应 save]
login Register or Login to the docker registry server 注册或者登陆一个 docker 源服务器
logout Log out from a Docker registry server 从当前 Docker registry 退出
logs Fetch the logs of a container 输出当前容器日志信息
port Lookup the public-facing port which is NAT-ed to PRIVATE_PORT 查看映射端口对应的容器内部源端口
pause Pause all processes within a container 暂停容器
p List containers 列出容器列表
pull Pull an image or a repository from the docker registry server 从docker镜像源服务器拉取指定镜像或者库镜像
push Push an image or a repository to the docker registry server 推送指定镜像或者库镜像至docker源服务器
restart Restart a running container 重启运行的容器
rm Remove one or more containers 移除一个或者多个容器
rmi Remove one or more images 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除]
run Run a command in a new container 创建一个新的容器并运行一个命令
save Save an image to a tar archive 保存一个镜像为一个 tar 包[对应 load]
search Search for an image on the Docker Hub 在 docker hub 中搜索镜像
start Start a stopped containers 启动容器
stop Stop a running containers 停止容器
tag Tag an image into a repository 给源中镜像打标签
top Lookup the running processes of a container 查看容器中运行的进程信息
unpause Unpause a paused container 取消暂停容器
version Show the docker version information 查看 docker 版本号
wait Block until a container stops, then print its exit code 截取容器停止时的退出状态值
  • 图例

Docker数据管理

  • 先来看看Docker的理念:

    1. 将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的
    2. 容器之间希望有可能共享数据
  • Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。为了能保存数据在docker中我们使用卷,提出了数据卷容器。

  • 容器数据卷

    • 容器的持久化

    • 容器间继承+共享数据

    • 卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:

      1. 数据卷可在容器之间共享或重用数据

      2. 卷中的更改可以直接生效

      3. 数据卷中的更改不会包含在镜像的更新中

      4. 数据卷的生命周期一直持续到没有容器使用它为止

    • 卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷

数据卷

容器内添加

  • 直接命令添加,命令:

    1
    docker run -it -v /宿主机目录:/容器内目录 centos /bin/bash
  • (带权限的命令:)

    1
    docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
  • 查看数据卷是否挂载成功

    • docker inspect 容器ID

权限问题

  • Docker挂载主机目录Docker访问出现cannot open directory .: Permission denied

  • 解决办法:在挂载目录后多加一个--privileged=true参数即可

  • 例如:docker run -t -i --privileged centos:latest bash

DockerFile添加

  1. 根目录下新建mydocker文件夹并进入

  2. 可在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷

    1. 出于可移植和分享的考虑,用 -v 主机目录:容器目录 这种方法不能够直接在Dockerfile中实现。
    2. 由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。
    1
    VOLUME ["/dataVolumeContainer","/dataVolumeContainer2"]
  3. 编写DockerFile文件

    1
    2
    3
    FROM centos
    VOLUME ["/dataVolumeContainer","/dataVolumeContainer2"]
    CMD /bin/bash
  4. build后生成镜像,镜像名为980c9

    1
    docker build -f /mydocker/dockerfile -t zzyy/centos .
  5. run容器

    • 运行后,查看容器内部回出现dataVolumeContainer 的文件夹
    1
    docker run -it 980c9 /bin/bash
  6. 容器内的卷对应的主机目录地址

    • docker inspect 容器ID,可以查看对应默认地址

数据卷容器

  • 命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。

  • 简单说: 活动硬盘挂活动硬盘,实现数据的传递依赖

  • 班长的活动硬盘放到老师电脑,学习委员将活动硬盘放到班长那里 (一条绳上的蚂蚱)

  • 以上一步新建的镜像zzyy/centos为模板并运行容器dc01/dc02/dc03

    • 它们已经具有容器卷/dataVolumeContainer1, /dataVolumeContainer2

–volumes-from

  1. 先启动一个父容器dc01,在dataVolumeContainer2新增内容

  2. dc02/dc03继承(--volumes-from)自dc01

    • docker run -it --name dc02 --volumes-from dc01 zzyy/centos

  3. 回到dc01可以看到02/03各自添加的都能共享了

  4. 删除dc01,dc02修改后dc03可否访问

  5. 删除dc02后dc03可否访问

  6. 新建dc04继承dc03后再删除dc03,

结论

  • 容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止
  • 只要还有一个都可以全量备份

DockerFile

基础知识

  1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数

  2. 指令按照从上到下,顺序执行

  3. #表示注释

  4. 每条指令都会创建一个新的镜像层,并对镜像进行提交

  • 构建过程解析

大致执行流程

  1. docker从基础镜像运行一个容器
  2. 执行一条指令并对容器作出修改
  3. 执行类似docker commit的操作提交一个新的镜像层
  4. docker再基于刚提交的镜像运行一个新容器
  5. 执行dockerfile中的下一条指令直到所有指令都执行完成

DockerFile指令

保留字 说明
FROM 基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER 镜像维护者的姓名和邮箱地址
RUN 容器构建时需要运行的命令
EXPOSE 当前容器对外暴露出的端口
WORKDIR 指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点
ENV 用来在构建镜像过程中设置环境变量
ENV MY_PATH /usr/mytest,这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量,比如:WORKDIR $MY_PATH
ADD 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
COPY 类似ADD,拷贝文件和目录到镜像中(不会自解压)。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置COPY [“src”, “dest”]
VOLUME 容器数据卷,用于数据保存和持久化工作
CMD 指定一个容器启动时要运行的命令
Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
ENTRYPOINT 指定一个容器启动时要运行的命令,ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数
ONBUILD 当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发

自定义centos镜像

  • Hub默认CentOS镜像

    • 初始化的运行环境进入时默认路径为 /
    • 不支持vim
    • 不支持ifconfig
  • 编写DockerFile文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #继承自哪个镜像
    FROM centos
    #作者和邮箱
    MAINTAINER fulsun<fulsun@163.com>
    #自定义环境变量
    ENV mypath /usr/local
    #登录容器后的落脚点
    WORKDIR $mypath
    #登录容器后执行的安装命令
    RUN yum -y install vim
    RUN yum -y install net-tools
    #向外暴露的端口
    EXPOSE 80
    #容器运行后执行的命令
    CMD /bin/bash
  • 构建docker build -t 新镜像名字:TAG .

    • docker build 命令最后的. 表示当前目录
  • 运行docker run -it 新镜像名字:TAG

    • 可以看到,我们自己的新镜像已经支持vim/ifconfig命令,扩展成功了。

CMD/ENTRYPOINT

  • 都是指定一个容器启动时要运行的命令

  • Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换

    1
    2
    3
    4
    5
    6
    # tomcat 镜像最后的是
    CMD ["catalina.sh", "run"]
    # 启动tomcat 的命令,会打出日志
    docker run -it -p 7777:8080 tomcat
    # 在启动命令后添加ls -l后,则会打印落脚点下的目录
    docker run -it -p 7777:8080 tomcat ls -l
  • docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合(追加)